From c730a5d026ac741cafe110d62bfd9f2cc406b80f Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 30 Jun 2016 11:50:13 +0200 Subject: [PATCH 001/144] src: move ParseArrayIndex() to src/node_buffer.cc It's not used anywhere else so move it out of src/node_internals.h. PR-URL: https://github.com/nodejs/node/pull/7497 Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Conflicts: src/node_internals.h --- src/node_buffer.cc | 19 +++++++++++++++++++ src/node_internals.h | 18 ------------------ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index eabe1b9865ee48..f0de2872b024f4 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -193,6 +193,25 @@ void CallbackInfo::WeakCallback(Isolate* isolate) { } +// Parse index for external array data. +inline MUST_USE_RESULT bool ParseArrayIndex(Local arg, + size_t def, + size_t* ret) { + if (arg->IsUndefined()) { + *ret = def; + return true; + } + + int64_t tmp_i = arg->IntegerValue(); + + if (tmp_i < 0) + return false; + + *ret = static_cast(tmp_i); + return true; +} + + // Buffer methods bool HasInstance(Local val) { diff --git a/src/node_internals.h b/src/node_internals.h index d9c2baa7cd67d7..24ea9534bf1e08 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -176,24 +176,6 @@ inline bool IsBigEndian() { return GetEndianness() == kBigEndian; } -// parse index for external array data -inline MUST_USE_RESULT bool ParseArrayIndex(v8::Local arg, - size_t def, - size_t* ret) { - if (arg->IsUndefined()) { - *ret = def; - return true; - } - - int64_t tmp_i = arg->IntegerValue(); - - if (tmp_i < 0) - return false; - - *ret = static_cast(tmp_i); - return true; -} - void ThrowError(v8::Isolate* isolate, const char* errmsg); void ThrowTypeError(v8::Isolate* isolate, const char* errmsg); void ThrowRangeError(v8::Isolate* isolate, const char* errmsg); From f3e5b396967f70971f2738fca98d174c1ba071ba Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 30 Jun 2016 11:51:17 +0200 Subject: [PATCH 002/144] src: guard against overflow in ParseArrayIndex() ParseArrayIndex() would wrap around large (>=2^32) index values on platforms where sizeof(int64_t) > sizeof(size_t). Ensure that the return value fits in a size_t. PR-URL: https://github.com/nodejs/node/pull/7497 Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- src/node_buffer.cc | 5 +++++ test/parallel/test-buffer-alloc.js | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index f0de2872b024f4..ffc11cd9893edc 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -207,6 +207,11 @@ inline MUST_USE_RESULT bool ParseArrayIndex(Local arg, if (tmp_i < 0) return false; + // Check that the result fits in a size_t. + const uint64_t kSizeMax = static_cast(static_cast(-1)); + if (static_cast(tmp_i) > kSizeMax) + return false; + *ret = static_cast(tmp_i); return true; } diff --git a/test/parallel/test-buffer-alloc.js b/test/parallel/test-buffer-alloc.js index d76d9216649ea4..76a34319c17278 100644 --- a/test/parallel/test-buffer-alloc.js +++ b/test/parallel/test-buffer-alloc.js @@ -1454,6 +1454,13 @@ assert.throws(function() { Buffer.from(new ArrayBuffer(0), -1 >>> 0); }, /RangeError: 'offset' is out of bounds/); +// ParseArrayIndex() should reject values that don't fit in a 32 bits size_t. +assert.throws(() => { + const a = Buffer(1).fill(0); + const b = Buffer(1).fill(0); + a.copy(b, 0, 0x100000000, 0x100000001); +}), /out of range index/; + // Unpooled buffer (replaces SlowBuffer) const ubuf = Buffer.allocUnsafeSlow(10); assert(ubuf); From c967af8c0789d3acd116663a86f85504fe531920 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Thu, 7 Jul 2016 11:18:32 -0400 Subject: [PATCH 003/144] src: suppress coverity message Coverity marked a change in 630096b as a constant expression. However, on platforms where sizeof(int64_t) > sizeof(size_t), this should not be the case. This commit flags the comparison as OK to coverity. PR-URL: https://github.com/nodejs/node/pull/7587 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Michael Dawson --- src/node_buffer.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index ffc11cd9893edc..fa45d28b8fa171 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -209,6 +209,7 @@ inline MUST_USE_RESULT bool ParseArrayIndex(Local arg, // Check that the result fits in a size_t. const uint64_t kSizeMax = static_cast(static_cast(-1)); + // coverity[pointless_expression] if (static_cast(tmp_i) > kSizeMax) return false; From b3164ae22efc547d7f619f27185228118dcfb191 Mon Sep 17 00:00:00 2001 From: Diosney Sarmiento Date: Sun, 3 Jul 2016 18:29:34 -0400 Subject: [PATCH 004/144] repl: add support for custom completions Allow user code to override the default `complete()` function from `readline.Interface`. See: https://nodejs.org/api/readline.html#readline_use_of_the_completer_function Ref: https://github.com/nodejs/node-v0.x-archive/pull/8484 PR-URL: https://github.com/nodejs/node/pull/7527 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Lance Ball --- doc/api/repl.md | 3 ++ lib/repl.js | 17 ++++--- test/parallel/test-repl-tab-complete.js | 67 ++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 7 deletions(-) diff --git a/doc/api/repl.md b/doc/api/repl.md index 56efa5df5d79aa..636f38d706b884 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -382,6 +382,8 @@ added: v0.1.91 `undefined`. Defaults to `false`. * `writer` {Function} The function to invoke to format the output of each command before writing to `output`. Defaults to [`util.inspect()`][]. + * `completer` {Function} An optional function used for custom Tab auto + completion. See [`readline.InterfaceCompleter`][] for an example. * `replMode` - A flag that specifies whether the default evaluator executes all JavaScript commands in strict mode, default mode, or a hybrid mode ("magic" mode.) Acceptable values are: @@ -526,3 +528,4 @@ see: https://gist.github.com/2053342 [`util.inspect()`]: util.html#util_util_inspect_object_options [here]: util.html#util_custom_inspect_function_on_objects [`readline.Interface`]: readline.html#readline_class_interface +[`readline.InterfaceCompleter`]: readline.html#readline_use_of_the_completer_function diff --git a/lib/repl.js b/lib/repl.js index 9260776032a901..6cfffe03d09e2e 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -386,14 +386,15 @@ function REPLServer(prompt, self.bufferedCommand = ''; self.lines.level = []; - function complete(text, callback) { - self.complete(text, callback); - } + // Figure out which "complete" function to use. + self.completer = (typeof options.completer === 'function') + ? options.completer + : complete; Interface.call(this, { input: self.inputStream, output: self.outputStream, - completer: complete, + completer: self.completer, terminal: options.terminal, historySize: options.historySize, prompt @@ -706,6 +707,10 @@ function filteredOwnPropertyNames(obj) { return Object.getOwnPropertyNames(obj).filter(intFilter); } +REPLServer.prototype.complete = function() { + this.completer.apply(this, arguments); +}; + // Provide a list of completions for the given leading text. This is // given to the readline interface for handling tab completion. // @@ -716,7 +721,7 @@ function filteredOwnPropertyNames(obj) { // // Warning: This eval's code like "foo.bar.baz", so it will run property // getter code. -REPLServer.prototype.complete = function(line, callback) { +function complete(line, callback) { // There may be local variables to evaluate, try a nested REPL if (this.bufferedCommand !== undefined && this.bufferedCommand.length) { // Get a new array of inputed lines @@ -975,7 +980,7 @@ REPLServer.prototype.complete = function(line, callback) { callback(null, [completions || [], completeOn]); } -}; +} /** diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 3d32d8e0ce0019..73a3fd148bf524 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -32,7 +32,7 @@ testMe.complete('console.lo', common.mustCall(function(error, data) { assert.deepStrictEqual(data, [['console.log'], 'console.lo']); })); -// Tab Complete will return globaly scoped variables +// Tab Complete will return globally scoped variables putIn.run(['};']); testMe.complete('inner.o', common.mustCall(function(error, data) { assert.deepStrictEqual(data, works); @@ -283,3 +283,68 @@ if (typeof Intl === 'object') { testNonGlobal.complete('I', common.mustCall((error, data) => { assert.deepStrictEqual(data, builtins); })); + +// To test custom completer function. +// Sync mode. +const customCompletions = 'aaa aa1 aa2 bbb bb1 bb2 bb3 ccc ddd eee'.split(' '); +const testCustomCompleterSyncMode = repl.start({ + prompt: '', + input: putIn, + output: putIn, + completer: function completerSyncMode(line) { + const hits = customCompletions.filter((c) => { + return c.indexOf(line) === 0; + }); + // Show all completions if none found. + return [hits.length ? hits : customCompletions, line]; + } +}); + +// On empty line should output all the custom completions +// without complete anything. +testCustomCompleterSyncMode.complete('', common.mustCall((error, data) => { + assert.deepStrictEqual(data, [ + customCompletions, + '' + ]); +})); + +// On `a` should output `aaa aa1 aa2` and complete until `aa`. +testCustomCompleterSyncMode.complete('a', common.mustCall((error, data) => { + assert.deepStrictEqual(data, [ + 'aaa aa1 aa2'.split(' '), + 'a' + ]); +})); + +// To test custom completer function. +// Async mode. +const testCustomCompleterAsyncMode = repl.start({ + prompt: '', + input: putIn, + output: putIn, + completer: function completerAsyncMode(line, callback) { + const hits = customCompletions.filter((c) => { + return c.indexOf(line) === 0; + }); + // Show all completions if none found. + callback(null, [hits.length ? hits : customCompletions, line]); + } +}); + +// On empty line should output all the custom completions +// without complete anything. +testCustomCompleterAsyncMode.complete('', common.mustCall((error, data) => { + assert.deepStrictEqual(data, [ + customCompletions, + '' + ]); +})); + +// On `a` should output `aaa aa1 aa2` and complete until `aa`. +testCustomCompleterAsyncMode.complete('a', common.mustCall((error, data) => { + assert.deepStrictEqual(data, [ + 'aaa aa1 aa2'.split(' '), + 'a' + ]); +})); From 98f51ffeb6bcf79f896aa4ee100ea25866f20f01 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 30 Jun 2016 03:41:28 -0400 Subject: [PATCH 005/144] buffer: fix unintended unsigned overflow `offset` is user supplied variable and may be bigger than `ts_obj_length`. There is no need to subtract them and pass along, so just throw when the subtraction result would overflow. PR-URL: https://github.com/nodejs/node/pull/7494 Reviewed-By: Ben Noordhuis --- src/node_buffer.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index fa45d28b8fa171..eda51cac2086b3 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -718,6 +718,9 @@ void StringWrite(const FunctionCallbackInfo& args) { size_t max_length; CHECK_NOT_OOB(ParseArrayIndex(args[1], 0, &offset)); + if (offset >= ts_obj_length) + return env->ThrowRangeError("Offset is out of bounds"); + CHECK_NOT_OOB(ParseArrayIndex(args[2], ts_obj_length - offset, &max_length)); max_length = MIN(ts_obj_length - offset, max_length); @@ -725,9 +728,6 @@ void StringWrite(const FunctionCallbackInfo& args) { if (max_length == 0) return args.GetReturnValue().Set(0); - if (offset >= ts_obj_length) - return env->ThrowRangeError("Offset is out of bounds"); - uint32_t written = StringBytes::Write(env->isolate(), ts_obj_data + offset, max_length, From 5f3ab3ffd198ebf97a6a4891bbf90458c16df522 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 30 Jun 2016 03:42:54 -0400 Subject: [PATCH 006/144] crypto: fix undefined behavior in ParseExtension Many extensions are unknown to the `ClientHelloParser::ParseExtension`, do not cast user-supplied `uint16_t` to `enum`. PR-URL: https://github.com/nodejs/node/pull/7494 Reviewed-By: Ben Noordhuis --- src/node_crypto_clienthello.cc | 4 ++-- src/node_crypto_clienthello.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/node_crypto_clienthello.cc b/src/node_crypto_clienthello.cc index 8fbc3161f89969..8c862c1b6a5198 100644 --- a/src/node_crypto_clienthello.cc +++ b/src/node_crypto_clienthello.cc @@ -103,7 +103,7 @@ void ClientHelloParser::ParseHeader(const uint8_t* data, size_t avail) { } -void ClientHelloParser::ParseExtension(ClientHelloParser::ExtensionType type, +void ClientHelloParser::ParseExtension(const uint16_t type, const uint8_t* data, size_t len) { // NOTE: In case of anything we're just returning back, ignoring the problem. @@ -210,7 +210,7 @@ bool ClientHelloParser::ParseTLSClientHello(const uint8_t* data, size_t avail) { if (ext_off + ext_len > avail) return false; - ParseExtension(static_cast(ext_type), + ParseExtension(ext_type, data + ext_off, ext_len); diff --git a/src/node_crypto_clienthello.h b/src/node_crypto_clienthello.h index b0b63fb2e38138..3550807c20d05f 100644 --- a/src/node_crypto_clienthello.h +++ b/src/node_crypto_clienthello.h @@ -91,7 +91,7 @@ class ClientHelloParser { bool ParseRecordHeader(const uint8_t* data, size_t avail); void ParseHeader(const uint8_t* data, size_t avail); - void ParseExtension(ExtensionType type, + void ParseExtension(const uint16_t type, const uint8_t* data, size_t len); bool ParseTLSClientHello(const uint8_t* data, size_t avail); From e56db1477c1bb4a9a8e5c07aa66bf28970e4a24e Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Thu, 7 Jul 2016 20:14:51 -0700 Subject: [PATCH 007/144] test: fix flaky test-*-connect-address-family Skip tests if localhost does not resolve to ::1. Fixes: https://github.com/nodejs/node/issues/7288 PR-URL: https://github.com/nodejs/node/pull/7605 Reviewed-By: Rod Vagg Reviewed-By: Ben Noordhuis Reviewed-By: Sakthipriyan Vairamani Conflicts: test/parallel/test-https-connect-address-family.js test/parallel/test-tls-connect-address-family.js --- .../test-https-connect-address-family.js | 54 ++++++++++++------- .../test-tls-connect-address-family.js | 52 ++++++++++++------ 2 files changed, 71 insertions(+), 35 deletions(-) diff --git a/test/parallel/test-https-connect-address-family.js b/test/parallel/test-https-connect-address-family.js index b2f3c233cfd720..21d0bf8dc6a1a2 100644 --- a/test/parallel/test-https-connect-address-family.js +++ b/test/parallel/test-https-connect-address-family.js @@ -1,28 +1,46 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); -const https = require('https'); +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} if (!common.hasIPv6) { common.skip('no IPv6 support'); return; } -const ciphers = 'AECDH-NULL-SHA'; -https.createServer({ ciphers }, function(req, res) { - this.close(); - res.end(); -}).listen(common.PORT, '::1', function() { - const options = { - host: 'localhost', - port: common.PORT, - family: 6, - ciphers: ciphers, - rejectUnauthorized: false, - }; - // Will fail with ECONNREFUSED if the address family is not honored. - https.get(options, common.mustCall(function() { - assert.strictEqual('::1', this.socket.remoteAddress); - this.destroy(); +const assert = require('assert'); +const https = require('https'); +const dns = require('dns'); + +function runTest() { + const ciphers = 'AECDH-NULL-SHA'; + https.createServer({ ciphers }, common.mustCall(function(req, res) { + this.close(); + res.end(); + })).listen(common.PORT, '::1', common.mustCall(function() { + const options = { + host: 'localhost', + port: common.PORT, + family: 6, + ciphers: ciphers, + rejectUnauthorized: false, + }; + // Will fail with ECONNREFUSED if the address family is not honored. + https.get(options, common.mustCall(function() { + assert.strictEqual('::1', this.socket.remoteAddress); + this.destroy(); + })); })); +} + +dns.lookup('localhost', {family: 6, all: true}, (err, addresses) => { + if (err) + throw err; + + if (addresses.some((val) => val.address === '::1')) + runTest(); + else + common.skip('localhost does not resolve to ::1'); }); diff --git a/test/parallel/test-tls-connect-address-family.js b/test/parallel/test-tls-connect-address-family.js index 665a71dfe666d9..6274328956e63d 100644 --- a/test/parallel/test-tls-connect-address-family.js +++ b/test/parallel/test-tls-connect-address-family.js @@ -1,27 +1,45 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); -const tls = require('tls'); +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} if (!common.hasIPv6) { common.skip('no IPv6 support'); return; } -const ciphers = 'AECDH-NULL-SHA'; -tls.createServer({ ciphers }, function() { - this.close(); -}).listen(common.PORT, '::1', function() { - const options = { - host: 'localhost', - port: common.PORT, - family: 6, - ciphers: ciphers, - rejectUnauthorized: false, - }; - // Will fail with ECONNREFUSED if the address family is not honored. - tls.connect(options).once('secureConnect', common.mustCall(function() { - assert.strictEqual('::1', this.remoteAddress); - this.destroy(); +const assert = require('assert'); +const tls = require('tls'); +const dns = require('dns'); + +function runTest() { + const ciphers = 'AECDH-NULL-SHA'; + tls.createServer({ ciphers }, common.mustCall(function() { + this.close(); + })).listen(common.PORT, '::1', common.mustCall(function() { + const options = { + host: 'localhost', + port: common.PORT, + family: 6, + ciphers: ciphers, + rejectUnauthorized: false, + }; + // Will fail with ECONNREFUSED if the address family is not honored. + tls.connect(options).once('secureConnect', common.mustCall(function() { + assert.strictEqual('::1', this.remoteAddress); + this.destroy(); + })); })); +} + +dns.lookup('localhost', {family: 6, all: true}, (err, addresses) => { + if (err) + throw err; + + if (addresses.some((val) => val.address === '::1')) + runTest(); + else + common.skip('localhost does not resolve to ::1'); }); From f0312e65603fe5ad858c262c0500ae8be7ea2a53 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Sun, 10 Jul 2016 16:08:42 +0200 Subject: [PATCH 008/144] build: export more openssl symbols on Windows This exports even more openssl symbols when building on Windows. SSL_set_fd is one example of added symbol. PR-URL: https://github.com/nodejs/node/pull/7576 Reviewed-By: Ben Noordhuis Reviewed-By: Roman Reiss --- node.gyp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/node.gyp b/node.gyp index 95dd06a428c4fb..70dc80c4035f0f 100644 --- a/node.gyp +++ b/node.gyp @@ -558,7 +558,8 @@ 'mkssldef_flags': [ # Categories to export. '-CAES,BF,BIO,DES,DH,DSA,EC,ECDH,ECDSA,ENGINE,EVP,HMAC,MD4,MD5,' - 'NEXTPROTONEG,PSK,RC2,RC4,RSA,SHA,SHA0,SHA1,SHA256,SHA512,TLSEXT', + 'NEXTPROTONEG,PSK,RC2,RC4,RSA,SHA,SHA0,SHA1,SHA256,SHA512,SOCK,' + 'STDIO,TLSEXT', # Defines. '-DWIN32', # Symbols to filter from the export list. From dbbcb9dbd93dbb9c8a8664b6680cae6295e75daa Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Tue, 12 Jan 2016 12:21:09 +0000 Subject: [PATCH 009/144] win,msi: Added Italian translation As titled. Tested by @piccoloaiutante. PR-URL: https://github.com/nodejs/node/pull/4647 Refs: https://github.com/wixtoolset/wix3/pull/366 Reviewed-By: Rod Vagg Reviewed-By: Frederic Hemberger --- tools/msvs/msi/i18n/it-it.wxl | 38 ++++++++++++++++++++++++++++++++++ tools/msvs/msi/nodemsi.wixproj | 3 +++ 2 files changed, 41 insertions(+) create mode 100644 tools/msvs/msi/i18n/it-it.wxl diff --git a/tools/msvs/msi/i18n/it-it.wxl b/tools/msvs/msi/i18n/it-it.wxl new file mode 100644 index 00000000000000..54a251ea2530b4 --- /dev/null +++ b/tools/msvs/msi/i18n/it-it.wxl @@ -0,0 +1,38 @@ + + + + 1040 + + Installazione di [ProductName] sul tuo computer. + Scegliere una cartella di destinazione o premere Avanti per installare nella cartella predefinita. + + Una versione successiva di [ProductName] è già installata. Il setup terminerà ora. + + + Node.js runtime + Installa [ProductName] runtime (node.exe). + + Performance counters + Installa il supporto per i performance counters specifici di [ProductName]. + + Event tracing (ETW) + Installa il supporto per gli eventi "event tracing" (ETW) generati da [ProductName]. + + npm package manager + Installa npm, il package manager raccomandato per [ProductName]. + + Collegamenti alla documentazione online + Aggiunge i collegamenti al menu start alla documentazione online per [ProductName] [FullVersion] e per il sito web di [ProductName]. + + Aggiunta al PATH + Aggiunge [ProductName], npm, e i moduli installati globalmente da npm alla variable di ambiente PATH. + + Node.js e npm + Aggiunge [ProductName] e npm (se installato) alla variabile di ambiente PATH. + + Moduli npm + Aggiunge i moduli installati globalmente da npm alla variabile di ambiente PATH. Questa opzione avrà effetto solo per l'utente corrente, gli altri utenti dovranno aggiornare la loro variabile PATH manualmente. + + + Node.js è stato installato correttamente. + diff --git a/tools/msvs/msi/nodemsi.wixproj b/tools/msvs/msi/nodemsi.wixproj index 70ffec50bcc8e4..d21a3cf2327432 100644 --- a/tools/msvs/msi/nodemsi.wixproj +++ b/tools/msvs/msi/nodemsi.wixproj @@ -56,6 +56,7 @@ + @@ -78,7 +79,9 @@ From 51a2041b90e5a47d58cb62671ce6c5a588147fda Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Mon, 30 May 2016 18:29:27 +0200 Subject: [PATCH 010/144] dgram: generalized send queue to handle close If the udp socket is not ready and we are accumulating messages to send, it needs to delay closing the socket when all messages are flushed. Fixes: https://github.com/nodejs/node/issues/7061 PR-URL: https://github.com/nodejs/node/pull/7066 Reviewed-By: Anna Henningsen --- lib/dgram.js | 32 ++++++++++++------- .../parallel/test-dgram-close-in-listening.js | 18 +++++++++++ 2 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 test/parallel/test-dgram-close-in-listening.js diff --git a/lib/dgram.js b/lib/dgram.js index e6cc169dc644fe..c088bffa7ff477 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -283,20 +283,25 @@ function fixBufferList(list) { function enqueue(self, toEnqueue) { // If the send queue hasn't been initialized yet, do it, and install an // event handler that flushes the send queue after binding is done. - if (!self._sendQueue) { - self._sendQueue = []; - self.once('listening', function() { - // Flush the send queue. - for (var i = 0; i < this._sendQueue.length; i++) - this.send.apply(self, this._sendQueue[i]); - this._sendQueue = undefined; - }); + if (!self._queue) { + self._queue = []; + self.once('listening', clearQueue); } - self._sendQueue.push(toEnqueue); + self._queue.push(toEnqueue); return; } +function clearQueue() { + const queue = this._queue; + this._queue = undefined; + + // Flush the send queue. + for (var i = 0; i < queue.length; i++) + queue[i](); +} + + // valid combinations // send(buffer, offset, length, port, address, callback) // send(buffer, offset, length, port, address) @@ -353,7 +358,7 @@ Socket.prototype.send = function(buffer, // If the socket hasn't been bound yet, push the outbound packet onto the // send queue and send after binding is complete. if (self._bindState != BIND_STATE_BOUND) { - enqueue(self, [list, port, address, callback]); + enqueue(self, self.send.bind(self, list, port, address, callback)); return; } @@ -407,10 +412,15 @@ function afterSend(err, sent) { this.callback(err, sent); } - Socket.prototype.close = function(callback) { if (typeof callback === 'function') this.on('close', callback); + + if (this._queue) { + this._queue.push(this.close.bind(this)); + return this; + } + this._healthCheck(); this._stopReceiving(); this._handle.close(); diff --git a/test/parallel/test-dgram-close-in-listening.js b/test/parallel/test-dgram-close-in-listening.js new file mode 100644 index 00000000000000..e181f40de67dcf --- /dev/null +++ b/test/parallel/test-dgram-close-in-listening.js @@ -0,0 +1,18 @@ +'use strict'; +// Ensure that if a dgram socket is closed before the sendQueue is drained +// will not crash + +const common = require('../common'); +const dgram = require('dgram'); + +const buf = Buffer.alloc(1024, 42); + +const socket = dgram.createSocket('udp4'); + +socket.on('listening', function() { + socket.close(); +}); + +// adds a listener to 'listening' to send the data when +// the socket is available +socket.send(buf, 0, buf.length, common.PORT, 'localhost'); From 0ffeddb5b407dbbbeeca7b8345f40b84e63a9170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BA=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=90=D0=BD=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sat, 9 Jul 2016 08:13:09 +0300 Subject: [PATCH 011/144] doc: various documentation formatting fixes * Fix markdown code sample in releases.md, it was Reviewed-By: Roman Reiss Conflicts: doc/api/zlib.md doc/changelogs/CHANGELOG_V4.md --- doc/api/addons.md | 12 +- doc/api/buffer.md | 2 +- doc/api/cluster.md | 2 +- doc/api/debugger.md | 6 +- doc/api/dgram.md | 1 - doc/api/dns.md | 8 +- doc/api/documentation.md | 8 +- doc/api/errors.md | 2 +- doc/api/fs.md | 2 +- doc/api/globals.md | 6 +- doc/api/http.md | 35 ++-- doc/api/modules.md | 14 +- doc/api/net.md | 4 +- doc/api/process.md | 25 ++- doc/api/repl.md | 4 +- doc/api/stream.md | 12 +- doc/api/synopsis.md | 2 +- doc/api/timers.md | 2 +- doc/api/tls.md | 20 +-- doc/api/tty.md | 4 +- doc/api/url.md | 4 +- doc/api/util.md | 5 +- doc/api/v8.md | 2 +- doc/api/vm.md | 3 +- doc/api/zlib.md | 26 +-- doc/changelogs/CHANGELOG_V4.md | 224 ++++++++++++++++++++++++- doc/changelogs/CHANGELOG_V5.md | 4 +- doc/changelogs/CHANGELOG_V6.md | 4 +- doc/ctc-meetings/2016-02-03.md | 2 +- doc/ctc-meetings/2016-06-15.md | 3 +- doc/guides/building-node-with-ninja.md | 2 +- doc/onboarding-extras.md | 2 +- doc/releases.md | 29 ++-- doc/topics/blocking-vs-non-blocking.md | 2 +- doc/topics/domain-postmortem.md | 2 +- doc/tsc-meetings/io.js/2014-12-10.md | 2 +- 36 files changed, 344 insertions(+), 143 deletions(-) diff --git a/doc/api/addons.md b/doc/api/addons.md index 1187eafdc33a63..1333b3b1360e3a 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -102,7 +102,7 @@ top-level of the project describing the build configuration of your module using a JSON-like format. This file is used by [node-gyp][] -- a tool written specifically to compile Node.js Addons. -``` +```json { "targets": [ { @@ -222,7 +222,7 @@ templates, etc. Each of these examples using the following `binding.gyp` file: -``` +```json { "targets": [ { @@ -236,14 +236,14 @@ Each of these examples using the following `binding.gyp` file: In cases where there is more than one `.cc` file, simply add the additional filename to the `sources` array. For example: -``` +```json "sources": ["addon.cc", "myexample.cc"] ``` Once the `binding.gyp` file is ready, the example Addons can be configured and built using `node-gyp`: -``` +```sh $ node-gyp configure build ``` @@ -621,7 +621,7 @@ void MyObject::PlusOne(const FunctionCallbackInfo& args) { To build this example, the `myobject.cc` file must be added to the `binding.gyp`: -``` +```json { "targets": [ { @@ -813,7 +813,7 @@ void MyObject::PlusOne(const FunctionCallbackInfo& args) { Once again, to build this example, the `myobject.cc` file must be added to the `binding.gyp`: -``` +```json { "targets": [ { diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 66416f7de0f341..f0104207c50f22 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -114,7 +114,7 @@ significant impact* on performance. Use of the `--zero-fill-buffers` option is recommended only when absolutely necessary to enforce that newly allocated `Buffer` instances cannot contain potentially sensitive data. -``` +```txt $ node --zero-fill-buffers > Buffer.allocUnsafe(5); diff --git a/doc/api/cluster.md b/doc/api/cluster.md index 1c769567c45144..6f0b424e05e083 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -35,7 +35,7 @@ if (cluster.isMaster) { Running Node.js will now share port 8000 between the workers: -``` +```txt $ NODE_DEBUG=cluster node server.js 23521,Master Worker 23524 online 23521,Master Worker 23526 online diff --git a/doc/api/debugger.md b/doc/api/debugger.md index 6a31212d9c220b..d146292f2d704e 100644 --- a/doc/api/debugger.md +++ b/doc/api/debugger.md @@ -9,7 +9,7 @@ via a simple [TCP-based protocol][] and built-in debugging client. To use it, start Node.js with the `debug` argument followed by the path to the script to debug; a prompt will be displayed indicating successful launch of the debugger: -``` +```txt $ node debug myscript.js < debugger listening on port 5858 connecting... ok @@ -38,7 +38,7 @@ console.log('hello'); Once the debugger is run, a breakpoint will occur at line 4: -``` +```txt $ node debug myscript.js < debugger listening on port 5858 connecting... ok @@ -119,7 +119,7 @@ on line 1 It is also possible to set a breakpoint in a file (module) that isn't loaded yet: -``` +```txt $ ./node debug test/fixtures/break-in-module/main.js < debugger listening on port 5858 connecting to port 5858... ok diff --git a/doc/api/dgram.md b/doc/api/dgram.md index df479a8e31df60..1a5cce0b91e150 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -425,7 +425,6 @@ and `udp6` sockets). The bound address and port can be retrieved using [`EventEmitter`]: events.html [`Buffer`]: buffer.html [`'close'`]: #dgram_event_close -[`addMembership()`]: #dgram_socket_addmembership_multicastaddress_multicastinterface [`close()`]: #dgram_socket_close_callback [`dgram.createSocket()`]: #dgram_dgram_createsocket_options_callback [`dgram.Socket#bind()`]: #dgram_socket_bind_options_callback diff --git a/doc/api/dns.md b/doc/api/dns.md index 3f90d632a85d30..7192be9a861999 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -86,7 +86,7 @@ Alternatively, `options` can be an object containing these properties: All properties are optional. An example usage of options is shown below. -``` +```js { family: 4, hints: dns.ADDRCONFIG | dns.V4MAPPED, @@ -279,7 +279,7 @@ be an object with the following properties: * `expire` * `minttl` -``` +```js { nsname: 'ns.example.com', hostmaster: 'root.example.com', @@ -305,7 +305,7 @@ be an array of objects with the following properties: * `port` * `name` -``` +```js { priority: 10, weight: 5, @@ -437,8 +437,6 @@ uses. For instance, _they do not use the configuration from `/etc/hosts`_. [DNS error codes]: #dns_error_codes [`dns.lookup()`]: #dns_dns_lookup_hostname_options_callback -[`dns.resolve()`]: #dns_dns_resolve_hostname_rrtype_callback -[`dns.resolve4()`]: #dns_dns_resolve4_hostname_callback [`dns.resolveSoa()`]: #dns_dns_resolvesoa_hostname_callback [`Error`]: errors.html#errors_class_error [Implementation considerations section]: #dns_implementation_considerations diff --git a/doc/api/documentation.md b/doc/api/documentation.md index 61d623fe3e054a..1acb21a8969fa2 100644 --- a/doc/api/documentation.md +++ b/doc/api/documentation.md @@ -37,26 +37,26 @@ and in the process of being redesigned. The stability indices are as follows: -``` +```txt Stability: 0 - Deprecated This feature is known to be problematic, and changes are planned. Do not rely on it. Use of the feature may cause warnings. Backwards compatibility should not be expected. ``` -``` +```txt Stability: 1 - Experimental This feature is subject to change, and is gated by a command line flag. It may change or be removed in future versions. ``` -``` +```txt Stability: 2 - Stable The API has proven satisfactory. Compatibility with the npm ecosystem is a high priority, and will not be broken unless absolutely necessary. ``` -``` +```txt Stability: 3 - Locked Only fixes related to security, performance, or bug fixes will be accepted. Please do not suggest API changes in this area; they will be refused. diff --git a/doc/api/errors.md b/doc/api/errors.md index e80dabe609400a..5ede6e6e38ea45 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -268,7 +268,7 @@ instantiated. For example: -``` +```txt Error: Things keep happening! at /home/gbusey/file.js:525:2 at Frobnicator.refrobulate (/home/gbusey/business-logic.js:424:21) diff --git a/doc/api/fs.md b/doc/api/fs.md index e8b158ac5edbcb..0c84c44b58ee31 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -74,7 +74,7 @@ Most fs functions let you omit the callback argument. If you do, a default callback is used that rethrows errors. To get a trace to the original call site, set the `NODE_DEBUG` environment variable: -``` +```txt $ cat script.js function bad() { require('fs').readFile('/'); diff --git a/doc/api/globals.md b/doc/api/globals.md index 1bd2dffc5fa4df..7db4fbe1aaae00 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -207,9 +207,9 @@ but rather than loading the module, just return the resolved filename. [Modules]: modules.html#modules_modules [native addons]: addons.html [timers]: timers.html -[`clearImmediate`]: timers.html#timers_clearimmediate_immediateobject -[`clearInterval`]: timers.html#timers_clearinterval_immediateobject -[`clearTimeout`]: timers.html#timers_cleartimeout_timeoutobject +[`clearImmediate`]: timers.html#timers_clearimmediate_immediate +[`clearInterval`]: timers.html#timers_clearinterval_timeout +[`clearTimeout`]: timers.html#timers_cleartimeout_timeout [`setImmediate`]: timers.html#timers_setimmediate_callback_arg [`setInterval`]: timers.html#timers_setinterval_callback_delay_arg [`setTimeout`]: timers.html#timers_settimeout_callback_delay_arg diff --git a/doc/api/http.md b/doc/api/http.md index 2646d95c06592a..606f79f39576de 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -12,7 +12,7 @@ user is able to stream data. HTTP message headers are represented by an object like this: -``` +```js { 'content-length': '123', 'content-type': 'text/plain', 'connection': 'keep-alive', @@ -34,7 +34,7 @@ property, which is an array of `[key, value, key2, value2, ...]`. For example, the previous message header object might have a `rawHeaders` list like the following: -``` +```js [ 'ConTent-Length', '123456', 'content-LENGTH', '123', 'content-type', 'text/plain', @@ -222,16 +222,16 @@ header is still mutable using the `setHeader(name, value)`, `getHeader(name)`, `removeHeader(name)` API. The actual header will be sent along with the first data chunk or when closing the connection. -To get the response, add a listener for `'response'` to the request object. -`'response'` will be emitted from the request object when the response -headers have been received. The `'response'` event is executed with one +To get the response, add a listener for [`'response'`][] to the request object. +[`'response'`][] will be emitted from the request object when the response +headers have been received. The [`'response'`][] event is executed with one argument which is an instance of [`http.IncomingMessage`][]. -During the `'response'` event, one can add listeners to the +During the [`'response'`][] event, one can add listeners to the response object; particularly to listen for the `'data'` event. -If no `'response'` handler is added, then the response will be -entirely discarded. However, if you add a `'response'` event handler, +If no [`'response'`][] handler is added, then the response will be +entirely discarded. However, if you add a [`'response'`][] event handler, then you **must** consume the data from the response object, either by calling `response.read()` whenever there is a `'readable'` event, or by adding a `'data'` handler, or by calling the `.resume()` method. @@ -677,7 +677,7 @@ already been bound to a port or domain socket. Listening on a file descriptor is not supported on Windows. This function is asynchronous. `callback` will be added as a listener for the -`'listening'` event. See also [`net.Server.listen()`][]. +[`'listening'`][] event. See also [`net.Server.listen()`][]. Returns `server`. @@ -689,7 +689,7 @@ added: v0.1.90 Start a UNIX socket server listening for connections on the given `path`. This function is asynchronous. `callback` will be added as a listener for the -`'listening'` event. See also [`net.Server.listen(path)`][]. +[`'listening'`][] event. See also [`net.Server.listen(path)`][]. ### server.listen(port[, hostname][, backlog][, callback]) All of the constants defined in `zlib.h` are also defined on `require('zlib')`. -In the normal course of operations, it will not be necessary to use these -constants. They are documented so that their presence is not surprising. This +In the normal course of operations, it will not be necessary to use these +constants. They are documented so that their presence is not surprising. This section is taken almost directly from the [zlib documentation][]. See for more details. @@ -387,6 +387,10 @@ added: v0.7.0 Reset the compressor/decompressor to factory defaults. Only applicable to the inflate and deflate algorithms. +## zlib.constants + +Provides an object enumerating Zlib-related constants. + ## zlib.createDeflate([options]) -All of these take a [Buffer][] or string as the first argument, an optional -second argument to supply options to the `zlib` classes and will call the +All of these take a [Buffer][] or string as the first argument, an optional +second argument to supply options to the `zlib` classes and will call the supplied callback with `callback(error, result)`. Every method has a `*Sync` counterpart, which accept the same arguments, but diff --git a/doc/changelogs/CHANGELOG_V4.md b/doc/changelogs/CHANGELOG_V4.md index 6d11a647b040eb..09ce887e2552ae 100644 --- a/doc/changelogs/CHANGELOG_V4.md +++ b/doc/changelogs/CHANGELOG_V4.md @@ -40,11 +40,227 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) - -**Note:** Node.js v4 is covered by the + +**Note:** Node.js v4 is covered by the [Node.js Long Term Support Plan](https://github.com/nodejs/LTS) and will be supported actively until April 2017 and maintained until April 2018. + +## 2016-06-28, Version 4.4.7 'Argon' (LTS), @thealphanerd + +This LTS release comes with 89 commits. This includes 46 commits that are docs related, 11 commits that are test related, 8 commits that are build related, and 4 commits that are benchmark related. + +### Notable Changes + +- **debugger**: + - All properties of an array (aside from length) can now be printed in the repl (cjihrig) [#6448](https://github.com/nodejs/node/pull/6448) +- **npm**: + - Upgrade npm to 2.15.8 (Rebecca Turner) [#7412](https://github.com/nodejs/node/pull/7412) +- **stream**: + - Fix for a bug that became more prevalent with the stream changes that landed in v4.4.5. (Anna Henningsen) [#7160](https://github.com/nodejs/node/pull/7160) +- **V8**: + - Fix for a bug in crankshaft that was causing crashes on arm64 (Myles Borins) [#7442](https://github.com/nodejs/node/pull/7442) + - Add missing classes to postmortem info such as JSMap and JSSet (evan.lucas) [#3792](https://github.com/nodejs/node/pull/3792) + +### Commits + +* [[`87cdb83a96`](https://github.com/nodejs/node/commit/87cdb83a96)] - **benchmark**: merge url.js with url-resolve.js (Andreas Madsen) [#5177](https://github.com/nodejs/node/pull/5177) +* [[`921e8568d5`](https://github.com/nodejs/node/commit/921e8568d5)] - **benchmark**: move misc to categorized directories (Andreas Madsen) [#5177](https://github.com/nodejs/node/pull/5177) +* [[`c189eec14e`](https://github.com/nodejs/node/commit/c189eec14e)] - **benchmark**: fix configuation parameters (Andreas Madsen) [#5177](https://github.com/nodejs/node/pull/5177) +* [[`58ad451f0b`](https://github.com/nodejs/node/commit/58ad451f0b)] - **benchmark**: move string-decoder to its own category (Andreas Madsen) [#5177](https://github.com/nodejs/node/pull/5177) +* [[`a01caa3166`](https://github.com/nodejs/node/commit/a01caa3166)] - **build**: don't compile with -B, redux (Ben Noordhuis) [#6650](https://github.com/nodejs/node/pull/6650) +* [[`37606caeaf`](https://github.com/nodejs/node/commit/37606caeaf)] - **build**: don't compile with -B (Ben Noordhuis) [#6393](https://github.com/nodejs/node/pull/6393) +* [[`64fb7a1929`](https://github.com/nodejs/node/commit/64fb7a1929)] - **build**: update android-configure script for npm (Robert Chiras) [#6349](https://github.com/nodejs/node/pull/6349) +* [[`43ce6fc8d2`](https://github.com/nodejs/node/commit/43ce6fc8d2)] - **build**: fix DESTCPU detection for binary target (Richard Lau) [#6310](https://github.com/nodejs/node/pull/6310) +* [[`6dfe7aeed5`](https://github.com/nodejs/node/commit/6dfe7aeed5)] - **cares**: Support malloc(0) scenarios for AIX (Gireesh Punathil) [#6305](https://github.com/nodejs/node/pull/6305) +* [[`2389006720`](https://github.com/nodejs/node/commit/2389006720)] - **debugger**: display array contents in repl (cjihrig) [#6448](https://github.com/nodejs/node/pull/6448) +* [[`1c6809ce75`](https://github.com/nodejs/node/commit/1c6809ce75)] - **debugger**: introduce exec method for debugger (Jackson Tian) +* [[`200b3ca9ed`](https://github.com/nodejs/node/commit/200b3ca9ed)] - **deps**: upgrade npm in LTS to 2.15.8 (Rebecca Turner) [#7412](https://github.com/nodejs/node/pull/7412) +* [[`49921e8819`](https://github.com/nodejs/node/commit/49921e8819)] - **deps**: backport 102e3e87e7 from V8 upstream (Myles Borins) [#7442](https://github.com/nodejs/node/pull/7442) +* [[`de00f91041`](https://github.com/nodejs/node/commit/de00f91041)] - **deps**: backport bc2e393 from v8 upstream (evan.lucas) [#3792](https://github.com/nodejs/node/pull/3792) +* [[`1549899531`](https://github.com/nodejs/node/commit/1549899531)] - **dgram,test**: add addMembership/dropMembership tests (Rich Trott) [#6753](https://github.com/nodejs/node/pull/6753) +* [[`0ba3c2ca66`](https://github.com/nodejs/node/commit/0ba3c2ca66)] - **doc**: fix layout problem in v4 changelog (Myles Borins) [#7394](https://github.com/nodejs/node/pull/7394) +* [[`98469ad84d`](https://github.com/nodejs/node/commit/98469ad84d)] - **doc**: correct args for cluster message event (Colin Ihrig) [#7297](https://github.com/nodejs/node/pull/7297) +* [[`67863f110b`](https://github.com/nodejs/node/commit/67863f110b)] - **doc**: update licenses (Myles Borins) [#7127](https://github.com/nodejs/node/pull/7127) +* [[`c31eaad42d`](https://github.com/nodejs/node/commit/c31eaad42d)] - **doc**: clarify buffer class (Steve Mao) [#6914](https://github.com/nodejs/node/pull/6914) +* [[`e0dd476fe5`](https://github.com/nodejs/node/commit/e0dd476fe5)] - **doc**: fix typos in timers topic to aid readability (Kevin Donahue) [#6916](https://github.com/nodejs/node/pull/6916) +* [[`a8391bc9fc`](https://github.com/nodejs/node/commit/a8391bc9fc)] - **doc**: add jhamhader to collaborators (Yuval Brik) [#6946](https://github.com/nodejs/node/pull/6946) +* [[`22ca7b877b`](https://github.com/nodejs/node/commit/22ca7b877b)] - **doc**: add @othiym23 to list of collaborators (Forrest L Norvell) [#6945](https://github.com/nodejs/node/pull/6945) +* [[`2c3c4e5819`](https://github.com/nodejs/node/commit/2c3c4e5819)] - **doc**: reference list of language-specific globals (Anna Henningsen) [#6900](https://github.com/nodejs/node/pull/6900) +* [[`5a1a0b5ed1`](https://github.com/nodejs/node/commit/5a1a0b5ed1)] - **doc**: make the api doc print-friendly (Marian) [#6748](https://github.com/nodejs/node/pull/6748) +* [[`03db88e012`](https://github.com/nodejs/node/commit/03db88e012)] - **doc**: add bengl to collaborators (Bryan English) [#6921](https://github.com/nodejs/node/pull/6921) +* [[`fbf95dde94`](https://github.com/nodejs/node/commit/fbf95dde94)] - **doc**: Update DCO to v1.1 (William Kapke) [#6353](https://github.com/nodejs/node/pull/6353) +* [[`f23a9c39c0`](https://github.com/nodejs/node/commit/f23a9c39c0)] - **doc**: fix typo in Error.captureStackTrace (Mohsen) [#6811](https://github.com/nodejs/node/pull/6811) +* [[`30ab6a890c`](https://github.com/nodejs/node/commit/30ab6a890c)] - **doc**: fix name to match git log (Robert Jefe Lindstaedt) [#6880](https://github.com/nodejs/node/pull/6880) +* [[`2b0f40ca16`](https://github.com/nodejs/node/commit/2b0f40ca16)] - **doc**: add note for fs.watch virtualized env (Robert Jefe Lindstaedt) [#6809](https://github.com/nodejs/node/pull/6809) +* [[`3b461870be`](https://github.com/nodejs/node/commit/3b461870be)] - **doc**: Backport ee.once doc clarifications to 4.x. (Lance Ball) [#7103](https://github.com/nodejs/node/pull/7103) +* [[`eadb7e5b20`](https://github.com/nodejs/node/commit/eadb7e5b20)] - **doc**: subdivide TOC, add auxiliary links (Jeremiah Senkpiel) [#6167](https://github.com/nodejs/node/pull/6167) +* [[`107839c5dd`](https://github.com/nodejs/node/commit/107839c5dd)] - **doc**: no Node.js(1) (Jeremiah Senkpiel) [#6167](https://github.com/nodejs/node/pull/6167) +* [[`401325f9e2`](https://github.com/nodejs/node/commit/401325f9e2)] - **doc**: better example & synopsis (Jeremiah Senkpiel) [#6167](https://github.com/nodejs/node/pull/6167) +* [[`c654184f28`](https://github.com/nodejs/node/commit/c654184f28)] - **doc**: remove link to Sign in crypto.md (Kirill Fomichev) [#6812](https://github.com/nodejs/node/pull/6812) +* [[`3e9288e466`](https://github.com/nodejs/node/commit/3e9288e466)] - **doc**: fix exec example in child_process (Evan Lucas) [#6660](https://github.com/nodejs/node/pull/6660) +* [[`3d820e45b4`](https://github.com/nodejs/node/commit/3d820e45b4)] - **doc**: "a" -> "an" in api/documentation.md (Anchika Agarwal) [#6689](https://github.com/nodejs/node/pull/6689) +* [[`352496daa2`](https://github.com/nodejs/node/commit/352496daa2)] - **doc**: move the readme newcomers section (Jeremiah Senkpiel) [#6681](https://github.com/nodejs/node/pull/6681) +* [[`ac6b921ce5`](https://github.com/nodejs/node/commit/ac6b921ce5)] - **doc**: mention existence/purpose of module wrapper (Matt Harrison) [#6433](https://github.com/nodejs/node/pull/6433) +* [[`97d1fc0fc6`](https://github.com/nodejs/node/commit/97d1fc0fc6)] - **doc**: improve onboarding-extras.md formatting (Jeremiah Senkpiel) [#6548](https://github.com/nodejs/node/pull/6548) +* [[`c9b144ddd4`](https://github.com/nodejs/node/commit/c9b144ddd4)] - **doc**: linkify remaining references to fs.Stats object (Kevin Donahue) [#6485](https://github.com/nodejs/node/pull/6485) +* [[`d909c25a33`](https://github.com/nodejs/node/commit/d909c25a33)] - **doc**: fix the lint of an example in cluster.md (yorkie) [#6516](https://github.com/nodejs/node/pull/6516) +* [[`21d02f460f`](https://github.com/nodejs/node/commit/21d02f460f)] - **doc**: add missing underscore for markdown italics (Kevin Donahue) [#6529](https://github.com/nodejs/node/pull/6529) +* [[`18ecc779bb`](https://github.com/nodejs/node/commit/18ecc779bb)] - **doc**: ensure consistent grammar in node.1 file (justshiv) [#6426](https://github.com/nodejs/node/pull/6426) +* [[`52d9e7b61d`](https://github.com/nodejs/node/commit/52d9e7b61d)] - **doc**: fix a typo in __dirname section (William Luo) [#6473](https://github.com/nodejs/node/pull/6473) +* [[`de20235235`](https://github.com/nodejs/node/commit/de20235235)] - **doc**: remove all scrollbar styling (Claudio Rodriguez) [#6479](https://github.com/nodejs/node/pull/6479) +* [[`a6f45b4eda`](https://github.com/nodejs/node/commit/a6f45b4eda)] - **doc**: Remove extra space in REPL example (Juan) [#6447](https://github.com/nodejs/node/pull/6447) +* [[`feda15b2b8`](https://github.com/nodejs/node/commit/feda15b2b8)] - **doc**: update build instructions for OS X (Rich Trott) [#6309](https://github.com/nodejs/node/pull/6309) +* [[`3d1a3e4a30`](https://github.com/nodejs/node/commit/3d1a3e4a30)] - **doc**: change references to Stable to Current (Myles Borins) [#6318](https://github.com/nodejs/node/pull/6318) +* [[`e28598b1ef`](https://github.com/nodejs/node/commit/e28598b1ef)] - **doc**: update authors (James M Snell) [#6373](https://github.com/nodejs/node/pull/6373) +* [[`0f3a94acbd`](https://github.com/nodejs/node/commit/0f3a94acbd)] - **doc**: add JacksonTian to collaborators (Jackson Tian) [#6388](https://github.com/nodejs/node/pull/6388) +* [[`d7d54c8fd2`](https://github.com/nodejs/node/commit/d7d54c8fd2)] - **doc**: add Minqi Pan to collaborators (Minqi Pan) [#6387](https://github.com/nodejs/node/pull/6387) +* [[`83721c6fd2`](https://github.com/nodejs/node/commit/83721c6fd2)] - **doc**: add eljefedelrodeodeljefe to collaborators (Robert Jefe Lindstaedt) [#6389](https://github.com/nodejs/node/pull/6389) +* [[`b112fd1b4e`](https://github.com/nodejs/node/commit/b112fd1b4e)] - **doc**: add ronkorving to collaborators (ronkorving) [#6385](https://github.com/nodejs/node/pull/6385) +* [[`ac60d9cc86`](https://github.com/nodejs/node/commit/ac60d9cc86)] - **doc**: add estliberitas to collaborators (Alexander Makarenko) [#6386](https://github.com/nodejs/node/pull/6386) +* [[`435cd56de5`](https://github.com/nodejs/node/commit/435cd56de5)] - **doc**: DCO anchor that doesn't change (William Kapke) [#6257](https://github.com/nodejs/node/pull/6257) +* [[`7d8141dd1b`](https://github.com/nodejs/node/commit/7d8141dd1b)] - **doc**: add stefanmb to collaborators (Stefan Budeanu) [#6227](https://github.com/nodejs/node/pull/6227) +* [[`6dfc96326d`](https://github.com/nodejs/node/commit/6dfc96326d)] - **doc**: add iWuzHere to collaborators (Imran Iqbal) [#6226](https://github.com/nodejs/node/pull/6226) +* [[`3dbcc73159`](https://github.com/nodejs/node/commit/3dbcc73159)] - **doc**: add santigimeno to collaborators (Santiago Gimeno) [#6225](https://github.com/nodejs/node/pull/6225) +* [[`ae3eb24a3d`](https://github.com/nodejs/node/commit/ae3eb24a3d)] - **doc**: add addaleax to collaborators (Anna Henningsen) [#6224](https://github.com/nodejs/node/pull/6224) +* [[`46ee7bb4ba`](https://github.com/nodejs/node/commit/46ee7bb4ba)] - **doc**: fix incorrect references in buffer docs (Amery) [#6194](https://github.com/nodejs/node/pull/6194) +* [[`e3f78eb7c1`](https://github.com/nodejs/node/commit/e3f78eb7c1)] - **doc**: improve rendering of v4.4.5 changelog entry (Myles Borins) [#6958](https://github.com/nodejs/node/pull/6958) +* [[`bac87d01d9`](https://github.com/nodejs/node/commit/bac87d01d9)] - **gitignore**: adding .vs/ directory to .gitignore (Mike Kaufman) [#6070](https://github.com/nodejs/node/pull/6070) +* [[`93f2314dc2`](https://github.com/nodejs/node/commit/93f2314dc2)] - **gitignore**: ignore VS 2015 *.VC.opendb files (Mike Kaufman) [#6070](https://github.com/nodejs/node/pull/6070) +* [[`c98aaf59bf`](https://github.com/nodejs/node/commit/c98aaf59bf)] - **http**: speed up checkIsHttpToken (Jackson Tian) [#4790](https://github.com/nodejs/node/pull/4790) +* [[`552e25cb6b`](https://github.com/nodejs/node/commit/552e25cb6b)] - **lib,test**: update in preparation for linter update (Rich Trott) [#6498](https://github.com/nodejs/node/pull/6498) +* [[`aaeeec4765`](https://github.com/nodejs/node/commit/aaeeec4765)] - **lib,test,tools**: alignment on variable assignments (Rich Trott) [#6869](https://github.com/nodejs/node/pull/6869) +* [[`b3acbc5648`](https://github.com/nodejs/node/commit/b3acbc5648)] - **net**: replace `__defineGetter__` with defineProperty (Fedor Indutny) [#6284](https://github.com/nodejs/node/pull/6284) +* [[`4c1eb5bf03`](https://github.com/nodejs/node/commit/4c1eb5bf03)] - **repl**: create history file with mode 0600 (Carl Lei) [#3394](https://github.com/nodejs/node/pull/3394) +* [[`90306bb81d`](https://github.com/nodejs/node/commit/90306bb81d)] - **src**: use size_t for http parser array size fields (Ben Noordhuis) [#5969](https://github.com/nodejs/node/pull/5969) +* [[`af41a63d0f`](https://github.com/nodejs/node/commit/af41a63d0f)] - **src**: replace ARRAY_SIZE with typesafe arraysize (Ben Noordhuis) [#5969](https://github.com/nodejs/node/pull/5969) +* [[`037291e31f`](https://github.com/nodejs/node/commit/037291e31f)] - **src**: make sure Utf8Value always zero-terminates (Anna Henningsen) [#7101](https://github.com/nodejs/node/pull/7101) +* [[`a08a0179e9`](https://github.com/nodejs/node/commit/a08a0179e9)] - **stream**: ensure awaitDrain is increased once (David Halls) [#7292](https://github.com/nodejs/node/pull/7292) +* [[`b73ec46dcb`](https://github.com/nodejs/node/commit/b73ec46dcb)] - **stream**: reset awaitDrain after manual .resume() (Anna Henningsen) [#7160](https://github.com/nodejs/node/pull/7160) +* [[`55319fe798`](https://github.com/nodejs/node/commit/55319fe798)] - **stream_base**: expose `bytesRead` getter (Fedor Indutny) [#6284](https://github.com/nodejs/node/pull/6284) +* [[`0414d882ce`](https://github.com/nodejs/node/commit/0414d882ce)] - **test**: fix test-net-* error code check for getaddrinfo(3) (Natanael Copa) [#5099](https://github.com/nodejs/node/pull/5099) +* [[`be0bb5f5fc`](https://github.com/nodejs/node/commit/be0bb5f5fc)] - **test**: fix unreliable known_issues test (Rich Trott) [#6555](https://github.com/nodejs/node/pull/6555) +* [[`ab50e82f42`](https://github.com/nodejs/node/commit/ab50e82f42)] - **test**: fix test-process-exec-argv flakiness (Santiago Gimeno) [#7128](https://github.com/nodejs/node/pull/7128) +* [[`4e38655d5f`](https://github.com/nodejs/node/commit/4e38655d5f)] - **test**: refactor test-tls-reuse-host-from-socket (Rich Trott) [#6756](https://github.com/nodejs/node/pull/6756) +* [[`1c4549a31e`](https://github.com/nodejs/node/commit/1c4549a31e)] - **test**: fix flaky test-stdout-close-catch (Santiago Gimeno) [#6808](https://github.com/nodejs/node/pull/6808) +* [[`3b94e31245`](https://github.com/nodejs/node/commit/3b94e31245)] - **test**: robust handling of env for npm-test-install (Myles Borins) [#6797](https://github.com/nodejs/node/pull/6797) +* [[`4067cde7ee`](https://github.com/nodejs/node/commit/4067cde7ee)] - **test**: abstract skip functionality to common (Jeremiah Senkpiel) [#7114](https://github.com/nodejs/node/pull/7114) +* [[`8b396e3d71`](https://github.com/nodejs/node/commit/8b396e3d71)] - **test**: fix test-debugger-repl-break-in-module (Rich Trott) [#6686](https://github.com/nodejs/node/pull/6686) +* [[`847b29c050`](https://github.com/nodejs/node/commit/847b29c050)] - **test**: fix test-debugger-repl-term (Rich Trott) [#6682](https://github.com/nodejs/node/pull/6682) +* [[`1d68bdbe3f`](https://github.com/nodejs/node/commit/1d68bdbe3f)] - **test**: fix error message checks in test-module-loading (James M Snell) [#5986](https://github.com/nodejs/node/pull/5986) +* [[`7e739ae159`](https://github.com/nodejs/node/commit/7e739ae159)] - **test,tools**: adjust function argument alignment (Rich Trott) [#7100](https://github.com/nodejs/node/pull/7100) +* [[`216486c2b6`](https://github.com/nodejs/node/commit/216486c2b6)] - **tools**: lint for function argument alignment (Rich Trott) [#7100](https://github.com/nodejs/node/pull/7100) +* [[`6a76485ad7`](https://github.com/nodejs/node/commit/6a76485ad7)] - **tools**: update ESLint to 2.9.0 (Rich Trott) [#6498](https://github.com/nodejs/node/pull/6498) +* [[`a31153c02c`](https://github.com/nodejs/node/commit/a31153c02c)] - **tools**: remove the minifying logic (Sakthipriyan Vairamani) [#6636](https://github.com/nodejs/node/pull/6636) +* [[`10bd1a73fd`](https://github.com/nodejs/node/commit/10bd1a73fd)] - **tools**: fix license-builder.sh again for ICU (Steven R. Loomis) [#6068](https://github.com/nodejs/node/pull/6068) +* [[`0f6146c6c0`](https://github.com/nodejs/node/commit/0f6146c6c0)] - **tools**: add tests for the doctool (Ian Kronquist) [#6031](https://github.com/nodejs/node/pull/6031) +* [[`cc3645cff3`](https://github.com/nodejs/node/commit/cc3645cff3)] - **tools**: lint for alignment of variable assignments (Rich Trott) [#6869](https://github.com/nodejs/node/pull/6869) + + +## 2016-06-23, Version 4.4.6 'Argon' (LTS), @thealphanerd + +### Notable Changes + +This is an important security release. All Node.js users should consult the security release summary at nodejs.org for details on patched vulnerabilities. + +This release is specifically related to a Buffer overflow vulnerability discovered in v8, more details can be found [in the CVE](https://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-1669) + +### Commits + +* [[`134c3b3977`](https://github.com/nodejs/node/commit/134c3b3977)] - **deps**: backport 3a9bfec from v8 upstream (Ben Noordhuis) [nodejs/node-private#38](https://github.com/nodejs/node-private/pull/38) + + +## 2016-05-24, Version 4.4.5 'Argon' (LTS), @thealphanerd + +### Notable Changes + +- **buffer**: + - Buffer.indexOf now returns correct values for all UTF-16 input (Anna Henningsen) [#6511](https://github.com/nodejs/node/pull/6511) +- **contextify**: + - Context objects are now properly garbage collected, this solves a problem some individuals were experiencing with extreme memory growth (Ali Ijaz Sheikh) [#6871](https://github.com/nodejs/node/pull/6871) +- **deps**: + - update npm to 2.15.5 (Rebecca Turner) [#6663](https://github.com/nodejs/node/pull/6663) +- **http**: + - Invalid status codes can no longer be sent. Limited to 3 digit numbers between 100 - 999 (Brian White) [#6291](https://github.com/nodejs/node/pull/6291) + +### Commits + +* [[`59a977dd22`](https://github.com/nodejs/node/commit/59a977dd22)] - **assert**: respect assert.doesNotThrow message. (Ilya Shaisultanov) [#2407](https://github.com/nodejs/node/pull/2407) +* [[`8b077faa82`](https://github.com/nodejs/node/commit/8b077faa82)] - **buffer**: fix UCS2 indexOf for odd buffer length (Anna Henningsen) [#6511](https://github.com/nodejs/node/pull/6511) +* [[`12a9699fcf`](https://github.com/nodejs/node/commit/12a9699fcf)] - **buffer**: fix needle length misestimation for UCS2 (Anna Henningsen) [#6511](https://github.com/nodejs/node/pull/6511) +* [[`292b1b733e`](https://github.com/nodejs/node/commit/292b1b733e)] - **build**: fix make tar-headers for Linux (Gibson Fahnestock) [#5978](https://github.com/nodejs/node/pull/5978) +* [[`918d33ad4b`](https://github.com/nodejs/node/commit/918d33ad4b)] - **build**: add script to create Android .mk files (Robert Chiras) [#5544](https://github.com/nodejs/node/pull/5544) +* [[`4ad71847bc`](https://github.com/nodejs/node/commit/4ad71847bc)] - **build**: add suport for x86 architecture (Robert Chiras) [#5544](https://github.com/nodejs/node/pull/5544) +* [[`6ad85914b1`](https://github.com/nodejs/node/commit/6ad85914b1)] - **child_process**: add nullptr checks after allocs (Anna Henningsen) [#6256](https://github.com/nodejs/node/pull/6256) +* [[`823f726f66`](https://github.com/nodejs/node/commit/823f726f66)] - **contextify**: tie lifetimes of context & sandbox (Ali Ijaz Sheikh) [#5800](https://github.com/nodejs/node/pull/5800) +* [[`9ddb44ba61`](https://github.com/nodejs/node/commit/9ddb44ba61)] - **contextify**: cache sandbox and context in locals (Ali Ijaz Sheikh) [#5392](https://github.com/nodejs/node/pull/5392) +* [[`8ebdcd65b0`](https://github.com/nodejs/node/commit/8ebdcd65b0)] - **contextify**: replace deprecated SetWeak usage (Ali Ijaz Sheikh) [#5392](https://github.com/nodejs/node/pull/5392) +* [[`9e6d8170f7`](https://github.com/nodejs/node/commit/9e6d8170f7)] - **contextify**: cleanup weak ref for sandbox (Ali Ijaz Sheikh) [#5392](https://github.com/nodejs/node/pull/5392) +* [[`b6fc15347d`](https://github.com/nodejs/node/commit/b6fc15347d)] - **contextify**: cleanup weak ref for global proxy (Ali Ijaz Sheikh) [#5392](https://github.com/nodejs/node/pull/5392) +* [[`0dc875e2c7`](https://github.com/nodejs/node/commit/0dc875e2c7)] - **deps**: upgrade npm in LTS to 2.15.5 (Rebecca Turner) +* [[`3c50350f41`](https://github.com/nodejs/node/commit/3c50350f41)] - **deps**: fix null pointer checks in v8 (Michaël Zasso) [#6669](https://github.com/nodejs/node/pull/6669) +* [[`a40730b4b4`](https://github.com/nodejs/node/commit/a40730b4b4)] - **deps**: backport IsValid changes from 4e8736d in V8 (Michaël Zasso) [#6669](https://github.com/nodejs/node/pull/6669) +* [[`855604c53a`](https://github.com/nodejs/node/commit/855604c53a)] - **deps**: upgrade npm in LTS to 2.15.4 (Rebecca Turner) [#6663](https://github.com/nodejs/node/pull/6663) +* [[`433fb9a968`](https://github.com/nodejs/node/commit/433fb9a968)] - **deps**: cherry-pick 1383d00 from v8 upstream (Fedor Indutny) [#6179](https://github.com/nodejs/node/pull/6179) +* [[`d1fca27ef8`](https://github.com/nodejs/node/commit/d1fca27ef8)] - **deps**: backport 125ac66 from v8 upstream (Myles Borins) [#6086](https://github.com/nodejs/node/pull/6086) +* [[`df299019a0`](https://github.com/nodejs/node/commit/df299019a0)] - **deps**: upgrade npm in LTS to 2.15.2 (Kat Marchán) +* [[`50f02bd8d6`](https://github.com/nodejs/node/commit/50f02bd8d6)] - **doc**: update vm.runInDebugContext() example (Ben Noordhuis) [#6757](https://github.com/nodejs/node/pull/6757) +* [[`b872feade3`](https://github.com/nodejs/node/commit/b872feade3)] - **doc**: replace functions with arrow functions (abouthiroppy) [#6203](https://github.com/nodejs/node/pull/6203) +* [[`7160229be4`](https://github.com/nodejs/node/commit/7160229be4)] - **doc**: note that zlib.flush acts after pending writes (Anna Henningsen) [#6172](https://github.com/nodejs/node/pull/6172) +* [[`d069f2de8c`](https://github.com/nodejs/node/commit/d069f2de8c)] - **doc**: add full example for zlib.flush() (Anna Henningsen) [#6172](https://github.com/nodejs/node/pull/6172) +* [[`59814acfef`](https://github.com/nodejs/node/commit/59814acfef)] - **doc**: describe child.kill() pitfalls on linux (Robert Jefe Lindstaedt) [#2098](https://github.com/nodejs/node/issues/2098) +* [[`840c09492d`](https://github.com/nodejs/node/commit/840c09492d)] - **doc**: update openssl.org hash links (silverwind) [#6817](https://github.com/nodejs/node/pull/6817) +* [[`126fdc3171`](https://github.com/nodejs/node/commit/126fdc3171)] - **doc**: fix issues related to page scrolling (Roman Reiss) +* [[`29e25d8489`](https://github.com/nodejs/node/commit/29e25d8489)] - **doc**: add steps for running addons + npm tests (Myles Borins) [#6231](https://github.com/nodejs/node/pull/6231) +* [[`fcc6a347f7`](https://github.com/nodejs/node/commit/fcc6a347f7)] - **doc**: get rid of sneaky hard tabs in CHANGELOG (Myles Borins) [#6608](https://github.com/nodejs/node/pull/6608) +* [[`369569018e`](https://github.com/nodejs/node/commit/369569018e)] - **doc**: revert backported commits (Myles Borins) [#6530](https://github.com/nodejs/node/pull/6530) +* [[`4ec9ae8a1c`](https://github.com/nodejs/node/commit/4ec9ae8a1c)] - **doc**: explain differences in console.assert between node and browsers (James M Snell) [#6169](https://github.com/nodejs/node/pull/6169) +* [[`df5ce6fad4`](https://github.com/nodejs/node/commit/df5ce6fad4)] - **doc**: native module reloading is not supported (Bryan English) [#6168](https://github.com/nodejs/node/pull/6168) +* [[`30f354f72b`](https://github.com/nodejs/node/commit/30f354f72b)] - **doc**: clarify fs.watch() and inodes on linux, os x (Joran Dirk Greef) [#6099](https://github.com/nodejs/node/pull/6099) +* [[`29f821b73d`](https://github.com/nodejs/node/commit/29f821b73d)] - **doc**: clarifies http.serverResponse implementation (Allen Hernandez) [#6072](https://github.com/nodejs/node/pull/6072) +* [[`6d560094f4`](https://github.com/nodejs/node/commit/6d560094f4)] - **doc**: minor argument formatting in stream.markdown (James M Snell) [#6016](https://github.com/nodejs/node/pull/6016) +* [[`6a197ec617`](https://github.com/nodejs/node/commit/6a197ec617)] - **doc**: fix http response event, Agent#getName (Matthew Douglass) [#5993](https://github.com/nodejs/node/pull/5993) +* [[`620a261240`](https://github.com/nodejs/node/commit/620a261240)] - **http**: disallow sending obviously invalid status codes (Brian White) [#6291](https://github.com/nodejs/node/pull/6291) +* [[`9a8b53124d`](https://github.com/nodejs/node/commit/9a8b53124d)] - **http**: unref socket timer on parser execute (Fedor Indutny) [#6286](https://github.com/nodejs/node/pull/6286) +* [[`b28e44deb2`](https://github.com/nodejs/node/commit/b28e44deb2)] - **http**: Corrects IPv6 address in Host header (Mihai Potra) [#5314](https://github.com/nodejs/node/pull/5314) +* [[`2fac15ba94`](https://github.com/nodejs/node/commit/2fac15ba94)] - **src**: fix FindFirstCharacter argument alignment (Anna Henningsen) [#6511](https://github.com/nodejs/node/pull/6511) +* [[`2942cff069`](https://github.com/nodejs/node/commit/2942cff069)] - **src**: add missing 'inline' keywords (Ben Noordhuis) [#6056](https://github.com/nodejs/node/pull/6056) +* [[`e0eebf412e`](https://github.com/nodejs/node/commit/e0eebf412e)] - **src,tools**: remove null sentinel from source array (Ben Noordhuis) [#5418](https://github.com/nodejs/node/pull/5418) +* [[`8f18414cd5`](https://github.com/nodejs/node/commit/8f18414cd5)] - **src,tools**: drop nul byte from built-in source code (Ben Noordhuis) [#5418](https://github.com/nodejs/node/pull/5418) +* [[`d7a3ea457b`](https://github.com/nodejs/node/commit/d7a3ea457b)] - **src,tools**: allow utf-8 in built-in js source code (Ben Noordhuis) [#5418](https://github.com/nodejs/node/pull/5418) +* [[`51c0808b55`](https://github.com/nodejs/node/commit/51c0808b55)] - **stream**: Fix readableState.awaitDrain mechanism (Anna Henningsen) [#6023](https://github.com/nodejs/node/pull/6023) +* [[`49a5941d30`](https://github.com/nodejs/node/commit/49a5941d30)] - **test**: fix test-debug-port-cluster flakiness (Rich Trott) [#6769](https://github.com/nodejs/node/pull/6769) +* [[`f8144e4c4a`](https://github.com/nodejs/node/commit/f8144e4c4a)] - **test**: add logging for test-debug-port-cluster (Rich Trott) [#6769](https://github.com/nodejs/node/pull/6769) +* [[`773ea20d0e`](https://github.com/nodejs/node/commit/773ea20d0e)] - **test**: include component in tap output (Ben Noordhuis) [#6653](https://github.com/nodejs/node/pull/6653) +* [[`333369e1ff`](https://github.com/nodejs/node/commit/333369e1ff)] - **test**: increase the platform timeout for AIX (Michael Dawson) [#6342](https://github.com/nodejs/node/pull/6342) +* [[`06e5fafe84`](https://github.com/nodejs/node/commit/06e5fafe84)] - **test**: add tests for console.assert (Evan Lucas) [#6302](https://github.com/nodejs/node/pull/6302) +* [[`f60ba54811`](https://github.com/nodejs/node/commit/f60ba54811)] - **test**: add zlib close-after-error regression test (Anna Henningsen) [#6270](https://github.com/nodejs/node/pull/6270) +* [[`24ac16f4be`](https://github.com/nodejs/node/commit/24ac16f4be)] - **test**: fix flaky test-http-set-timeout-server (Santiago Gimeno) [#6248](https://github.com/nodejs/node/pull/6248) +* [[`5002a71357`](https://github.com/nodejs/node/commit/5002a71357)] - **test**: assert - fixed error messages to match the tests (surya panikkal) [#6241](https://github.com/nodejs/node/pull/6241) +* [[`0f9405dd33`](https://github.com/nodejs/node/commit/0f9405dd33)] - **test**: move more tests from sequential to parallel (Santiago Gimeno) [#6187](https://github.com/nodejs/node/pull/6187) +* [[`37cc249218`](https://github.com/nodejs/node/commit/37cc249218)] - **test**: fix test-net-settimeout flakiness (Santiago Gimeno) [#6166](https://github.com/nodejs/node/pull/6166) +* [[`69dcbb642f`](https://github.com/nodejs/node/commit/69dcbb642f)] - **test**: fix flaky test-child-process-fork-net (Rich Trott) [#6138](https://github.com/nodejs/node/pull/6138) +* [[`a97a6a9d69`](https://github.com/nodejs/node/commit/a97a6a9d69)] - **test**: fix issues for ESLint 2.7.0 (silverwind) [#6132](https://github.com/nodejs/node/pull/6132) +* [[`a865975909`](https://github.com/nodejs/node/commit/a865975909)] - **test**: fix flaky test-http-client-abort (Rich Trott) [#6124](https://github.com/nodejs/node/pull/6124) +* [[`25d4b5b1e9`](https://github.com/nodejs/node/commit/25d4b5b1e9)] - **test**: move some test from sequential to parallel (Santiago Gimeno) [#6087](https://github.com/nodejs/node/pull/6087) +* [[`28040ccf49`](https://github.com/nodejs/node/commit/28040ccf49)] - **test**: refactor test-file-write-stream3 (Rich Trott) [#6050](https://github.com/nodejs/node/pull/6050) +* [[`3a67a05ed4`](https://github.com/nodejs/node/commit/3a67a05ed4)] - **test**: enforce strict mode for test-domain-crypto (Rich Trott) [#6047](https://github.com/nodejs/node/pull/6047) +* [[`0b376cb3f9`](https://github.com/nodejs/node/commit/0b376cb3f9)] - **test**: fix pummel test failures (Rich Trott) [#6012](https://github.com/nodejs/node/pull/6012) +* [[`7b60b8f8e9`](https://github.com/nodejs/node/commit/7b60b8f8e9)] - **test**: fix flakiness of stringbytes-external (Ali Ijaz Sheikh) [#6705](https://github.com/nodejs/node/pull/6705) +* [[`cc4c5187ed`](https://github.com/nodejs/node/commit/cc4c5187ed)] - **test**: ensure test-npm-install uses correct node (Myles Borins) [#6658](https://github.com/nodejs/node/pull/6658) +* [[`3d4d5777bc`](https://github.com/nodejs/node/commit/3d4d5777bc)] - **test**: refactor http-end-throw-socket-handling (Santiago Gimeno) [#5676](https://github.com/nodejs/node/pull/5676) +* [[`c76f214b90`](https://github.com/nodejs/node/commit/c76f214b90)] - **test,tools**: enable linting for undefined vars (Rich Trott) [#6255](https://github.com/nodejs/node/pull/6255) +* [[`9222689215`](https://github.com/nodejs/node/commit/9222689215)] - **test,vm**: enable strict mode for vm tests (Rich Trott) [#6209](https://github.com/nodejs/node/pull/6209) +* [[`b8c9d6b64e`](https://github.com/nodejs/node/commit/b8c9d6b64e)] - **tools**: enable linting for v8_prof_processor.js (Rich Trott) [#6262](https://github.com/nodejs/node/pull/6262) +* [[`8fa202947d`](https://github.com/nodejs/node/commit/8fa202947d)] - **tools**: lint rule for assert.fail() (Rich Trott) [#6261](https://github.com/nodejs/node/pull/6261) +* [[`1aa6c5b7a9`](https://github.com/nodejs/node/commit/1aa6c5b7a9)] - **tools**: update ESLint to 2.7.0 (silverwind) [#6132](https://github.com/nodejs/node/pull/6132) +* [[`68c7de4372`](https://github.com/nodejs/node/commit/68c7de4372)] - **tools**: remove simplejson dependency (Sakthipriyan Vairamani) [#6101](https://github.com/nodejs/node/pull/6101) +* [[`4fb4ba98a8`](https://github.com/nodejs/node/commit/4fb4ba98a8)] - **tools**: remove disabling of already-disabled rule (Rich Trott) [#6013](https://github.com/nodejs/node/pull/6013) +* [[`4e6ea7f01a`](https://github.com/nodejs/node/commit/4e6ea7f01a)] - **tools**: remove obsolete npm test-legacy command (Kat Marchán) +* [[`4c73ab4302`](https://github.com/nodejs/node/commit/4c73ab4302)] - **tools,doc**: fix json for grouped optional params (firedfox) [#5977](https://github.com/nodejs/node/pull/5977) +* [[`c893cd33d1`](https://github.com/nodejs/node/commit/c893cd33d1)] - **tools,doc**: parse types in braces everywhere (Alexander Makarenko) [#5329](https://github.com/nodejs/node/pull/5329) +* [[`48684af55f`](https://github.com/nodejs/node/commit/48684af55f)] - **zlib**: fix use after null when calling .close (James Lal) [#5982](https://github.com/nodejs/node/pull/5982) + ## 2016-05-05, Version 4.4.4 'Argon' (LTS), @thealphanerd @@ -493,7 +709,7 @@ Notable semver patch changes include: * [[`c9e2dce247`](https://github.com/nodejs/node/commit/c9e2dce247)] - **querystring**: improve parse() performance (Brian White) [#4675](https://github.com/nodejs/node/pull/4675) * [[`18542c41fe`](https://github.com/nodejs/node/commit/18542c41fe)] - **repl**: remove variable redeclaration (Rich Trott) [#4977](https://github.com/nodejs/node/pull/4977) * [[`10be8dc360`](https://github.com/nodejs/node/commit/10be8dc360)] - **src**: force line buffering for stderr (Rich Trott) [#3701](https://github.com/nodejs/node/pull/3701) -* [[`7958664e85`](https://github.com/nodejs/node/commit/7958664e85)] - **src**: clean up usage of __proto__ (Jackson Tian) [#5069](https://github.com/nodejs/node/pull/5069) +* [[`7958664e85`](https://github.com/nodejs/node/commit/7958664e85)] - **src**: clean up usage of `__proto__` (Jackson Tian) [#5069](https://github.com/nodejs/node/pull/5069) * [[`4e0a0d51b3`](https://github.com/nodejs/node/commit/4e0a0d51b3)] - **src**: remove no longer relevant comments (Chris911) [#4843](https://github.com/nodejs/node/pull/4843) * [[`51c8bc8abc`](https://github.com/nodejs/node/commit/51c8bc8abc)] - **src**: remove __builtin_bswap16 call (Ben Noordhuis) [#4290](https://github.com/nodejs/node/pull/4290) * [[`5e1976e37c`](https://github.com/nodejs/node/commit/5e1976e37c)] - **src**: remove unused BITS_PER_LONG macro (Ben Noordhuis) [#4290](https://github.com/nodejs/node/pull/4290) @@ -1314,7 +1530,7 @@ See https://github.com/nodejs/node/labels/confirmed-bug for complete and current * [[`54795620f6`](https://github.com/nodejs/node/commit/54795620f6)] - **buffer**: don't abort on prototype getters (Trevor Norris) [#3302](https://github.com/nodejs/node/pull/3302) * [[`660f7591c8`](https://github.com/nodejs/node/commit/660f7591c8)] - **buffer**: FreeCallback should be tied to ArrayBuffer (Fedor Indutny) [#3198](https://github.com/nodejs/node/pull/3198) * [[`651a5b51eb`](https://github.com/nodejs/node/commit/651a5b51eb)] - **buffer**: only check if instance is Uint8Array (Trevor Norris) [#3080](https://github.com/nodejs/node/pull/3080) -* [[`d5a1b1ad7c`](https://github.com/nodejs/node/commit/d5a1b1ad7c)] - **buffer**: clean up usage of __proto__ (Trevor Norris) [#3080](https://github.com/nodejs/node/pull/3080) +* [[`d5a1b1ad7c`](https://github.com/nodejs/node/commit/d5a1b1ad7c)] - **buffer**: clean up usage of `__proto__` (Trevor Norris) [#3080](https://github.com/nodejs/node/pull/3080) * [[`af24376e18`](https://github.com/nodejs/node/commit/af24376e18)] - **build**: Intl: deps: bump ICU to 56.1 (GA) (Steven R. Loomis) [#3281](https://github.com/nodejs/node/pull/3281) * [[`9136359d57`](https://github.com/nodejs/node/commit/9136359d57)] - **build**: make icu download path customizable (Johan Bergström) [#3200](https://github.com/nodejs/node/pull/3200) * [[`b3c5ad10a8`](https://github.com/nodejs/node/commit/b3c5ad10a8)] - **build**: add --with-arm-fpu option (Jérémy Lal) [#3228](https://github.com/nodejs/node/pull/3228) diff --git a/doc/changelogs/CHANGELOG_V5.md b/doc/changelogs/CHANGELOG_V5.md index 717c218e77bc9c..06ce6a35e0dde4 100644 --- a/doc/changelogs/CHANGELOG_V5.md +++ b/doc/changelogs/CHANGELOG_V5.md @@ -137,7 +137,7 @@ around June 2016. Users of v5 should upgrade to [Node.js v6](CHANGELOG_V6.md). * [[`a259ee4018`](https://github.com/nodejs/node/commit/a259ee4018)] - **http**: unref socket timer on parser execute (Fedor Indutny) [#6286](https://github.com/nodejs/node/pull/6286) * [[`d4abca5b27`](https://github.com/nodejs/node/commit/d4abca5b27)] - **lib**: remove bootstrap global context indirection (Jeremiah Senkpiel) [#5881](https://github.com/nodejs/node/pull/5881) * [[`c8783aff21`](https://github.com/nodejs/node/commit/c8783aff21)] - **lib,test,tools**: alignment on variable assignments (Rich Trott) [#6242](https://github.com/nodejs/node/pull/6242) -* [[`d5d4f194f1`](https://github.com/nodejs/node/commit/d5d4f194f1)] - **net**: replace __defineGetter__ with defineProperty (Fedor Indutny) [#6284](https://github.com/nodejs/node/pull/6284) +* [[`d5d4f194f1`](https://github.com/nodejs/node/commit/d5d4f194f1)] - **net**: replace `__defineGetter__` with defineProperty (Fedor Indutny) [#6284](https://github.com/nodejs/node/pull/6284) * [[`6d9c0c9aa7`](https://github.com/nodejs/node/commit/6d9c0c9aa7)] - **(SEMVER-MINOR)** **net**: support DNS hints in createConnection() (Colin Ihrig) [#6000](https://github.com/nodejs/node/pull/6000) * [[`457f24f19c`](https://github.com/nodejs/node/commit/457f24f19c)] - **(SEMVER-MINOR)** **node**: make builtin libs available for `--eval` (Anna Henningsen) [#6207](https://github.com/nodejs/node/pull/6207) * [[`fc89d17656`](https://github.com/nodejs/node/commit/fc89d17656)] - **path**: fixing a test that breaks on some machines. (Mike Kaufman) [#6067](https://github.com/nodejs/node/pull/6067) @@ -821,7 +821,7 @@ This is an important security release. All Node.js users should consult the secu * [[`2844cc03dc`](https://github.com/nodejs/node/commit/2844cc03dc)] - **repl**: remove variable redeclaration (Rich Trott) [#4977](https://github.com/nodejs/node/pull/4977) * [[`ac6627a0fe`](https://github.com/nodejs/node/commit/ac6627a0fe)] - **src**: avoid compiler warning in node_revert.cc (James M Snell) * [[`459c5844c8`](https://github.com/nodejs/node/commit/459c5844c8)] - **(SEMVER-MINOR)** **src**: add --security-revert command line flag (James M Snell) -* [[`95615196de`](https://github.com/nodejs/node/commit/95615196de)] - **src**: clean up usage of __proto__ (Jackson Tian) [#5069](https://github.com/nodejs/node/pull/5069) +* [[`95615196de`](https://github.com/nodejs/node/commit/95615196de)] - **src**: clean up usage of `__proto__` (Jackson Tian) [#5069](https://github.com/nodejs/node/pull/5069) * [[`e93b024214`](https://github.com/nodejs/node/commit/e93b024214)] - **src**: remove no longer relevant comments (Chris911) [#4843](https://github.com/nodejs/node/pull/4843) * [[`a2c257a3ef`](https://github.com/nodejs/node/commit/a2c257a3ef)] - **src**: fix negative values in process.hrtime() (Ben Noordhuis) [#4757](https://github.com/nodejs/node/pull/4757) * [[`b46f3b84d4`](https://github.com/nodejs/node/commit/b46f3b84d4)] - **src,deps**: replace LoadLibrary by LoadLibraryW (Cheng Zhao) [iojs/io.js#226](https://github.com/iojs/io.js/pull/226) diff --git a/doc/changelogs/CHANGELOG_V6.md b/doc/changelogs/CHANGELOG_V6.md index d3accdbb61c66f..709c03b9106455 100644 --- a/doc/changelogs/CHANGELOG_V6.md +++ b/doc/changelogs/CHANGELOG_V6.md @@ -511,7 +511,7 @@ October 2016. * [[`4cc6a18448`](https://github.com/nodejs/node/commit/4cc6a18448)] - **test**: verify IPC messages are emitted on next tick (Santiago Gimeno) [#6909](https://github.com/nodejs/node/pull/6909) * [[`69e119dbfb`](https://github.com/nodejs/node/commit/69e119dbfb)] - **test**: refactor spawnSync() cwd test (cjihrig) [#6939](https://github.com/nodejs/node/pull/6939) * [[`32cc43a1bd`](https://github.com/nodejs/node/commit/32cc43a1bd)] - **test**: fix component printing on windows (Ben Noordhuis) [#6915](https://github.com/nodejs/node/pull/6915) -* [[`c81b6f8d0d`](https://github.com/nodejs/node/commit/c81b6f8d0d)] - **test**: refactor to eliminate __defineGetter__ (Rich Trott) [#6774](https://github.com/nodejs/node/pull/6774) +* [[`c81b6f8d0d`](https://github.com/nodejs/node/commit/c81b6f8d0d)] - **test**: refactor to eliminate `__defineGetter__` (Rich Trott) [#6774](https://github.com/nodejs/node/pull/6774) * [[`1965e445ec`](https://github.com/nodejs/node/commit/1965e445ec)] - **test**: refactor test-tls-reuse-host-from-socket (Rich Trott) [#6756](https://github.com/nodejs/node/pull/6756) * [[`2cf3a53ce1`](https://github.com/nodejs/node/commit/2cf3a53ce1)] - **test**: fix test-debug-port-cluster flakiness (Rich Trott) [#6769](https://github.com/nodejs/node/pull/6769) * [[`5374afdef8`](https://github.com/nodejs/node/commit/5374afdef8)] - **test**: add logging for test-debug-port-cluster (Rich Trott) [#6769](https://github.com/nodejs/node/pull/6769) @@ -622,7 +622,7 @@ running in big endian mode in addition to the existing 64-bit binaries for runni * [[`2000072903`](https://github.com/nodejs/node/commit/2000072903)] - **handle_wrap**: IsRefed -> Unrefed, no isAlive check (Jeremiah Senkpiel) [#6204](https://github.com/nodejs/node/pull/6204) * [[`d3132048cb`](https://github.com/nodejs/node/commit/d3132048cb)] - **(SEMVER-MINOR)** **handle_wrap**: expose an `isRefed()` check to JS (Jeremiah Senkpiel) [#5834](https://github.com/nodejs/node/pull/5834) * [[`59666502c5`](https://github.com/nodejs/node/commit/59666502c5)] - **intl**: Don't crash if v8BreakIterator not available (Steven R. Loomis) [#4253](https://github.com/nodejs/node/pull/4253) -* [[`74582aa590`](https://github.com/nodejs/node/commit/74582aa590)] - **lib**: replace legacy uses of __defineGetter__ (James M Snell) [#6768](https://github.com/nodejs/node/pull/6768) +* [[`74582aa590`](https://github.com/nodejs/node/commit/74582aa590)] - **lib**: replace legacy uses of `__defineGetter__` (James M Snell) [#6768](https://github.com/nodejs/node/pull/6768) * [[`559c2583e0`](https://github.com/nodejs/node/commit/559c2583e0)] - **lib,test**: update in preparation for linter update (Rich Trott) [#6498](https://github.com/nodejs/node/pull/6498) * [[`226b9668db`](https://github.com/nodejs/node/commit/226b9668db)] - **(SEMVER-MINOR)** **repl**: copying tabs shouldn't trigger completion (Eugene Obrezkov) [#5958](https://github.com/nodejs/node/pull/5958) * [[`ce2d5be4a1`](https://github.com/nodejs/node/commit/ce2d5be4a1)] - **(SEMVER-MINOR)** **repl**: exports `Recoverable` (Blake Embrey) [#3488](https://github.com/nodejs/node/pull/3488) diff --git a/doc/ctc-meetings/2016-02-03.md b/doc/ctc-meetings/2016-02-03.md index d44596dfd87b93..687cbe7ee7e9a3 100644 --- a/doc/ctc-meetings/2016-02-03.md +++ b/doc/ctc-meetings/2016-02-03.md @@ -180,7 +180,7 @@ James: If you’ve been holding off on it, I don’t really care about the name Rod: Likely a two line comment at the top of all files. -### @srl295: [path for full-icu data?](https://github.com/nodejs/node/issues/3460) - ./node_modules vs ./node/ ? (npm linkage) +### @srl295: [path for full-icu data?](https://github.com/nodejs/node/issues/3460) - ./node_modules vs ./node/ ? (npm linkage) Steven: Put together a proof of concept. Core question here is: is full-icu try to use a directory such as node_modules, or is that hijacking it for improper use [cd: unsure if I captured that correctly] diff --git a/doc/ctc-meetings/2016-06-15.md b/doc/ctc-meetings/2016-06-15.md index 3af642b840228f..4168b3613136fa 100644 --- a/doc/ctc-meetings/2016-06-15.md +++ b/doc/ctc-meetings/2016-06-15.md @@ -137,8 +137,6 @@ replaces https://github.com/nodejs/node-eps/blob/master/002-es6-modules.md#51-de This would be part of ECMA262 so browsers would do the same, but needs to be ironed out in TC39. On [agenda][TC39 Agenda] for 7/26 TC39 meeting. -[TC39 Agenda]: https://github.com/tc39/agendas/blob/master/2016/07.md - What if nothing is imported or exported? Could do `export default null` to export nothing. Starting off, preferred goal when preparing code would be CommonJS/script, later on could change to ES6/module. @@ -173,3 +171,4 @@ None. ## Next Meeting 2016-06-22 +[TC39 Agenda]: https://github.com/tc39/agendas/blob/master/2016/07.md diff --git a/doc/guides/building-node-with-ninja.md b/doc/guides/building-node-with-ninja.md index eb5791af548145..a9a3a922ed6820 100644 --- a/doc/guides/building-node-with-ninja.md +++ b/doc/guides/building-node-with-ninja.md @@ -9,7 +9,7 @@ To build Node with ninja, there are 3 steps that must be taken: 3. Lastly, make symlink to `./node` using `ln -fs out/Release/node node`. When running `ninja -C out/Release` you will see output similar to the following if the build has succeeded: -``` +```txt ninja: Entering directory `out/Release` [4/4] LINK node, POSTBUILDS ``` diff --git a/doc/onboarding-extras.md b/doc/onboarding-extras.md index 5fc5424224ca38..279bb386381755 100644 --- a/doc/onboarding-extras.md +++ b/doc/onboarding-extras.md @@ -66,7 +66,7 @@ Please use these when possible / appropriate * minor vs. patch: roughly: "does it add a new method / does it add a new section to the docs" * major vs. everything else: run last versions tests against this version, if they pass, **probably** minor or patch * A breaking change helper ([full source](https://gist.github.com/chrisdickinson/ba532fa0e4e243fb7b44)): - ``` + ```sh git checkout $(git show -s --pretty='%T' $(git show-ref -d $(git describe --abbrev=0) | tail -n1 | awk '{print $1}')) -- test; make -j8 test ``` diff --git a/doc/releases.md b/doc/releases.md index 8ea4484c2a6430..b5e57d1251747c 100644 --- a/doc/releases.md +++ b/doc/releases.md @@ -1,5 +1,4 @@ -Node.js Release Process -===================== +# Node.js Release Process This document describes the technical aspects of the Node.js release process. The intended audience is those who have been authorized by the Node.js Foundation Technical Steering Committee (TSC) to create, promote, and sign official release builds for Node.js, hosted on . @@ -35,8 +34,8 @@ A SHASUMS256.txt file is produced for every promoted build, nightly, and release The GPG keys should be fetchable from a known third-party keyserver. The SKS Keyservers at are recommended. Use the [submission](https://sks-keyservers.net/i/#submit) form to submit a new GPG key. Keys should be fetchable via: -``` -gpg --keyserver pool.sks-keyservers.net --recv-keys +```sh +$ gpg --keyserver pool.sks-keyservers.net --recv-keys ``` The key you use may be a child/subkey of an existing key. @@ -56,7 +55,7 @@ Create a new branch named _"vx.y.z-proposal"_, or something similar. Using `git For a list of commits that could be landed in a patch release on v5.x -``` +```sh $ branch-diff v5.x master --exclude-label=semver-major,semver-minor,dont-land-on-v5.x --filter-release --format=simple ``` @@ -66,7 +65,7 @@ Carefully review the list of commits looking for errors (incorrect `PR-URL`, inc Set the version for the proposed release using the following macros, which are already defined in `src/node_version.h`: -``` +```c #define NODE_MAJOR_VERSION x #define NODE_MINOR_VERSION y #define NODE_PATCH_VERSION z @@ -74,7 +73,7 @@ Set the version for the proposed release using the following macros, which are a Set the `NODE_VERSION_IS_RELEASE` macro value to `1`. This causes the build to be produced with a version string that does not have a trailing pre-release tag: -``` +```c #define NODE_VERSION_IS_RELEASE 1 ``` @@ -95,13 +94,13 @@ The general rule is to bump this version when there are _breaking ABI_ changes a Collect a formatted list of commits since the last release. Use [`changelog-maker`](https://github.com/rvagg/changelog-maker) to do this. -``` +```sh $ changelog-maker --group ``` Note that changelog-maker counts commits since the last tag and if the last tag in the repository was not on the current branch you may have to supply a `--start-ref` argument: -``` +```sh $ changelog-maker --group --start-ref v2.3.1 ``` @@ -117,8 +116,8 @@ file in the release branch (e.g. a release for Node.js v4 would be added to the The new entry should take the following form: -``` - ## YYYY-MM-DD, Version x.y.z (Release Type), @releaser ### Notable changes @@ -161,7 +160,7 @@ The `CHANGELOG.md`, `doc/changelogs/CHANGELOG_*.md`, `src/node_version.h`, and `REPLACEME` changes should be the final commit that will be tagged for the release. When committing these to git, use the following message format: -``` +```txt YYYY-MM-DD, Version x.y.z (Release Type) Notable changes: @@ -219,7 +218,7 @@ Tag summaries have a predictable format, look at a recent tag to see, `git tag - Create a tag using the following command: -``` +```sh $ git tag -sm 'YYYY-MM-DD Node.js vx.y.z (Release Type) Release' ``` @@ -227,7 +226,7 @@ The tag **must** be signed using the GPG key that's listed for you on the projec Push the tag to the repo before you promote the builds. If you haven't pushed your tag first, then build promotion won't work properly. Push the tag using the following command: -``` +```sh $ git push ``` @@ -240,7 +239,7 @@ On release proposal branch, edit `src/node_version.h` again and: Commit this change with the following commit message format: -``` +```txt Working on vx.y.z # where 'z' is the incremented patch number PR-URL: diff --git a/doc/topics/blocking-vs-non-blocking.md b/doc/topics/blocking-vs-non-blocking.md index 788887ae3b4a11..606371789e8caa 100644 --- a/doc/topics/blocking-vs-non-blocking.md +++ b/doc/topics/blocking-vs-non-blocking.md @@ -6,7 +6,7 @@ prior knowledge of those topics is required. Readers are assumed to have a basic understanding of the JavaScript language and Node.js callback pattern. > "I/O" refers primarily to interaction with the system's disk and -network supported by [libuv](http://libuv.org/). +> network supported by [libuv](http://libuv.org/). ## Blocking diff --git a/doc/topics/domain-postmortem.md b/doc/topics/domain-postmortem.md index c33c85b430e02a..e03012db926b08 100644 --- a/doc/topics/domain-postmortem.md +++ b/doc/topics/domain-postmortem.md @@ -298,4 +298,4 @@ proposal for Zones being prepared for the TC39. At such time there is suitable functionality to replace domains it will undergo the full deprecation cycle and eventually be removed from core. -[domain-resource-cleanup-example.js]: ./domain-resource-cleanup-example.js +[`domain-resource-cleanup-example.js`]: ./domain-resource-cleanup-example.js diff --git a/doc/tsc-meetings/io.js/2014-12-10.md b/doc/tsc-meetings/io.js/2014-12-10.md index 8bbfdfed10df78..a28ad644a5b9ac 100644 --- a/doc/tsc-meetings/io.js/2014-12-10.md +++ b/doc/tsc-meetings/io.js/2014-12-10.md @@ -130,7 +130,7 @@ https://github.com/nodejs/io.js/issues/11 * Chris: +0 -### Working with nvm, nvmw and similar installation managers +### Working with nvm, nvmw and similar installation managers https://github.com/nodejs/io.js/issues/40 From 2f45941807e570ec0278bf8b46159a67309b875a Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sat, 16 Jul 2016 13:24:52 -0700 Subject: [PATCH 012/144] test: handle IPv6 localhost issues within tests The issue of hosts that do not resolve `localhost` to `::1` is now handled within the tests. Remove flaky status for test-https-connect-address-family and test-tls-connect-address-family. PR-URL: https://github.com/nodejs/node/pull/7766 Reviewed-By: Sakthipriyan Vairamani Reviewed-By: Michael Dawson Reviewed-By: Ben Noordhuis --- test/parallel/parallel.status | 7 ------- test/parallel/test-https-connect-address-family.js | 7 ++++++- test/parallel/test-tls-connect-address-family.js | 7 ++++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index fc71d4165743a6..88d0cb9465353e 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -12,13 +12,6 @@ test-tick-processor : PASS,FLAKY [$system==linux] test-tick-processor : PASS,FLAKY -# Flaky until https://github.com/nodejs/build/issues/415 is resolved. -# On some of the buildbots, AAAA queries for localhost don't resolve -# to an address and neither do any of the alternatives from the -# localIPv6Hosts list from test/common.js. -test-https-connect-address-family : PASS,FLAKY -test-tls-connect-address-family : PASS,FLAKY - [$system==macos] [$system==solaris] # Also applies to SmartOS diff --git a/test/parallel/test-https-connect-address-family.js b/test/parallel/test-https-connect-address-family.js index 21d0bf8dc6a1a2..ab13e060be06ac 100644 --- a/test/parallel/test-https-connect-address-family.js +++ b/test/parallel/test-https-connect-address-family.js @@ -36,8 +36,13 @@ function runTest() { } dns.lookup('localhost', {family: 6, all: true}, (err, addresses) => { - if (err) + if (err) { + if (err.code === 'ENOTFOUND') { + common.skip('localhost does not resolve to ::1'); + return; + } throw err; + } if (addresses.some((val) => val.address === '::1')) runTest(); diff --git a/test/parallel/test-tls-connect-address-family.js b/test/parallel/test-tls-connect-address-family.js index 6274328956e63d..35216d91f6e49f 100644 --- a/test/parallel/test-tls-connect-address-family.js +++ b/test/parallel/test-tls-connect-address-family.js @@ -35,8 +35,13 @@ function runTest() { } dns.lookup('localhost', {family: 6, all: true}, (err, addresses) => { - if (err) + if (err) { + if (err.code === 'ENOTFOUND') { + common.skip('localhost does not resolve to ::1'); + return; + } throw err; + } if (addresses.some((val) => val.address === '::1')) runTest(); From da481c634ff32e23199a0c4855b2f0cadc11e6df Mon Sep 17 00:00:00 2001 From: cjihrig Date: Wed, 20 Jul 2016 12:49:41 -0400 Subject: [PATCH 013/144] child_process: support stdio option in fork() This commit allows child_process.fork() to pass stdio options to spawn(). This allows fork() to more easily take advantage of additional stdio channels. Refs: https://github.com/nodejs/node-v0.x-archive/issues/5727 PR-URL: https://github.com/nodejs/node/pull/7811 Reviewed-By: Myles Borins Reviewed-By: Minwoo Jung Reviewed-By: Santiago Gimeno --- doc/api/child_process.md | 2 + lib/child_process.js | 12 +++-- .../parallel/test-child-process-fork-stdio.js | 54 +++++++++++++++++++ 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 test/parallel/test-child-process-fork-stdio.js diff --git a/doc/api/child_process.md b/doc/api/child_process.md index e79b411e91eacf..7c01e34cecb7b2 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -253,6 +253,8 @@ added: v0.5.0 piped to the parent, otherwise they will be inherited from the parent, see the `'pipe'` and `'inherit'` options for [`child_process.spawn()`][]'s [`stdio`][] for more details (Default: `false`) + * `stdio` {Array} Supports the array version of [`child_process.spawn()`][]'s + [`stdio`][] option. When this option is provided, it overrides `silent`. * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) * Return: {ChildProcess} diff --git a/lib/child_process.js b/lib/child_process.js index ba8fe911f5c224..1df450e1aa4a28 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -44,10 +44,14 @@ exports.fork = function(modulePath /*, args, options*/) { args = execArgv.concat([modulePath], args); - // Leave stdin open for the IPC channel. stdout and stderr should be the - // same as the parent's if silent isn't set. - options.stdio = options.silent ? ['pipe', 'pipe', 'pipe', 'ipc'] : - [0, 1, 2, 'ipc']; + if (!Array.isArray(options.stdio)) { + // Leave stdin open for the IPC channel. stdout and stderr should be the + // same as the parent's if silent isn't set. + options.stdio = options.silent ? ['pipe', 'pipe', 'pipe', 'ipc'] : + [0, 1, 2, 'ipc']; + } else if (options.stdio.indexOf('ipc') === -1) { + throw new TypeError('Forked processes must have an IPC channel'); + } options.execPath = options.execPath || process.execPath; diff --git a/test/parallel/test-child-process-fork-stdio.js b/test/parallel/test-child-process-fork-stdio.js new file mode 100644 index 00000000000000..89a5ff98e5f8a8 --- /dev/null +++ b/test/parallel/test-child-process-fork-stdio.js @@ -0,0 +1,54 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); +const net = require('net'); + +if (process.argv[2] === 'child') { + process.stdout.write('this should be ignored'); + process.stderr.write('this should not be ignored'); + + const pipe = new net.Socket({ fd: 4 }); + + process.on('disconnect', () => { + pipe.unref(); + }); + + pipe.setEncoding('utf8'); + pipe.on('data', (data) => { + process.send(data); + }); +} else { + assert.throws(() => { + cp.fork(__filename, {stdio: ['pipe', 'pipe', 'pipe', 'pipe']}); + }, /Forked processes must have an IPC channel/); + + let ipc = ''; + let stderr = ''; + const buf = Buffer.from('data to send via pipe'); + const child = cp.fork(__filename, ['child'], { + stdio: [0, 'ignore', 'pipe', 'ipc', 'pipe'] + }); + + assert.strictEqual(child.stdout, null); + + child.on('message', (msg) => { + ipc += msg; + + if (ipc === buf.toString()) { + child.disconnect(); + } + }); + + child.stderr.on('data', (chunk) => { + stderr += chunk; + }); + + child.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + assert.strictEqual(stderr, 'this should not be ignored'); + })); + + child.stdio[4].write(buf); +} From 17ae49a055558be123f0be3928f1724807d653da Mon Sep 17 00:00:00 2001 From: Brian White Date: Tue, 19 Jul 2016 17:57:04 -0400 Subject: [PATCH 014/144] doc: improve Buffer code examples PR-URL: https://github.com/nodejs/node/pull/7784 Reviewed-By: James M Snell Reviewed-By: Trevor Norris --- doc/api/buffer.md | 812 ++++++++++++++++++++++++++++------------------ 1 file changed, 500 insertions(+), 312 deletions(-) diff --git a/doc/api/buffer.md b/doc/api/buffer.md index f0104207c50f22..32114540531980 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -21,26 +21,26 @@ The `Buffer` class is a global within Node.js, making it unlikely that one would need to ever use `require('buffer').Buffer`. ```js +// Creates a zero-filled Buffer of length 10. const buf1 = Buffer.alloc(10); - // Creates a zero-filled Buffer of length 10. +// Creates a Buffer of length 10, filled with 0x1. const buf2 = Buffer.alloc(10, 1); - // Creates a Buffer of length 10, filled with 0x01. +// Creates an uninitialized buffer of length 10. +// This is faster than calling Buffer.alloc() but the returned +// Buffer instance might contain old data that needs to be +// overwritten using either fill() or write(). const buf3 = Buffer.allocUnsafe(10); - // Creates an uninitialized buffer of length 10. - // This is faster than calling Buffer.alloc() but the returned - // Buffer instance might contain old data that needs to be - // overwritten using either fill() or write(). -const buf4 = Buffer.from([1,2,3]); - // Creates a Buffer containing [01, 02, 03]. +// Creates a Buffer containing [0x1, 0x2, 0x3]. +const buf4 = Buffer.from([1, 2, 3]); +// Creates a Buffer containing ASCII bytes [0x74, 0x65, 0x73, 0x74]. const buf5 = Buffer.from('test'); - // Creates a Buffer containing ASCII bytes [74, 65, 73, 74]. +// Creates a Buffer containing UTF-8 bytes [0x74, 0xc3, 0xa9, 0x73, 0x74]. const buf6 = Buffer.from('tést', 'utf8'); - // Creates a Buffer containing UTF8 bytes [74, c3, a9, 73, 74]. ``` ## `Buffer.from()`, `Buffer.alloc()`, and `Buffer.allocUnsafe()` @@ -142,10 +142,12 @@ by using an explicit encoding method. ```js const buf = Buffer.from('hello world', 'ascii'); + +// Prints: 68656c6c6f20776f726c64 console.log(buf.toString('hex')); - // prints: 68656c6c6f20776f726c64 + +// Prints: aGVsbG8gd29ybGQ= console.log(buf.toString('base64')); - // prints: aGVsbG8gd29ybGQ= ``` The character encodings currently supported by Node.js include: @@ -204,22 +206,29 @@ a TypedArray instance by using the TypeArray object's `.buffer` property: ```js const arr = new Uint16Array(2); + arr[0] = 5000; arr[1] = 4000; -const buf1 = Buffer.from(arr); // copies the buffer -const buf2 = Buffer.from(arr.buffer); // shares the memory with arr; +// Copies the contents of `arr` +const buf1 = Buffer.from(arr); + +// Shares memory with `arr` +const buf2 = Buffer.from(arr.buffer); +// Prints: console.log(buf1); - // Prints: , copied buffer has only two elements + +// Prints: console.log(buf2); - // Prints: arr[1] = 6000; + +// Prints: console.log(buf1); - // Prints: + +// Prints: console.log(buf2); - // Prints: ``` Note that when creating a `Buffer` using the TypedArray's `.buffer`, it is @@ -229,8 +238,9 @@ possible to use only a portion of the underlying `ArrayBuffer` by passing in ```js const arr = new Uint16Array(20); const buf = Buffer.from(arr.buffer, 0, 16); + +// Prints: 16 console.log(buf.length); - // Prints: 16 ``` The `Buffer.from()` and [`TypedArray.from()`][] (e.g.`Uint8Array.from()`) have @@ -255,13 +265,13 @@ Buffers can be iterated over using the ECMAScript 2015 (ES6) `for..of` syntax: ```js const buf = Buffer.from([1, 2, 3]); -for (var b of buf) - console.log(b); - // Prints: // 1 // 2 // 3 +for (var b of buf) { + console.log(b); +} ``` Additionally, the [`buf.values()`][], [`buf.keys()`][], and @@ -285,9 +295,8 @@ deprecated: v6.0.0 Allocates a new Buffer using an `array` of octets. ```js -const buf = new Buffer([0x62,0x75,0x66,0x66,0x65,0x72]); - // creates a new Buffer containing ASCII bytes - // ['b','u','f','f','e','r'] +// Creates a new Buffer containing the ASCII bytes of the string 'buffer' +const buf = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); ``` ### new Buffer(buffer) @@ -307,10 +316,12 @@ const buf1 = new Buffer('buffer'); const buf2 = new Buffer(buf1); buf1[0] = 0x61; + +// Prints: auffer console.log(buf1.toString()); - // 'auffer' + +// Prints: buffer console.log(buf2.toString()); - // 'buffer' (copy is not changed) ``` ### new Buffer(arrayBuffer[, byteOffset [, length]]) @@ -336,19 +347,21 @@ the `arrayBuffer` that will be shared by the `Buffer`. ```js const arr = new Uint16Array(2); + arr[0] = 5000; arr[1] = 4000; -const buf = new Buffer(arr.buffer); // shares the memory with arr; +// Shares memory with `arr` +const buf = new Buffer(arr.buffer); +// Prints: console.log(buf); - // Prints: -// changing the TypdArray changes the Buffer also +// Changing the original Uint16Array changes the Buffer also arr[1] = 6000; +// Prints: console.log(buf); - // Prints: ``` ### new Buffer(size) @@ -375,12 +388,14 @@ a `Buffer` to zeroes. ```js const buf = new Buffer(5); + +// Prints (contents may vary): console.log(buf); - // - // (octets will be different, every time) + buf.fill(0); + +// Prints: console.log(buf); - // ``` ### new Buffer(str[, encoding]) @@ -399,14 +414,18 @@ provided, the `encoding` parameter identifies the strings character encoding. ```js const buf1 = new Buffer('this is a tést'); + +// Prints: this is a tést console.log(buf1.toString()); - // prints: this is a tést + +// Prints: this is a tC)st console.log(buf1.toString('ascii')); - // prints: this is a tC)st + const buf2 = new Buffer('7468697320697320612074c3a97374', 'hex'); + +// Prints: this is a tést console.log(buf2.toString()); - // prints: this is a tést ``` ### Class Method: Buffer.alloc(size[, fill[, encoding]]) @@ -423,8 +442,9 @@ Allocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the ```js const buf = Buffer.alloc(5); + +// Prints: console.log(buf); - // ``` The `size` must be less than or equal to the value of @@ -437,8 +457,9 @@ If `fill` is specified, the allocated `Buffer` will be initialized by calling ```js const buf = Buffer.alloc(5, 'a'); + +// Prints: console.log(buf); - // ``` If both `fill` and `encoding` are specified, the allocated `Buffer` will be @@ -446,8 +467,9 @@ initialized by calling `buf.fill(fill, encoding)`. For example: ```js const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64'); + +// Prints: console.log(buf); - // ``` Calling `Buffer.alloc(size)` can be significantly slower than the alternative @@ -476,12 +498,14 @@ initialized*. The contents of the newly created `Buffer` are unknown and ```js const buf = Buffer.allocUnsafe(5); + +// Prints (contents may vary): console.log(buf); - // - // (octets will be different, every time) + buf.fill(0); + +// Prints: console.log(buf); - // ``` A `TypeError` will be thrown if `size` is not a number. @@ -532,15 +556,18 @@ to create an un-pooled Buffer instance using `Buffer.allocUnsafeSlow()` then copy out the relevant bits. ```js -// need to keep around a few small chunks of memory +// Need to keep around a few small chunks of memory const store = []; socket.on('readable', () => { const data = socket.read(); - // allocate for retained data + + // Allocate for retained data const sb = Buffer.allocUnsafeSlow(10); - // copy the data into the new allocation + + // Copy the data into the new allocation data.copy(sb, 0, 0, 10); + store.push(sb); }); ``` @@ -565,10 +592,9 @@ Example: ```js const str = '\u00bd + \u00bc = \u00be'; +// Prints: ½ + ¼ = ¾: 9 characters, 12 bytes console.log(`${str}: ${str.length} characters, ` + `${Buffer.byteLength(str, 'utf8')} bytes`); - -// ½ + ¼ = ¾: 9 characters, 12 bytes ``` When `string` is a `Buffer`/[`DataView`][]/[`TypedArray`][]/`ArrayBuffer`, @@ -589,8 +615,13 @@ Compares `buf1` to `buf2` typically for the purpose of sorting arrays of Buffers. This is equivalent is calling [`buf1.compare(buf2)`][]. ```js -const arr = [Buffer.from('1234'), Buffer.from('0123')]; -arr.sort(Buffer.compare); +const buf1 = Buffer.from('1234'); +const buf2 = Buffer.from('0123'); +const arr = [buf1, buf2]; + +// Prints: [ , ] +// (This result is equal to: [buf2, buf1]) +console.log(arr.sort(Buffer.compare)); ``` ### Class Method: Buffer.concat(list[, totalLength]) @@ -621,14 +652,16 @@ const buf2 = Buffer.alloc(14); const buf3 = Buffer.alloc(18); const totalLength = buf1.length + buf2.length + buf3.length; +// Prints: 42 console.log(totalLength); + const bufA = Buffer.concat([buf1, buf2, buf3], totalLength); + +// Prints: console.log(bufA); -console.log(bufA.length); -// 42 -// -// 42 +// Prints: 42 +console.log(bufA.length); ``` ### Class Method: Buffer.from(array) @@ -641,9 +674,8 @@ added: v3.0.0 Allocates a new `Buffer` using an `array` of octets. ```js -const buf = Buffer.from([0x62,0x75,0x66,0x66,0x65,0x72]); - // creates a new Buffer containing ASCII bytes - // ['b','u','f','f','e','r'] +// Creates a new Buffer containing ASCII bytes of the string 'buffer' +const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); ``` A `TypeError` will be thrown if `array` is not an `Array`. @@ -664,19 +696,21 @@ TypedArray. ```js const arr = new Uint16Array(2); + arr[0] = 5000; arr[1] = 4000; -const buf = Buffer.from(arr.buffer); // shares the memory with arr; +// Shares memory with `arr` +const buf = Buffer.from(arr.buffer); +// Prints: console.log(buf); - // Prints: -// changing the TypedArray changes the Buffer also +// Changing the original Uint16Array changes the Buffer also arr[1] = 6000; +// Prints: console.log(buf); - // Prints: ``` The optional `byteOffset` and `length` arguments specify a memory range within @@ -685,8 +719,9 @@ the `arrayBuffer` that will be shared by the `Buffer`. ```js const ab = new ArrayBuffer(10); const buf = Buffer.from(ab, 0, 2); + +// Prints: 2 console.log(buf.length); - // Prints: 2 ``` A `TypeError` will be thrown if `arrayBuffer` is not an `ArrayBuffer`. @@ -705,10 +740,12 @@ const buf1 = Buffer.from('buffer'); const buf2 = Buffer.from(buf1); buf1[0] = 0x61; + +// Prints: auffer console.log(buf1.toString()); - // 'auffer' + +// Prints: buffer console.log(buf2.toString()); - // 'buffer' (copy is not changed) ``` A `TypeError` will be thrown if `buffer` is not a `Buffer`. @@ -727,14 +764,18 @@ If not provided, `encoding` defaults to `'utf8'`. ```js const buf1 = Buffer.from('this is a tést'); + +// Prints: this is a tést console.log(buf1.toString()); - // prints: this is a tést + +// Prints: this is a tC)st console.log(buf1.toString('ascii')); - // prints: this is a tC)st + const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex'); + +// Prints: this is a tést console.log(buf2.toString()); - // prints: this is a tést ``` A `TypeError` will be thrown if `str` is not a string. @@ -770,15 +811,15 @@ range is between `0x00` and `0xFF` (hex) or `0` and `255` (decimal). Example: copy an ASCII string into a Buffer, one byte at a time: ```js -const str = "Node.js"; +const str = 'Node.js'; const buf = Buffer.allocUnsafe(str.length); for (let i = 0; i < str.length ; i++) { buf[i] = str.charCodeAt(i); } +// Prints: Node.js console.log(buf.toString('ascii')); - // Prints: Node.js ``` ### buf.compare(target[, targetStart[, targetEnd[, sourceStart[, sourceEnd]]]]) @@ -810,19 +851,24 @@ const buf1 = Buffer.from('ABC'); const buf2 = Buffer.from('BCD'); const buf3 = Buffer.from('ABCD'); +// Prints: 0 console.log(buf1.compare(buf1)); - // Prints: 0 + +// Prints: -1 console.log(buf1.compare(buf2)); - // Prints: -1 + +// Prints: -1 console.log(buf1.compare(buf3)); - // Prints: -1 + +// Prints: 1 console.log(buf2.compare(buf1)); - // Prints: 1 + +// Prints: 1 console.log(buf2.compare(buf3)); - // Prints: 1 -[buf1, buf2, buf3].sort(Buffer.compare); - // produces sort order [buf1, buf3, buf2] +// Prints: [ , , ] +// (This result is equal to: [buf1, buf3, buf2]) +console.log([buf1, buf2, buf3].sort(Buffer.compare)); ``` The optional `targetStart`, `targetEnd`, `sourceStart`, and `sourceEnd` @@ -833,12 +879,14 @@ arguments can be used to limit the comparison to specific ranges within the two const buf1 = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9]); const buf2 = Buffer.from([5, 6, 7, 8, 9, 1, 2, 3, 4]); +// Prints: 0 console.log(buf1.compare(buf2, 5, 9, 0, 4)); - // Prints: 0 + +// Prints: -1 console.log(buf1.compare(buf2, 0, 6, 4)); - // Prints: -1 + +// Prints: 1 console.log(buf1.compare(buf2, 5, 6, 5)); - // Prints: 1 ``` A `RangeError` will be thrown if: `targetStart < 0`, `sourceStart < 0`, @@ -863,12 +911,14 @@ const buf1 = Buffer.allocUnsafe(26); const buf2 = Buffer.allocUnsafe(26).fill('!'); for (let i = 0 ; i < 26 ; i++) { - buf1[i] = i + 97; // 97 is ASCII a + // 97 is the decimal ASCII value for 'a' + buf1[i] = i + 97; } buf1.copy(buf2, 8, 16, 20); + +// Prints: !!!!!!!!qrst!!!!!!!!!!!!! console.log(buf2.toString('ascii', 0, 25)); - // Prints: !!!!!!!!qrst!!!!!!!!!!!!! ``` Example: Build a single Buffer, then copy data from one region to an overlapping @@ -878,13 +928,14 @@ region in the same Buffer const buf = Buffer.allocUnsafe(26); for (var i = 0 ; i < 26 ; i++) { - buf[i] = i + 97; // 97 is ASCII a + // 97 is the decimal ASCII value for 'a' + buf[i] = i + 97; } buf.copy(buf, 0, 4, 10); -console.log(buf.toString()); -// efghijghijklmnopqrstuvwxyz +// Prints: efghijghijklmnopqrstuvwxyz +console.log(buf.toString()); ``` ### buf.entries() @@ -899,16 +950,17 @@ contents. ```js const buf = Buffer.from('buffer'); -for (var pair of buf.entries()) { - console.log(pair); -} -// prints: + +// Prints: // [0, 98] // [1, 117] // [2, 102] // [3, 102] // [4, 101] // [5, 114] +for (var pair of buf.entries()) { + console.log(pair); +} ``` ### buf.equals(otherBuffer) @@ -927,10 +979,11 @@ const buf1 = Buffer.from('ABC'); const buf2 = Buffer.from('414243', 'hex'); const buf3 = Buffer.from('ABCD'); +// Prints: true console.log(buf1.equals(buf2)); - // Prints: true + +// Prints: false console.log(buf1.equals(buf3)); - // Prints: false ``` ### buf.fill(value[, offset[, end]][, encoding]) @@ -952,8 +1005,9 @@ creation and fill of the Buffer to be done on a single line: ```js const b = Buffer.allocUnsafe(50).fill('h'); + +// Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh console.log(b.toString()); - // Prints: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh ``` `encoding` is only relevant if `value` is a string. Otherwise it is ignored. @@ -964,8 +1018,8 @@ falls in between a multi-byte character then whatever bytes fit into the buffer are written. ```js -Buffer(3).fill('\u0222'); - // Prints: +// Prints: +console.log(Buffer.allocUnsafe(3).fill('\u0222')); ``` ### buf.indexOf(value[, byteOffset][, encoding]) @@ -988,25 +1042,33 @@ integer values between `0` and `255`. ```js const buf = Buffer.from('this is a buffer'); -buf.indexOf('this'); - // returns 0 -buf.indexOf('is'); - // returns 2 -buf.indexOf(Buffer.from('a buffer')); - // returns 8 -buf.indexOf(97); // ascii for 'a' - // returns 8 -buf.indexOf(Buffer.from('a buffer example')); - // returns -1 -buf.indexOf(Buffer.from('a buffer example').slice(0,8)); - // returns 8 +// Prints: 0 +console.log(buf.indexOf('this'))); + +// Prints: 2 +console.log(buf.indexOf('is')); + +// Prints: 8 +console.log(buf.indexOf(Buffer.from('a buffer'))); + +// Prints: 8 +// (97 is the decimal ASCII value for 'a') +console.log(buf.indexOf(97)); + +// Prints: -1 +console.log(buf.indexOf(Buffer.from('a buffer example'))); + +// Prints: 8 +console.log(buf.indexOf(Buffer.from('a buffer example').slice(0, 8))); + const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); -utf16Buffer.indexOf('\u03a3', 0, 'ucs2'); - // returns 4 -utf16Buffer.indexOf('\u03a3', -4, 'ucs2'); - // returns 6 +// Prints: 4 +console.log(utf16Buffer.indexOf('\u03a3', 0, 'ucs2')); + +// Prints: 6 +console.log(utf16Buffer.indexOf('\u03a3', -4, 'ucs2')); ``` ### buf.includes(value[, byteOffset][, encoding]) @@ -1030,20 +1092,27 @@ The `byteOffset` indicates the index in `buf` where searching begins. ```js const buf = Buffer.from('this is a buffer'); -buf.includes('this'); - // returns true -buf.includes('is'); - // returns true -buf.includes(Buffer.from('a buffer')); - // returns true -buf.includes(97); // ascii for 'a' - // returns true -buf.includes(Buffer.from('a buffer example')); - // returns false -buf.includes(Buffer.from('a buffer example').slice(0,8)); - // returns true -buf.includes('this', 4); - // returns false +// Prints: true +console.log(buf.includes('this')); + +// Prints: true +console.log(buf.includes('is')); + +// Prints: true +console.log(buf.includes(Buffer.from('a buffer'))); + +// Prints: true +// (97 is the decimal ASCII value for 'a') +console.log(buf.includes(97)); + +// Prints: false +console.log(buf.includes(Buffer.from('a buffer example'))); + +// Prints: true +console.log(buf.includes(Buffer.from('a buffer example').slice(0, 8))); + +// Prints: false +console.log(buf.includes('this', 4)); ``` ### buf.keys() @@ -1057,16 +1126,17 @@ Creates and returns an [iterator][] of Buffer keys (indices). ```js const buf = Buffer.from('buffer'); -for (var key of buf.keys()) { - console.log(key); -} -// prints: + +// Prints: // 0 // 1 // 2 // 3 // 4 // 5 +for (var key of buf.keys()) { + console.log(key); +} ``` ### buf.lastIndexOf(value[, byteOffset][, encoding]) @@ -1087,29 +1157,38 @@ String, Buffer or Number. Strings are by default interpreted as UTF8. If `byteOffset`. ```js -const buf = new Buffer('this buffer is a buffer'); +const buf = Buffer.from('this buffer is a buffer'); + +// Prints: 0 +console.log(buf.lastIndexOf('this')); + +// Prints: 17 +console.log(buf.lastIndexOf('buffer')); + +// Prints: 17 +console.log(buf.lastIndexOf(Buffer.from('buffer'))); + +// Prints: 15 +// (97 is the decimal ASCII value for 'a') +console.log(buf.lastIndexOf(97)); -buf.lastIndexOf('this'); - // returns 0 -buf.lastIndexOf('buffer'); - // returns 17 -buf.lastIndexOf(new Buffer('buffer')); - // returns 17 -buf.lastIndexOf(97); // ascii for 'a' - // returns 15 -buf.lastIndexOf(new Buffer('yolo')); - // returns -1 -buf.lastIndexOf('buffer', 5) - // returns 5 -buf.lastIndexOf('buffer', 4) - // returns -1 +// Prints: -1 +console.log(buf.lastIndexOf(Buffer.from('yolo'))); -const utf16Buffer = new Buffer('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); +// Prints: 5 +console.log(buf.lastIndexOf('buffer', 5)); -utf16Buffer.lastIndexOf('\u03a3', null, 'ucs2'); - // returns 6 -utf16Buffer.lastIndexOf('\u03a3', -5, 'ucs2'); - // returns 4 +// Prints: -1 +console.log(buf.lastIndexOf('buffer', 4)); + + +const utf16Buffer = Buffer.from('\u039a\u0391\u03a3\u03a3\u0395', 'ucs2'); + +// Prints: 6 +console.log(utf16Buffer.lastIndexOf('\u03a3', null, 'ucs2')); + +// Prints: 4 +console.log(utf16Buffer.lastIndexOf('\u03a3', -5, 'ucs2')); ``` ### buf.length @@ -1124,12 +1203,13 @@ allocated, but only 11 ASCII bytes are written. ```js const buf = Buffer.alloc(1234); +// Prints: 1234 console.log(buf.length); - // Prints: 1234 buf.write('some string', 0, 'ascii'); + +// Prints: 1234 console.log(buf.length); - // Prints: 1234 ``` While the `length` property is not immutable, changing the value of `length` @@ -1139,12 +1219,16 @@ use [`buf.slice()`][] to create a new Buffer. ```js var buf = Buffer.allocUnsafe(10); + buf.write('abcdefghj', 0, 'ascii'); + +// Prints: 10 console.log(buf.length); - // Prints: 10 -buf = buf.slice(0,5); + +buf = buf.slice(0, 5); + +// Prints: 5 console.log(buf.length); - // Prints: 5 ``` ### buf.readDoubleBE(offset[, noAssert]) @@ -1162,17 +1246,20 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the `offset` to be beyond the end of the Buffer. ```js -const buf = Buffer.from([1,2,3,4,5,6,7,8]); +const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]); + +// Prints: 8.20788039913184e-304 +console.log(buf.readDoubleBE()); -buf.readDoubleBE(); - // Returns: 8.20788039913184e-304 -buf.readDoubleLE(); - // Returns: 5.447603722011605e-270 -buf.readDoubleLE(1); - // throws RangeError: Index out of range +// Prints: 5.447603722011605e-270 +console.log(buf.readDoubleLE()); -buf.readDoubleLE(1, true); // Warning: reads passed end of buffer! - // Segmentation fault! don't do this! +// Throws an exception: RangeError: Index out of range +console.log(buf.readDoubleLE(1)); + +// Warning: reads passed end of buffer! +// This will result in a segmentation fault! Don't do this! +console.log(buf.readDoubleLE(1, true)); ``` ### buf.readFloatBE(offset[, noAssert]) @@ -1190,17 +1277,20 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the `offset` to be beyond the end of the Buffer. ```js -const buf = Buffer.from([1,2,3,4]); +const buf = Buffer.from([1, 2, 3, 4]); + +// Prints: 2.387939260590663e-38 +console.log(buf.readFloatBE()); + +// Prints: 1.539989614439558e-36 +console.log(buf.readFloatLE()); -buf.readFloatBE(); - // Returns: 2.387939260590663e-38 -buf.readFloatLE(); - // Returns: 1.539989614439558e-36 -buf.readFloatLE(1); - // throws RangeError: Index out of range +// Throws an exception: RangeError: Index out of range +console.log(buf.readFloatLE(1)); -buf.readFloatLE(1, true); // Warning: reads passed end of buffer! - // Segmentation fault! don't do this! +// Warning: reads passed end of buffer! +// This will result in a segmentation fault! Don't do this! +console.log(buf.readFloatLE(1, true)); ``` ### buf.readInt8(offset[, noAssert]) @@ -1217,12 +1307,16 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the Integers read from the Buffer are interpreted as two's complement signed values. ```js -const buf = Buffer.from([1,-2,3,4]); +const buf = Buffer.from([-1, 5]); -buf.readInt8(0); - // returns 1 -buf.readInt8(1); - // returns -2 +// Prints: -1 +console.log(buf.readInt8(0)); + +// Prints: 5 +console.log(buf.readInt8(1)); + +// Throws an exception: RangeError: Index out of range +console.log(buf.readInt8(2)); ``` ### buf.readInt16BE(offset[, noAssert]) @@ -1242,12 +1336,16 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the Integers read from the Buffer are interpreted as two's complement signed values. ```js -const buf = Buffer.from([1,-2,3,4]); +const buf = Buffer.from([0, 5]); + +// Prints: 5 +console.log(buf.readInt16BE()); -buf.readInt16BE(); - // returns 510 -buf.readInt16LE(1); - // returns 1022 +// Prints: 1280 +console.log(buf.readInt16LE(1)); + +// Throws an exception: RangeError: Index out of range +console.log(buf.readInt16LE(1)); ``` ### buf.readInt32BE(offset[, noAssert]) @@ -1267,14 +1365,16 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the Integers read from the Buffer are interpreted as two's complement signed values. ```js -const buf = Buffer.from([1,-2,3,4]); +const buf = Buffer.from([0, 0, 0, 5]); + +// Prints: 5 +console.log(buf.readInt32BE()); + +// Prints: 83886080 +console.log(buf.readInt32LE()); -buf.readInt32BE(); - // returns 33424132 -buf.readInt32LE(); - // returns 67370497 -buf.readInt32LE(1); - // throws RangeError: Index out of range +// Throws an exception: RangeError: Index out of range +console.log(buf.readInt32LE(1)); ``` ### buf.readIntBE(offset, byteLength[, noAssert]) @@ -1293,14 +1393,16 @@ and interprets the result as a two's complement signed value. Supports up to 48 bits of accuracy. For example: ```js -const buf = Buffer.allocUnsafe(6); -buf.writeUInt16LE(0x90ab, 0); -buf.writeUInt32LE(0x12345678, 2); -buf.readIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) -// Returns: '1234567890ab' +const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); + +// Prints: 1234567890ab +console.log(buf.readIntLE(0, 6).toString(16)); -buf.readIntBE(0, 6).toString(16); -// Returns: -546f87a9cbee +// Prints: -546f87a9cbee +console.log(buf.readIntBE(0, 6).toString(16)); + +// Throws an exception: RangeError: Index out of range +console.log(buf.readIntBE(1, 6).toString(16)); ``` Setting `noAssert` to `true` skips validation of the `offset`. This allows the @@ -1318,12 +1420,16 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the `offset` to be beyond the end of the Buffer. ```js -const buf = Buffer.from([1,-2,3,4]); +const buf = Buffer.from([1, -2]); + +// Prints: 1 +console.log(buf.readUInt8(0)); -buf.readUInt8(0); - // returns 1 -buf.readUInt8(1); - // returns 254 +// Prints: 254 +console.log(buf.readUInt8(1)); + +// Throws an exception: RangeError: Index out of range +console.log(buf.readUInt8(2)); ``` ### buf.readUInt16BE(offset[, noAssert]) @@ -1343,20 +1449,22 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the Example: ```js -const buf = Buffer.from([0x3, 0x4, 0x23, 0x42]); +const buf = Buffer.from([0x12, 0x34, 0x56]); + +// Prints: 1234 +console.log(buf.readUInt16BE(0).toString(16)); + +// Prints: 3412 +console.log(buf.readUInt16LE(0).toString(16)); -buf.readUInt16BE(0); - // Returns: 0x0304 -buf.readUInt16LE(0); - // Returns: 0x0403 -buf.readUInt16BE(1); - // Returns: 0x0423 -buf.readUInt16LE(1); - // Returns: 0x2304 -buf.readUInt16BE(2); - // Returns: 0x2342 -buf.readUInt16LE(2); - // Returns: 0x4223 +// Prints: 3456 +console.log(buf.readUInt16BE(1).toString(16)); + +// Prints: 5634 +console.log(buf.readUInt16LE(1).toString(16)); + +// Throws an exception: RangeError: Index out of range +console.log(buf.readUInt16LE(2).toString(16)); ``` ### buf.readUInt32BE(offset[, noAssert]) @@ -1376,12 +1484,16 @@ Setting `noAssert` to `true` skips validation of the `offset`. This allows the Example: ```js -const buf = Buffer.from([0x3, 0x4, 0x23, 0x42]); +const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]); + +// Prints: 12345678 +console.log(buf.readUInt32BE(0).toString(16)); + +// Prints: 78563412 +console.log(buf.readUInt32LE(0).toString(16)); -buf.readUInt32BE(0); - // Returns: 0x03042342 -console.log(buf.readUInt32LE(0)); - // Returns: 0x42230403 +// Throws an exception: RangeError: Index out of range +console.log(buf.readUInt32LE(1).toString(16)); ``` ### buf.readUIntBE(offset, byteLength[, noAssert]) @@ -1400,14 +1512,16 @@ and interprets the result as an unsigned integer. Supports up to 48 bits of accuracy. For example: ```js -const buf = Buffer.allocUnsafe(6); -buf.writeUInt16LE(0x90ab, 0); -buf.writeUInt32LE(0x12345678, 2); -buf.readUIntLE(0, 6).toString(16); // Specify 6 bytes (48 bits) -// Returns: '1234567890ab' +const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); + +// Prints: 1234567890ab +console.log(buf.readUIntLE(0, 6).toString(16)); + +// Prints: ab9078563412 +console.log(buf.readUIntBE(0, 6).toString(16)); -buf.readUIntBE(0, 6).toString(16); -// Returns: ab9078563412 +// Throws an exception: RangeError: Index out of range +console.log(buf.readUIntBE(1, 6).toString(16)); ``` Setting `noAssert` to `true` skips validation of the `offset`. This allows the @@ -1432,15 +1546,19 @@ byte from the original Buffer. const buf1 = Buffer.allocUnsafe(26); for (var i = 0 ; i < 26 ; i++) { - buf1[i] = i + 97; // 97 is ASCII a + // 97 is the decimal ASCII value for 'a' + buf1[i] = i + 97; } const buf2 = buf1.slice(0, 3); -buf2.toString('ascii', 0, buf2.length); - // Returns: 'abc' + +// Prints: abc +console.log(buf2.toString('ascii', 0, buf2.length)); + buf1[0] = 33; -buf2.toString('ascii', 0, buf2.length); - // Returns : '!bc' + +// Prints: !bc +console.log(buf2.toString('ascii', 0, buf2.length)); ``` Specifying negative indexes causes the slice to be generated relative to the @@ -1449,12 +1567,17 @@ end of the Buffer rather than the beginning. ```js const buf = Buffer.from('buffer'); -buf.slice(-6, -1).toString(); - // Returns 'buffe', equivalent to buf.slice(0, 5) -buf.slice(-6, -2).toString(); - // Returns 'buff', equivalent to buf.slice(0, 4) -buf.slice(-5, -2).toString(); - // Returns 'uff', equivalent to buf.slice(1, 4) +// Prints: buffe +// (Equivalent to buf.slice(0, 5)) +console.log(buf.slice(-6, -1).toString()); + +// Prints: buff +// (Equivalent to buf.slice(0, 4)) +console.log(buf.slice(-6, -2).toString()); + +// Prints: uff +// (Equivalent to buf.slice(1, 4)) +console.log(buf.slice(-5, -2).toString()); ``` ### buf.swap16() @@ -1470,12 +1593,21 @@ not a multiple of 16 bits. The method returns a reference to the Buffer, so calls can be chained. ```js -const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); -console.log(buf); - // Prints -buf.swap16(); -console.log(buf); - // Prints +const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + +// Prints: +console.log(buf1); + +buf1.swap16(); + +// Prints: +console.log(buf1); + + +const buf2 = Buffer.from([0x1, 0x2, 0x3]); + +// Throws an exception: RangeError: Buffer size must be a multiple of 16-bits +buf2.swap32(); ``` ### buf.swap32() @@ -1491,12 +1623,21 @@ not a multiple of 32 bits. The method returns a reference to the Buffer, so calls can be chained. ```js -const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); -console.log(buf); - // Prints -buf.swap32(); -console.log(buf); - // Prints +const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + +// Prints +console.log(buf1); + +buf1.swap32(); + +// Prints +console.log(buf1); + + +const buf2 = Buffer.from([0x1, 0x2, 0x3]); + +// Throws an exception: RangeError: Buffer size must be a multiple of 32-bits +buf2.swap32(); ``` ### buf.swap64() @@ -1512,12 +1653,21 @@ not a multiple of 64 bits. The method returns a reference to the Buffer, so calls can be chained. ```js -const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); -console.log(buf); - // Prints -buf.swap64(); -console.log(buf); - // Prints +const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + +// Prints +console.log(buf1); + +buf1.swap64(); + +// Prints +console.log(buf1); + + +const buf2 = Buffer.from([0x1, 0x2, 0x3]); + +// Throws an exception: RangeError: Buffer size must be a multiple of 64-bits +buf2.swap64(); ``` Note that JavaScript cannot encode 64-bit integers. This method is intended @@ -1534,18 +1684,27 @@ Decodes and returns a string from the Buffer data using the specified character set `encoding`. ```js -const buf = Buffer.allocUnsafe(26); +const buf1 = Buffer.allocUnsafe(26); + for (var i = 0 ; i < 26 ; i++) { - buf[i] = i + 97; // 97 is ASCII a + // 97 is the decimal ASCII value for 'a' + buf1[i] = i + 97; } -buf.toString('ascii'); - // Returns: 'abcdefghijklmnopqrstuvwxyz' -buf.toString('ascii',0,5); - // Returns: 'abcde' -buf.toString('utf8',0,5); - // Returns: 'abcde' -buf.toString(undefined,0,5); - // Returns: 'abcde', encoding defaults to 'utf8' + +// Prints: abcdefghijklmnopqrstuvwxyz +console.log(buf.toString('ascii')); + +// Prints: abcde +console.log(buf.toString('ascii', 0, 5)); + + +const buf2 = Buffer.from('tést'); + +// Prints: tés +console.log(buf.toString('utf8', 0, 3)); + +// Prints: tés +console.log(buf.toString(undefined, 0, 3)); ``` ### buf.toJSON() @@ -1561,20 +1720,20 @@ implicitly calls this function when stringifying a Buffer instance. Example: ```js -const buf = Buffer.from('test'); +const buf = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5]); const json = JSON.stringify(buf); +// Prints: {"type":"Buffer","data":[1,2,3,4,5]} console.log(json); -// Prints: '{"type":"Buffer","data":[116,101,115,116]}' const copy = JSON.parse(json, (key, value) => { - return value && value.type === 'Buffer' - ? Buffer.from(value.data) - : value; - }); + return value && value.type === 'Buffer' + ? Buffer.from(value.data) + : value; +}); -console.log(copy.toString()); -// Prints: 'test' +// Prints: +console.log(copy); ``` ### buf.values() @@ -1589,27 +1748,28 @@ called automatically when the Buffer is used in a `for..of` statement. ```js const buf = Buffer.from('buffer'); -for (var value of buf.values()) { - console.log(value); -} -// prints: + +// Prints: // 98 // 117 // 102 // 102 // 101 // 114 - -for (var value of buf) { +for (var value of buf.values()) { console.log(value); } -// prints: + +// Prints: // 98 // 117 // 102 // 102 // 101 // 114 +for (var value of buf) { + console.log(value); +} ``` ### buf.write(string[, offset[, length]][, encoding]) @@ -1628,9 +1788,11 @@ characters. ```js const buf = Buffer.allocUnsafe(256); + const len = buf.write('\u00bd + \u00bc = \u00be', 0); + +// Prints: 12 bytes: ½ + ¼ = ¾ console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); - // Prints: 12 bytes: ½ + ¼ = ¾ ``` ### buf.writeDoubleBE(value, offset[, noAssert]) @@ -1655,15 +1817,16 @@ Example: ```js const buf = Buffer.allocUnsafe(8); + buf.writeDoubleBE(0xdeadbeefcafebabe, 0); +// Prints: console.log(buf); - // Prints: buf.writeDoubleLE(0xdeadbeefcafebabe, 0); +// Prints: console.log(buf); - // Prints: ``` ### buf.writeFloatBE(value, offset[, noAssert]) @@ -1688,15 +1851,16 @@ Example: ```js const buf = Buffer.allocUnsafe(4); + buf.writeFloatBE(0xcafebabe, 0); +// Prints: console.log(buf); - // Prints: buf.writeFloatLE(0xcafebabe, 0); +// Prints: console.log(buf); - // Prints: ``` ### buf.writeInt8(value, offset[, noAssert]) @@ -1719,10 +1883,12 @@ The `value` is interpreted and written as a two's complement signed integer. ```js const buf = Buffer.allocUnsafe(2); + buf.writeInt8(2, 0); buf.writeInt8(-2, 1); + +// Prints: console.log(buf); - // Prints: ``` ### buf.writeInt16BE(value, offset[, noAssert]) @@ -1747,10 +1913,12 @@ The `value` is interpreted and written as a two's complement signed integer. ```js const buf = Buffer.allocUnsafe(4); -buf.writeInt16BE(0x0102,0); -buf.writeInt16LE(0x0304,2); + +buf.writeInt16BE(0x0102, 0); +buf.writeInt16LE(0x0304, 2); + +// Prints: console.log(buf); - // Prints: ``` ### buf.writeInt32BE(value, offset[, noAssert]) @@ -1775,10 +1943,12 @@ The `value` is interpreted and written as a two's complement signed integer. ```js const buf = Buffer.allocUnsafe(8); -buf.writeInt32BE(0x01020304,0); -buf.writeInt32LE(0x05060708,4); + +buf.writeInt32BE(0x01020304, 0); +buf.writeInt32LE(0x05060708, 4); + +// Prints: console.log(buf); - // Prints: ``` ### buf.writeIntBE(value, offset, byteLength[, noAssert]) @@ -1797,15 +1967,17 @@ Writes `value` to the Buffer at the specified `offset` and `byteLength`. Supports up to 48 bits of accuracy. For example: ```js -const buf1 = Buffer.allocUnsafe(6); -buf1.writeUIntBE(0x1234567890ab, 0, 6); -console.log(buf1); - // Prints: +const buf = Buffer.allocUnsafe(6); -const buf2 = Buffer.allocUnsafe(6); -buf2.writeUIntLE(0x1234567890ab, 0, 6); -console.log(buf2); - // Prints: +buf.writeUIntBE(0x1234567890ab, 0, 6); + +// Prints: +console.log(buf); + +buf.writeUIntLE(0x1234567890ab, 0, 6); + +// Prints: +console.log(buf); ``` Set `noAssert` to true to skip validation of `value` and `offset`. This means @@ -1835,13 +2007,14 @@ Example: ```js const buf = Buffer.allocUnsafe(4); + buf.writeUInt8(0x3, 0); buf.writeUInt8(0x4, 1); buf.writeUInt8(0x23, 2); buf.writeUInt8(0x42, 3); +// Prints: console.log(buf); - // Prints: ``` ### buf.writeUInt16BE(value, offset[, noAssert]) @@ -1866,17 +2039,18 @@ Example: ```js const buf = Buffer.allocUnsafe(4); + buf.writeUInt16BE(0xdead, 0); buf.writeUInt16BE(0xbeef, 2); +// Prints: console.log(buf); - // Prints: buf.writeUInt16LE(0xdead, 0); buf.writeUInt16LE(0xbeef, 2); +// Prints: console.log(buf); - // Prints: ``` ### buf.writeUInt32BE(value, offset[, noAssert]) @@ -1901,15 +2075,16 @@ Example: ```js const buf = Buffer.allocUnsafe(4); + buf.writeUInt32BE(0xfeedface, 0); +// Prints: console.log(buf); - // Prints: buf.writeUInt32LE(0xfeedface, 0); +// Prints: console.log(buf); - // Prints: ``` ### buf.writeUIntBE(value, offset, byteLength[, noAssert]) @@ -1926,9 +2101,16 @@ Supports up to 48 bits of accuracy. For example: ```js const buf = Buffer.allocUnsafe(6); + buf.writeUIntBE(0x1234567890ab, 0, 6); + +// Prints: +console.log(buf); + +buf.writeUIntLE(0x1234567890ab, 0, 6); + +// Prints: console.log(buf); - // Prints: ``` Set `noAssert` to true to skip validation of `value` and `offset`. This means @@ -1969,15 +2151,18 @@ pool for an indeterminate amount of time, it may be appropriate to create an un-pooled Buffer instance using `SlowBuffer` then copy out the relevant bits. ```js -// need to keep around a few small chunks of memory +// Need to keep around a few small chunks of memory const store = []; socket.on('readable', () => { - var data = socket.read(); - // allocate for retained data - var sb = SlowBuffer(10); - // copy the data into the new allocation + const data = socket.read(); + + // Allocate for retained data + const sb = SlowBuffer(10); + + // Copy the data into the new allocation data.copy(sb, 0, 0, 10); + store.push(sb); }); ``` @@ -2007,13 +2192,16 @@ sensitive data. Use [`buf.fill(0)`][] to initialize a `SlowBuffer` to zeroes. ```js const SlowBuffer = require('buffer').SlowBuffer; + const buf = new SlowBuffer(5); + +// Prints (contents may vary): console.log(buf); - // - // (octets will be different, every time) + buf.fill(0); + +// Prints: console.log(buf); - // ``` [iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols From 0103d9dcea4ba975836303fecca950840d33f680 Mon Sep 17 00:00:00 2001 From: Brian White Date: Tue, 19 Jul 2016 17:57:53 -0400 Subject: [PATCH 015/144] doc: reorganize Buffer link references This commit adds more links and separates internal doc links from external web links. PR-URL: https://github.com/nodejs/node/pull/7784 Reviewed-By: James M Snell Reviewed-By: Trevor Norris --- doc/api/buffer.md | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 32114540531980..b97ee992a8cb1c 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -2204,29 +2204,36 @@ buf.fill(0); console.log(buf); ``` -[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols -[`Array#indexOf()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf -[`Buffer#indexOf()`]: #buffer_buf_indexof_value_byteoffset_encoding -[`Array#includes()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes +[`buf.compare()`]: #buffer_buf_compare_target_targetstart_targetend_sourcestart_sourceend [`buf.entries()`]: #buffer_buf_entries -[`buf.fill(0)`]: #buffer_buf_fill_value_offset_end_encoding +[`buf.indexOf()`]: #buffer_buf_indexof_value_byteoffset_encoding [`buf.fill()`]: #buffer_buf_fill_value_offset_end_encoding [`buf.keys()`]: #buffer_buf_keys +[`buf.length`]: #buffer_buf_length [`buf.slice()`]: #buffer_buf_slice_start_end [`buf.values()`]: #buffer_buf_values -[`buf1.compare(buf2)`]: #buffer_buf_compare_target_targetstart_targetend_sourcestart_sourceend -[`JSON.stringify()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify +[`buffer.kMaxLength`]: #buffer_buffer_kmaxlength +[`Buffer.alloc()`]: #buffer_class_method_buffer_alloc_size_fill_encoding +[`Buffer.allocUnsafe()`]: #buffer_class_method_buffer_allocunsafe_size +[`Buffer.allocUnsafeSlow()`]: #buffer_class_method_buffer_allocunsafeslow_size +[`Buffer.from(array)`]: #buffer_class_method_buffer_from_array +[`Buffer.from(arrayBuffer)`]: #buffer_class_method_buffer_from_arraybuffer_byteoffset_length +[`Buffer.from(buffer)`]: #buffer_class_method_buffer_from_buffer +[`Buffer.from(string)`]: #buffer_class_method_buffer_from_str_encoding +[`Buffer.poolSize`]: #buffer_class_property_buffer_poolsize [`RangeError`]: errors.html#errors_class_rangeerror -[`String.prototype.length`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length [`util.inspect()`]: util.html#util_util_inspect_object_options -[RFC 4648, Section 5]: https://tools.ietf.org/html/rfc4648#section-5 -[buffer_from_array]: #buffer_class_method_buffer_from_array -[buffer_from_buffer]: #buffer_class_method_buffer_from_buffer -[buffer_from_arraybuf]: #buffer_class_method_buffer_from_arraybuffer_byteoffset_length -[buffer_from_string]: #buffer_class_method_buffer_from_str_encoding -[buffer_allocunsafe]: #buffer_class_method_buffer_allocunsafe_size -[buffer_allocunsafeslow]: #buffer_class_method_buffer_allocunsafeslow_size -[buffer_alloc]: #buffer_class_method_buffer_alloc_size_fill_encoding -[`TypedArray.from()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from + +[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer +[`ArrayBuffer#slice()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/slice [`DataView`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView +[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols +[`JSON.stringify()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify +[RFC1345]: https://tools.ietf.org/html/rfc1345 +[RFC4648, Section 5]: https://tools.ietf.org/html/rfc4648#section-5 +[`String.prototype.length`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length [`TypedArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray +[`TypedArray.from()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from +[`Uint32Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array +[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array +[WHATWG spec]: https://encoding.spec.whatwg.org/ From 9a4a00bcdb0cda2cbe95240b3d2969257368f6ed Mon Sep 17 00:00:00 2001 From: Brian White Date: Tue, 19 Jul 2016 18:38:00 -0400 Subject: [PATCH 016/144] doc: improve links in Buffer docs This commit adds more links and reuses existing link references more. PR-URL: https://github.com/nodejs/node/pull/7784 Reviewed-By: James M Snell Reviewed-By: Trevor Norris --- doc/api/buffer.md | 222 +++++++++++++++++++++++----------------------- 1 file changed, 109 insertions(+), 113 deletions(-) diff --git a/doc/api/buffer.md b/doc/api/buffer.md index b97ee992a8cb1c..44f6807002a62f 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -2,14 +2,14 @@ Stability: 2 - Stable -Prior to the introduction of `TypedArray` in ECMAScript 2015 (ES6), the +Prior to the introduction of [`TypedArray`] in ECMAScript 2015 (ES6), the JavaScript language had no mechanism for reading or manipulating streams of binary data. The `Buffer` class was introduced as part of the Node.js API to make it possible to interact with octet streams in the context of things like TCP streams and file system operations. -Now that `TypedArray` has been added in ES6, the `Buffer` class implements the -`Uint8Array` API in a manner that is more optimized and suitable for Node.js' +Now that [`TypedArray`] has been added in ES6, the `Buffer` class implements the +[`Uint8Array`] API in a manner that is more optimized and suitable for Node.js' use cases. Instances of the `Buffer` class are similar to arrays of integers but @@ -52,15 +52,15 @@ differently based on what arguments are provided: * Passing a number as the first argument to `Buffer()` (e.g. `new Buffer(10)`), allocates a new `Buffer` object of the specified size. The memory allocated for such `Buffer` instances is *not* initialized and *can contain sensitive - data*. Such `Buffer` objects *must* be initialized *manually* by using either - [`buf.fill(0)`][] or by writing to the `Buffer` completely. While this - behavior is *intentional* to improve performance, development experience has - demonstrated that a more explicit distinction is required between creating a - fast-but-uninitialized `Buffer` versus creating a slower-but-safer `Buffer`. + data*. Such `Buffer` instances *must* be initialized *manually* by using either + [`buf.fill(0)`][`buf.fill()`] or by writing to the `Buffer` completely. While + this behavior is *intentional* to improve performance, development experience + has demonstrated that a more explicit distinction is required between creating + a fast-but-uninitialized `Buffer` versus creating a slower-but-safer `Buffer`. * Passing a string, array, or `Buffer` as the first argument copies the passed object's data into the `Buffer`. -* Passing an `ArrayBuffer` returns a `Buffer` that shares allocated memory with - the given `ArrayBuffer`. +* Passing an [`ArrayBuffer`] returns a `Buffer` that shares allocated memory with + the given [`ArrayBuffer`]. Because the behavior of `new Buffer()` changes significantly based on the type of value passed as the first argument, applications that do not properly @@ -70,34 +70,34 @@ introduce security and reliability issues into their code. To make the creation of `Buffer` objects more reliable and less error prone, the various forms of the `new Buffer()` constructor have been **deprecated** -and replaced by separate `Buffer.from()`, `Buffer.alloc()`, and -`Buffer.allocUnsafe()` methods. +and replaced by separate `Buffer.from()`, [`Buffer.alloc()`], and +[`Buffer.allocUnsafe()`] methods. *Developers should migrate all existing uses of the `new Buffer()` constructors to one of these new APIs.* -* [`Buffer.from(array)`][buffer_from_array] returns a new `Buffer` containing - a *copy* of the provided octets. -* [`Buffer.from(arrayBuffer[, byteOffset [, length]])`][buffer_from_arraybuf] +* [`Buffer.from(array)`] returns a new `Buffer` containing a *copy* of the provided + octets. +* [`Buffer.from(arrayBuffer[, byteOffset [, length]])`][`Buffer.from(arrayBuffer)`] returns a new `Buffer` that *shares* the same allocated memory as the given - `ArrayBuffer`. -* [`Buffer.from(buffer)`][buffer_from_buffer] returns a new `Buffer` - containing a *copy* of the contents of the given `Buffer`. -* [`Buffer.from(str[, encoding])`][buffer_from_string] returns a new `Buffer` + [`ArrayBuffer`]. +* [`Buffer.from(buffer)`] returns a new `Buffer` containing a *copy* of the + contents of the given `Buffer`. +* [`Buffer.from(string[, encoding])`][`Buffer.from(string)`] returns a new `Buffer` containing a *copy* of the provided string. -* [`Buffer.alloc(size[, fill[, encoding]])`][buffer_alloc] returns a "filled" +* [`Buffer.alloc(size[, fill[, encoding]])`][`Buffer.alloc()`] returns a "filled" `Buffer` instance of the specified size. This method can be significantly - slower than [`Buffer.allocUnsafe(size)`][buffer_allocunsafe] but ensures + slower than [`Buffer.allocUnsafe(size)`][`Buffer.allocUnsafe()`] but ensures that newly created `Buffer` instances never contain old and potentially sensitive data. -* [`Buffer.allocUnsafe(size)`][buffer_allocunsafe] and - [`Buffer.allocUnsafeSlow(size)`][buffer_allocunsafeslow] each return a +* [`Buffer.allocUnsafe(size)`][`Buffer.allocUnsafe()`] and + [`Buffer.allocUnsafeSlow(size)`][`Buffer.allocUnsafeSlow()`] each return a new `Buffer` of the specified `size` whose content *must* be initialized - using either [`buf.fill(0)`][] or written to completely. + using either [`buf.fill(0)`][`buf.fill()`] or written to completely. -`Buffer` instances returned by `Buffer.allocUnsafe(size)` *may* be allocated -off a shared internal memory pool if `size` is less than or equal to half -`Buffer.poolSize`. Instances returned by `Buffer.allocUnsafeSlow(size)` *never* +`Buffer` instances returned by [`Buffer.allocUnsafe()`] *may* be allocated off +a shared internal memory pool if `size` is less than or equal to half +[`Buffer.poolSize`]. Instances returned by [`Buffer.allocUnsafeSlow()`] *never* use the shared internal memory pool. ### The `--zero-fill-buffers` command line option @@ -107,12 +107,12 @@ added: v5.10.0 Node.js can be started using the `--zero-fill-buffers` command line option to force all newly allocated `Buffer` instances created using either -`new Buffer(size)`, `Buffer.allocUnsafe(size)`, `Buffer.allocUnsafeSlow(size)` -or `new SlowBuffer(size)` to be *automatically zero-filled* upon creation. Use -of this flag *changes the default behavior* of these methods and *can have a -significant impact* on performance. Use of the `--zero-fill-buffers` option is -recommended only when absolutely necessary to enforce that newly allocated -`Buffer` instances cannot contain potentially sensitive data. +`new Buffer(size)`, [`Buffer.allocUnsafe()`], [`Buffer.allocUnsafeSlow()`] or +`new SlowBuffer(size)` to be *automatically zero-filled* upon creation. Use of +this flag *changes the default behavior* of these methods and *can have a significant +impact* on performance. Use of the `--zero-fill-buffers` option is recommended +only when necessary to enforce that newly allocated `Buffer` instances cannot +contain potentially sensitive data. ```txt $ node --zero-fill-buffers @@ -120,16 +120,16 @@ $ node --zero-fill-buffers ``` -### What makes `Buffer.allocUnsafe(size)` and `Buffer.allocUnsafeSlow(size)` "unsafe"? +### What makes [`Buffer.allocUnsafe()`] and [`Buffer.allocUnsafeSlow()`] "unsafe"? -When calling `Buffer.allocUnsafe()` (and `Buffer.allocUnsafeSlow()`), the +When calling [`Buffer.allocUnsafe()`] and [`Buffer.allocUnsafeSlow()`], the segment of allocated memory is *uninitialized* (it is not zeroed-out). While this design makes the allocation of memory quite fast, the allocated segment of memory might contain old data that is potentially sensitive. Using a `Buffer` -created by `Buffer.allocUnsafe()` without *completely* overwriting the memory +created by [`Buffer.allocUnsafe()`] without *completely* overwriting the memory can allow this old data to be leaked when the `Buffer` memory is read. -While there are clear performance advantages to using `Buffer.allocUnsafe()`, +While there are clear performance advantages to using [`Buffer.allocUnsafe()`], extra care *must* be taken in order to avoid introducing security vulnerabilities into an application. @@ -165,44 +165,44 @@ The character encodings currently supported by Node.js include: * `'base64'` - Base64 string encoding. When creating a buffer from a string, this encoding will also correctly accept "URL and Filename Safe Alphabet" as - specified in [RFC 4648, Section 5]. + specified in [RFC4648, Section 5]. -* `'latin1'` - A way of encoding the buffer into a one-byte encoded string - (as defined by the IANA in [RFC1345](https://tools.ietf.org/html/rfc1345), +* `'latin1'` - A way of encoding the `Buffer` into a one-byte encoded string + (as defined by the IANA in [RFC1345], page 63, to be the Latin-1 supplement block and C0/C1 control codes). * `'binary'` - Alias for `latin1`. * `'hex'` - Encode each byte as two hexadecimal characters. -_Note_: Today's browsers follow the [WHATWG -spec](https://encoding.spec.whatwg.org/) that aliases both `latin1` and -`iso-8859-1` to `win-1252`. Meaning, while doing something like `http.get()`, +_Note_: Today's browsers follow the [WHATWG spec] which aliases both 'latin1' and +ISO-8859-1 to Windows-1252. This means that while doing something like `http.get()`, if the returned charset is one of those listed in the WHATWG spec it's possible that the server actually returned `win-1252` encoded data, and using `latin1` encoding may incorrectly decode the graphical characters. ## Buffers and TypedArray -Buffers are also `Uint8Array` TypedArray instances. However, there are subtle -incompatibilities with the TypedArray specification in ECMAScript 2015. For -instance, while `ArrayBuffer#slice()` creates a copy of the slice, -the implementation of [`Buffer#slice()`][`buf.slice()`] creates a view over the -existing Buffer without copying, making `Buffer#slice()` far more efficient. +`Buffer` instances are also [`Uint8Array`] instances. However, there are subtle +incompatibilities with the TypedArray specification in ECMAScript 2015. +For example, while [`ArrayBuffer#slice()`] creates a copy of the slice, the +implementation of [`Buffer#slice()`][`buf.slice()`] creates a view over the +existing `Buffer` without copying, making [`Buffer#slice()`][`buf.slice()`] far +more efficient. -It is also possible to create new TypedArray instances from a `Buffer` with the -following caveats: +It is also possible to create new [`TypedArray`] instances from a `Buffer` with +the following caveats: -1. The `Buffer` object's memory is copied to the TypedArray, not shared. +1. The `Buffer` object's memory is copied to the [`TypedArray`], not shared. 2. The `Buffer` object's memory is interpreted as an array of distinct elements, and not as a byte array of the target type. That is, -`new Uint32Array(Buffer.from([1,2,3,4]))` creates a 4-element `Uint32Array` - with elements `[1,2,3,4]`, not a `Uint32Array` with a single element +`new Uint32Array(Buffer.from([1, 2, 3, 4]))` creates a 4-element [`Uint32Array`] + with elements `[1, 2, 3, 4]`, not a [`Uint32Array`] with a single element `[0x1020304]` or `[0x4030201]`. It is possible to create a new `Buffer` that shares the same allocated memory as -a TypedArray instance by using the TypeArray object's `.buffer` property: +a [`TypedArray`] instance by using the TypeArray object's `.buffer` property. ```js const arr = new Uint16Array(2); @@ -231,9 +231,9 @@ console.log(buf1); console.log(buf2); ``` -Note that when creating a `Buffer` using the TypedArray's `.buffer`, it is -possible to use only a portion of the underlying `ArrayBuffer` by passing in -`byteOffset` and `length` parameters: +Note that when creating a `Buffer` using a [`TypedArray`]'s `.buffer`, it is +possible to use only a portion of the underlying [`ArrayBuffer`] by passing in +`byteOffset` and `length` parameters. ```js const arr = new Uint16Array(20); @@ -243,8 +243,8 @@ const buf = Buffer.from(arr.buffer, 0, 16); console.log(buf.length); ``` -The `Buffer.from()` and [`TypedArray.from()`][] (e.g.`Uint8Array.from()`) have -different signatures and implementations. Specifically, the TypedArray variants +The `Buffer.from()` and [`TypedArray.from()`] (e.g. `Uint8Array.from()`) have +different signatures and implementations. Specifically, the [`TypedArray`] variants accept a second argument that is a mapping function that is invoked on every element of the typed array: @@ -253,10 +253,10 @@ element of the typed array: The `Buffer.from()` method, however, does not support the use of a mapping function: -* [`Buffer.from(array)`][buffer_from_array] -* [`Buffer.from(buffer)`][buffer_from_buffer] -* [`Buffer.from(arrayBuffer[, byteOffset [, length]])`][buffer_from_arraybuf] -* [`Buffer.from(str[, encoding])`][buffer_from_string] +* [`Buffer.from(array)`] +* [`Buffer.from(buffer)`] +* [`Buffer.from(arrayBuffer[, byteOffset [, length]])`][`Buffer.from(arrayBuffer)`] +* [`Buffer.from(string[, encoding])`][`Buffer.from(string)`] ## Buffers and ES6 iteration @@ -274,8 +274,8 @@ for (var b of buf) { } ``` -Additionally, the [`buf.values()`][], [`buf.keys()`][], and -[`buf.entries()`][] methods can be used to create iterators. +Additionally, the [`buf.values()`], [`buf.keys()`], and +[`buf.entries()`] methods can be used to create iterators. ## Class: Buffer @@ -287,8 +287,7 @@ It can be constructed in a variety of ways. deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use [`Buffer.from(array)`][buffer_from_array] - instead. + Stability: 0 - Deprecated: Use [`Buffer.from(array)`] instead. * `array` {Array} @@ -304,8 +303,7 @@ const buf = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use [`Buffer.from(buffer)`][buffer_from_buffer] - instead. + Stability: 0 - Deprecated: Use [`Buffer.from(buffer)`] instead. * `buffer` {Buffer} @@ -330,7 +328,7 @@ deprecated: v6.0.0 --> Stability: 0 - Deprecated: Use - [`Buffer.from(arrayBuffer[, byteOffset [, length]])`][buffer_from_arraybuf] + [`Buffer.from(arrayBuffer[, byteOffset [, length]])`][`Buffer.from(arrayBuffer)`] instead. * `arrayBuffer` {ArrayBuffer} The `.buffer` property of a `TypedArray` or a @@ -338,9 +336,9 @@ deprecated: v6.0.0 * `byteOffset` {Number} Default: `0` * `length` {Number} Default: `arrayBuffer.length - byteOffset` -When passed a reference to the `.buffer` property of a `TypedArray` instance, -the newly created Buffer will share the same allocated memory as the -TypedArray. +When passed a reference to the `.buffer` property of a [`TypedArray`] instance, +the newly created `Buffer` will share the same allocated memory as the +[`TypedArray`]. The optional `byteOffset` and `length` arguments specify a memory range within the `arrayBuffer` that will be shared by the `Buffer`. @@ -369,9 +367,8 @@ console.log(buf); deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use - [`Buffer.alloc(size[, fill[, encoding]])`][buffer_alloc] instead (also - see [`Buffer.allocUnsafe(size)`][buffer_allocunsafe]). + Stability: 0 - Deprecated: Use [`Buffer.alloc()`] instead (also see + [`Buffer.allocUnsafe()`]). * `size` {Number} @@ -381,10 +378,10 @@ architectures, `kMaxLength` is `(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will be created if a `size` less than or equal to 0 is specified. -Unlike `ArrayBuffers`, the underlying memory for `Buffer` instances created in -this way is *not initialized*. The contents of a newly created `Buffer` are -unknown and *could contain sensitive data*. Use [`buf.fill(0)`][] to initialize -a `Buffer` to zeroes. +Unlike [`ArrayBuffers`][`ArrayBuffer`], the underlying memory for `Buffer` instances +created in this way is *not initialized*. The contents of a newly created `Buffer` +are unknown and *could contain sensitive data*. Use [`buf.fill(0)`][`buf.fill()`] +to initialize a `Buffer` to zeroes. ```js const buf = new Buffer(5); @@ -453,7 +450,7 @@ The `size` must be less than or equal to the value of be created if a `size` less than or equal to 0 is specified. If `fill` is specified, the allocated `Buffer` will be initialized by calling -`buf.fill(fill)`. See [`buf.fill()`][] for more information. +[`buf.fill(fill)`][`buf.fill()`]. ```js const buf = Buffer.alloc(5, 'a'); @@ -463,7 +460,7 @@ console.log(buf); ``` If both `fill` and `encoding` are specified, the allocated `Buffer` will be -initialized by calling `buf.fill(fill, encoding)`. For example: +initialized by calling [`buf.fill(fill, encoding)`][`buf.fill()`]. ```js const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64'); @@ -472,8 +469,8 @@ const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64'); console.log(buf); ``` -Calling `Buffer.alloc(size)` can be significantly slower than the alternative -`Buffer.allocUnsafe(size)` but ensures that the newly created `Buffer` instance +Calling [`Buffer.alloc()`] can be significantly slower than the alternative +[`Buffer.allocUnsafe()`] but ensures that the newly created `Buffer` instance contents will *never contain sensitive data*. A `TypeError` will be thrown if `size` is not a number. @@ -493,7 +490,7 @@ thrown. A zero-length Buffer will be created if a `size` less than or equal to The underlying memory for `Buffer` instances created in this way is *not initialized*. The contents of the newly created `Buffer` are unknown and -*may contain sensitive data*. Use [`buf.fill(0)`][] to initialize such +*may contain sensitive data*. Use [`buf.fill(0)`][`buf.fill()`] to initialize such `Buffer` instances to zeroes. ```js @@ -511,8 +508,8 @@ console.log(buf); A `TypeError` will be thrown if `size` is not a number. Note that the `Buffer` module pre-allocates an internal `Buffer` instance of -size `Buffer.poolSize` that is used as a pool for the fast allocation of new -`Buffer` instances created using `Buffer.allocUnsafe(size)` (and the deprecated +size [`Buffer.poolSize`] that is used as a pool for the fast allocation of new +`Buffer` instances created using [`Buffer.allocUnsafe()`] (and the deprecated `new Buffer(size)` constructor) only when `size` is less than or equal to `Buffer.poolSize >> 1` (floor of `Buffer.poolSize` divided by two). The default value of `Buffer.poolSize` is `8192` but can be modified. @@ -523,7 +520,7 @@ Specifically, `Buffer.alloc(size, fill)` will *never* use the internal Buffer pool, while `Buffer.allocUnsafe(size).fill(fill)` *will* use the internal Buffer pool if `size` is less than or equal to half `Buffer.poolSize`. The difference is subtle but can be important when an application requires the -additional performance that `Buffer.allocUnsafe(size)` provides. +additional performance that [`Buffer.allocUnsafe()`] provides. ### Class Method: Buffer.allocUnsafeSlow(size) - Stability: 0 - Deprecated: Use - [`Buffer.allocUnsafeSlow(size)`][buffer_allocunsafeslow] instead. + Stability: 0 - Deprecated: Use [`Buffer.allocUnsafeSlow()`] instead. Returns an un-pooled `Buffer`. @@ -2175,8 +2172,7 @@ has observed undue memory retention in their applications. deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use - [`Buffer.allocUnsafeSlow(size)`][buffer_allocunsafeslow] instead. + Stability: 0 - Deprecated: Use [`Buffer.allocUnsafeSlow()`] instead. * `size` Number @@ -2188,7 +2184,7 @@ thrown. A zero-length Buffer will be created if a `size` less than or equal to The underlying memory for `SlowBuffer` instances is *not initialized*. The contents of a newly created `SlowBuffer` are unknown and could contain -sensitive data. Use [`buf.fill(0)`][] to initialize a `SlowBuffer` to zeroes. +sensitive data. Use [`buf.fill(0)`][`buf.fill()`] to initialize a `SlowBuffer` to zeroes. ```js const SlowBuffer = require('buffer').SlowBuffer; From a8e7c7f2bff41fae6619ce75465832739e5e4fa3 Mon Sep 17 00:00:00 2001 From: Brian White Date: Tue, 19 Jul 2016 18:57:50 -0400 Subject: [PATCH 017/144] doc: improve wording and style of Buffer docs PR-URL: https://github.com/nodejs/node/pull/7784 Reviewed-By: James M Snell Reviewed-By: Trevor Norris --- doc/api/buffer.md | 528 ++++++++++++++++++++++++++-------------------- 1 file changed, 300 insertions(+), 228 deletions(-) diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 44f6807002a62f..0c24fc2201b6aa 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -20,6 +20,8 @@ resized. The `Buffer` class is a global within Node.js, making it unlikely that one would need to ever use `require('buffer').Buffer`. +Examples: + ```js // Creates a zero-filled Buffer of length 10. const buf1 = Buffer.alloc(10); @@ -68,7 +70,7 @@ validate the input arguments passed to `new Buffer()`, or that fail to appropriately initialize newly allocated `Buffer` content, can inadvertently introduce security and reliability issues into their code. -To make the creation of `Buffer` objects more reliable and less error prone, +To make the creation of `Buffer` instances more reliable and less error prone, the various forms of the `new Buffer()` constructor have been **deprecated** and replaced by separate `Buffer.from()`, [`Buffer.alloc()`], and [`Buffer.allocUnsafe()`] methods. @@ -114,6 +116,8 @@ impact* on performance. Use of the `--zero-fill-buffers` option is recommended only when necessary to enforce that newly allocated `Buffer` instances cannot contain potentially sensitive data. +Example: + ```txt $ node --zero-fill-buffers > Buffer.allocUnsafe(5); @@ -135,10 +139,12 @@ vulnerabilities into an application. ## Buffers and Character Encodings -Buffers are commonly used to represent sequences of encoded characters -such as UTF8, UCS2, Base64 or even Hex-encoded data. It is possible to -convert back and forth between Buffers and ordinary JavaScript string objects -by using an explicit encoding method. +`Buffer` instances are commonly used to represent sequences of encoded characters +such as UTF-8, UCS2, Base64 or even Hex-encoded data. It is possible to +convert back and forth between `Buffer` instances and ordinary JavaScript strings +by using an explicit character encoding. + +Example: ```js const buf = Buffer.from('hello world', 'ascii'); @@ -152,8 +158,8 @@ console.log(buf.toString('base64')); The character encodings currently supported by Node.js include: -* `'ascii'` - for 7-bit ASCII data only. This encoding method is very fast and - will strip the high bit if set. +* `'ascii'` - for 7-bit ASCII data only. This encoding is fast and will strip + the high bit if set. * `'utf8'` - Multibyte encoded Unicode characters. Many web pages and other document formats use UTF-8. @@ -163,7 +169,7 @@ The character encodings currently supported by Node.js include: * `'ucs2'` - Alias of `'utf16le'`. -* `'base64'` - Base64 string encoding. When creating a buffer from a string, +* `'base64'` - Base64 encoding. When creating a `Buffer` from a string, this encoding will also correctly accept "URL and Filename Safe Alphabet" as specified in [RFC4648, Section 5]. @@ -171,15 +177,15 @@ The character encodings currently supported by Node.js include: (as defined by the IANA in [RFC1345], page 63, to be the Latin-1 supplement block and C0/C1 control codes). -* `'binary'` - Alias for `latin1`. +* `'binary'` - Alias for `'latin1'`. * `'hex'` - Encode each byte as two hexadecimal characters. _Note_: Today's browsers follow the [WHATWG spec] which aliases both 'latin1' and -ISO-8859-1 to Windows-1252. This means that while doing something like `http.get()`, +ISO-8859-1 to win-1252. This means that while doing something like `http.get()`, if the returned charset is one of those listed in the WHATWG spec it's possible -that the server actually returned `win-1252` encoded data, and using `latin1` -encoding may incorrectly decode the graphical characters. +that the server actually returned win-1252-encoded data, and using `'latin1'` +encoding may incorrectly decode the characters. ## Buffers and TypedArray @@ -204,6 +210,8 @@ elements, and not as a byte array of the target type. That is, It is possible to create a new `Buffer` that shares the same allocated memory as a [`TypedArray`] instance by using the TypeArray object's `.buffer` property. +Example: + ```js const arr = new Uint16Array(2); @@ -235,6 +243,8 @@ Note that when creating a `Buffer` using a [`TypedArray`]'s `.buffer`, it is possible to use only a portion of the underlying [`ArrayBuffer`] by passing in `byteOffset` and `length` parameters. +Example: + ```js const arr = new Uint16Array(20); const buf = Buffer.from(arr.buffer, 0, 16); @@ -260,7 +270,10 @@ function: ## Buffers and ES6 iteration -Buffers can be iterated over using the ECMAScript 2015 (ES6) `for..of` syntax: +`Buffer` instances can be iterated over using the ECMAScript 2015 (ES6) `for..of` +syntax. + +Example: ```js const buf = Buffer.from([1, 2, 3]); @@ -279,7 +292,7 @@ Additionally, the [`buf.values()`], [`buf.keys()`], and ## Class: Buffer -The Buffer class is a global type for dealing with binary data directly. +The `Buffer` class is a global type for dealing with binary data directly. It can be constructed in a variety of ways. ### new Buffer(array) @@ -291,7 +304,9 @@ deprecated: v6.0.0 * `array` {Array} -Allocates a new Buffer using an `array` of octets. +Allocates a new `Buffer` using an `array` of octets. + +Example: ```js // Creates a new Buffer containing the ASCII bytes of the string 'buffer' @@ -309,6 +324,8 @@ deprecated: v6.0.0 Copies the passed `buffer` data onto a new `Buffer` instance. +Example: + ```js const buf1 = new Buffer('buffer'); const buf2 = new Buffer(buf1); @@ -343,6 +360,8 @@ the newly created `Buffer` will share the same allocated memory as the The optional `byteOffset` and `length` arguments specify a memory range within the `arrayBuffer` that will be shared by the `Buffer`. +Example: + ```js const arr = new Uint16Array(2); @@ -383,6 +402,8 @@ created in this way is *not initialized*. The contents of a newly created `Buffe are unknown and *could contain sensitive data*. Use [`buf.fill(0)`][`buf.fill()`] to initialize a `Buffer` to zeroes. +Example: + ```js const buf = new Buffer(5); @@ -409,6 +430,8 @@ deprecated: v6.0.0 Creates a new Buffer containing the given JavaScript string `str`. If provided, the `encoding` parameter identifies the strings character encoding. +Examples: + ```js const buf1 = new Buffer('this is a tést'); @@ -437,6 +460,8 @@ added: v5.10.0 Allocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the `Buffer` will be *zero-filled*. +Example: + ```js const buf = Buffer.alloc(5); @@ -452,6 +477,8 @@ be created if a `size` less than or equal to 0 is specified. If `fill` is specified, the allocated `Buffer` will be initialized by calling [`buf.fill(fill)`][`buf.fill()`]. +Example: + ```js const buf = Buffer.alloc(5, 'a'); @@ -462,6 +489,8 @@ console.log(buf); If both `fill` and `encoding` are specified, the allocated `Buffer` will be initialized by calling [`buf.fill(fill, encoding)`][`buf.fill()`]. +Example: + ```js const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64'); @@ -482,7 +511,7 @@ added: v5.10.0 * `size` {Number} -Allocates a new *non-zero-filled* `Buffer` of `size` bytes. The `size` must +Allocates a new *non-zero-filled* `Buffer` of `size` bytes. The `size` must be less than or equal to the value of `require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is `(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will be created if a `size` less than or equal to @@ -493,6 +522,8 @@ initialized*. The contents of the newly created `Buffer` are unknown and *may contain sensitive data*. Use [`buf.fill(0)`][`buf.fill()`] to initialize such `Buffer` instances to zeroes. +Example: + ```js const buf = Buffer.allocUnsafe(5); @@ -516,7 +547,7 @@ value of `Buffer.poolSize` is `8192` but can be modified. Use of this pre-allocated internal memory pool is a key difference between calling `Buffer.alloc(size, fill)` vs. `Buffer.allocUnsafe(size).fill(fill)`. -Specifically, `Buffer.alloc(size, fill)` will *never* use the internal Buffer +Specifically, `Buffer.alloc(size, fill)` will *never* use the internal `Buffer` pool, while `Buffer.allocUnsafe(size).fill(fill)` *will* use the internal Buffer pool if `size` is less than or equal to half `Buffer.poolSize`. The difference is subtle but can be important when an application requires the @@ -529,7 +560,7 @@ added: v5.10.0 * `size` {Number} -Allocates a new *non-zero-filled* and non-pooled `Buffer` of `size` bytes. The +Allocates a new *non-zero-filled* and non-pooled `Buffer` of `size` bytes. The `size` must be less than or equal to the value of `require('buffer').kMaxLength` (on 64-bit architectures, `kMaxLength` is `(2^31)-1`). Otherwise, a [`RangeError`][] is thrown. A zero-length Buffer will @@ -543,15 +574,17 @@ initialized*. The contents of the newly created `Buffer` are unknown and When using [`Buffer.allocUnsafe()`] to allocate new `Buffer` instances, allocations under 4KB are, by default, sliced from a single pre-allocated `Buffer`. This allows applications to avoid the garbage collection overhead of -creating many individually allocated Buffers. This approach improves both -performance and memory usage by eliminating the need to track and cleanup as +creating many individually allocated `Buffer` instances. This approach improves +both performance and memory usage by eliminating the need to track and cleanup as many `Persistent` objects. However, in the case where a developer may need to retain a small chunk of memory from a pool for an indeterminate amount of time, it may be appropriate -to create an un-pooled Buffer instance using `Buffer.allocUnsafeSlow()` then +to create an un-pooled `Buffer` instance using `Buffer.allocUnsafeSlow()` then copy out the relevant bits. +Example: + ```js // Need to keep around a few small chunks of memory const store = []; @@ -612,6 +645,8 @@ Compares `buf1` to `buf2` typically for the purpose of sorting arrays of `Buffer` instances. This is equivalent to calling [`buf1.compare(buf2)`][`buf.compare()`]. +Example: + ```js const buf1 = Buffer.from('1234'); const buf2 = Buffer.from('0123'); @@ -632,17 +667,18 @@ added: v0.7.11 when concatenated * Return: {Buffer} -Returns a new Buffer which is the result of concatenating all the Buffers in -the `list` together. +Returns a new `Buffer` which is the result of concatenating all the `Buffer` +instances in the `list` together. If the list has no items, or if the `totalLength` is 0, then a new zero-length -Buffer is returned. +`Buffer` is returned. -If `totalLength` is not provided, it is calculated from the Buffers in the -`list`. This, however, adds an additional loop to the function, so it is faster -to provide the length explicitly. +If `totalLength` is not provided, it is calculated from the `Buffer` instances +in `list`. This however causes an additional loop to be executed in order to +calculate the `totalLength`, so it is faster to provide the length explicitly if +it is already known. -Example: build a single Buffer from a list of three Buffers: +Example: Create a single `Buffer` from a list of three `Buffer` instances ```js const buf1 = Buffer.alloc(10); @@ -671,6 +707,8 @@ added: v3.0.0 Allocates a new `Buffer` using an `array` of octets. +Example: + ```js // Creates a new Buffer containing ASCII bytes of the string 'buffer' const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); @@ -692,6 +730,8 @@ When passed a reference to the `.buffer` property of a [`TypedArray`] instance, the newly created `Buffer` will share the same allocated memory as the [`TypedArray`]. +Example: + ```js const arr = new Uint16Array(2); @@ -714,6 +754,8 @@ console.log(buf); The optional `byteOffset` and `length` arguments specify a memory range within the `arrayBuffer` that will be shared by the `Buffer`. +Example: + ```js const ab = new ArrayBuffer(10); const buf = Buffer.from(ab, 0, 2); @@ -733,6 +775,8 @@ added: v3.0.0 Copies the passed `buffer` data onto a new `Buffer` instance. +Example: + ```js const buf1 = Buffer.from('buffer'); const buf2 = Buffer.from(buf1); @@ -760,6 +804,8 @@ Creates a new `Buffer` containing the given JavaScript string `str`. If provided, the `encoding` parameter identifies the character encoding. If not provided, `encoding` defaults to `'utf8'`. +Examples: + ```js const buf1 = Buffer.from('this is a tést'); @@ -783,7 +829,7 @@ A `TypeError` will be thrown if `str` is not a string. * `obj` {Object} * Return: {Boolean} -Returns 'true' if `obj` is a Buffer. +Returns `true` if `obj` is a `Buffer`, `false` otherwise. ### Class Method: Buffer.isEncoding(encoding) The index operator `[index]` can be used to get and set the octet at position -`index` in the Buffer. The values refer to individual bytes, so the legal value +`index` in `buf`. The values refer to individual bytes, so the legal value range is between `0x00` and `0xFF` (hex) or `0` and `255` (decimal). -Example: copy an ASCII string into a Buffer, one byte at a time: +Example: Copy an ASCII string into a `Buffer`, one byte at a time ```js const str = 'Node.js'; @@ -836,14 +882,16 @@ added: v0.11.13 Ignored when `targetStart` is `undefined`. default = `buf.byteLength`. * Return: {Number} -Compares two Buffer instances and returns a number indicating whether `buf` -comes before, after, or is the same as the `target` in sort order. -Comparison is based on the actual sequence of bytes in each Buffer. +Compares `buf` with `target` and returns a number indicating whether `buf` +comes before, after, or is the same as `target` in sort order. +Comparison is based on the actual sequence of bytes in each `Buffer`. * `0` is returned if `target` is the same as `buf` * `1` is returned if `target` should come *before* `buf` when sorted. * `-1` is returned if `target` should come *after* `buf` when sorted. +Examples: + ```js const buf1 = Buffer.from('ABC'); const buf2 = Buffer.from('BCD'); @@ -870,8 +918,10 @@ console.log([buf1, buf2, buf3].sort(Buffer.compare)); ``` The optional `targetStart`, `targetEnd`, `sourceStart`, and `sourceEnd` -arguments can be used to limit the comparison to specific ranges within the two -`Buffer` objects. +arguments can be used to limit the comparison to specific ranges within `target` +and `buf` respectively. + +Examples: ```js const buf1 = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8, 9]); @@ -898,11 +948,11 @@ A `RangeError` will be thrown if: `targetStart < 0`, `sourceStart < 0`, * `sourceEnd` {Number} Default: `buffer.length` * Return: {Number} The number of bytes copied. -Copies data from a region of this Buffer to a region in the target Buffer even -if the target memory region overlaps with the source. +Copies data from a region of `buf` to a region in `target` even if the `target` +memory region overlaps with `buf`. -Example: build two Buffers, then copy `buf1` from byte 16 through byte 19 -into `buf2`, starting at the 8th byte in `buf2`. +Example: Create two `Buffer` instances, `buf1` and `buf2`, and copy `buf1` from +byte 16 through byte 19 into `buf2`, starting at the 8th byte in `buf2` ```js const buf1 = Buffer.allocUnsafe(26); @@ -919,8 +969,8 @@ buf1.copy(buf2, 8, 16, 20); console.log(buf2.toString('ascii', 0, 25)); ``` -Example: Build a single Buffer, then copy data from one region to an overlapping -region in the same Buffer +Example: Create a single `Buffer` and copy data from one region to an +overlapping region within the same `Buffer` ```js const buf = Buffer.allocUnsafe(26); @@ -946,6 +996,8 @@ added: v1.1.0 Creates and returns an [iterator] of `[index, byte]` pairs from the contents of `buf`. +Example: Log the entire contents of a `Buffer` + ```js const buf = Buffer.from('buffer'); @@ -969,8 +1021,10 @@ added: v1.0.0 * `otherBuffer` {Buffer} * Return: {Boolean} -Returns a boolean indicating whether `this` and `otherBuffer` have exactly the -same bytes. +Returns `true` if both `buf` and `otherBuffer` have exactly the same bytes, +`false` otherwise. + +Examples: ```js const buf1 = Buffer.from('ABC'); @@ -995,11 +1049,11 @@ added: v0.5.0 * `encoding` {String} Default: `'utf8'` * Return: {Buffer} -Fills the Buffer with the specified value. If the `offset` (defaults to `0`) -and `end` (defaults to `buf.length`) are not given the entire buffer will be -filled. The method returns a reference to the Buffer, so calls can be chained. -This is meant as a small simplification to creating a Buffer. Allowing the -creation and fill of the Buffer to be done on a single line: +Fills `buf` with the specified `value`. If the `offset` and `end` are not given, +the entire `buf` will be filled. This is meant to be a small simplification to +allow the creation and filling of a `Buffer` to be done on a single line. + +Example: Fill a `Buffer` with the ASCII character `'h'` ```js const b = Buffer.allocUnsafe(50).fill('h'); @@ -1011,9 +1065,10 @@ console.log(b.toString()); `encoding` is only relevant if `value` is a string. Otherwise it is ignored. `value` is coerced to a `uint32` value if it is not a String or Number. -The `fill()` operation writes bytes into the Buffer dumbly. If the final write -falls in between a multi-byte character then whatever bytes fit into the buffer -are written. +If the final write of a `fill()` operation falls on a multi-byte character, +then only the first bytes of that character that fit into `buf` are written. + +Example: Fill a `Buffer` with a two-byte character ```js // Prints: @@ -1030,12 +1085,16 @@ added: v1.5.0 * `encoding` {String} Default: `'utf8'` * Return: {Number} -Operates similar to [`Array#indexOf()`][] in that it returns either the -starting index position of `value` in Buffer or `-1` if the Buffer does not -contain `value`. The `value` can be a String, Buffer or Number. Strings are by -default interpreted as UTF8. Buffers will use the entire Buffer (to compare a -partial Buffer use [`buf.slice()`][]). Numbers will be interpreted as unsigned 8-bit -integer values between `0` and `255`. +If `value` is: + + * a string, `value` is interpreted according to the character encoding in + `encoding`. + * a `Buffer`, `value` will be used in its entirety. To compare a partial + `Buffer` use [`buf.slice()`]. + * a number, `value` will be interpreted as an unsigned 8-bit integer + value between `0` and `255`. + +Examples: ```js const buf = Buffer.from('this is a buffer'); @@ -1079,13 +1138,9 @@ added: v5.3.0 * `encoding` {String} Default: `'utf8'` * Return: {Boolean} -Operates similar to [`Array#includes()`][]. The `value` can be a String, Buffer -or Number. Strings are interpreted as UTF8 unless overridden with the -`encoding` argument. Buffers will use the entire Buffer (to compare a partial -Buffer use [`buf.slice()`][]). Numbers will be interpreted as unsigned 8-bit -integer values between `0` and `255`. +Equivalent to [`buf.indexOf() !== -1`][`buf.indexOf()`]. -The `byteOffset` indicates the index in `buf` where searching begins. +Examples: ```js const buf = Buffer.from('this is a buffer'); @@ -1122,6 +1177,8 @@ added: v1.1.0 Creates and returns an [iterator] of `buf` keys (indices). +Example: + ```js const buf = Buffer.from('buffer'); @@ -1147,12 +1204,10 @@ added: v6.0.0 * `encoding` {String} Default: `'utf8'` * Return: {Number} -Identical to [`Buffer#indexOf()`][], but searches the Buffer from back to front -instead of front to back. Returns the starting index position of `value` in -Buffer or `-1` if the Buffer does not contain `value`. The `value` can be a -String, Buffer or Number. Strings are by default interpreted as UTF8. If -`byteOffset` is provided, will return the last match that begins at or before -`byteOffset`. +Identical to [`buf.indexOf()`], except `buf` is searched from back to front +instead of front to back. + +Examples: ```js const buf = Buffer.from('this buffer is a buffer'); @@ -1193,10 +1248,10 @@ console.log(utf16Buffer.lastIndexOf('\u03a3', -5, 'ucs2')); * {Number} -Returns the amount of memory allocated for the Buffer in number of bytes. Note -that this does not necessarily reflect the amount of usable data within the -Buffer. For instance, in the example below, a Buffer with 1234 bytes is -allocated, but only 11 ASCII bytes are written. +Returns the amount of memory allocated for `buf` in bytes. Note that this +does not necessarily reflect the amount of "usable" data within `buf`. + +Example: Create a `Buffer` and write a shorter ASCII string to it ```js const buf = Buffer.alloc(1234); @@ -1215,6 +1270,8 @@ can result in undefined and inconsistent behavior. Applications that wish to modify the length of a `Buffer` should therefore treat `length` as read-only and use [`buf.slice()`] to create a new `Buffer`. +Examples: + ```js var buf = Buffer.allocUnsafe(10); @@ -1236,12 +1293,14 @@ console.log(buf.length); * `noAssert` {Boolean} Default: false * Return: {Number} -Reads a 64-bit double from the Buffer at the specified `offset` with specified +Reads a 64-bit double from `buf` at the specified `offset` with specified endian format (`readDoubleBE()` returns big endian, `readDoubleLE()` returns little endian). -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. + +Examples: ```js const buf = Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]); @@ -1267,12 +1326,14 @@ console.log(buf.readDoubleLE(1, true)); * `noAssert` {Boolean} Default: false * Return: {Number} -Reads a 32-bit float from the Buffer at the specified `offset` with specified +Reads a 32-bit float from `buf` at the specified `offset` with specified endian format (`readFloatBE()` returns big endian, `readFloatLE()` returns little endian). -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. + +Examples: ```js const buf = Buffer.from([1, 2, 3, 4]); @@ -1297,12 +1358,14 @@ console.log(buf.readFloatLE(1, true)); * `noAssert` {Boolean} Default: false * Return: {Number} -Reads a signed 8-bit integer from the Buffer at the specified `offset`. +Reads a signed 8-bit integer from `buf` at the specified `offset`. + +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. +Integers read from a `Buffer` are interpreted as two's complement signed values. -Integers read from the Buffer are interpreted as two's complement signed values. +Examples: ```js const buf = Buffer.from([-1, 5]); @@ -1324,14 +1387,16 @@ console.log(buf.readInt8(2)); * `noAssert` {Boolean} Default: false * Return: {Number} -Reads a signed 16-bit integer from the Buffer at the specified `offset` with +Reads a signed 16-bit integer from `buf` at the specified `offset` with the specified endian format (`readInt16BE()` returns big endian, `readInt16LE()` returns little endian). -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. -Integers read from the Buffer are interpreted as two's complement signed values. +Integers read from a `Buffer` are interpreted as two's complement signed values. + +Examples: ```js const buf = Buffer.from([0, 5]); @@ -1353,14 +1418,16 @@ console.log(buf.readInt16LE(1)); * `noAssert` {Boolean} Default: false * Return: {Number} -Reads a signed 32-bit integer from the Buffer at the specified `offset` with +Reads a signed 32-bit integer from `buf` at the specified `offset` with the specified endian format (`readInt32BE()` returns big endian, `readInt32LE()` returns little endian). -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. + +Integers read from a `Buffer` are interpreted as two's complement signed values. -Integers read from the Buffer are interpreted as two's complement signed values. +Examples: ```js const buf = Buffer.from([0, 0, 0, 5]); @@ -1386,9 +1453,14 @@ added: v1.0.0 * `noAssert` {Boolean} Default: false * Return: {Number} -Reads `byteLength` number of bytes from the Buffer at the specified `offset` +Reads `byteLength` number of bytes from `buf` at the specified `offset` and interprets the result as a two's complement signed value. Supports up to 48 -bits of accuracy. For example: +bits of accuracy. + +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. + +Examples: ```js const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); @@ -1403,19 +1475,18 @@ console.log(buf.readIntBE(0, 6).toString(16)); console.log(buf.readIntBE(1, 6).toString(16)); ``` -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. - ### buf.readUInt8(offset[, noAssert]) * `offset` {Number} `0 <= offset <= buf.length - 1` * `noAssert` {Boolean} Default: false * Return: {Number} -Reads an unsigned 8-bit integer from the Buffer at the specified `offset`. +Reads an unsigned 8-bit integer from `buf` at the specified `offset`. + +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. +Examples: ```js const buf = Buffer.from([1, -2]); @@ -1437,14 +1508,14 @@ console.log(buf.readUInt8(2)); * `noAssert` {Boolean} Default: false * Return: {Number} -Reads an unsigned 16-bit integer from the Buffer at the specified `offset` with -specified endian format (`readUInt16BE()` returns big endian, -`readUInt16LE()` returns little endian). +Reads an unsigned 16-bit integer from `buf` at the specified `offset` with +specified endian format (`readUInt16BE()` returns big endian, `readUInt16LE()` +returns little endian). -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. -Example: +Examples: ```js const buf = Buffer.from([0x12, 0x34, 0x56]); @@ -1472,14 +1543,14 @@ console.log(buf.readUInt16LE(2).toString(16)); * `noAssert` {Boolean} Default: false * Return: {Number} -Reads an unsigned 32-bit integer from the Buffer at the specified `offset` with +Reads an unsigned 32-bit integer from `buf` at the specified `offset` with specified endian format (`readUInt32BE()` returns big endian, `readUInt32LE()` returns little endian). -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. -Example: +Examples: ```js const buf = Buffer.from([0x12, 0x34, 0x56, 0x78]); @@ -1505,9 +1576,14 @@ added: v1.0.0 * `noAssert` {Boolean} Default: false * Return: {Number} -Reads `byteLength` number of bytes from the Buffer at the specified `offset` +Reads `byteLength` number of bytes from `buf` at the specified `offset` and interprets the result as an unsigned integer. Supports up to 48 -bits of accuracy. For example: +bits of accuracy. + +Setting `noAssert` to `true` allows `offset` to be beyond the end of `buf`, but +the result should be considered undefined behavior. + +Examples: ```js const buf = Buffer.from([0x12, 0x34, 0x56, 0x78, 0x90, 0xab]); @@ -1522,23 +1598,20 @@ console.log(buf.readUIntBE(0, 6).toString(16)); console.log(buf.readUIntBE(1, 6).toString(16)); ``` -Setting `noAssert` to `true` skips validation of the `offset`. This allows the -`offset` to be beyond the end of the Buffer. - ### buf.slice([start[, end]]) * `start` {Number} Default: 0 * `end` {Number} Default: `buffer.length` * Return: {Buffer} -Returns a new Buffer that references the same memory as the original, but +Returns a new `Buffer` that references the same memory as the original, but offset and cropped by the `start` and `end` indices. -**Note that modifying the new Buffer slice will modify the memory in the -original Buffer because the allocated memory of the two objects overlap.** +**Note that modifying the new `Buffer` slice will modify the memory in the +original `Buffer` because the allocated memory of the two objects overlap.** -Example: build a Buffer with the ASCII alphabet, take a slice, then modify one -byte from the original Buffer. +Example: Create a `Buffer` with the ASCII alphabet, take a slice, and then modify +one byte from the original `Buffer` ```js const buf1 = Buffer.allocUnsafe(26); @@ -1560,7 +1633,9 @@ console.log(buf2.toString('ascii', 0, buf2.length)); ``` Specifying negative indexes causes the slice to be generated relative to the -end of the Buffer rather than the beginning. +end of `buf` rather than the beginning. + +Examples: ```js const buf = Buffer.from('buffer'); @@ -1585,10 +1660,10 @@ added: v5.10.0 * Return: {Buffer} -Interprets the `Buffer` as an array of unsigned 16-bit integers and swaps -the byte-order *in-place*. Throws a `RangeError` if the `Buffer` length is -not a multiple of 16 bits. The method returns a reference to the Buffer, so -calls can be chained. +Interprets `buf` as an array of unsigned 16-bit integers and swaps the byte-order +*in-place*. Throws a `RangeError` if [`buf.length`] is not a multiple of 2. + +Examples: ```js const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); @@ -1615,10 +1690,10 @@ added: v5.10.0 * Return: {Buffer} -Interprets the `Buffer` as an array of unsigned 32-bit integers and swaps -the byte-order *in-place*. Throws a `RangeError` if the `Buffer` length is -not a multiple of 32 bits. The method returns a reference to the Buffer, so -calls can be chained. +Interprets `buf` as an array of unsigned 32-bit integers and swaps the byte-order +*in-place*. Throws a `RangeError` if [`buf.length`] is not a multiple of 4. + +Examples: ```js const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); @@ -1645,10 +1720,10 @@ added: v6.3.0 * Return: {Buffer} -Interprets the `Buffer` as an array of 64-bit numbers and swaps -the byte-order *in-place*. Throws a `RangeError` if the `Buffer` length is -not a multiple of 64 bits. The method returns a reference to the Buffer, so -calls can be chained. +Interprets `buf` as an array of 64-bit numbers and swaps the byte-order *in-place*. +Throws a `RangeError` if [`buf.length`] is not a multiple of 8. + +Examples: ```js const buf1 = Buffer.from([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); @@ -1678,8 +1753,10 @@ for working with 64-bit floats. * `end` {Number} Default: `buffer.length` * Return: {String} -Decodes and returns a string from the Buffer data using the specified -character set `encoding`. +Decodes `buf` to a string according to the specified character encoding in `encoding`. +`start` and `end` may be passed to decode only a subset of `buf`. + +Examples: ```js const buf1 = Buffer.allocUnsafe(26); @@ -1712,7 +1789,7 @@ added: v0.9.2 * Return: {Object} -Returns a JSON representation of `buf`. [`JSON.stringify()`] implicitly calls +Returns a JSON representation of `buf`. [`JSON.stringify()`] implicitly calls this function when stringifying a `Buffer` instance. Example: @@ -1744,6 +1821,8 @@ added: v1.1.0 Creates and returns an [iterator] for `buf` values (bytes). This function is called automatically when a `Buffer` is used in a `for..of` statement. +Examples: + ```js const buf = Buffer.from('buffer'); @@ -1778,11 +1857,12 @@ for (var value of buf) { * `encoding` {String} Default: `'utf8'` * Return: {Number} Numbers of bytes written -Writes `string` to the Buffer at `offset` using the given `encoding`. -The `length` parameter is the number of bytes to write. If the Buffer did not -contain enough space to fit the entire string, only a partial amount of the -string will be written however, it will not write only partially encoded -characters. +Writes `string` to `buf` at `offset` according to the character encoding in `encoding`. +The `length` parameter is the number of bytes to write. If `buf` did not contain +enough space to fit the entire string, only a partial amount of `string` will +be written. However, partially encoded characters will not be written. + +Example: ```js const buf = Buffer.allocUnsafe(256); @@ -1801,17 +1881,15 @@ console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset` with specified endian +Writes `value` to `buf` at the specified `offset` with specified endian format (`writeDoubleBE()` writes big endian, `writeDoubleLE()` writes little -endian). The `value` argument *should* be a valid 64-bit double. Behavior is -not defined when `value` is anything other than a 64-bit double. +endian). `value` *should* be a valid 64-bit double. Behavior is undefined when +`value` is anything other than a 64-bit double. -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. -Example: +Examples: ```js const buf = Buffer.allocUnsafe(8); @@ -1835,17 +1913,15 @@ console.log(buf); * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset` with specified endian +Writes `value` to `buf` at the specified `offset` with specified endian format (`writeFloatBE()` writes big endian, `writeFloatLE()` writes little -endian). Behavior is not defined when `value` is anything other than a 32-bit -float. +endian). `value` *should* be a valid 32-bit float. Behavior is undefined when +`value` is anything other than a 32-bit float. -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. -Example: +Examples: ```js const buf = Buffer.allocUnsafe(4); @@ -1868,16 +1944,16 @@ console.log(buf); * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset`. The `value` should be a -valid signed 8-bit integer. Behavior is not defined when `value` is anything -other than a signed 8-bit integer. +Writes `value` to `buf` at the specified `offset`. `value` *should* be a valid +signed 8-bit integer. Behavior is undefined when `value` is anything other than +a signed 8-bit integer. -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. -The `value` is interpreted and written as a two's complement signed integer. +`value` is interpreted and written as a two's complement signed integer. + +Examples: ```js const buf = Buffer.allocUnsafe(2); @@ -1897,17 +1973,17 @@ console.log(buf); * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset` with specified endian +Writes `value` to `buf` at the specified `offset` with specified endian format (`writeInt16BE()` writes big endian, `writeInt16LE()` writes little -endian). The `value` should be a valid signed 16-bit integer. Behavior is -not defined when `value` is anything other than a signed 16-bit integer. +endian). `value` *should* be a valid signed 16-bit integer. Behavior is undefined +when `value` is anything other than a signed 16-bit integer. + +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +`value` is interpreted and written as a two's complement signed integer. -The `value` is interpreted and written as a two's complement signed integer. +Examples: ```js const buf = Buffer.allocUnsafe(4); @@ -1927,17 +2003,17 @@ console.log(buf); * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset` with specified endian +Writes `value` to `buf` at the specified `offset` with specified endian format (`writeInt32BE()` writes big endian, `writeInt32LE()` writes little -endian). The `value` should be a valid signed 32-bit integer. Behavior is -not defined when `value` is anything other than a signed 32-bit integer. +endian). `value` *should* be a valid signed 32-bit integer. Behavior is undefined +when `value` is anything other than a signed 32-bit integer. + +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +`value` is interpreted and written as a two's complement signed integer. -The `value` is interpreted and written as a two's complement signed integer. +Examples: ```js const buf = Buffer.allocUnsafe(8); @@ -1961,8 +2037,14 @@ added: v1.0.0 * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset` and `byteLength`. -Supports up to 48 bits of accuracy. For example: +Writes `byteLength` bytes of `value` to `buf` at the specified `offset`. +Supports up to 48 bits of accuracy. Behavior is undefined when `value` is +anything other than a signed integer. + +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. + +Examples: ```js const buf = Buffer.allocUnsafe(6); @@ -1978,13 +2060,6 @@ buf.writeUIntLE(0x1234567890ab, 0, 6); console.log(buf); ``` -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. - -Behavior is not defined when `value` is anything other than an integer. - ### buf.writeUInt8(value, offset[, noAssert]) * `value` {Number} Bytes to be written to Buffer @@ -1992,16 +2067,14 @@ Behavior is not defined when `value` is anything other than an integer. * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset`. The `value` should be a -valid unsigned 8-bit integer. Behavior is not defined when `value` is anything +Writes `value` to `buf` at the specified `offset`. `value` *should* be a +valid unsigned 8-bit integer. Behavior is undefined when `value` is anything other than an unsigned 8-bit integer. -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. -Example: +Examples: ```js const buf = Buffer.allocUnsafe(4); @@ -2023,17 +2096,15 @@ console.log(buf); * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset` with specified endian +Writes `value` to `buf` at the specified `offset` with specified endian format (`writeUInt16BE()` writes big endian, `writeUInt16LE()` writes little -endian). The `value` should be a valid unsigned 16-bit integer. Behavior is -not defined when `value` is anything other than an unsigned 16-bit integer. +endian). `value` should be a valid unsigned 16-bit integer. Behavior is +undefined when `value` is anything other than an unsigned 16-bit integer. -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. -Example: +Examples: ```js const buf = Buffer.allocUnsafe(4); @@ -2059,17 +2130,15 @@ console.log(buf); * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset` with specified endian +Writes `value` to `buf` at the specified `offset` with specified endian format (`writeUInt32BE()` writes big endian, `writeUInt32LE()` writes little -endian). The `value` should be a valid unsigned 32-bit integer. Behavior is -not defined when `value` is anything other than an unsigned 32-bit integer. +endian). `value` should be a valid unsigned 32-bit integer. Behavior is +undefined when `value` is anything other than an unsigned 32-bit integer. -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. -Example: +Examples: ```js const buf = Buffer.allocUnsafe(4); @@ -2094,8 +2163,14 @@ console.log(buf); * `noAssert` {Boolean} Default: false * Return: {Number} The offset plus the number of written bytes -Writes `value` to the Buffer at the specified `offset` and `byteLength`. -Supports up to 48 bits of accuracy. For example: +Writes `byteLength` bytes of `value` to `buf` at the specified `offset`. +Supports up to 48 bits of accuracy. Behavior is undefined when `value` is +anything other than an unsigned integer. + +Setting `noAssert` to `true` allows the encoded form of `value` to extend beyond +the end of `buf`, but the result should be considered undefined behavior. + +Examples: ```js const buf = Buffer.allocUnsafe(6); @@ -2111,13 +2186,6 @@ buf.writeUIntLE(0x1234567890ab, 0, 6); console.log(buf); ``` -Set `noAssert` to true to skip validation of `value` and `offset`. This means -that `value` may be too large for the specific function and `offset` may be -beyond the end of the Buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. - -Behavior is not defined when `value` is anything other than an unsigned integer. - ## buffer.INSPECT_MAX_BYTES * {Number} Default: 50 @@ -2127,7 +2195,7 @@ Returns the maximum number of bytes that will be returned when [`util.inspect()`] for more details on `buf.inspect()` behavior. Note that this is a property on the `buffer` module as returned by -`require('buffer')`, not on the Buffer global or a Buffer instance. +`require('buffer')`, not on the `Buffer` global or a `Buffer` instance. ## Class: SlowBuffer + +* {Number} **Default:** `8192` + +This is the number of bytes used to determine the size of pre-allocated, internal +`Buffer` instances used for pooling. This value may be modified. + ### buf[index] + +* {Number} The largest size allowed for a single `Buffer` instance + +On 32-bit architectures, this value is `(2^30)-1` (~1GB). +On 64-bit architectures, this value is `(2^31)-1` (~2GB). + ## Class: SlowBuffer Stability: 0 - Deprecated: - Use [`Buffer.from(str[, encoding])`][buffer_from_string] instead. + Use [`Buffer.from(string[, encoding])`][`Buffer.from(string)`] instead. -* `str` {String} string to encode. -* `encoding` {String} Default: `'utf8'` +* `string` {String} String to encode +* `encoding` {String} The encoding of `string`. **Default:** `'utf8'` -Creates a new Buffer containing the given JavaScript string `str`. If -provided, the `encoding` parameter identifies the strings character encoding. +Creates a new `Buffer` containing the given JavaScript string `string`. If +provided, the `encoding` parameter identifies the character encoding of `string`. Examples: @@ -451,9 +452,11 @@ console.log(buf2.toString()); added: v5.10.0 --> -* `size` {Number} -* `fill` {Value} Default: `undefined` -* `encoding` {String} Default: `utf8` +* `size` {Integer} The desired length of the new `Buffer` +* `fill` {String | Buffer | Integer} A value to pre-fill the new `Buffer` with. + **Default:** `0` +* `encoding` {String} If `fill` is a string, this is its encoding. + **Default:** `'utf8'` Allocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the `Buffer` will be *zero-filled*. @@ -506,7 +509,7 @@ A `TypeError` will be thrown if `size` is not a number. added: v5.10.0 --> -* `size` {Number} +* `size` {Integer} The desired length of the new `Buffer` Allocates a new *non-zero-filled* `Buffer` of `size` bytes. The `size` must be less than or equal to the value of [`buffer.kMaxLength`]. Otherwise, a @@ -552,7 +555,7 @@ additional performance that [`Buffer.allocUnsafe()`] provides. added: v5.10.0 --> -* `size` {Number} +* `size` {Integer} The desired length of the new `Buffer` Allocates a new *non-zero-filled* and non-pooled `Buffer` of `size` bytes. The `size` must be less than or equal to the value of [`buffer.kMaxLength`]. @@ -602,9 +605,11 @@ A `TypeError` will be thrown if `size` is not a number. ### Class Method: Buffer.byteLength(string[, encoding]) -* `string` {String | Buffer | TypedArray | DataView | ArrayBuffer} -* `encoding` {String} Default: `'utf8'` -* Return: {Number} +* `string` {String | Buffer | TypedArray | DataView | ArrayBuffer} A value to + calculate the length of +* `encoding` {String} If `string` is a string, this is its encoding. + **Default:** `'utf8'` +* Return: {Integer} The number of bytes contained within `string` Returns the actual byte length of a string. This is not the same as [`String.prototype.length`] since that returns the number of *characters* in @@ -632,7 +637,7 @@ added: v0.11.13 * `buf1` {Buffer} * `buf2` {Buffer} -* Return: {Number} +* Return: {Integer} Compares `buf1` to `buf2` typically for the purpose of sorting arrays of `Buffer` instances. This is equivalent to calling @@ -655,8 +660,8 @@ console.log(arr.sort(Buffer.compare)); added: v0.7.11 --> -* `list` {Array} List of Buffer objects to concat -* `totalLength` {Number} Total length of the Buffers in the list +* `list` {Array} List of `Buffer` instances to concat +* `totalLength` {Integer} Total length of the `Buffer` instances in `list` when concatenated * Return: {Buffer} @@ -714,10 +719,11 @@ A `TypeError` will be thrown if `array` is not an `Array`. added: v5.10.0 --> -* `arrayBuffer` {ArrayBuffer} The `.buffer` property of a `TypedArray` or - a `new ArrayBuffer()` -* `byteOffset` {Number} Default: `0` -* `length` {Number} Default: `arrayBuffer.length - byteOffset` +* `arrayBuffer` {ArrayBuffer} The `.buffer` property of a [`TypedArray`] or + [`ArrayBuffer`] +* `byteOffset` {Integer} Where to start copying from `arrayBuffer`. **Default:** `0` +* `length` {Integer} How many bytes to copy from `arrayBuffer`. + **Default:** `arrayBuffer.length - byteOffset` When passed a reference to the `.buffer` property of a [`TypedArray`] instance, the newly created `Buffer` will share the same allocated memory as the @@ -764,7 +770,7 @@ A `TypeError` will be thrown if `arrayBuffer` is not an [`ArrayBuffer`]. added: v3.0.0 --> -* `buffer` {Buffer} +* `buffer` {Buffer} An existing `Buffer` to copy data from Copies the passed `buffer` data onto a new `Buffer` instance. @@ -785,17 +791,16 @@ console.log(buf2.toString()); A `TypeError` will be thrown if `buffer` is not a `Buffer`. -### Class Method: Buffer.from(str[, encoding]) +### Class Method: Buffer.from(string[, encoding]) -* `str` {String} String to encode. -* `encoding` {String} Encoding to use, Default: `'utf8'` +* `string` {String} A string to encode. +* `encoding` {String} The encoding of `string`. **Default:** `'utf8'` -Creates a new `Buffer` containing the given JavaScript string `str`. If -provided, the `encoding` parameter identifies the character encoding. -If not provided, `encoding` defaults to `'utf8'`. +Creates a new `Buffer` containing the given JavaScript string `string`. If +provided, the `encoding` parameter identifies the character encoding of `string`. Examples: @@ -829,7 +834,7 @@ Returns `true` if `obj` is a `Buffer`, `false` otherwise. added: v0.9.1 --> -* `encoding` {String} The encoding string to test +* `encoding` {String} A character encoding name to check * Return: {Boolean} Returns `true` if `encoding` contains a supported character encoding, or `false` @@ -840,7 +845,7 @@ otherwise. added: v0.11.3 --> -* {Number} **Default:** `8192` +* {Integer} **Default:** `8192` This is the number of bytes used to determine the size of pre-allocated, internal `Buffer` instances used for pooling. This value may be modified. @@ -874,16 +879,18 @@ console.log(buf.toString('ascii')); added: v0.11.13 --> -* `target` {Buffer} +* `target` {Buffer} A `Buffer` to compare to * `targetStart` {Integer} The offset within `target` at which to begin - comparison. default = `0`. -* `targetEnd` {Integer} The offset with `target` at which to end comparison. - Ignored when `targetStart` is `undefined`. default = `target.byteLength`. + comparison. **Default:** `0` +* `targetEnd` {Integer} The offset with `target` at which to end comparison + (not inclusive). Ignored when `targetStart` is `undefined`. + **Default:** `target.length` * `sourceStart` {Integer} The offset within `buf` at which to begin comparison. - Ignored when `targetStart` is `undefined`. default = `0` -* `sourceEnd` {Integer} The offset within `buf` at which to end comparison. - Ignored when `targetStart` is `undefined`. default = `buf.byteLength`. -* Return: {Number} + Ignored when `targetStart` is `undefined`. **Default:** `0` +* `sourceEnd` {Integer} The offset within `buf` at which to end comparison + (not inclusive). Ignored when `targetStart` is `undefined`. + **Default:** [`buf.length`] +* Return: {Integer} Compares `buf` with `target` and returns a number indicating whether `buf` comes before, after, or is the same as `target` in sort order. @@ -943,13 +950,16 @@ console.log(buf1.compare(buf2, 5, 6, 5)); A `RangeError` will be thrown if: `targetStart < 0`, `sourceStart < 0`, `targetEnd > target.byteLength` or `sourceEnd > source.byteLength`. -### buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]]) +### buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]]) -* `targetBuffer` {Buffer} Buffer to copy into -* `targetStart` {Number} Default: 0 -* `sourceStart` {Number} Default: 0 -* `sourceEnd` {Number} Default: `buffer.length` -* Return: {Number} The number of bytes copied. +* `target` {Buffer} A `Buffer` to copy into. +* `targetStart` {Integer} The offset within `target` at which to begin + copying to. **Default:** `0` +* `sourceStart` {Integer} The offset within `buf` at which to begin copying from. + Ignored when `targetStart` is `undefined`. **Default:** `0` +* `sourceEnd` {Integer} The offset within `buf` at which to stop copying (not + inclusive). Ignored when `sourceStart` is `undefined`. **Default:** [`buf.length`] +* Return: {Integer} The number of bytes copied. Copies data from a region of `buf` to a region in `target` even if the `target` memory region overlaps with `buf`. @@ -1021,7 +1031,7 @@ for (var pair of buf.entries()) { added: v1.0.0 --> -* `otherBuffer` {Buffer} +* `otherBuffer` {Buffer} A `Buffer` to compare to * Return: {Boolean} Returns `true` if both `buf` and `otherBuffer` have exactly the same bytes, @@ -1046,11 +1056,12 @@ console.log(buf1.equals(buf3)); added: v0.5.0 --> -* `value` {String|Buffer|Number} -* `offset` {Number} Default: 0 -* `end` {Number} Default: `buf.length` -* `encoding` {String} Default: `'utf8'` -* Return: {Buffer} +* `value` {String | Buffer | Integer} The value to fill `buf` with +* `offset` {Integer} Where to start filling `buf`. **Default:** `0` +* `end` {Integer} Where to stop filling `buf` (not inclusive). **Default:** [`buf.length`] +* `encoding` {String} If `value` is a string, this is its encoding. + **Default:** `'utf8'` +* Return: {Buffer} A reference to `buf` Fills `buf` with the specified `value`. If the `offset` and `end` are not given, the entire `buf` will be filled. This is meant to be a small simplification to @@ -1065,8 +1076,7 @@ const b = Buffer.allocUnsafe(50).fill('h'); console.log(b.toString()); ``` -`encoding` is only relevant if `value` is a string. Otherwise it is ignored. -`value` is coerced to a `uint32` value if it is not a String or Number. +`value` is coerced to a `uint32` value if it is not a String or Integer. If the final write of a `fill()` operation falls on a multi-byte character, then only the first bytes of that character that fit into `buf` are written. @@ -1083,10 +1093,12 @@ console.log(Buffer.allocUnsafe(3).fill('\u0222')); added: v1.5.0 --> -* `value` {String|Buffer|Number} -* `byteOffset` {Number} Default: 0 -* `encoding` {String} Default: `'utf8'` -* Return: {Number} +* `value` {String | Buffer | Integer} What to search for +* `byteOffset` {Integer} Where to begin searching in `buf`. **Default:** `0` +* `encoding` {String} If `value` is a string, this is its encoding. + **Default:** `'utf8'` +* Return: {Integer} The index of the first occurrence of `value` in `buf` or `-1` + if `buf` does not contain `value` If `value` is: @@ -1136,10 +1148,11 @@ console.log(utf16Buffer.indexOf('\u03a3', -4, 'ucs2')); added: v5.3.0 --> -* `value` {String|Buffer|Number} -* `byteOffset` {Number} Default: 0 -* `encoding` {String} Default: `'utf8'` -* Return: {Boolean} +* `value` {String | Buffer | Integer} What to search for +* `byteOffset` {Integer} Where to begin searching in `buf`. **Default:** `0` +* `encoding` {String} If `value` is a string, this is its encoding. + **Default:** `'utf8'` +* Return: {Boolean} `true` if `value` was found in `buf`, `false` otherwise Equivalent to [`buf.indexOf() !== -1`][`buf.indexOf()`]. @@ -1202,10 +1215,13 @@ for (var key of buf.keys()) { added: v6.0.0 --> -* `value` {String|Buffer|Number} -* `byteOffset` {Number} Default: `buf.length` -* `encoding` {String} Default: `'utf8'` -* Return: {Number} +* `value` {String | Buffer | Integer} What to search for +* `byteOffset` {Integer} Where to begin searching in `buf` (not inclusive). + **Default:** [`buf.length`] +* `encoding` {String} If `value` is a string, this is its encoding. + **Default:** `'utf8'` +* Return: {Integer} The index of the last occurrence of `value` in `buf` or `-1` + if `buf` does not contain `value` Identical to [`buf.indexOf()`], except `buf` is searched from back to front instead of front to back. @@ -1249,7 +1265,7 @@ console.log(utf16Buffer.lastIndexOf('\u03a3', -5, 'ucs2')); ### buf.length -* {Number} +* {Integer} Returns the amount of memory allocated for `buf` in bytes. Note that this does not necessarily reflect the amount of "usable" data within `buf`. @@ -1292,8 +1308,8 @@ console.log(buf.length); ### buf.readDoubleBE(offset[, noAssert]) ### buf.readDoubleLE(offset[, noAssert]) -* `offset` {Number} `0 <= offset <= buf.length - 8` -* `noAssert` {Boolean} Default: false +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 8` +* `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` * Return: {Number} Reads a 64-bit double from `buf` at the specified `offset` with specified @@ -1325,8 +1341,8 @@ console.log(buf.readDoubleLE(1, true)); ### buf.readFloatBE(offset[, noAssert]) ### buf.readFloatLE(offset[, noAssert]) -* `offset` {Number} `0 <= offset <= buf.length - 4` -* `noAssert` {Boolean} Default: false +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 4` +* `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` * Return: {Number} Reads a 32-bit float from `buf` at the specified `offset` with specified @@ -1357,9 +1373,9 @@ console.log(buf.readFloatLE(1, true)); ### buf.readInt8(offset[, noAssert]) -* `offset` {Number} `0 <= offset <= buf.length - 1` -* `noAssert` {Boolean} Default: false -* Return: {Number} +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 1` +* `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` +* Return: {Integer} Reads a signed 8-bit integer from `buf` at the specified `offset`. @@ -1386,9 +1402,9 @@ console.log(buf.readInt8(2)); ### buf.readInt16BE(offset[, noAssert]) ### buf.readInt16LE(offset[, noAssert]) -* `offset` {Number} `0 <= offset <= buf.length - 2` -* `noAssert` {Boolean} Default: false -* Return: {Number} +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 2` +* `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` +* Return: {Integer} Reads a signed 16-bit integer from `buf` at the specified `offset` with the specified endian format (`readInt16BE()` returns big endian, @@ -1417,9 +1433,9 @@ console.log(buf.readInt16LE(1)); ### buf.readInt32BE(offset[, noAssert]) ### buf.readInt32LE(offset[, noAssert]) -* `offset` {Number} `0 <= offset <= buf.length - 4` -* `noAssert` {Boolean} Default: false -* Return: {Number} +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 4` +* `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` +* Return: {Integer} Reads a signed 32-bit integer from `buf` at the specified `offset` with the specified endian format (`readInt32BE()` returns big endian, @@ -1451,10 +1467,10 @@ console.log(buf.readInt32LE(1)); added: v1.0.0 --> -* `offset` {Number} `0 <= offset <= buf.length - byteLength` -* `byteLength` {Number} `0 < byteLength <= 6` -* `noAssert` {Boolean} Default: false -* Return: {Number} +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - byteLength` +* `byteLength` {Integer} How many bytes to read. Must satisfy: `0 < byteLength <= 6` +* `noAssert` {Boolean} Skip `offset` and `byteLength` validation? **Default:** `false` +* Return: {Integer} Reads `byteLength` number of bytes from `buf` at the specified `offset` and interprets the result as a two's complement signed value. Supports up to 48 @@ -1480,9 +1496,9 @@ console.log(buf.readIntBE(1, 6).toString(16)); ### buf.readUInt8(offset[, noAssert]) -* `offset` {Number} `0 <= offset <= buf.length - 1` -* `noAssert` {Boolean} Default: false -* Return: {Number} +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 1` +* `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` +* Return: {Integer} Reads an unsigned 8-bit integer from `buf` at the specified `offset`. @@ -1507,9 +1523,9 @@ console.log(buf.readUInt8(2)); ### buf.readUInt16BE(offset[, noAssert]) ### buf.readUInt16LE(offset[, noAssert]) -* `offset` {Number} `0 <= offset <= buf.length - 2` -* `noAssert` {Boolean} Default: false -* Return: {Number} +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 2` +* `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` +* Return: {Integer} Reads an unsigned 16-bit integer from `buf` at the specified `offset` with specified endian format (`readUInt16BE()` returns big endian, `readUInt16LE()` @@ -1542,9 +1558,9 @@ console.log(buf.readUInt16LE(2).toString(16)); ### buf.readUInt32BE(offset[, noAssert]) ### buf.readUInt32LE(offset[, noAssert]) -* `offset` {Number} `0 <= offset <= buf.length - 4` -* `noAssert` {Boolean} Default: false -* Return: {Number} +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 4` +* `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` +* Return: {Integer} Reads an unsigned 32-bit integer from `buf` at the specified `offset` with specified endian format (`readUInt32BE()` returns big endian, @@ -1574,10 +1590,10 @@ console.log(buf.readUInt32LE(1).toString(16)); added: v1.0.0 --> -* `offset` {Number} `0 <= offset <= buf.length - byteLength` -* `byteLength` {Number} `0 < byteLength <= 6` -* `noAssert` {Boolean} Default: false -* Return: {Number} +* `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - byteLength` +* `byteLength` {Integer} How many bytes to read. Must satisfy: `0 < byteLength <= 6` +* `noAssert` {Boolean} Skip `offset` and `byteLength` validation? **Default:** `false` +* Return: {Integer} Reads `byteLength` number of bytes from `buf` at the specified `offset` and interprets the result as an unsigned integer. Supports up to 48 @@ -1603,8 +1619,9 @@ console.log(buf.readUIntBE(1, 6).toString(16)); ### buf.slice([start[, end]]) -* `start` {Number} Default: 0 -* `end` {Number} Default: `buffer.length` +* `start` {Integer} Where the new `Buffer` will start. **Default:** `0` +* `end` {Integer} Where the new `Buffer` will end (not inclusive). + **Default:** [`buf.length`] * Return: {Buffer} Returns a new `Buffer` that references the same memory as the original, but @@ -1661,7 +1678,7 @@ console.log(buf.slice(-5, -2).toString()); added: v5.10.0 --> -* Return: {Buffer} +* Return: {Buffer} A reference to `buf` Interprets `buf` as an array of unsigned 16-bit integers and swaps the byte-order *in-place*. Throws a `RangeError` if [`buf.length`] is not a multiple of 2. @@ -1691,7 +1708,7 @@ buf2.swap32(); added: v5.10.0 --> -* Return: {Buffer} +* Return: {Buffer} A reference to `buf` Interprets `buf` as an array of unsigned 32-bit integers and swaps the byte-order *in-place*. Throws a `RangeError` if [`buf.length`] is not a multiple of 4. @@ -1721,7 +1738,7 @@ buf2.swap32(); added: v6.3.0 --> -* Return: {Buffer} +* Return: {Buffer} A reference to `buf` Interprets `buf` as an array of 64-bit numbers and swaps the byte-order *in-place*. Throws a `RangeError` if [`buf.length`] is not a multiple of 8. @@ -1751,9 +1768,9 @@ for working with 64-bit floats. ### buf.toString([encoding[, start[, end]]]) -* `encoding` {String} Default: `'utf8'` -* `start` {Number} Default: 0 -* `end` {Number} Default: `buffer.length` +* `encoding` {String} The character encoding to decode to. **Default:** `'utf8'` +* `start` {Integer} Where to start decoding. **Default:** `0` +* `end` {Integer} Where to stop decoding (not inclusive). **Default:** [`buf.length`] * Return: {String} Decodes `buf` to a string according to the specified character encoding in `encoding`. @@ -1854,11 +1871,11 @@ for (var value of buf) { ### buf.write(string[, offset[, length]][, encoding]) -* `string` {String} Bytes to be written to buffer -* `offset` {Number} Default: 0 -* `length` {Number} Default: `buffer.length - offset` -* `encoding` {String} Default: `'utf8'` -* Return: {Number} Numbers of bytes written +* `string` {String} String to be written to `buf` +* `offset` {Integer} Where to start writing `string`. **Default:** `0` +* `length` {Integer} How many bytes to write. **Default:** `buf.length - offset` +* `encoding` {String} The character encoding of `string`. **Default:** `'utf8'` +* Return: {Integer} Number of bytes written Writes `string` to `buf` at `offset` according to the character encoding in `encoding`. The `length` parameter is the number of bytes to write. If `buf` did not contain @@ -1879,10 +1896,10 @@ console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); ### buf.writeDoubleBE(value, offset[, noAssert]) ### buf.writeDoubleLE(value, offset[, noAssert]) -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - 8` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Number} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 8` +* `noAssert` {Boolean} Skip `value` and `offset` validation? **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `value` to `buf` at the specified `offset` with specified endian format (`writeDoubleBE()` writes big endian, `writeDoubleLE()` writes little @@ -1911,10 +1928,10 @@ console.log(buf); ### buf.writeFloatBE(value, offset[, noAssert]) ### buf.writeFloatLE(value, offset[, noAssert]) -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - 4` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Number} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 4` +* `noAssert` {Boolean} Skip `value` and `offset` validation? **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `value` to `buf` at the specified `offset` with specified endian format (`writeFloatBE()` writes big endian, `writeFloatLE()` writes little @@ -1942,10 +1959,10 @@ console.log(buf); ### buf.writeInt8(value, offset[, noAssert]) -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - 1` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Integer} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 1` +* `noAssert` {Boolean} Skip `value` and `offset` validation? **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `value` to `buf` at the specified `offset`. `value` *should* be a valid signed 8-bit integer. Behavior is undefined when `value` is anything other than @@ -1971,10 +1988,10 @@ console.log(buf); ### buf.writeInt16BE(value, offset[, noAssert]) ### buf.writeInt16LE(value, offset[, noAssert]) -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - 2` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Integer} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 2` +* `noAssert` {Boolean} Skip `value` and `offset` validation? **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `value` to `buf` at the specified `offset` with specified endian format (`writeInt16BE()` writes big endian, `writeInt16LE()` writes little @@ -2001,10 +2018,10 @@ console.log(buf); ### buf.writeInt32BE(value, offset[, noAssert]) ### buf.writeInt32LE(value, offset[, noAssert]) -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - 4` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Integer} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 4` +* `noAssert` {Boolean} Skip `value` and `offset` validation? **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `value` to `buf` at the specified `offset` with specified endian format (`writeInt32BE()` writes big endian, `writeInt32LE()` writes little @@ -2034,11 +2051,12 @@ console.log(buf); added: v1.0.0 --> -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - byteLength` -* `byteLength` {Number} `0 < byteLength <= 6` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Integer} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - byteLength` +* `byteLength` {Integer} How many bytes to write. Must satisfy: `0 < byteLength <= 6` +* `noAssert` {Boolean} Skip `value`, `offset`, and `byteLength` validation? + **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `byteLength` bytes of `value` to `buf` at the specified `offset`. Supports up to 48 bits of accuracy. Behavior is undefined when `value` is @@ -2065,10 +2083,10 @@ console.log(buf); ### buf.writeUInt8(value, offset[, noAssert]) -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - 1` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Integer} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 1` +* `noAssert` {Boolean} Skip `value` and `offset` validation? **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `value` to `buf` at the specified `offset`. `value` *should* be a valid unsigned 8-bit integer. Behavior is undefined when `value` is anything @@ -2094,10 +2112,10 @@ console.log(buf); ### buf.writeUInt16BE(value, offset[, noAssert]) ### buf.writeUInt16LE(value, offset[, noAssert]) -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - 2` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Integer} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 2` +* `noAssert` {Boolean} Skip `value` and `offset` validation? **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `value` to `buf` at the specified `offset` with specified endian format (`writeUInt16BE()` writes big endian, `writeUInt16LE()` writes little @@ -2128,10 +2146,10 @@ console.log(buf); ### buf.writeUInt32BE(value, offset[, noAssert]) ### buf.writeUInt32LE(value, offset[, noAssert]) -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - 4` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Integer} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 4` +* `noAssert` {Boolean} Skip `value` and `offset` validation? **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `value` to `buf` at the specified `offset` with specified endian format (`writeUInt32BE()` writes big endian, `writeUInt32LE()` writes little @@ -2160,11 +2178,12 @@ console.log(buf); ### buf.writeUIntBE(value, offset, byteLength[, noAssert]) ### buf.writeUIntLE(value, offset, byteLength[, noAssert]) -* `value` {Number} Bytes to be written to Buffer -* `offset` {Number} `0 <= offset <= buf.length - byteLength` -* `byteLength` {Number} `0 < byteLength <= 6` -* `noAssert` {Boolean} Default: false -* Return: {Number} The offset plus the number of written bytes +* `value` {Integer} Number to be written to `buf` +* `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - byteLength` +* `byteLength` {Integer} How many bytes to write. Must satisfy: `0 < byteLength <= 6` +* `noAssert` {Boolean} Skip `value`, `offset`, and `byteLength` validation? + **Default:** `false` +* Return: {Integer} `offset` plus the number of bytes written Writes `byteLength` bytes of `value` to `buf` at the specified `offset`. Supports up to 48 bits of accuracy. Behavior is undefined when `value` is @@ -2191,7 +2210,7 @@ console.log(buf); ## buffer.INSPECT_MAX_BYTES -* {Number} Default: 50 +* {Integer} **Default:** `50` Returns the maximum number of bytes that will be returned when `buf.inspect()` is called. This can be overridden by user modules. See @@ -2205,7 +2224,7 @@ Note that this is a property on the `buffer` module as returned by added: v3.0.0 --> -* {Number} The largest size allowed for a single `Buffer` instance +* {Integer} The largest size allowed for a single `Buffer` instance On 32-bit architectures, this value is `(2^30)-1` (~1GB). On 64-bit architectures, this value is `(2^31)-1` (~2GB). @@ -2257,7 +2276,7 @@ deprecated: v6.0.0 Stability: 0 - Deprecated: Use [`Buffer.allocUnsafeSlow()`] instead. -* `size` Number +* `size` {Integer} The desired length of the new `SlowBuffer` Allocates a new `SlowBuffer` of `size` bytes. The `size` must be less than or equal to the value of [`buffer.kMaxLength`]. Otherwise, a [`RangeError`] is From 57fb0d2ee205e3f5ea48aface7381abdddbf84ad Mon Sep 17 00:00:00 2001 From: Brian White Date: Tue, 19 Jul 2016 19:07:19 -0400 Subject: [PATCH 020/144] doc: add/fix version metadata for Buffer methods PR-URL: https://github.com/nodejs/node/pull/7784 Reviewed-By: James M Snell Reviewed-By: Trevor Norris --- doc/api/buffer.md | 87 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 5bc5c5b72eac99..ebce7fc4ba30c3 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -604,6 +604,9 @@ a developer has observed undue memory retention in their applications. A `TypeError` will be thrown if `size` is not a number. ### Class Method: Buffer.byteLength(string[, encoding]) + * `string` {String | Buffer | TypedArray | DataView | ArrayBuffer} A value to calculate the length of @@ -698,7 +701,7 @@ console.log(bufA.length); ### Class Method: Buffer.from(array) * `array` {Array} @@ -767,7 +770,7 @@ A `TypeError` will be thrown if `arrayBuffer` is not an [`ArrayBuffer`]. ### Class Method: Buffer.from(buffer) * `buffer` {Buffer} An existing `Buffer` to copy data from @@ -823,6 +826,9 @@ console.log(buf2.toString()); A `TypeError` will be thrown if `str` is not a string. ### Class Method: Buffer.isBuffer(obj) + * `obj` {Object} * Return: {Boolean} @@ -951,6 +957,9 @@ A `RangeError` will be thrown if: `targetStart < 0`, `sourceStart < 0`, `targetEnd > target.byteLength` or `sourceEnd > source.byteLength`. ### buf.copy(target[, targetStart[, sourceStart[, sourceEnd]]]) + * `target` {Buffer} A `Buffer` to copy into. * `targetStart` {Integer} The offset within `target` at which to begin @@ -1028,7 +1037,7 @@ for (var pair of buf.entries()) { ### buf.equals(otherBuffer) * `otherBuffer` {Buffer} A `Buffer` to compare to @@ -1264,6 +1273,9 @@ console.log(utf16Buffer.lastIndexOf('\u03a3', -5, 'ucs2')); ``` ### buf.length + * {Integer} @@ -1307,6 +1319,9 @@ console.log(buf.length); ### buf.readDoubleBE(offset[, noAssert]) ### buf.readDoubleLE(offset[, noAssert]) + * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 8` * `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` @@ -1340,6 +1355,9 @@ console.log(buf.readDoubleLE(1, true)); ### buf.readFloatBE(offset[, noAssert]) ### buf.readFloatLE(offset[, noAssert]) + * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 4` * `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` @@ -1372,6 +1390,9 @@ console.log(buf.readFloatLE(1, true)); ``` ### buf.readInt8(offset[, noAssert]) + * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 1` * `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` @@ -1401,6 +1422,9 @@ console.log(buf.readInt8(2)); ### buf.readInt16BE(offset[, noAssert]) ### buf.readInt16LE(offset[, noAssert]) + * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 2` * `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` @@ -1432,6 +1456,9 @@ console.log(buf.readInt16LE(1)); ### buf.readInt32BE(offset[, noAssert]) ### buf.readInt32LE(offset[, noAssert]) + * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 4` * `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` @@ -1464,7 +1491,7 @@ console.log(buf.readInt32LE(1)); ### buf.readIntBE(offset, byteLength[, noAssert]) ### buf.readIntLE(offset, byteLength[, noAssert]) * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - byteLength` @@ -1495,6 +1522,9 @@ console.log(buf.readIntBE(1, 6).toString(16)); ``` ### buf.readUInt8(offset[, noAssert]) + * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 1` * `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` @@ -1522,6 +1552,9 @@ console.log(buf.readUInt8(2)); ### buf.readUInt16BE(offset[, noAssert]) ### buf.readUInt16LE(offset[, noAssert]) + * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 2` * `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` @@ -1557,6 +1590,9 @@ console.log(buf.readUInt16LE(2).toString(16)); ### buf.readUInt32BE(offset[, noAssert]) ### buf.readUInt32LE(offset[, noAssert]) + * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - 4` * `noAssert` {Boolean} Skip `offset` validation? **Default:** `false` @@ -1587,7 +1623,7 @@ console.log(buf.readUInt32LE(1).toString(16)); ### buf.readUIntBE(offset, byteLength[, noAssert]) ### buf.readUIntLE(offset, byteLength[, noAssert]) * `offset` {Integer} Where to start reading. Must satisfy: `0 <= offset <= buf.length - byteLength` @@ -1618,6 +1654,9 @@ console.log(buf.readUIntBE(1, 6).toString(16)); ``` ### buf.slice([start[, end]]) + * `start` {Integer} Where the new `Buffer` will start. **Default:** `0` * `end` {Integer} Where the new `Buffer` will end (not inclusive). @@ -1767,6 +1806,9 @@ Note that JavaScript cannot encode 64-bit integers. This method is intended for working with 64-bit floats. ### buf.toString([encoding[, start[, end]]]) + * `encoding` {String} The character encoding to decode to. **Default:** `'utf8'` * `start` {Integer} Where to start decoding. **Default:** `0` @@ -1870,6 +1912,9 @@ for (var value of buf) { ``` ### buf.write(string[, offset[, length]][, encoding]) + * `string` {String} String to be written to `buf` * `offset` {Integer} Where to start writing `string`. **Default:** `0` @@ -1895,6 +1940,9 @@ console.log(`${len} bytes: ${buf.toString('utf8', 0, len)}`); ### buf.writeDoubleBE(value, offset[, noAssert]) ### buf.writeDoubleLE(value, offset[, noAssert]) + * `value` {Number} Number to be written to `buf` * `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 8` @@ -1927,6 +1975,9 @@ console.log(buf); ### buf.writeFloatBE(value, offset[, noAssert]) ### buf.writeFloatLE(value, offset[, noAssert]) + * `value` {Number} Number to be written to `buf` * `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 4` @@ -1958,6 +2009,9 @@ console.log(buf); ``` ### buf.writeInt8(value, offset[, noAssert]) + * `value` {Integer} Number to be written to `buf` * `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 1` @@ -1987,6 +2041,9 @@ console.log(buf); ### buf.writeInt16BE(value, offset[, noAssert]) ### buf.writeInt16LE(value, offset[, noAssert]) + * `value` {Integer} Number to be written to `buf` * `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 2` @@ -2017,6 +2074,9 @@ console.log(buf); ### buf.writeInt32BE(value, offset[, noAssert]) ### buf.writeInt32LE(value, offset[, noAssert]) + * `value` {Integer} Number to be written to `buf` * `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 4` @@ -2048,7 +2108,7 @@ console.log(buf); ### buf.writeIntBE(value, offset, byteLength[, noAssert]) ### buf.writeIntLE(value, offset, byteLength[, noAssert]) * `value` {Integer} Number to be written to `buf` @@ -2082,6 +2142,9 @@ console.log(buf); ``` ### buf.writeUInt8(value, offset[, noAssert]) + * `value` {Integer} Number to be written to `buf` * `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 1` @@ -2111,6 +2174,9 @@ console.log(buf); ### buf.writeUInt16BE(value, offset[, noAssert]) ### buf.writeUInt16LE(value, offset[, noAssert]) + * `value` {Integer} Number to be written to `buf` * `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 2` @@ -2145,6 +2211,9 @@ console.log(buf); ### buf.writeUInt32BE(value, offset[, noAssert]) ### buf.writeUInt32LE(value, offset[, noAssert]) + * `value` {Integer} Number to be written to `buf` * `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - 4` @@ -2177,6 +2246,9 @@ console.log(buf); ### buf.writeUIntBE(value, offset, byteLength[, noAssert]) ### buf.writeUIntLE(value, offset, byteLength[, noAssert]) + * `value` {Integer} Number to be written to `buf` * `offset` {Integer} Where to start writing. Must satisfy: `0 <= offset <= buf.length - byteLength` @@ -2209,6 +2281,9 @@ console.log(buf); ``` ## buffer.INSPECT_MAX_BYTES + * {Integer} **Default:** `50` From 303f4102d309dd17c894a796cd4ce06157275476 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Mon, 4 Jul 2016 19:20:33 +0200 Subject: [PATCH 021/144] src: pull OnConnection from pipe_wrap and tcp_wrap One of the issues in #4641 concerns OnConnection in pipe_wrap and tcp_wrap which are very similar with some minor difference in how they are coded. This commit extracts OnConnection so both these classes can share the same implementation. PR-URL: https://github.com/nodejs/node/pull/7547 Reviewed-By: Anna Henningsen Reviewed-By: Trevor Norris Reviewed-By: Ben Noordhuis --- node.gyp | 2 + src/base-object-inl.h | 16 ++++---- src/base-object.h | 2 +- src/connection_wrap.cc | 93 ++++++++++++++++++++++++++++++++++++++++++ src/connection_wrap.h | 36 ++++++++++++++++ src/pipe_wrap.cc | 54 +++--------------------- src/pipe_wrap.h | 9 +--- src/tcp_wrap.cc | 53 +++--------------------- src/tcp_wrap.h | 9 +--- 9 files changed, 154 insertions(+), 120 deletions(-) create mode 100644 src/connection_wrap.cc create mode 100644 src/connection_wrap.h diff --git a/node.gyp b/node.gyp index 70dc80c4035f0f..186b4d75d5b610 100644 --- a/node.gyp +++ b/node.gyp @@ -141,6 +141,7 @@ 'src/env.cc', 'src/fs_event_wrap.cc', 'src/cares_wrap.cc', + 'src/connection_wrap.cc', 'src/handle_wrap.cc', 'src/js_stream.cc', 'src/node.cc', @@ -177,6 +178,7 @@ 'src/async-wrap-inl.h', 'src/base-object.h', 'src/base-object-inl.h', + 'src/connection_wrap.h', 'src/debug-agent.h', 'src/env.h', 'src/env-inl.h', diff --git a/src/base-object-inl.h b/src/base-object-inl.h index b4c3730f1ae870..4ddc5e1349bc13 100644 --- a/src/base-object-inl.h +++ b/src/base-object-inl.h @@ -13,7 +13,7 @@ namespace node { inline BaseObject::BaseObject(Environment* env, v8::Local handle) - : handle_(env->isolate(), handle), + : persistent_handle_(env->isolate(), handle), env_(env) { CHECK_EQ(false, handle.IsEmpty()); // The zero field holds a pointer to the handle. Immediately set it to @@ -24,17 +24,17 @@ inline BaseObject::BaseObject(Environment* env, v8::Local handle) inline BaseObject::~BaseObject() { - CHECK(handle_.IsEmpty()); + CHECK(persistent_handle_.IsEmpty()); } inline v8::Persistent& BaseObject::persistent() { - return handle_; + return persistent_handle_; } inline v8::Local BaseObject::object() { - return PersistentToLocal(env_->isolate(), handle_); + return PersistentToLocal(env_->isolate(), persistent_handle_); } @@ -58,14 +58,14 @@ inline void BaseObject::MakeWeak(Type* ptr) { v8::Local handle = object(); CHECK_GT(handle->InternalFieldCount(), 0); Wrap(handle, ptr); - handle_.MarkIndependent(); - handle_.SetWeak(ptr, WeakCallback, - v8::WeakCallbackType::kParameter); + persistent_handle_.MarkIndependent(); + persistent_handle_.SetWeak(ptr, WeakCallback, + v8::WeakCallbackType::kParameter); } inline void BaseObject::ClearWeak() { - handle_.ClearWeak(); + persistent_handle_.ClearWeak(); } } // namespace node diff --git a/src/base-object.h b/src/base-object.h index afec3442ce84b5..27251379770e2c 100644 --- a/src/base-object.h +++ b/src/base-object.h @@ -44,7 +44,7 @@ class BaseObject { static inline void WeakCallback( const v8::WeakCallbackInfo& data); - v8::Persistent handle_; + v8::Persistent persistent_handle_; Environment* env_; }; diff --git a/src/connection_wrap.cc b/src/connection_wrap.cc new file mode 100644 index 00000000000000..f98fb79eb910c6 --- /dev/null +++ b/src/connection_wrap.cc @@ -0,0 +1,93 @@ +#include "connection_wrap.h" + +#include "env-inl.h" +#include "env.h" +#include "pipe_wrap.h" +#include "stream_wrap.h" +#include "tcp_wrap.h" +#include "util.h" +#include "util-inl.h" + +namespace node { + +using v8::Context; +using v8::HandleScope; +using v8::Integer; +using v8::Local; +using v8::Object; +using v8::Value; + + +template +ConnectionWrap::ConnectionWrap(Environment* env, + Local object, + ProviderType provider, + AsyncWrap* parent) + : StreamWrap(env, + object, + reinterpret_cast(&handle_), + provider, + parent) {} + + +template +void ConnectionWrap::OnConnection(uv_stream_t* handle, + int status) { + WrapType* wrap_data = static_cast(handle->data); + CHECK_NE(wrap_data, nullptr); + CHECK_EQ(&wrap_data->handle_, reinterpret_cast(handle)); + + Environment* env = wrap_data->env(); + HandleScope handle_scope(env->isolate()); + Context::Scope context_scope(env->context()); + + // We should not be getting this callback if someone has already called + // uv_close() on the handle. + CHECK_EQ(wrap_data->persistent().IsEmpty(), false); + + Local argv[] = { + Integer::New(env->isolate(), status), + Undefined(env->isolate()) + }; + + if (status == 0) { + // Instantiate the client javascript object and handle. + Local client_obj = WrapType::Instantiate(env, wrap_data); + + // Unwrap the client javascript object. + WrapType* wrap; + ASSIGN_OR_RETURN_UNWRAP(&wrap, client_obj); + uv_stream_t* client_handle = + reinterpret_cast(&wrap->handle_); + // uv_accept can fail if the new connection has already been closed, in + // which case an EAGAIN (resource temporarily unavailable) will be + // returned. + if (uv_accept(handle, client_handle)) + return; + + // Successful accept. Call the onconnection callback in JavaScript land. + argv[1] = client_obj; + } + wrap_data->MakeCallback(env->onconnection_string(), arraysize(argv), argv); +} + +template ConnectionWrap::ConnectionWrap( + Environment* env, + Local object, + ProviderType provider, + AsyncWrap* parent); + +template ConnectionWrap::ConnectionWrap( + Environment* env, + Local object, + ProviderType provider, + AsyncWrap* parent); + +template void ConnectionWrap::OnConnection( + uv_stream_t* handle, int status); + +template void ConnectionWrap::OnConnection( + uv_stream_t* handle, int status); + + +} // namespace node diff --git a/src/connection_wrap.h b/src/connection_wrap.h new file mode 100644 index 00000000000000..7f7a50ae7ca6cf --- /dev/null +++ b/src/connection_wrap.h @@ -0,0 +1,36 @@ +#ifndef SRC_CONNECTION_WRAP_H_ +#define SRC_CONNECTION_WRAP_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "env.h" +#include "stream_wrap.h" +#include "v8.h" + +namespace node { + +template +class ConnectionWrap : public StreamWrap { + public: + UVType* UVHandle() { + return &handle_; + } + + static void OnConnection(uv_stream_t* handle, int status); + + protected: + ConnectionWrap(Environment* env, + v8::Local object, + ProviderType provider, + AsyncWrap* parent); + ~ConnectionWrap() = default; + + UVType handle_; +}; + + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_CONNECTION_WRAP_H_ diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 286ea30a87cf31..8baf04ba7cef6f 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -1,6 +1,7 @@ #include "pipe_wrap.h" #include "async-wrap.h" +#include "connection_wrap.h" #include "env.h" #include "env-inl.h" #include "handle_wrap.h" @@ -27,7 +28,6 @@ using v8::Integer; using v8::Local; using v8::Object; using v8::String; -using v8::Undefined; using v8::Value; @@ -51,11 +51,6 @@ static void NewPipeConnectWrap(const FunctionCallbackInfo& args) { } -uv_pipe_t* PipeWrap::UVHandle() { - return &handle_; -} - - Local PipeWrap::Instantiate(Environment* env, AsyncWrap* parent) { EscapableHandleScope handle_scope(env->isolate()); CHECK_EQ(false, env->pipe_constructor_template().IsEmpty()); @@ -125,11 +120,10 @@ PipeWrap::PipeWrap(Environment* env, Local object, bool ipc, AsyncWrap* parent) - : StreamWrap(env, - object, - reinterpret_cast(&handle_), - AsyncWrap::PROVIDER_PIPEWRAP, - parent) { + : ConnectionWrap(env, + object, + AsyncWrap::PROVIDER_PIPEWRAP, + parent) { int r = uv_pipe_init(env->event_loop(), &handle_, ipc); CHECK_EQ(r, 0); // How do we proxy this error up to javascript? // Suggestion: uv_pipe_init() returns void. @@ -167,44 +161,6 @@ void PipeWrap::Listen(const FunctionCallbackInfo& args) { } -// TODO(bnoordhuis) maybe share with TCPWrap? -void PipeWrap::OnConnection(uv_stream_t* handle, int status) { - PipeWrap* pipe_wrap = static_cast(handle->data); - CHECK_EQ(&pipe_wrap->handle_, reinterpret_cast(handle)); - - Environment* env = pipe_wrap->env(); - HandleScope handle_scope(env->isolate()); - Context::Scope context_scope(env->context()); - - // We should not be getting this callback if someone as already called - // uv_close() on the handle. - CHECK_EQ(pipe_wrap->persistent().IsEmpty(), false); - - Local argv[] = { - Integer::New(env->isolate(), status), - Undefined(env->isolate()) - }; - - if (status != 0) { - pipe_wrap->MakeCallback(env->onconnection_string(), arraysize(argv), argv); - return; - } - - // Instanciate the client javascript object and handle. - Local client_obj = Instantiate(env, pipe_wrap); - - // Unwrap the client javascript object. - PipeWrap* wrap; - ASSIGN_OR_RETURN_UNWRAP(&wrap, client_obj); - uv_stream_t* client_handle = reinterpret_cast(&wrap->handle_); - if (uv_accept(handle, client_handle)) - return; - - // Successful accept. Call the onconnection callback in JavaScript land. - argv[1] = client_obj; - pipe_wrap->MakeCallback(env->onconnection_string(), arraysize(argv), argv); -} - // TODO(bnoordhuis) Maybe share this with TCPWrap? void PipeWrap::AfterConnect(uv_connect_t* req, int status) { PipeConnectWrap* req_wrap = static_cast(req->data); diff --git a/src/pipe_wrap.h b/src/pipe_wrap.h index f4784ac13a089f..1e11221abc5d8b 100644 --- a/src/pipe_wrap.h +++ b/src/pipe_wrap.h @@ -4,15 +4,13 @@ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #include "async-wrap.h" +#include "connection_wrap.h" #include "env.h" -#include "stream_wrap.h" namespace node { -class PipeWrap : public StreamWrap { +class PipeWrap : public ConnectionWrap { public: - uv_pipe_t* UVHandle(); - static v8::Local Instantiate(Environment* env, AsyncWrap* parent); static void Initialize(v8::Local target, v8::Local unused, @@ -37,10 +35,7 @@ class PipeWrap : public StreamWrap { const v8::FunctionCallbackInfo& args); #endif - static void OnConnection(uv_stream_t* handle, int status); static void AfterConnect(uv_connect_t* req, int status); - - uv_pipe_t handle_; }; diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 6904b27efd5e6e..674c0592541b99 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -1,5 +1,6 @@ #include "tcp_wrap.h" +#include "connection_wrap.h" #include "env.h" #include "env-inl.h" #include "handle_wrap.h" @@ -28,7 +29,6 @@ using v8::Integer; using v8::Local; using v8::Object; using v8::String; -using v8::Undefined; using v8::Value; @@ -121,11 +121,6 @@ void TCPWrap::Initialize(Local target, } -uv_tcp_t* TCPWrap::UVHandle() { - return &handle_; -} - - void TCPWrap::New(const FunctionCallbackInfo& args) { // This constructor should not be exposed to public javascript. // Therefore we assert that we are not trying to call this as a @@ -146,11 +141,10 @@ void TCPWrap::New(const FunctionCallbackInfo& args) { TCPWrap::TCPWrap(Environment* env, Local object, AsyncWrap* parent) - : StreamWrap(env, - object, - reinterpret_cast(&handle_), - AsyncWrap::PROVIDER_TCPWRAP, - parent) { + : ConnectionWrap(env, + object, + AsyncWrap::PROVIDER_TCPWRAP, + parent) { int r = uv_tcp_init(env->event_loop(), &handle_); CHECK_EQ(r, 0); // How do we proxy this error up to javascript? // Suggestion: uv_tcp_init() returns void. @@ -258,43 +252,6 @@ void TCPWrap::Listen(const FunctionCallbackInfo& args) { } -void TCPWrap::OnConnection(uv_stream_t* handle, int status) { - TCPWrap* tcp_wrap = static_cast(handle->data); - CHECK_EQ(&tcp_wrap->handle_, reinterpret_cast(handle)); - Environment* env = tcp_wrap->env(); - - HandleScope handle_scope(env->isolate()); - Context::Scope context_scope(env->context()); - - // We should not be getting this callback if someone as already called - // uv_close() on the handle. - CHECK_EQ(tcp_wrap->persistent().IsEmpty(), false); - - Local argv[2] = { - Integer::New(env->isolate(), status), - Undefined(env->isolate()) - }; - - if (status == 0) { - // Instantiate the client javascript object and handle. - Local client_obj = - Instantiate(env, static_cast(tcp_wrap)); - - // Unwrap the client javascript object. - TCPWrap* wrap = Unwrap(client_obj); - CHECK_NE(wrap, nullptr); - uv_stream_t* client_handle = reinterpret_cast(&wrap->handle_); - if (uv_accept(handle, client_handle)) - return; - - // Successful accept. Call the onconnection callback in JavaScript land. - argv[1] = client_obj; - } - - tcp_wrap->MakeCallback(env->onconnection_string(), arraysize(argv), argv); -} - - void TCPWrap::AfterConnect(uv_connect_t* req, int status) { TCPConnectWrap* req_wrap = static_cast(req->data); TCPWrap* wrap = static_cast(req->handle->data); diff --git a/src/tcp_wrap.h b/src/tcp_wrap.h index af2d08d1ae80f4..26eb410c430a71 100644 --- a/src/tcp_wrap.h +++ b/src/tcp_wrap.h @@ -5,19 +5,17 @@ #include "async-wrap.h" #include "env.h" -#include "stream_wrap.h" +#include "connection_wrap.h" namespace node { -class TCPWrap : public StreamWrap { +class TCPWrap : public ConnectionWrap { public: static v8::Local Instantiate(Environment* env, AsyncWrap* parent); static void Initialize(v8::Local target, v8::Local unused, v8::Local context); - uv_tcp_t* UVHandle(); - size_t self_size() const override { return sizeof(*this); } private: @@ -45,10 +43,7 @@ class TCPWrap : public StreamWrap { const v8::FunctionCallbackInfo& args); #endif - static void OnConnection(uv_stream_t* handle, int status); static void AfterConnect(uv_connect_t* req, int status); - - uv_tcp_t handle_; }; From d7143095cb9b50205c1ee3753703db5739e241f8 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Mon, 25 Jul 2016 11:48:14 -0700 Subject: [PATCH 022/144] src: fix build on CentOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 85af1a6 was added (squashed into another commit) without running through CI. Unfortunately, it breaks some of the CI builds, notably on three of the CentOS setups. Undoing that one small change to get builds green again. Refs: https://github.com/nodejs/node/pull/7547#issuecomment-235045450 PR-URL: https://github.com/nodejs/node/pull/7873 Reviewed-By: Jeremiah Senkpiel Reviewed-By: Johan Bergström Reviewed-By: Ben Noordhuis Reviewed-By: Anna Henningsen --- src/connection_wrap.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/connection_wrap.h b/src/connection_wrap.h index 7f7a50ae7ca6cf..1702e22dd31188 100644 --- a/src/connection_wrap.h +++ b/src/connection_wrap.h @@ -23,7 +23,8 @@ class ConnectionWrap : public StreamWrap { v8::Local object, ProviderType provider, AsyncWrap* parent); - ~ConnectionWrap() = default; + ~ConnectionWrap() { + } UVType handle_; }; From a03e3d3cffa6cc275f98604c530e147320a827df Mon Sep 17 00:00:00 2001 From: Matt Loring Date: Tue, 12 Jul 2016 13:08:34 -0700 Subject: [PATCH 023/144] deps: cherry-pick b93c80a from v8 upstream Original commit message: If we can't rehash the backing store for weak sets & maps, do a last resort GC BUG=v8:4909 R=hpayer@chromium.org Committed: https://crrev.com/b93c80a6039c757723e70420ae73375b5d277814 Cr-Commit-Position: refs/heads/master@{#37591} Fixes: https://github.com/nodejs/node/issues/6180 PR-URL: https://github.com/nodejs/node/pull/7689 Reviewed-By: Matt Loring Reviewed-By: Ben Noordhuis --- deps/v8/src/objects.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index bb15b9aa14f597..5d04eb5f4e7c64 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -18789,6 +18789,19 @@ Handle ObjectHashTable::Put(Handle table, if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) { table->Rehash(isolate->factory()->undefined_value()); } + // If we're out of luck, we didn't get a GC recently, and so rehashing + // isn't enough to avoid a crash. + int nof = table->NumberOfElements() + 1; + if (!table->HasSufficientCapacity(nof)) { + int capacity = ObjectHashTable::ComputeCapacity(nof * 2); + if (capacity > ObjectHashTable::kMaxCapacity) { + for (size_t i = 0; i < 2; ++i) { + isolate->heap()->CollectAllGarbage( + Heap::kFinalizeIncrementalMarkingMask, "full object hash table"); + } + table->Rehash(isolate->factory()->undefined_value()); + } + } // Check whether the hash table should be extended. table = EnsureCapacity(table, 1, key); From e6887e2ceb1894d172cf3af27378b38fa3751d1d Mon Sep 17 00:00:00 2001 From: Matt Loring Date: Wed, 20 Jul 2016 13:37:45 -0700 Subject: [PATCH 024/144] deps: cherry-pick a76d133 from v8 upstream Original commit message: Fix incorrect parameter to HasSufficientCapacity It takes the number of additional elements, not the total target capacity. Also, avoid right-shifting a negative integer as this is undefined in general BUG=v8:4909 R=verwaest@chromium.org Review-Url: https://codereview.chromium.org/2162333002 Cr-Commit-Position: refs/heads/master@{#37901} Fixes: https://github.com/nodejs/node/issues/6180 PR-URL: https://github.com/nodejs/node/pull/7689 Reviewed-By: Matt Loring Reviewed-By: Ben Noordhuis --- deps/v8/src/objects.cc | 18 +++++++++--------- deps/v8/src/objects.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index 5d04eb5f4e7c64..a3da050fa49898 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -17437,7 +17437,7 @@ Handle HashTable::EnsureCapacity( int capacity = table->Capacity(); int nof = table->NumberOfElements() + n; - if (table->HasSufficientCapacity(n)) return table; + if (table->HasSufficientCapacityToAdd(n)) return table; const int kMinCapacityForPretenure = 256; bool should_pretenure = pretenure == TENURED || @@ -17453,16 +17453,16 @@ Handle HashTable::EnsureCapacity( return new_table; } - template -bool HashTable::HasSufficientCapacity(int n) { +bool HashTable::HasSufficientCapacityToAdd( + int number_of_additional_elements) { int capacity = Capacity(); - int nof = NumberOfElements() + n; + int nof = NumberOfElements() + number_of_additional_elements; int nod = NumberOfDeletedElements(); // Return true if: - // 50% is still free after adding n elements and + // 50% is still free after adding number_of_additional_elements elements and // at most 50% of the free elements are deleted elements. - if (nod <= (capacity - nof) >> 1) { + if ((nof < capacity) && ((nod <= (capacity - nof) >> 1))) { int needed_free = nof >> 1; if (nof + needed_free <= capacity) return true; } @@ -18378,7 +18378,7 @@ void Dictionary::SetRequiresCopyOnCapacityChange() { DCHECK_EQ(0, DerivedHashTable::NumberOfDeletedElements()); // Make sure that HashTable::EnsureCapacity will create a copy. DerivedHashTable::SetNumberOfDeletedElements(DerivedHashTable::Capacity()); - DCHECK(!DerivedHashTable::HasSufficientCapacity(1)); + DCHECK(!DerivedHashTable::HasSufficientCapacityToAdd(1)); } @@ -18791,8 +18791,8 @@ Handle ObjectHashTable::Put(Handle table, } // If we're out of luck, we didn't get a GC recently, and so rehashing // isn't enough to avoid a crash. - int nof = table->NumberOfElements() + 1; - if (!table->HasSufficientCapacity(nof)) { + if (!table->HasSufficientCapacityToAdd(1)) { + int nof = table->NumberOfElements() + 1; int capacity = ObjectHashTable::ComputeCapacity(nof * 2); if (capacity > ObjectHashTable::kMaxCapacity) { for (size_t i = 0; i < 2; ++i) { diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index 4a8a55764f9a89..e5d52e0c757ca4 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -3307,7 +3307,7 @@ class HashTable : public HashTableBase { PretenureFlag pretenure = NOT_TENURED); // Returns true if this table has sufficient capacity for adding n elements. - bool HasSufficientCapacity(int n); + bool HasSufficientCapacityToAdd(int number_of_additional_elements); // Sets the capacity of the hash table. void SetCapacity(int capacity) { From 8f51e368981c7e584e1f7f278a940d6f31c076fb Mon Sep 17 00:00:00 2001 From: Santiago Gimeno Date: Sun, 29 May 2016 17:53:40 +0200 Subject: [PATCH 025/144] test: use common platform helpers everywhere Use the common.isWindows, common.isFreeBSD and common.isSunOS where possible. Add common.isOSX and common.isLinux. Fix `test-fs-read-file-sync-hostname` as in its current form was not being run anywhere. PR-URL: https://github.com/nodejs/node/pull/7845 Reviewed-By: Colin Ihrig Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- test/common.js | 10 ++++++---- test/internet/test-dns-ipv6.js | 2 +- test/parallel/test-cwd-enoent-preload.js | 2 +- test/parallel/test-cwd-enoent-repl.js | 2 +- test/parallel/test-cwd-enoent.js | 2 +- test/parallel/test-dgram-empty-packet.js | 2 +- test/parallel/test-dgram-send-empty-array.js | 2 +- test/parallel/test-dgram-send-empty-buffer.js | 2 +- test/parallel/test-domain-abort-on-uncaught.js | 2 +- ...omain-no-error-handler-abort-on-uncaught.js | 2 +- ...en-throw-from-uncaught-exception-handler.js | 2 +- ...-domain-with-abort-on-uncaught-exception.js | 2 +- .../test-fs-read-file-sync-hostname.js | 18 +++++++++++------- test/parallel/test-fs-readdir-ucs2.js | 2 +- test/parallel/test-fs-watch-recursive.js | 2 +- test/parallel/test-os.js | 2 +- .../parallel/test-process-constants-noatime.js | 4 ++-- test/parallel/test-process-getgroups.js | 2 +- test/parallel/test-repl-sigint-nested-eval.js | 2 +- test/parallel/test-repl-sigint.js | 2 +- test/parallel/test-setproctitle.js | 5 +++-- test/parallel/test-util-sigint-watchdog.js | 2 +- .../test-vm-sigint-existing-handler.js | 2 +- test/parallel/test-vm-sigint.js | 2 +- test/pummel/test-net-pingpong.js | 5 ++--- test/sequential/test-fs-watch.js | 4 ++-- 26 files changed, 46 insertions(+), 40 deletions(-) diff --git a/test/common.js b/test/common.js index aacea9ae768fc7..4aa48de48f4b6f 100644 --- a/test/common.js +++ b/test/common.js @@ -26,6 +26,8 @@ exports.isLinuxPPCBE = (process.platform === 'linux') && (os.endianness() === 'BE'); exports.isSunOS = process.platform === 'sunos'; exports.isFreeBSD = process.platform === 'freebsd'; +exports.isLinux = process.platform === 'linux'; +exports.isOSX = process.platform === 'darwin'; exports.enoughTestMem = os.totalmem() > 0x40000000; /* 1 Gb */ exports.rootDir = exports.isWindows ? 'c:\\' : '/'; @@ -61,7 +63,7 @@ function rmdirSync(p, originalEr) { if (e.code === 'ENOTDIR') throw originalEr; if (e.code === 'ENOTEMPTY' || e.code === 'EEXIST' || e.code === 'EPERM') { - const enc = process.platform === 'linux' ? 'buffer' : 'utf8'; + const enc = exports.isLinux ? 'buffer' : 'utf8'; fs.readdirSync(p, enc).forEach((f) => { if (f instanceof Buffer) { const buf = Buffer.concat([Buffer.from(p), Buffer.from(path.sep), f]); @@ -91,7 +93,7 @@ var inFreeBSDJail = null; var localhostIPv4 = null; exports.localIPv6Hosts = ['localhost']; -if (process.platform === 'linux') { +if (exports.isLinux) { exports.localIPv6Hosts = [ // Debian/Ubuntu 'ip6-localhost', @@ -110,7 +112,7 @@ Object.defineProperty(exports, 'inFreeBSDJail', { get: function() { if (inFreeBSDJail !== null) return inFreeBSDJail; - if (process.platform === 'freebsd' && + if (exports.isFreeBSD && child_process.execSync('sysctl -n security.jail.jailed').toString() === '1\n') { inFreeBSDJail = true; @@ -469,7 +471,7 @@ exports.nodeProcessAborted = function nodeProcessAborted(exitCode, signal) { // On Windows, v8's base::OS::Abort triggers an access violation, // which corresponds to exit code 3221225477 (0xC0000005) - if (process.platform === 'win32') + if (exports.isWindows) expectedExitCodes = [3221225477]; // When using --abort-on-uncaught-exception, V8 will use diff --git a/test/internet/test-dns-ipv6.js b/test/internet/test-dns-ipv6.js index a9e46c8478d52b..f14b45df07ebf2 100644 --- a/test/internet/test-dns-ipv6.js +++ b/test/internet/test-dns-ipv6.js @@ -123,7 +123,7 @@ TEST(function test_lookup_ipv6_hint(done) { }, function(err, ip, family) { if (err) { // FreeBSD does not support V4MAPPED - if (process.platform === 'freebsd') { + if (common.isFreeBSD) { assert(err instanceof Error); assert.strictEqual(err.code, 'EAI_BADFLAGS'); assert.strictEqual(err.hostname, 'www.google.com'); diff --git a/test/parallel/test-cwd-enoent-preload.js b/test/parallel/test-cwd-enoent-preload.js index b2f7ae0a4aed08..8418e1177e6c89 100644 --- a/test/parallel/test-cwd-enoent-preload.js +++ b/test/parallel/test-cwd-enoent-preload.js @@ -5,7 +5,7 @@ const fs = require('fs'); const spawn = require('child_process').spawn; // Fails with EINVAL on SmartOS, EBUSY on Windows, EBUSY on AIX. -if (process.platform === 'sunos' || common.isWindows || common.isAix) { +if (common.isSunOS || common.isWindows || common.isAix) { common.skip('cannot rmdir current working directory'); return; } diff --git a/test/parallel/test-cwd-enoent-repl.js b/test/parallel/test-cwd-enoent-repl.js index 3c8b543cf139d6..2782ec4394ea06 100644 --- a/test/parallel/test-cwd-enoent-repl.js +++ b/test/parallel/test-cwd-enoent-repl.js @@ -5,7 +5,7 @@ var fs = require('fs'); var spawn = require('child_process').spawn; // Fails with EINVAL on SmartOS, EBUSY on Windows, EBUSY on AIX. -if (process.platform === 'sunos' || common.isWindows || common.isAix) { +if (common.isSunOS || common.isWindows || common.isAix) { common.skip('cannot rmdir current working directory'); return; } diff --git a/test/parallel/test-cwd-enoent.js b/test/parallel/test-cwd-enoent.js index 9ff9f86405a333..f5c04fe068e945 100644 --- a/test/parallel/test-cwd-enoent.js +++ b/test/parallel/test-cwd-enoent.js @@ -5,7 +5,7 @@ var fs = require('fs'); var spawn = require('child_process').spawn; // Fails with EINVAL on SmartOS, EBUSY on Windows, EBUSY on AIX. -if (process.platform === 'sunos' || common.isWindows || common.isAix) { +if (common.isSunOS || common.isWindows || common.isAix) { common.skip('cannot rmdir current working directory'); return; } diff --git a/test/parallel/test-dgram-empty-packet.js b/test/parallel/test-dgram-empty-packet.js index cdda183e2afcaa..1c7e7205d1edf2 100644 --- a/test/parallel/test-dgram-empty-packet.js +++ b/test/parallel/test-dgram-empty-packet.js @@ -6,7 +6,7 @@ var callbacks = 0; var client; var timer; -if (process.platform === 'darwin') { +if (common.isOSX) { common.skip('because of 17894467 Apple bug'); return; } diff --git a/test/parallel/test-dgram-send-empty-array.js b/test/parallel/test-dgram-send-empty-array.js index 959fbed158a70d..c5050a7d548265 100644 --- a/test/parallel/test-dgram-send-empty-array.js +++ b/test/parallel/test-dgram-send-empty-array.js @@ -4,7 +4,7 @@ const common = require('../common'); const assert = require('assert'); const dgram = require('dgram'); -if (process.platform === 'darwin') { +if (common.isOSX) { common.skip('because of 17894467 Apple bug'); return; } diff --git a/test/parallel/test-dgram-send-empty-buffer.js b/test/parallel/test-dgram-send-empty-buffer.js index d6d31f41665f0b..ac541a9c243947 100644 --- a/test/parallel/test-dgram-send-empty-buffer.js +++ b/test/parallel/test-dgram-send-empty-buffer.js @@ -2,7 +2,7 @@ const common = require('../common'); const dgram = require('dgram'); -if (process.platform === 'darwin') { +if (common.isOSX) { common.skip('because of 17894467 Apple bug'); return; } diff --git a/test/parallel/test-domain-abort-on-uncaught.js b/test/parallel/test-domain-abort-on-uncaught.js index 4f290d22e75355..2a5eb804bc34ec 100644 --- a/test/parallel/test-domain-abort-on-uncaught.js +++ b/test/parallel/test-domain-abort-on-uncaught.js @@ -233,7 +233,7 @@ if (process.argv[2] === 'child') { tests.forEach(function(test, testIndex) { var testCmd = ''; - if (process.platform !== 'win32') { + if (!common.isWindows) { // Do not create core files, as it can take a lot of disk space on // continuous testing and developers' machines testCmd += 'ulimit -c 0 && '; diff --git a/test/parallel/test-domain-no-error-handler-abort-on-uncaught.js b/test/parallel/test-domain-no-error-handler-abort-on-uncaught.js index 329772e7444238..76ca3faad702b6 100644 --- a/test/parallel/test-domain-no-error-handler-abort-on-uncaught.js +++ b/test/parallel/test-domain-no-error-handler-abort-on-uncaught.js @@ -144,7 +144,7 @@ if (process.argv[2] === 'child') { tests.forEach(function(test, testIndex) { var testCmd = ''; - if (process.platform !== 'win32') { + if (!common.isWindows) { // Do not create core files, as it can take a lot of disk space on // continuous testing and developers' machines testCmd += 'ulimit -c 0 && '; diff --git a/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js b/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js index ae86ef2cdf20d3..b490a30b52d39f 100644 --- a/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js +++ b/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js @@ -82,7 +82,7 @@ function runTestWithAbortOnUncaughtException() { function createTestCmdLine(options) { var testCmd = ''; - if (process.platform !== 'win32') { + if (!common.isWindows) { // Do not create core files, as it can take a lot of disk space on // continuous testing and developers' machines testCmd += 'ulimit -c 0 && '; diff --git a/test/parallel/test-domain-with-abort-on-uncaught-exception.js b/test/parallel/test-domain-with-abort-on-uncaught-exception.js index 423c77136fa5f6..455acc7804b230 100644 --- a/test/parallel/test-domain-with-abort-on-uncaught-exception.js +++ b/test/parallel/test-domain-with-abort-on-uncaught-exception.js @@ -93,7 +93,7 @@ if (process.argv[2] === 'child') { throwInDomainErrHandlerOpt = 'throwInDomainErrHandler'; var cmdToExec = ''; - if (process.platform !== 'win32') { + if (!common.isWindows) { // Do not create core files, as it can take a lot of disk space on // continuous testing and developers' machines cmdToExec += 'ulimit -c 0 && '; diff --git a/test/parallel/test-fs-read-file-sync-hostname.js b/test/parallel/test-fs-read-file-sync-hostname.js index de105737969865..ca300819e704c6 100644 --- a/test/parallel/test-fs-read-file-sync-hostname.js +++ b/test/parallel/test-fs-read-file-sync-hostname.js @@ -1,10 +1,14 @@ 'use strict'; -require('../common'); -var assert = require('assert'); -var fs = require('fs'); +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); -// test reading from hostname -if (process.platform === 'linux2') { - var hostname = fs.readFileSync('/proc/sys/kernel/hostname'); - assert.ok(hostname.length > 0); +if (!common.isLinux) { + common.skip('Test is linux specific.'); + return; } + +// Test to make sure reading a file under the /proc directory works. See: +// https://groups.google.com/forum/#!topic/nodejs-dev/rxZ_RoH1Gn0 +const hostname = fs.readFileSync('/proc/sys/kernel/hostname'); +assert.ok(hostname.length > 0); diff --git a/test/parallel/test-fs-readdir-ucs2.js b/test/parallel/test-fs-readdir-ucs2.js index 46c99954351429..916758fe943f86 100644 --- a/test/parallel/test-fs-readdir-ucs2.js +++ b/test/parallel/test-fs-readdir-ucs2.js @@ -5,7 +5,7 @@ const path = require('path'); const fs = require('fs'); const assert = require('assert'); -if (process.platform !== 'linux') { +if (!common.isLinux) { common.skip('Test is linux specific.'); return; } diff --git a/test/parallel/test-fs-watch-recursive.js b/test/parallel/test-fs-watch-recursive.js index 7853baaa02b797..23a92129a75f01 100644 --- a/test/parallel/test-fs-watch-recursive.js +++ b/test/parallel/test-fs-watch-recursive.js @@ -2,7 +2,7 @@ const common = require('../common'); -if (!(process.platform === 'darwin' || common.isWindows)) { +if (!(common.isOSX || common.isWindows)) { common.skip('recursive option is darwin/windows specific'); return; } diff --git a/test/parallel/test-os.js b/test/parallel/test-os.js index 2b01b78d2bff38..8f4db817071b53 100644 --- a/test/parallel/test-os.js +++ b/test/parallel/test-os.js @@ -71,7 +71,7 @@ var arch = os.arch(); console.log('arch = ', arch); assert.ok(arch.length > 0); -if (process.platform != 'sunos') { +if (!common.isSunOS) { // not implemeneted yet assert.ok(os.loadavg().length > 0); assert.ok(os.freemem() > 0); diff --git a/test/parallel/test-process-constants-noatime.js b/test/parallel/test-process-constants-noatime.js index bf4ed4d395bbcf..d0c027f0b9353d 100644 --- a/test/parallel/test-process-constants-noatime.js +++ b/test/parallel/test-process-constants-noatime.js @@ -1,10 +1,10 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const constants = process.binding('constants'); -if (process.platform === 'linux') { +if (common.isLinux) { assert('O_NOATIME' in constants.fs); assert.strictEqual(constants.fs.O_NOATIME, 0x40000); } else { diff --git a/test/parallel/test-process-getgroups.js b/test/parallel/test-process-getgroups.js index 6d07692a764e52..7910eb3e292fc3 100644 --- a/test/parallel/test-process-getgroups.js +++ b/test/parallel/test-process-getgroups.js @@ -3,7 +3,7 @@ const common = require('../common'); var assert = require('assert'); var exec = require('child_process').exec; -if (process.platform === 'darwin') { +if (common.isOSX) { common.skip('Output of `id -G` is unreliable on Darwin.'); return; } diff --git a/test/parallel/test-repl-sigint-nested-eval.js b/test/parallel/test-repl-sigint-nested-eval.js index 288c4bceebcd61..1bb09ba3963f3e 100644 --- a/test/parallel/test-repl-sigint-nested-eval.js +++ b/test/parallel/test-repl-sigint-nested-eval.js @@ -4,7 +4,7 @@ const assert = require('assert'); const spawn = require('child_process').spawn; -if (process.platform === 'win32') { +if (common.isWindows) { // No way to send CTRL_C_EVENT to processes from JS right now. common.skip('platform not supported'); return; diff --git a/test/parallel/test-repl-sigint.js b/test/parallel/test-repl-sigint.js index 6b342ce8612d28..5ee974aaea340e 100644 --- a/test/parallel/test-repl-sigint.js +++ b/test/parallel/test-repl-sigint.js @@ -4,7 +4,7 @@ const assert = require('assert'); const spawn = require('child_process').spawn; -if (process.platform === 'win32') { +if (common.isWindows) { // No way to send CTRL_C_EVENT to processes from JS right now. common.skip('platform not supported'); return; diff --git a/test/parallel/test-setproctitle.js b/test/parallel/test-setproctitle.js index 943cd60769c29a..4d096b1941865f 100644 --- a/test/parallel/test-setproctitle.js +++ b/test/parallel/test-setproctitle.js @@ -1,9 +1,10 @@ 'use strict'; // Original test written by Jakub Lekstan +const common = require('../common'); require('../common'); // FIXME add sunos support -if ('linux freebsd darwin'.indexOf(process.platform) === -1) { +if (!(common.isFreeBSD || common.isOSX || common.isLinux)) { console.log(`1..0 # Skipped: Unsupported platform [${process.platform}]`); return; } @@ -26,7 +27,7 @@ exec('ps -p ' + process.pid + ' -o args=', function(error, stdout, stderr) { assert.equal(stderr, ''); // freebsd always add ' (procname)' to the process title - if (process.platform === 'freebsd') + if (common.isFreeBSD) title += ` (${path.basename(process.execPath)})`; // omitting trailing whitespace and \n diff --git a/test/parallel/test-util-sigint-watchdog.js b/test/parallel/test-util-sigint-watchdog.js index 2f95286a5e72e0..f9bb3ecd93d39b 100644 --- a/test/parallel/test-util-sigint-watchdog.js +++ b/test/parallel/test-util-sigint-watchdog.js @@ -3,7 +3,7 @@ const common = require('../common'); const assert = require('assert'); const binding = process.binding('util'); -if (process.platform === 'win32') { +if (common.isWindows) { // No way to send CTRL_C_EVENT to processes from JS right now. common.skip('platform not supported'); return; diff --git a/test/parallel/test-vm-sigint-existing-handler.js b/test/parallel/test-vm-sigint-existing-handler.js index e86bbeec0b5e9b..0f86b53dd282be 100644 --- a/test/parallel/test-vm-sigint-existing-handler.js +++ b/test/parallel/test-vm-sigint-existing-handler.js @@ -5,7 +5,7 @@ const vm = require('vm'); const spawn = require('child_process').spawn; -if (process.platform === 'win32') { +if (common.isWindows) { // No way to send CTRL_C_EVENT to processes from JS right now. common.skip('platform not supported'); return; diff --git a/test/parallel/test-vm-sigint.js b/test/parallel/test-vm-sigint.js index 11497733ce7eb1..2488b0d1c028f6 100644 --- a/test/parallel/test-vm-sigint.js +++ b/test/parallel/test-vm-sigint.js @@ -5,7 +5,7 @@ const vm = require('vm'); const spawn = require('child_process').spawn; -if (process.platform === 'win32') { +if (common.isWindows) { // No way to send CTRL_C_EVENT to processes from JS right now. common.skip('platform not supported'); return; diff --git a/test/pummel/test-net-pingpong.js b/test/pummel/test-net-pingpong.js index a7ede0b0565ac9..85dce02b6cf635 100644 --- a/test/pummel/test-net-pingpong.js +++ b/test/pummel/test-net-pingpong.js @@ -94,9 +94,8 @@ pingPongTest(common.PORT, 'localhost'); pingPongTest(common.PORT + 1, null); // This IPv6 isn't working on Solaris -var solaris = /sunos/i.test(process.platform); -if (!solaris) pingPongTest(common.PORT + 2, '::1'); +if (!common.isSunOS) pingPongTest(common.PORT + 2, '::1'); process.on('exit', function() { - assert.equal(solaris ? 2 : 3, tests_run); + assert.equal(common.isSunOS ? 2 : 3, tests_run); }); diff --git a/test/sequential/test-fs-watch.js b/test/sequential/test-fs-watch.js index 249164c7e4e991..f254ebc17cf5ae 100644 --- a/test/sequential/test-fs-watch.js +++ b/test/sequential/test-fs-watch.js @@ -5,8 +5,8 @@ var path = require('path'); var fs = require('fs'); var expectFilePath = common.isWindows || - process.platform === 'linux' || - process.platform === 'darwin'; + common.isLinux || + common.isOSX; var watchSeenOne = 0; var watchSeenTwo = 0; From 63c62cce35abafd764da2dad75478b3e21f68ce5 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Sun, 17 Jul 2016 18:55:45 -0400 Subject: [PATCH 026/144] src: Only use TR1 type_traits on OSX<10.9 Mac OSX 10.9 has switched to using libc++ by default. libc++ provides a C++11 implementation, so we only need to use the TR1 version when targetting OSX 10.8 or 10.7. PR-URL: https://github.com/nodejs/node/pull/7778 Reviewed-By: Ben Noordhuis Reviewed-By: Colin Ihrig Reviewed-By: Anna Henningsen --- src/util.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/util.h b/src/util.h index e57651c3a6981d..08fb01e5ac89cf 100644 --- a/src/util.h +++ b/src/util.h @@ -11,7 +11,12 @@ #include #include -#ifdef __APPLE__ +// OSX 10.9 defaults to libc++ which provides a C++11 header. +#if defined(__APPLE__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1090 +#define USE_TR1_TYPE_TRAITS +#endif + +#ifdef USE_TR1_TYPE_TRAITS #include // NOLINT(build/c++tr1) #else #include // std::remove_reference @@ -31,7 +36,7 @@ NO_RETURN void Abort(); NO_RETURN void Assert(const char* const (*args)[4]); void DumpBacktrace(FILE* fp); -#ifdef __APPLE__ +#ifdef USE_TR1_TYPE_TRAITS template using remove_reference = std::tr1::remove_reference; #else template using remove_reference = std::remove_reference; From 5c4b938665936ecbe91d39014af408a0af0a6fc4 Mon Sep 17 00:00:00 2001 From: Alex Perkins Date: Sat, 16 Jul 2016 09:36:00 -0700 Subject: [PATCH 027/144] doc: minor typo fixes in stream docs PR-URL: https://github.com/nodejs/node/pull/7763 Reviewed-By: Colin Ihrig Reviewed-By: Minwoo Jung Reviewed-By: Sakthipriyan Vairamani --- doc/api/stream.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/stream.md b/doc/api/stream.md index bee0d1d07110af..36a624dede6b54 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -20,7 +20,7 @@ const stream = require('stream'); ``` While it is important for all Node.js users to understand how streams works, -the `stream` module itself is most useful for developer's that are creating new +the `stream` module itself is most useful for developers that are creating new types of stream instances. Developer's who are primarily *consuming* stream objects will rarely (if ever) have need to use the `stream` module directly. @@ -343,7 +343,7 @@ The buffered data will be flushed when either the [`stream.uncork()`][] or [`stream.end()`][stream-end] methods are called. The primary intent of `writable.cork()` is to avoid a situation where writing -many small chunks of data to a stream do not cause an backup in the internal +many small chunks of data to a stream do not cause a backup in the internal buffer that would have an adverse impact on performance. In such situations, implementations that implement the `writable._writev()` method can perform buffered writes in a more optimized manner. @@ -1554,7 +1554,7 @@ class Counter extends Readable { A [Duplex][] stream is one that implements both [Readable][] and [Writable][], such as a TCP socket connection. -Because Javascript does not have support for multiple inheritance, the +Because JavaScript does not have support for multiple inheritance, the `stream.Duplex` class is extended to implement a [Duplex][] stream (as opposed to extending the `stream.Readable` *and* `stream.Writable` classes). From 577adc74cd0e2327bb722f5aa84af3b68a1d1abc Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Fri, 15 Jul 2016 02:24:38 +0300 Subject: [PATCH 028/144] test: ensure stream preprocessing order Sometimes it is necessary to preprocess some initial bit of a stream data before giving the entire stream to the main processing function. Sometimes this bit should be extracted from the stream before the main processing; sometimes it should be returned to the stream. This test checks an order of stream modes, methods and events for a possible preprocessing algorithm. Stream BOM stripping is selected as a use case. See https://github.com/nodejs/help/issues/221 as the prehistory. PR-URL: https://github.com/nodejs/node/pull/7741 Reviewed-By: Anna Henningsen --- test/fixtures/file-to-read-with-bom.txt | 3 + test/fixtures/file-to-read-without-bom.txt | 3 + test/parallel/test-stream-preprocess.js | 67 ++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 test/fixtures/file-to-read-with-bom.txt create mode 100644 test/fixtures/file-to-read-without-bom.txt create mode 100644 test/parallel/test-stream-preprocess.js diff --git a/test/fixtures/file-to-read-with-bom.txt b/test/fixtures/file-to-read-with-bom.txt new file mode 100644 index 00000000000000..d46c8708d97946 --- /dev/null +++ b/test/fixtures/file-to-read-with-bom.txt @@ -0,0 +1,3 @@ +abc +def +ghi diff --git a/test/fixtures/file-to-read-without-bom.txt b/test/fixtures/file-to-read-without-bom.txt new file mode 100644 index 00000000000000..8edb37e36dfbc0 --- /dev/null +++ b/test/fixtures/file-to-read-without-bom.txt @@ -0,0 +1,3 @@ +abc +def +ghi diff --git a/test/parallel/test-stream-preprocess.js b/test/parallel/test-stream-preprocess.js new file mode 100644 index 00000000000000..9cb4c1d3cca8ae --- /dev/null +++ b/test/parallel/test-stream-preprocess.js @@ -0,0 +1,67 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const fs = require('fs'); +const path = require('path'); +const rl = require('readline'); + +const BOM = '\uFEFF'; + +// Get the data using a non-stream way to compare with the streamed data. +const modelData = fs.readFileSync( + path.join(common.fixturesDir, 'file-to-read-without-bom.txt'), 'utf8' +); +const modelDataFirstCharacter = modelData[0]; + +// Detect the number of forthcoming 'line' events for mustCall() 'expected' arg. +const lineCount = modelData.match(/\n/g).length; + +// Ensure both without-bom and with-bom test files are textwise equal. +assert.strictEqual( + fs.readFileSync( + path.join(common.fixturesDir, 'file-to-read-with-bom.txt'), 'utf8' + ), + `${BOM}${modelData}` +); + +// An unjustified BOM stripping with a non-BOM character unshifted to a stream. +const inputWithoutBOM = fs.createReadStream( + path.join(common.fixturesDir, 'file-to-read-without-bom.txt'), 'utf8' +); + +inputWithoutBOM.once('readable', common.mustCall(() => { + const maybeBOM = inputWithoutBOM.read(1); + assert.strictEqual(maybeBOM, modelDataFirstCharacter); + assert.notStrictEqual(maybeBOM, BOM); + + inputWithoutBOM.unshift(maybeBOM); + + let streamedData = ''; + rl.createInterface({ + input: inputWithoutBOM, + }).on('line', common.mustCall((line) => { + streamedData += `${line}\n`; + }, lineCount)).on('close', common.mustCall(() => { + assert.strictEqual(streamedData, modelData); + })); +})); + +// A justified BOM stripping. +const inputWithBOM = fs.createReadStream( + path.join(common.fixturesDir, 'file-to-read-with-bom.txt'), 'utf8' +); + +inputWithBOM.once('readable', common.mustCall(() => { + const maybeBOM = inputWithBOM.read(1); + assert.strictEqual(maybeBOM, BOM); + + let streamedData = ''; + rl.createInterface({ + input: inputWithBOM, + }).on('line', common.mustCall((line) => { + streamedData += `${line}\n`; + }, lineCount)).on('close', common.mustCall(() => { + assert.strictEqual(streamedData, modelData); + })); +})); From fc3ba2ff4f654c355c49cbe2be0518a6fe8fc27d Mon Sep 17 00:00:00 2001 From: Prince J Wesley Date: Thu, 7 Jul 2016 23:19:22 +0530 Subject: [PATCH 029/144] repl: Use displayErrors for SyntaxError MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ```js node 🙈 ₹ git:(upstream ⚡ display-error-repl) ./node > var 4; var 4; ^ SyntaxError: Unexpected number > ``` PR-URL: https://github.com/nodejs/node/pull/7589 Reviewed-By: James M Snell Reviewed-By: Rod Vagg Conflicts: test/parallel/test-repl.js --- lib/repl.js | 11 ++++++++--- test/parallel/test-repl.js | 34 ++++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 6cfffe03d09e2e..d6eedffa3c4dc8 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -254,7 +254,7 @@ function REPLServer(prompt, } var script = vm.createScript(code, { filename: file, - displayErrors: false + displayErrors: true }); } catch (e) { debug('parse error %j', code, e); @@ -298,7 +298,7 @@ function REPLServer(prompt, try { try { const scriptOptions = { - displayErrors: false, + displayErrors: true, breakOnSigint: self.breakEvalOnSigint }; @@ -350,7 +350,12 @@ function REPLServer(prompt, debug('domain error'); const top = replMap.get(self); internalUtil.decorateErrorStack(e); - if (e.stack && self.replMode === exports.REPL_MODE_STRICT) { + if (e instanceof SyntaxError && e.stack) { + // remove repl:line-number and stack trace + e.stack = e.stack + .replace(/^repl:\d+\r?\n/, '') + .replace(/^\s+at\s.*\n?/gm, ''); + } else if (e.stack && self.replMode === exports.REPL_MODE_STRICT) { e.stack = e.stack.replace(/(\s+at\s+repl:)(\d+)/, (_, pre, line) => pre + (line - 1)); } diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js index ed3c2feb0db8e1..cb55b2876b451e 100644 --- a/test/parallel/test-repl.js +++ b/test/parallel/test-repl.js @@ -120,7 +120,7 @@ function error_test() { expect: prompt_unix }, // But passing the same string to eval() should throw { client: client_unix, send: 'eval("function test_func() {")', - expect: /^SyntaxError: Unexpected end of input/ }, + expect: /\bSyntaxError: Unexpected end of input/ }, // Can handle multiline template literals { client: client_unix, send: '`io.js', expect: prompt_multiline }, @@ -149,35 +149,35 @@ function error_test() { // invalid input to JSON.parse error is special case of syntax error, // should throw { client: client_unix, send: 'JSON.parse(\'{invalid: \\\'json\\\'}\');', - expect: /^SyntaxError: Unexpected token i/ }, + expect: /\bSyntaxError: Unexpected token i/ }, // end of input to JSON.parse error is special case of syntax error, // should throw { client: client_unix, send: 'JSON.parse(\'066\');', - expect: /^SyntaxError: Unexpected number/ }, + expect: /\bSyntaxError: Unexpected number/ }, // should throw { client: client_unix, send: 'JSON.parse(\'{\');', - expect: /^SyntaxError: Unexpected end of JSON input/ }, + expect: /\bSyntaxError: Unexpected end of JSON input/ }, // invalid RegExps are a special case of syntax error, // should throw { client: client_unix, send: '/(/;', - expect: /^SyntaxError: Invalid regular expression\:/ }, + expect: /\bSyntaxError: Invalid regular expression\:/ }, // invalid RegExp modifiers are a special case of syntax error, // should throw (GH-4012) { client: client_unix, send: 'new RegExp("foo", "wrong modifier");', - expect: /^SyntaxError: Invalid flags supplied to RegExp constructor/ }, + expect: /\bSyntaxError: Invalid flags supplied to RegExp constructor/ }, // strict mode syntax errors should be caught (GH-5178) { client: client_unix, send: '(function() { "use strict"; return 0755; })()', - expect: /^SyntaxError: Octal literals are not allowed in strict mode/ }, + expect: /\bSyntaxError: Octal literals are not allowed in strict mode/ }, { client: client_unix, send: '(function(a, a, b) { "use strict"; return a + b + c; })()', - expect: /^SyntaxError: Duplicate parameter name not allowed in this context/ }, + expect: /\bSyntaxError: Duplicate parameter name not allowed in this context/ }, { client: client_unix, send: '(function() { "use strict"; with (this) {} })()', - expect: /^SyntaxError: Strict mode code may not include a with statement/ }, + expect: /\bSyntaxError: Strict mode code may not include a with statement/ }, { client: client_unix, send: '(function() { "use strict"; var x; delete x; })()', - expect: /^SyntaxError: Delete of an unqualified identifier in strict mode/ }, + expect: /\bSyntaxError: Delete of an unqualified identifier in strict mode/ }, { client: client_unix, send: '(function() { "use strict"; eval = 17; })()', - expect: /^SyntaxError: Unexpected eval or arguments in strict mode/ }, + expect: /\bSyntaxError: Unexpected eval or arguments in strict mode/ }, { client: client_unix, send: '(function() { "use strict"; if (true) function f() { } })()', - expect: /^SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function/ }, + expect: /\bSyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function/ }, // Named functions can be used: { client: client_unix, send: 'function blah() { return 1; }', expect: prompt_unix }, @@ -228,7 +228,7 @@ function error_test() { expect: 'Invalid REPL keyword\n' + prompt_unix }, // fail when we are not inside a String and a line continuation is used { client: client_unix, send: '[] \\', - expect: /^SyntaxError: Unexpected token ILLEGAL/ }, + expect: /\bSyntaxError: Unexpected token ILLEGAL/ }, // do not fail when a String is created with line continuation { client: client_unix, send: '\'the\\\nfourth\\\neye\'', expect: prompt_multiline + prompt_multiline + @@ -327,12 +327,18 @@ function error_test() { // Illegal token is not recoverable outside string literal, RegExp literal, // or block comment. https://github.com/nodejs/node/issues/3611 { client: client_unix, send: 'a = 3.5e', - expect: /^SyntaxError: Unexpected token ILLEGAL/ }, + expect: /\bSyntaxError: Unexpected token ILLEGAL/ }, // Mitigate https://github.com/nodejs/node/issues/548 { client: client_unix, send: 'function name(){ return "node"; };name()', expect: "'node'\n" + prompt_unix }, { client: client_unix, send: 'function name(){ return "nodejs"; };name()', expect: "'nodejs'\n" + prompt_unix }, + // Avoid emitting repl:line-number for SyntaxError + { client: client_unix, send: 'a = 3.5e', + expect: /^(?!repl)/ }, + // Avoid emitting stack trace + { client: client_unix, send: 'a = 3.5e', + expect: /^(?!\s+at\s)/gm }, ]); } From 14a0c3181c633bdab7914984b5a6682021666576 Mon Sep 17 00:00:00 2001 From: Bethany N Griggs Date: Mon, 18 Jul 2016 16:58:05 +0100 Subject: [PATCH 030/144] doc: remove platform assumption from CONTRIBUTING MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Specify that the ‘make test’ commands are Unix/OS X specific. - Link to BUILDING.md for other platform commands. Fixes: https://github.com/nodejs/node/issues/7646 PR-URL: https://github.com/nodejs/node/pull/7783 Reviewed-By: Rich Trott Reviewed-By: Anna Henningsen --- CONTRIBUTING.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 50db95b3de9537..500e0a79d579a0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -135,7 +135,6 @@ $ git fetch upstream $ git rebase upstream/master ``` - ### Step 5: Test Bug fixes and features **should come with tests**. Add your tests in the @@ -143,15 +142,28 @@ Bug fixes and features **should come with tests**. Add your tests in the project, see this [guide](./doc/guides/writing_tests.md). Looking at other tests to see how they should be structured can also help. +To run the tests on Unix / OS X: + ```text $ ./configure && make -j8 test ``` +Windows: + +```text +> vcbuild test +``` + +(See the [BUILDING.md](./BUILDING.md) for more details.) + Make sure the linter is happy and that all tests pass. Please, do not submit patches that fail either check. -Running `make test` will run the linter as well unless one or more tests fail. -If you want to run the linter without running tests, use `make lint`. +Running `make test`/`vcbuild test` will run the linter as well unless one or +more tests fail. + +If you want to run the linter without running tests, use +`make lint`/`vcbuild jslint`. If you are updating tests and just want to run a single test to check it, you can use this syntax to run it exactly as the test harness would: From 0645c3d0c411a8d84b2039ace3e19af081d30599 Mon Sep 17 00:00:00 2001 From: Prince J Wesley Date: Sat, 23 Jul 2016 12:10:45 +0530 Subject: [PATCH 031/144] doc: align breakEvalOnSigint - repl option PR-URL: https://github.com/nodejs/node/pull/7849 Reviewed-By: Anna Henningsen Reviewed-By: JungMinu - Minwoo Jung Reviewed-By: Colin Ihrig --- doc/api/repl.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/repl.md b/doc/api/repl.md index 124106e642ee62..5499f4dacb5462 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -392,9 +392,9 @@ added: v0.1.91 equivalent to prefacing every repl statement with `'use strict'`. * `repl.REPL_MODE_MAGIC` - attempt to evaluates expressions in default mode. If expressions fail to parse, re-try in strict mode. - * `breakEvalOnSigint` - Stop evaluating the current piece of code when - `SIGINT` is received, i.e. `Ctrl+C` is pressed. This cannot be used together - with a custom `eval` function. Defaults to `false`. + * `breakEvalOnSigint` - Stop evaluating the current piece of code when + `SIGINT` is received, i.e. `Ctrl+C` is pressed. This cannot be used together + with a custom `eval` function. Defaults to `false`. The `repl.start()` method creates and starts a `repl.REPLServer` instance. From cf65a7ce9e14b694cdb821a3a8f9611b1f5f12f6 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Wed, 29 Jun 2016 20:20:54 +0200 Subject: [PATCH 032/144] src: unifying PipeConnectWrap and TCPConnectWrap This commit attempts to address one of the items in #4641 which is related to src/pipe_wrap.cc and src/tcp_wrap.cc. Currently both pipe_wrap.cc and tcp_wrap.cc contain a class that are almost identical. This commit extracts these parts into a separate class that both can share. PR-URL: https://github.com/nodejs/node/pull/7501 Reviewed-By: Ben Noordhuis Reviewed-By: Anna Henningsen --- node.gyp | 2 ++ src/connect_wrap.cc | 22 ++++++++++++++++++++++ src/connect_wrap.h | 26 ++++++++++++++++++++++++++ src/pipe_wrap.cc | 34 ++++++++-------------------------- src/tcp_wrap.cc | 35 ++++++++++------------------------- 5 files changed, 68 insertions(+), 51 deletions(-) create mode 100644 src/connect_wrap.cc create mode 100644 src/connect_wrap.h diff --git a/node.gyp b/node.gyp index 186b4d75d5b610..3ba64986a98bb4 100644 --- a/node.gyp +++ b/node.gyp @@ -142,6 +142,7 @@ 'src/fs_event_wrap.cc', 'src/cares_wrap.cc', 'src/connection_wrap.cc', + 'src/connect_wrap.cc', 'src/handle_wrap.cc', 'src/js_stream.cc', 'src/node.cc', @@ -179,6 +180,7 @@ 'src/base-object.h', 'src/base-object-inl.h', 'src/connection_wrap.h', + 'src/connect_wrap.h', 'src/debug-agent.h', 'src/env.h', 'src/env-inl.h', diff --git a/src/connect_wrap.cc b/src/connect_wrap.cc new file mode 100644 index 00000000000000..df3f093e732972 --- /dev/null +++ b/src/connect_wrap.cc @@ -0,0 +1,22 @@ +#include "connect_wrap.h" + +#include "env.h" +#include "env-inl.h" +#include "req-wrap.h" +#include "req-wrap-inl.h" +#include "util.h" +#include "util-inl.h" + +namespace node { + +using v8::Local; +using v8::Object; + + +ConnectWrap::ConnectWrap(Environment* env, + Local req_wrap_obj, + AsyncWrap::ProviderType provider) : ReqWrap(env, req_wrap_obj, provider) { + Wrap(req_wrap_obj, this); +} + +} // namespace node diff --git a/src/connect_wrap.h b/src/connect_wrap.h new file mode 100644 index 00000000000000..28d4872d7ed416 --- /dev/null +++ b/src/connect_wrap.h @@ -0,0 +1,26 @@ +#ifndef SRC_CONNECT_WRAP_H_ +#define SRC_CONNECT_WRAP_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "env.h" +#include "req-wrap.h" +#include "async-wrap.h" +#include "v8.h" + +namespace node { + +class ConnectWrap : public ReqWrap { + public: + ConnectWrap(Environment* env, + v8::Local req_wrap_obj, + AsyncWrap::ProviderType provider); + + size_t self_size() const override { return sizeof(*this); } +}; + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_CONNECT_WRAP_H_ diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 8baf04ba7cef6f..e013811687f9d9 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -8,8 +8,7 @@ #include "node.h" #include "node_buffer.h" #include "node_wrap.h" -#include "req-wrap.h" -#include "req-wrap-inl.h" +#include "connect_wrap.h" #include "stream_wrap.h" #include "util-inl.h" #include "util.h" @@ -31,26 +30,6 @@ using v8::String; using v8::Value; -// TODO(bnoordhuis) share with TCPWrap? -class PipeConnectWrap : public ReqWrap { - public: - PipeConnectWrap(Environment* env, Local req_wrap_obj); - - size_t self_size() const override { return sizeof(*this); } -}; - - -PipeConnectWrap::PipeConnectWrap(Environment* env, Local req_wrap_obj) - : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_PIPECONNECTWRAP) { - Wrap(req_wrap_obj, this); -} - - -static void NewPipeConnectWrap(const FunctionCallbackInfo& args) { - CHECK(args.IsConstructCall()); -} - - Local PipeWrap::Instantiate(Environment* env, AsyncWrap* parent) { EscapableHandleScope handle_scope(env->isolate()); CHECK_EQ(false, env->pipe_constructor_template().IsEmpty()); @@ -92,8 +71,10 @@ void PipeWrap::Initialize(Local target, env->set_pipe_constructor_template(t); // Create FunctionTemplate for PipeConnectWrap. - Local cwt = - FunctionTemplate::New(env->isolate(), NewPipeConnectWrap); + auto constructor = [](const FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); + }; + auto cwt = FunctionTemplate::New(env->isolate(), constructor); cwt->InstanceTemplate()->SetInternalFieldCount(1); cwt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap")); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap"), @@ -163,7 +144,7 @@ void PipeWrap::Listen(const FunctionCallbackInfo& args) { // TODO(bnoordhuis) Maybe share this with TCPWrap? void PipeWrap::AfterConnect(uv_connect_t* req, int status) { - PipeConnectWrap* req_wrap = static_cast(req->data); + ConnectWrap* req_wrap = static_cast(req->data); PipeWrap* wrap = static_cast(req->handle->data); CHECK_EQ(req_wrap->env(), wrap->env()); Environment* env = wrap->env(); @@ -226,7 +207,8 @@ void PipeWrap::Connect(const FunctionCallbackInfo& args) { Local req_wrap_obj = args[0].As(); node::Utf8Value name(env->isolate(), args[1]); - PipeConnectWrap* req_wrap = new PipeConnectWrap(env, req_wrap_obj); + ConnectWrap* req_wrap = + new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_PIPECONNECTWRAP); uv_pipe_connect(&req_wrap->req_, &wrap->handle_, *name, diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 674c0592541b99..92037d0d6838e6 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -6,8 +6,7 @@ #include "handle_wrap.h" #include "node_buffer.h" #include "node_wrap.h" -#include "req-wrap.h" -#include "req-wrap-inl.h" +#include "connect_wrap.h" #include "stream_wrap.h" #include "util.h" #include "util-inl.h" @@ -32,24 +31,6 @@ using v8::String; using v8::Value; -class TCPConnectWrap : public ReqWrap { - public: - TCPConnectWrap(Environment* env, Local req_wrap_obj); - size_t self_size() const override { return sizeof(*this); } -}; - - -TCPConnectWrap::TCPConnectWrap(Environment* env, Local req_wrap_obj) - : ReqWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP) { - Wrap(req_wrap_obj, this); -} - - -static void NewTCPConnectWrap(const FunctionCallbackInfo& args) { - CHECK(args.IsConstructCall()); -} - - Local TCPWrap::Instantiate(Environment* env, AsyncWrap* parent) { EscapableHandleScope handle_scope(env->isolate()); CHECK_EQ(env->tcp_constructor_template().IsEmpty(), false); @@ -112,8 +93,10 @@ void TCPWrap::Initialize(Local target, env->set_tcp_constructor_template(t); // Create FunctionTemplate for TCPConnectWrap. - Local cwt = - FunctionTemplate::New(env->isolate(), NewTCPConnectWrap); + auto constructor = [](const FunctionCallbackInfo& args) { + CHECK(args.IsConstructCall()); + }; + auto cwt = FunctionTemplate::New(env->isolate(), constructor); cwt->InstanceTemplate()->SetInternalFieldCount(1); cwt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap")); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap"), @@ -253,7 +236,7 @@ void TCPWrap::Listen(const FunctionCallbackInfo& args) { void TCPWrap::AfterConnect(uv_connect_t* req, int status) { - TCPConnectWrap* req_wrap = static_cast(req->data); + ConnectWrap* req_wrap = static_cast(req->data); TCPWrap* wrap = static_cast(req->handle->data); CHECK_EQ(req_wrap->env(), wrap->env()); Environment* env = wrap->env(); @@ -300,7 +283,8 @@ void TCPWrap::Connect(const FunctionCallbackInfo& args) { int err = uv_ip4_addr(*ip_address, port, &addr); if (err == 0) { - TCPConnectWrap* req_wrap = new TCPConnectWrap(env, req_wrap_obj); + ConnectWrap* req_wrap = + new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP); err = uv_tcp_connect(&req_wrap->req_, &wrap->handle_, reinterpret_cast(&addr), @@ -334,7 +318,8 @@ void TCPWrap::Connect6(const FunctionCallbackInfo& args) { int err = uv_ip6_addr(*ip_address, port, &addr); if (err == 0) { - TCPConnectWrap* req_wrap = new TCPConnectWrap(env, req_wrap_obj); + ConnectWrap* req_wrap = + new ConnectWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_TCPCONNECTWRAP); err = uv_tcp_connect(&req_wrap->req_, &wrap->handle_, reinterpret_cast(&addr), From 23b64686674a1701fbf8410d2966b3cec9d487c7 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Wed, 20 Jul 2016 15:25:16 -0700 Subject: [PATCH 033/144] doc: add information about CTC quorum rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CTC quorum rules were not in writing. There was an informal understanding between CTC members. Document the rules to avoid differences in interpretation. PR-URL: https://github.com/nodejs/node/pull/7813 Reviewed-By: Сковорода Никита Андреевич Reviewed-By: Julien Gilli --- GOVERNANCE.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 34b2f5fd1ec936..7e4fbf5e7c4565 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -119,6 +119,8 @@ When an agenda item has appeared to reach a consensus, the moderator will ask "Does anyone object?" as a final call for dissent from the consensus. If an agenda item cannot reach a consensus, a CTC member can call for either a -closing vote or a vote to table the issue to the next meeting. The call for a -vote must be approved by a simple majority of the CTC or else the discussion -will continue. +closing vote or a vote to table the issue to the next meeting. All votes +(including votes to close or table) pass if and only if more than 50% of the CTC +members (excluding individuals who explicitly abstain) vote in favor. For +example, if there are 20 CTC members, and 5 of those members indicate that they +abstain, then 8 votes in favor are required for a resolution to pass. From 376d73b3b9bb80b26178e0f47cbfd637c1e5b79f Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Thu, 14 Jul 2016 20:16:26 -0700 Subject: [PATCH 034/144] meta: provide example activities Provide example activities to better distinguish Collaborator activities from CTC member activities. PR-URL: https://github.com/nodejs/node/pull/7744 Reviewed-By: Ben Noordhuis Reviewed-By: Julien Gilli --- GOVERNANCE.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 7e4fbf5e7c4565..490a2c91a678fc 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -56,6 +56,18 @@ For the current list of Collaborators, see the project A guide for Collaborators is maintained in [COLLABORATOR_GUIDE.md](./COLLABORATOR_GUIDE.md). +Typical activities of a Collaborator include: + +* helping users and novice contributors +* contributing code and documentation changes that improve the project +* reviewing and commenting on issues and pull requests +* participation in working groups +* merging pull requests + +While the above are typical things done by Collaborators, there are no required +activities to retain Collaborator status. There is currently no process by which +inactive Collaborators are removed from the project. + ## CTC Membership CTC seats are not time-limited. There is no fixed size of the CTC. The CTC @@ -80,6 +92,18 @@ the CTC membership shares an employer, then the situation must be immediately remedied by the resignation or removal of one or more CTC members affiliated with the over-represented employer(s). +Typical activities of a CTC member include: + +* attending the weekly meeting +* commenting on the weekly CTC meeting issue and issues labeled `ctc-agenda` +* participating in CTC email threads +* volunteering for tasks that arise from CTC meetings and related discussions +* other activities (beyond those typical of Collaborators) that facilitate the + smooth day-to-day operation of the Node.js project + +Note that CTC members are also Collaborators and therefore typically perform +Collaborator activities as well. + ## CTC Meetings The CTC meets weekly in a voice conference call. The meeting is run by a From ccfa6bf4d428e8b60fc3563d726f9a58886514fe Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Tue, 26 Jul 2016 21:35:35 -0700 Subject: [PATCH 035/144] test: speed up test-net-reconnect-error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test takes 50 seconds on some of the project's Windows CI infrastructure. Reducing the test repetitions from 50 to 20 trims that to about 20 seconds. Tests will timeout at 60 seconds, so this helps keep the test reliable. (There was a timeout on CI today when testing an unrelated code change.) Refs: https://github.com/nodejs/node/pull/7827#issuecomment-235476222 PR-URL: https://github.com/nodejs/node/pull/7886 Reviewed-By: Santiago Gimeno Reviewed-By: JungMinu - Minwoo Jung Reviewed-By: Michaël Zasso --- test/parallel/test-net-reconnect-error.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-net-reconnect-error.js b/test/parallel/test-net-reconnect-error.js index ed889829ec8abe..4e322bd09d2914 100644 --- a/test/parallel/test-net-reconnect-error.js +++ b/test/parallel/test-net-reconnect-error.js @@ -2,7 +2,7 @@ var common = require('../common'); var net = require('net'); var assert = require('assert'); -var N = 50; +var N = 20; var client_error_count = 0; var disconnect_count = 0; From 6ce9c80ccb04f5ee59bfa261927e5b96870d7eb4 Mon Sep 17 00:00:00 2001 From: Joe Esposito Date: Tue, 26 Jul 2016 22:25:08 -0400 Subject: [PATCH 036/144] doc: remove extra spaces and concats in examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/7885 Reviewed-By: Brian White Reviewed-By: Anna Henningsen Reviewed-By: Сковорода Никита Андреевич Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- doc/api/addons.md | 2 +- doc/api/child_process.md | 2 +- doc/api/console.md | 2 +- doc/api/https.md | 8 ++++---- doc/api/modules.md | 2 +- doc/api/process.md | 4 ++-- doc/api/vm.md | 8 ++++---- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/api/addons.md b/doc/api/addons.md index 1333b3b1360e3a..a239e15de651a8 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -423,7 +423,7 @@ const addon = require('./build/Release/addon'); var obj1 = addon('hello'); var obj2 = addon('world'); -console.log(obj1.msg + ' ' + obj2.msg); // 'hello world' +console.log(obj1.msg, obj2.msg); // 'hello world' ``` diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 7c01e34cecb7b2..708511e0470016 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -832,7 +832,7 @@ const spawn = require('child_process').spawn; let child = spawn('sh', ['-c', `node -e "setInterval(() => { - console.log(process.pid + 'is alive') + console.log(process.pid, 'is alive') }, 500);"` ], { stdio: ['inherit', 'inherit', 'inherit'] diff --git a/doc/api/console.md b/doc/api/console.md index 9fb8c37a6df66e..70e325178abe74 100644 --- a/doc/api/console.md +++ b/doc/api/console.md @@ -220,7 +220,7 @@ values similar to `printf(3)` (the arguments are all passed to var count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout -console.log('count: ', count); +console.log('count:', count); // Prints: count: 5, to stdout ``` diff --git a/doc/api/https.md b/doc/api/https.md index 620b6b36c74906..af1516a494c966 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -107,8 +107,8 @@ Example: const https = require('https'); https.get('https://encrypted.google.com/', (res) => { - console.log('statusCode: ', res.statusCode); - console.log('headers: ', res.headers); + console.log('statusCode:', res.statusCode); + console.log('headers:', res.headers); res.on('data', (d) => { process.stdout.write(d); @@ -151,8 +151,8 @@ var options = { }; var req = https.request(options, (res) => { - console.log('statusCode: ', res.statusCode); - console.log('headers: ', res.headers); + console.log('statusCode:', res.statusCode); + console.log('headers:', res.headers); res.on('data', (d) => { process.stdout.write(d); diff --git a/doc/api/modules.md b/doc/api/modules.md index 9f6093aaece850..7528e1004229e3 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -12,7 +12,7 @@ The contents of `foo.js`: ```js const circle = require('./circle.js'); -console.log( `The area of a circle of radius 4 is ${circle.area(4)}`); +console.log(`The area of a circle of radius 4 is ${circle.area(4)}`); ``` The contents of `circle.js`: diff --git a/doc/api/process.md b/doc/api/process.md index 12eb9b47c66d4d..cb6a1814fcd8ec 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -223,8 +223,8 @@ For example: ```js process.on('unhandledRejection', (reason, p) => { - console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason); - // application specific logging, throwing an error, or other logic here + console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); + // application specific logging, throwing an error, or other logic here }); somePromise.then((res) => { diff --git a/doc/api/vm.md b/doc/api/vm.md index c774ebe6a44bd7..c6290f1e93b76d 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -376,12 +376,12 @@ const vm = require('vm'); var localVar = 'initial value'; const vmResult = vm.runInThisContext('localVar = "vm";'); -console.log('vmResult: ', vmResult); -console.log('localVar: ', localVar); +console.log('vmResult:', vmResult); +console.log('localVar:', localVar); const evalResult = eval('localVar = "eval";'); -console.log('evalResult: ', evalResult); -console.log('localVar: ', localVar); +console.log('evalResult:', evalResult); +console.log('localVar:', localVar); // vmResult: 'vm', localVar: 'initial value' // evalResult: 'eval', localVar: 'eval' From 8d8d70d826611320fd5621df1f9584effe943f8c Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Tue, 26 Jul 2016 00:19:45 -0700 Subject: [PATCH 037/144] doc: fill in missing V8 version PR-URL: https://github.com/nodejs/node/pull/7878 Reviewed-By: Anna Henningsen Reviewed-By: Evan Lucas Reviewed-By: Minwoo Jung Reviewed-By: Brian White Reviewed-By: James M Snell --- doc/changelogs/CHANGELOG_V6.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changelogs/CHANGELOG_V6.md b/doc/changelogs/CHANGELOG_V6.md index 709c03b9106455..58c316de011253 100644 --- a/doc/changelogs/CHANGELOG_V6.md +++ b/doc/changelogs/CHANGELOG_V6.md @@ -39,7 +39,7 @@ October 2016. * Improve performance of Buffer.from(str, 'hex') and Buffer#write(str, 'hex'). (Christopher Jeffrey) [#7602](https://github.com/nodejs/node/pull/7602) * Fix creating from zero-length ArrayBuffer. (Ingvar Stepanyan) [#7176](https://github.com/nodejs/node/pull/7176) * **deps**: - * Upgrade to V8 5.0.71.xx. (Ben Noordhuis) [#7531](https://github.com/nodejs/node/pull/7531) + * Upgrade to V8 5.0.71.57. (Ben Noordhuis) [#7531](https://github.com/nodejs/node/pull/7531) * Backport V8 instanceof bugfix (Franziska Hinkelmann) [#7638](https://github.com/nodejs/node/pull/7638) * **repl**: Fix issue with function redeclaration. (Prince J Wesley) [#7794](https://github.com/nodejs/node/pull/7794) * **util**: Fix inspecting of boxed symbols. (Anna Henningsen) [#7641](https://github.com/nodejs/node/pull/7641) From 381aef8145c3090224df187f98e5f878da9977ff Mon Sep 17 00:00:00 2001 From: Erin Spiceland Date: Thu, 21 Jul 2016 13:50:25 -0500 Subject: [PATCH 038/144] timers: fix cleanup of nested same-timeout timers For nested timers with the same timeout, we can get into a situation where we have recreated a timer list immediately before we need to clean up an old timer list with the same key. Fix: make sure the list to be deleted is the same instance as the list whose reference was used to determine that a cleanup is necessary. If it's not the same instance, a new list with the same key has been created, and it should not be deleted. Fixes: https://github.com/nodejs/node/issues/7722 PR-URL: https://github.com/nodejs/node/pull/7827 Reviewed-By: Rich Trott Reviewed-By: James M Snell Reviewed-By: Julien Gilli --- lib/timers.js | 8 +- ...-timers-same-timeout-wrong-list-deleted.js | 80 +++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-timers-same-timeout-wrong-list-deleted.js diff --git a/lib/timers.js b/lib/timers.js index 7379cfe3591e02..52667a7d8646b4 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -211,9 +211,13 @@ function listOnTimeout() { debug('%d list empty', msecs); assert(L.isEmpty(list)); this.close(); - if (list._unrefed === true) { + + // Either refedLists[msecs] or unrefedLists[msecs] may have been removed and + // recreated since the reference to `list` was created. Make sure they're + // the same instance of the list before destroying. + if (list._unrefed === true && list === unrefedLists[msecs]) { delete unrefedLists[msecs]; - } else { + } else if (list === refedLists[msecs]) { delete refedLists[msecs]; } } diff --git a/test/parallel/test-timers-same-timeout-wrong-list-deleted.js b/test/parallel/test-timers-same-timeout-wrong-list-deleted.js new file mode 100644 index 00000000000000..05c0233e124b83 --- /dev/null +++ b/test/parallel/test-timers-same-timeout-wrong-list-deleted.js @@ -0,0 +1,80 @@ +'use strict'; + +/* + * This is a regression test for https://github.com/nodejs/node/issues/7722. + * + * When nested timers have the same timeout, calling clearTimeout on the + * older timer after it has fired causes the list the newer timer is in + * to be deleted. Since the newer timer was not cleared, it still blocks + * the event loop completing for the duration of its timeout, however, since + * no reference exists to it in its list, it cannot be canceled and its + * callback is not called when the timeout elapses. + */ + +const common = require('../common'); +const assert = require('assert'); +const Timer = process.binding('timer_wrap').Timer; + +const TIMEOUT = common.platformTimeout(100); +const start = Timer.now(); + +// This bug also prevents the erroneously dereferenced timer's callback +// from being called, so we can't use it's execution or lack thereof +// to assert that the bug is fixed. +process.on('exit', function() { + const end = Timer.now(); + assert.equal(end - start < TIMEOUT * 2, true, + 'Elapsed time does not include second timer\'s timeout.'); +}); + +const handle1 = setTimeout(common.mustCall(function() { + // Cause the old TIMEOUT list to be deleted + clearTimeout(handle1); + + // Cause a new list with the same key (TIMEOUT) to be created for this timer + const handle2 = setTimeout(function() { + common.fail('Inner callback is not called'); + }, TIMEOUT); + + setTimeout(common.mustCall(function() { + // Attempt to cancel the second timer. Fix for this bug will keep the + // newer timer from being dereferenced by keeping its list from being + // erroneously deleted. If we are able to cancel the timer successfully, + // the bug is fixed. + clearTimeout(handle2); + setImmediate(common.mustCall(function() { + setImmediate(common.mustCall(function() { + const activeHandles = process._getActiveHandles(); + const activeTimers = activeHandles.filter(function(handle) { + return handle instanceof Timer; + }); + + // Make sure our clearTimeout succeeded. One timer finished and + // the other was canceled, so none should be active. + assert.equal(activeTimers.length, 0, 'No Timers remain.'); + })); + })); + }), 10); + + // Make sure our timers got added to the list. + const activeHandles = process._getActiveHandles(); + const activeTimers = activeHandles.filter(function(handle) { + return handle instanceof Timer; + }); + const shortTimer = activeTimers.find(function(handle) { + return handle._list.msecs === 10; + }); + const longTimers = activeTimers.filter(function(handle) { + return handle._list.msecs === TIMEOUT; + }); + + // Make sure our clearTimeout succeeded. One timer finished and + // the other was canceled, so none should be active. + assert.equal(activeTimers.length, 3, 'There are 3 timers in the list.'); + assert(shortTimer instanceof Timer, 'The shorter timer is in the list.'); + assert.equal(longTimers.length, 2, 'Both longer timers are in the list.'); + + // When this callback completes, `listOnTimeout` should now look at the + // correct list and refrain from removing the new TIMEOUT list which + // contains the reference to the newer timer. +}), TIMEOUT); From 10f0c94c354ed699c06ea200958c206203060217 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sat, 23 Jul 2016 14:11:50 -0700 Subject: [PATCH 039/144] test: fix flaky test-tls-wrap-timeout Competing timers were causing a race condition and thus the test was flaky. Instead, we check an object property on process exit. Fixes: https://github.com/nodejs/node/issues/7650 PR-URL: https://github.com/nodejs/node/pull/7857 Reviewed-By: Santiago Gimeno Reviewed-By: Fedor Indutny Reviewed-By: jasnell - James M Snell --- test/parallel/test-tls-wrap-timeout.js | 50 ++++++++++++++++---------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/test/parallel/test-tls-wrap-timeout.js b/test/parallel/test-tls-wrap-timeout.js index ab0f307a970bb3..0454242d92ecb6 100644 --- a/test/parallel/test-tls-wrap-timeout.js +++ b/test/parallel/test-tls-wrap-timeout.js @@ -1,42 +1,54 @@ 'use strict'; -var common = require('../common'); -var assert = require('assert'); +const common = require('../common'); if (!common.hasCrypto) { common.skip('missing crypto'); return; } -var tls = require('tls'); +const assert = require('assert'); +const tls = require('tls'); -var net = require('net'); -var fs = require('fs'); +const net = require('net'); +const fs = require('fs'); -var options = { +const options = { key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem') }; -var server = tls.createServer(options, function(c) { - setTimeout(function() { - c.write('hello'); - setTimeout(function() { - c.destroy(); - server.close(); - }, 150); - }, 150); -}); +const server = tls.createServer(options, common.mustCall((c) => { + setImmediate(() => { + c.write('hello', () => { + setImmediate(() => { + c.destroy(); + server.close(); + }); + }); + }); +})); + +var socket; +var lastIdleStart; -server.listen(0, function() { - var socket = net.connect(this.address().port, function() { - var s = socket.setTimeout(common.platformTimeout(240), function() { +server.listen(0, () => { + socket = net.connect(server.address().port, function() { + const s = socket.setTimeout(Number.MAX_VALUE, function() { throw new Error('timeout'); }); assert.ok(s instanceof net.Socket); - var tsocket = tls.connect({ + assert.notStrictEqual(socket._idleTimeout, -1); + lastIdleStart = socket._idleStart; + + const tsocket = tls.connect({ socket: socket, rejectUnauthorized: false }); tsocket.resume(); }); }); + +process.on('exit', () => { + assert.strictEqual(socket._idleTimeout, -1); + assert(lastIdleStart < socket._idleStart); +}); From fecf611ca8b66cade027fe1df12c19684ee07dea Mon Sep 17 00:00:00 2001 From: Santiago Gimeno Date: Sun, 24 Jul 2016 08:24:48 +0200 Subject: [PATCH 040/144] tools,test: show signal code when test crashes On every platform but `Windows`. Also, print the crash information when using the tap reporter. PR-URL: https://github.com/nodejs/node/pull/7859 Reviewed-By: Ben Noordhuis --- tools/test.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tools/test.py b/tools/test.py index c6b67e2e1e522f..2613ad59d7dbc3 100755 --- a/tools/test.py +++ b/tools/test.py @@ -196,7 +196,7 @@ def Done(self): print failed.output.stdout.strip() print "Command: %s" % EscapeCommand(failed.command) if failed.HasCrashed(): - print "--- CRASHED ---" + print "--- %s ---" % PrintCrashed(failed.output.exit_code) if failed.HasTimedOut(): print "--- TIMEOUT ---" if len(self.failed) == 0: @@ -285,6 +285,9 @@ def HasRun(self, output): logger.info(status_line) self._printDiagnostic("\n".join(output.diagnostic)) + if output.HasCrashed(): + self._printDiagnostic(PrintCrashed(output.output.exit_code)) + if output.HasTimedOut(): self._printDiagnostic('TIMEOUT') @@ -347,7 +350,7 @@ def HasRun(self, output): print self.templates['stderr'] % stderr print "Command: %s" % EscapeCommand(output.command) if output.HasCrashed(): - print "--- CRASHED ---" + print "--- %s ---" % PrintCrashed(output.output.exit_code) if output.HasTimedOut(): print "--- TIMEOUT ---" @@ -1476,6 +1479,13 @@ def FormatTime(d): return time.strftime("%M:%S.", time.gmtime(d)) + ("%03i" % millis) +def PrintCrashed(code): + if utils.IsWindows(): + return "CRASHED" + else: + return "CRASHED (Signal: %d)" % -code + + def Main(): parser = BuildOptions() (options, args) = parser.parse_args() From 4aee970d92f11b053f03844cd13bbb30be2b3d7c Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Sat, 16 Jul 2016 04:17:36 +0300 Subject: [PATCH 041/144] test: decrease inconsistency in the common.js 1. `process.env['PROCESSOR_ARCHITEW6432']` -> `process.env.PROCESSOR_ARCHITEW6432`. 2. `path.dirname(__filename)` -> `__dirname`. 3. `path.resolve(__dirname)` -> `__dirname`. PR-URL: https://github.com/nodejs/node/pull/7758 Reviewed-By: Colin Ihrig Reviewed-By: Jeremiah Senkpiel Reviewed-By: Anna Henningsen Reviewed-By: Sakthipriyan Vairamani --- test/common.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/common.js b/test/common.js index 4aa48de48f4b6f..e25088a6688bd4 100644 --- a/test/common.js +++ b/test/common.js @@ -9,17 +9,17 @@ const stream = require('stream'); const util = require('util'); const Timer = process.binding('timer_wrap').Timer; -const testRoot = path.resolve(process.env.NODE_TEST_DIR || - path.dirname(__filename)); +const testRoot = process.env.NODE_TEST_DIR ? + path.resolve(process.env.NODE_TEST_DIR) : __dirname; -exports.testDir = path.dirname(__filename); +exports.testDir = __dirname; exports.fixturesDir = path.join(exports.testDir, 'fixtures'); exports.libDir = path.join(exports.testDir, '../lib'); exports.tmpDirName = 'tmp'; exports.PORT = +process.env.NODE_COMMON_PORT || 12346; exports.isWindows = process.platform === 'win32'; exports.isWOW64 = exports.isWindows && - (process.env['PROCESSOR_ARCHITEW6432'] !== undefined); + (process.env.PROCESSOR_ARCHITEW6432 !== undefined); exports.isAix = process.platform === 'aix'; exports.isLinuxPPCBE = (process.platform === 'linux') && (process.arch === 'ppc64') && From 04ec64aacc4465d878c58eea9df4197217db307c Mon Sep 17 00:00:00 2001 From: Ravindra barthwal Date: Fri, 29 Jul 2016 08:57:45 +0530 Subject: [PATCH 042/144] doc: add missing semicolon PR-URL: https://github.com/nodejs/node/pull/7915 Reviewed-By: Colin Ihrig Reviewed-By: Brian White Reviewed-By: Minwoo Jung Reviewed-By: James M Snell --- doc/api/assert.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/assert.md b/doc/api/assert.md index bc5c0b833ae5aa..d5fd7c26995781 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -258,7 +258,7 @@ const obj3 = { a : { b : 1 } -} +}; const obj4 = Object.create(obj1); assert.notDeepEqual(obj1, obj1); From ddf292fc32b176ba16098e998d7218082fb8ffc5 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 16 Jul 2016 16:17:41 +0200 Subject: [PATCH 043/144] build: don't link against liblog on host system Don't link binaries that run on the host system against liblog, it breaks cross-compiling for android. Fixes: https://github.com/nodejs/node/issues/7731 PR-URL: https://github.com/nodejs/node/pull/7762 Reviewed-By: Anna Henningsen --- common.gypi | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/common.gypi b/common.gypi index 646db0d7bbb339..5eea907a0ef1e2 100644 --- a/common.gypi +++ b/common.gypi @@ -301,9 +301,13 @@ }], ], }], - [ 'OS=="android"', { - 'defines': ['_GLIBCXX_USE_C99_MATH'], - 'libraries': [ '-llog' ], + ['OS=="android"', { + 'target_conditions': [ + ['_toolset=="target"', { + 'defines': [ '_GLIBCXX_USE_C99_MATH' ], + 'libraries': [ '-llog' ], + }], + ], }], ['OS=="mac"', { 'defines': ['_DARWIN_USE_64_BIT_INODE=1'], From 7d0c1bf781e423e501c7e792d99cb0d72efdf779 Mon Sep 17 00:00:00 2001 From: Joey Cozza Date: Thu, 21 Jul 2016 00:09:55 -0600 Subject: [PATCH 044/144] doc: fix path markdown formatting Single quotes in two of the examples were throwing off the formatting of the path documentation on the Node.js website. This commit expands two contractions to remove the offending quotes. PR-URL: https://github.com/nodejs/node/pull/7817 Reviewed-By: Colin Ihrig Reviewed-By: Claudio Rodriguez Reviewed-By: James M Snell --- doc/api/path.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/path.md b/doc/api/path.md index fd07cd6802df9a..d977173596b8de 100644 --- a/doc/api/path.md +++ b/doc/api/path.md @@ -367,7 +367,7 @@ path.parse('/home/user/dir/file.txt') │ root │ │ name │ ext │ " / home/user/dir / file .txt " └──────┴──────────────┴──────┴─────┘ -(all spaces in the "" line should be ignored -- they're purely for formatting) +(all spaces in the "" line should be ignored -- they are purely for formatting) ``` On Windows: @@ -391,7 +391,7 @@ path.parse('C:\\path\\dir\\file.txt') │ root │ │ name │ ext │ " C:\ path\dir \ file .txt " └──────┴──────────────┴──────┴─────┘ -(all spaces in the "" line should be ignored -- they're purely for formatting) +(all spaces in the "" line should be ignored -- they are purely for formatting) ``` A [`TypeError`][] is thrown if `path` is not a string. From facd7dade1cd3e4ed164872c24847ff0b4f96378 Mon Sep 17 00:00:00 2001 From: Prince J Wesley Date: Sun, 31 Jul 2016 22:45:19 +0530 Subject: [PATCH 045/144] test: don't hard code deprecation count PR-URL: https://github.com/nodejs/node/pull/7927 Reviewed-By: Brian White Reviewed-By: Claudio Rodriguez Reviewed-By: Sakthipriyan Vairamani Reviewed-By: Santiago Gimeno Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- test/parallel/test-crypto-deprecated.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/parallel/test-crypto-deprecated.js b/test/parallel/test-crypto-deprecated.js index c702e9129ac956..a471b192e1ff45 100644 --- a/test/parallel/test-crypto-deprecated.js +++ b/test/parallel/test-crypto-deprecated.js @@ -9,6 +9,11 @@ if (!common.hasCrypto) { const crypto = require('crypto'); const tls = require('tls'); +const expected = [ + 'crypto.Credentials is deprecated. Use tls.SecureContext instead.', + 'crypto.createCredentials is deprecated. Use tls.createSecureContext instead.' +]; + process.on('warning', common.mustCall((warning) => { assert.strictEqual(warning.name, 'DeprecationWarning'); assert.notStrictEqual(expected.indexOf(warning.message), -1, @@ -16,12 +21,7 @@ process.on('warning', common.mustCall((warning) => { // Remove a warning message after it is seen so that we guarantee that we get // each message only once. expected.splice(expected.indexOf(warning.message), 1); -}, 2)); - -var expected = [ - 'crypto.Credentials is deprecated. Use tls.SecureContext instead.', - 'crypto.createCredentials is deprecated. Use tls.createSecureContext instead.' -]; +}, expected.length)); // Accessing the deprecated function is enough to trigger the warning event. // It does not need to be called. So the assert serves the purpose of both From bb908673393674ce43c288232d329abdab1d072f Mon Sep 17 00:00:00 2001 From: William Kapke Date: Wed, 27 Jul 2016 22:24:21 +0000 Subject: [PATCH 046/144] doc: add CTC meeting minutes 2016-07-27 PR-URL: https://github.com/nodejs/node/pull/7900 Reviewed-By: Rich Trott Reviewed-By: James M Snell --- doc/ctc-meetings/2016-07-27.md | 237 +++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 doc/ctc-meetings/2016-07-27.md diff --git a/doc/ctc-meetings/2016-07-27.md b/doc/ctc-meetings/2016-07-27.md new file mode 100644 index 00000000000000..d0b19393865f5b --- /dev/null +++ b/doc/ctc-meetings/2016-07-27.md @@ -0,0 +1,237 @@ +# Node Foundation CTC Meeting 2016-07-27 + +## Links + +* **Audio Recording**: https://www.youtube.com/watch?v=QAufnqo4ElY +* **GitHub Issue**: https://github.com/nodejs/node/issues/7881 +* **Minutes Google Doc**: +* _Previous Minutes Google Doc: _ + +## Present + +* Anna Henningsen @addaleax (observer) +* Сковорода Никита Андреевич @ChALkeR (CTC) +* Jeremiah Senkpiel @Fishrock123 (CTC) +* Fedor Indutny @indutny (CTC) +* James M Snell @jasnell (CTC) +* Julien Gilli @misterdjules (CTC) +* Mikeal Rogers @mikeal (observer/Node.js Foundation) +* Brian White @mscdex (CTC) +* Alexis Campailla @orangemocha (CTC) +* Rod Vagg @rvagg (CTC) +* Steven R Loomis @srl295 (observer/IBM/ICU) +* Trevor Norris @trevnorris (CTC) +* Rich Trott @Trott (CTC) +* William Kapke @williamkapke (observer) + + +## Standup + +* Anna Henningsen @addaleax (observer) + * Issues & PRs + * Some realpath work +* Сковорода Никита Андреевич @ChALkeR (CTC) + * Mostly comments and reviews, nothing significant +* Fedor Indutny @indutny (CTC) + * Issues, PRs, Direct-to-BIO experiments +* James M Snell @jasnell (CTC) + * Glorious vacation … + * Catching up + * Small clarification PR for IRC moderation +* Julien Gilli @misterdjules (CTC) + * PR reviews, especially https://github.com/nodejs/node/pull/7827, which looks like a very solid first contribution from a new contributor. +* Brian White @mscdex (CTC) + * Continued reworking of API docs + * Reviewed PRs, commented on issues +* Alexis Campailla @orangemocha (CTC) + * Investigating issues related to fs.realPath + * Investigating binary compatibility between Node and native modules compiled with different VS versions + * Working with team on various Windows issues in Node and libuv +* Rod Vagg @rvagg (CTC) + * NodeSummit / travel, Node v5 blog post nearly ready to post, bug in require() (still need to post in nodejs/node) + * Steven R Loomis @srl295 (observer/IBM/ICU) + * @ NodeSummit / prep… thinking about how to keep an eye on upcoming v8 changes. Did some more work on https://github.com/nodejs/node/issues/3460 (detect full-icu module). +* Trevor Norris @trevnorris (CTC) + * NodeSummit talk + * fs.realpath() + * Prepping AsyncWrap, target end of August +* Rich Trott @Trott (CTC) + * Updating governance text and whatnot + * Flaky tests + * NodeSummit talk +* William Kapke @williamkapke (Observer) + + +## Agenda + +Extracted from **ctc-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. + +### nodejs/node + +* Role of CTC in semver-major changes needs clarification [#7848](https://github.com/nodejs/node/issues/7848) +* Revert fs changes [#7846](https://github.com/nodejs/node/pull/7846) +* doc: add information about CTC quorum rules [#7813](https://github.com/nodejs/node/pull/7813) +* meta: provide example activities [#7744](https://github.com/nodejs/node/pull/7744) +* meta: realpath issues in v6 [#7726](https://github.com/nodejs/node/issues/7726) +* v4.5.0 proposal [#7688](https://github.com/nodejs/node/pull/7688) +* punycode: deprecate punycode module [#7552](https://github.com/nodejs/node/pull/7552) +* Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/issues/7175) +* http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) +* Seek legal advice on LICENSE and copyright blocks in code [#3979](https://github.com/nodejs/node/issues/3979) + +### nodejs/post-mortem + +* Repositories to contribute collaboratively [#30](https://github.com/nodejs/post-mortem/issues/30) + +### nodejs/node-eps + +* proposal: WHATWG URL standard implementation [#28](https://github.com/nodejs/node-eps/pull/28) + + +## Previous Meeting + +### nodejs/node + +* [meta] realpath issues in v6 [#7726](https://github.com/nodejs/node/issues/7726) +* v4.5.0 proposal [#7688](https://github.com/nodejs/node/pull/7688) +* http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) + +### nodejs/node-eps + +* proposal: WHATWG URL standard implementation [#28](https://github.com/nodejs/node-eps/pull/28) + +## Minutes + + +### Role of CTC in semver-major changes needs clarification [#7848](https://github.com/nodejs/node/issues/7848) + + + + +### Revert fs changes [#7846](https://github.com/nodejs/node/pull/7846) + + +James: has to do with recent changes - making callback mandatory on all async functions apparently _broke the planet_, quite a few modules broke including a number used by npm, so `npm set` failed to work for example. + +James: technically this should be viewed as a bugfix but we’ve already treated things involving errors as sensitive but this is on master and things a broken right now so suggesting that we revert this. Some alternatives are: not revert and get fixes in the ecosystem, revert and add warning. + +Rich: Myles endorsed [#7897](https://github.com/nodejs/node/pull/7897) as a better alternative to reverting as it includes a warning. What’s the preferred approach here James? + +James: revert, even though I don’t like it, we should revert and revisit. + +Trevor: the fact that it was allowed was a bad decision because throwing can lead to hard-to-debug situations. Reverting is the _only course of action_. + +Rod: wanted to clarify as a matter of culture - we should fix master as soon as we’re aware of breakage in the ecosystem and deal with things more cleanly as we can. + +Julien: multiple commits in the revert PR, we should have separate discussions about them. + +James: will ask on the PR that they be split into two. + +James: second question here is whether we want to emit a warning instead? + +Rod: the graceful-fs warnings are still widespread because lots of packages rely on very old versions and it’s taking a long time to get updates through the ecosystem. We have to be careful about (1) warning fatigue, (2) users not understanding the subtlety and interpreting warnings as errors. Would be good if we go a bit slower on moving to warnings. + +James: we could run with warnings off by default as a way of dealing warning fatigue but that’s another discussion we can have on GitHub. + +Rich: moving on, this can be done on Github. + +### doc: add information about CTC quorum rules [#7813](https://github.com/nodejs/node/pull/7813) + +Rich: there was a counter-proposal which seemed to be better so I updated to use Chalker’s alternative wording. **If anyone doesn’t want this to land please comment on it within the next 24 hours or so**. There hasn’t been too much discussion or disagreement. + +### meta: provide example activities [#7744](https://github.com/nodejs/node/pull/7744) + +Rich: Similar to the previous issue - have not got a whole lot of response, or a luke-warm response at least. Please comment in there if you have any problems with it, there are no negatives so it’ll land in the next 24 hours or so so please comment! + +### \[meta\] realpath issues in v6 [#7726](https://github.com/nodejs/node/issues/7726) + +Trevor: ran some benchmarks in CI to see how much time it would take to require() with and without cache in realpath. Haven’t done Windows but on the others there was between 10% to 100%, which is between 30us to 300us difference per require(). + +Alexis: [#7899](https://github.com/nodejs/node/pull/7899) reverts and also includes Myles’ reversions from the other fs issues. + +Trevor: probably should revert and leave cache out, we might take a small hit now in perf but will lead to greater potential in the future. + +Alexis: the cache was never a great API in the first place anyway. + +Trevor: propose we revert and leave the cache and introduce a better fix. + +Anna: agree with Trevor and Alexis. + +Rod: should we get benchmarks on Windows? + +Alexis: much more concerned about correctness than performance. + +Trevor: this is a short-term fix, so we shouldn’t have a problem bringing it in. + +Rich asked for disagreement with moving forward with reversion without cache? No disagreement. Need to comment on 7899, review & lgtm. Anna, Trevor or Alexis will move it forward. + +### v4.5.0 proposal [#7688](https://github.com/nodejs/node/pull/7688) + +James: because this adds some semver-minor’s Myles is very concerned about stability. + +Julien: any ideas on how we might be able to get more testers for these? + +James: maybe in a week, will get some suggestions posted to the LTS repo that we can discuss. + +### punycode: deprecate punycode module [#7552](https://github.com/nodejs/node/pull/7552) + +James: this is a 3rd party dependency that we expose and there’s some fairly extensive usage out there but there is a newer version out there in npm that people should be using. + +Rich: no more comments? Please post on the repo. + +Rod: deprecation is fine but would really like a long deprecation cycle. + +James: how about soft deprecation in v7 and hard in v8? + +Rod: soft in v7 and revisit decision to hard prior to v8. + +Brian: if people build without ICU what would happen to punycode since we need it? + +James: This particular PR introduces a hard deprecation that moves it to internal/ and has a shim that exposes it, so we could still use it internally but just deprecate the external API. + +Brian: are we going to continue updating the non-ICU version for people going forward or just leave it? + +James: would prefer to just leave it as is. + +Chalker: on npm it has 5.7M downloads per month so people are already using it. + +James: clarify: soft deprecate now and revisit hard deprecation prior to v8? + +### http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) + +Rod: wanted to mention that Chris Dickinson expressed concerns on Twitter about us doing this same thing on querystring and that it was causing problems for him and didn’t like that it crept in to v6. + +James: Doug, from the express side, thinks this is a good decision and cleans up things for users. The querystring thing has + +… discussion tended towards accepting the change but CTC would like to solicit input from Chris Dickinson before getting it landed since he had raised some objections + +### Seek legal advice on LICENSE and copyright blocks in code [#3979](https://github.com/nodejs/node/issues/3979) + +Mikeal Rogers: discussing the SPDX stuff and restoration of licenses in the files. Mikeal and Rod will take the lead on moving forward with this. + +### Repositories to contribute collaboratively [post-mortem#30](https://github.com/nodejs/post-mortem/issues/30) + +Move to TSC meeting + +### proposal: WHATWG URL standard implementation [node-eps#28](https://github.com/nodejs/node-eps/pull/28) + +James: Passing WHATWG tests except some intentional ones. Performance is slower than our own url impl because of tests we fail. Any objections to moving forward? + +Rod: we’re going to have two implementations, this seems like a difficult thing to agree on. + +James: would like to eventually deprecate existing url.parse. + +Rich: let’s move on because this will be a big conversation. Let’s have a brief conversation next week and slot a bigger discussion next week. + +## Q/A on public fora + +No questions. + +## Upcoming Meetings + +* CTC: 2016-08-03 +* TSC: 2016-07-28 +* Build: 2016-08-09 +* Diagnostics: 2016-08-03 +* Post-Mortem: August +* API: August From 636cf2236a3b2b79c8663f0f70cca048de5c2bee Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Wed, 27 Jul 2016 11:58:11 +0200 Subject: [PATCH 047/144] build: adding config.gypi dep to addons/.buildstamp Currently the build-addons target is called as part of the test target, and it has test/addons/.buildstamp as a dependency. When running ./configure --debug and later switching/ updating branches you can be in a situation where the config.gypi files in the addons build directories are using an incorrect value for default_configuration. Currently this can happen and you will get test errors as there are a few test that depend on the value of default_configuration to be Release. Ben Noordhuis provided the solution for this by adding a dependency to config.gypi, which is generated when running ./configure, and will correct this situation. This commit is related to #7860. Please see the dicussion in that issue regarding the test using hard-coded paths. PR-URL: https://github.com/nodejs/node/pull/7893 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Ben Noordhuis --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d82926dab75200..7e68c20972394c 100644 --- a/Makefile +++ b/Makefile @@ -150,7 +150,8 @@ ADDONS_BINDING_SOURCES := \ # Implicitly depends on $(NODE_EXE), see the build-addons rule for rationale. # Depends on node-gyp package.json so that build-addons is (re)executed when # node-gyp is updated as part of an npm update. -test/addons/.buildstamp: deps/npm/node_modules/node-gyp/package.json \ +test/addons/.buildstamp: config.gypi \ + deps/npm/node_modules/node-gyp/package.json \ $(ADDONS_BINDING_GYPS) $(ADDONS_BINDING_SOURCES) \ deps/uv/include/*.h deps/v8/include/*.h \ src/node.h src/node_buffer.h src/node_object_wrap.h \ From 79ecfb5183ed880a64bcd37a380b6aabb7f37efa Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Wed, 13 Jul 2016 15:41:17 -0700 Subject: [PATCH 048/144] meta: include a minimal CTC removal policy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add language identifying a request for voluntary resignation as the typical mechanism for addressing inactive CTC members. PR-URL: https://github.com/nodejs/node/pull/7720 Reviewed-By: Rod Vagg Reviewed-By: Сковорода Никита Андреевич Reviewed-By: Ben Noordhuis Reviewed-By: Fedor Indutny Reviewed-By: Jeremiah Senkpiel Reviewed-By: Evan Lucas Reviewed-By: Shigeki Ohtsu Reviewed-By: Michael Dawson Reviewed-By: Rich Trott Reviewed-By: Brian White Reviewed-By: Julien Gilli Reviewed-By: James M Snell --- GOVERNANCE.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 490a2c91a678fc..d3ba8355e0fca8 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -56,6 +56,8 @@ For the current list of Collaborators, see the project A guide for Collaborators is maintained in [COLLABORATOR_GUIDE.md](./COLLABORATOR_GUIDE.md). +### Collaborator Activities + Typical activities of a Collaborator include: * helping users and novice contributors @@ -79,11 +81,15 @@ membership beyond these rules. The CTC may add additional members to the CTC by a standard CTC motion. -A CTC member may be removed from the CTC by voluntary resignation, or by -a standard CTC motion. +When a CTC member's participation in [CTC activities](#ctc-activities) has become +minimal for a sustained period of time, the CTC will request that the member +either indicate an intention to increase participation or voluntarily resign. + +CTC members may only be removed by voluntary resignation or through a standard +CTC motion. Changes to CTC membership should be posted in the agenda, and may be -suggested as any other agenda item (see "CTC Meetings" below). +suggested as any other agenda item (see [CTC Meetings](#ctc-meetings) below). No more than 1/3 of the CTC members may be affiliated with the same employer. If removal or resignation of a CTC member, or a change of @@ -92,6 +98,8 @@ the CTC membership shares an employer, then the situation must be immediately remedied by the resignation or removal of one or more CTC members affiliated with the over-represented employer(s). +### CTC Activities + Typical activities of a CTC member include: * attending the weekly meeting @@ -104,7 +112,7 @@ Typical activities of a CTC member include: Note that CTC members are also Collaborators and therefore typically perform Collaborator activities as well. -## CTC Meetings +### CTC Meetings The CTC meets weekly in a voice conference call. The meeting is run by a designated moderator approved by the CTC. Each meeting is streamed on YouTube. From 46162611101bb92bd623645a0be04ca28f449e59 Mon Sep 17 00:00:00 2001 From: Josh Gavant Date: Wed, 6 Jul 2016 14:33:51 -0700 Subject: [PATCH 049/144] doc: add CTC meeting minutes 2016-06-29 PR-URL: https://github.com/nodejs/node/pull/7571 Reviewed-By: James M Snell Reviewed-By: Michael Dawson --- doc/ctc-meetings/2016-06-29.md | 187 +++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 doc/ctc-meetings/2016-06-29.md diff --git a/doc/ctc-meetings/2016-06-29.md b/doc/ctc-meetings/2016-06-29.md new file mode 100644 index 00000000000000..859cdc1df27c59 --- /dev/null +++ b/doc/ctc-meetings/2016-06-29.md @@ -0,0 +1,187 @@ +# Node Foundation CTC Meeting 2016-06-29 + +## Links + +* **Audio Recording**: TBP +* **GitHub Issue**: https://github.com/nodejs/node/issues/7474 +* **Minutes Google Doc**: +* _Previous Minutes Google Doc: _ + +## Present + +* Bradley Meck @bmeck (observer/GoDaddy/TC39) +* Сковорода Никита Андреевич @ChALkeR (CTC) +* Colin Ihrig @cjihrig (CTC) +* Evan Lucas @evanlucas (CTC) +* Jeremiah Senkpiel @Fishrock123 (CTC) +* James M Snell @jasnell (CTC) +* John-David Dalton @jdalton (observer/Lodash/Microsoft) +* Josh Gavant @joshgav (observer/Microsoft) +* Michael Dawson @mhdawson (CTC) +* Brian White @mscdex (CTC) +* Ali Ijaz Sheikh @ofrobots (CTC) +* Rod Vagg @rvagg (CTC) +* Trevor Norris @trevnorris (CTC) +* Rich Trott @Trott (CTC) + + +## Agenda + +Extracted from **ctc-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. + +### nodejs/node + +* New Buffer API backport to v4.x [#7475](https://github.com/nodejs/node/pull/7475) +* child_process: validate fork/execFile arguments [#7399](https://github.com/nodejs/node/pull/7399) +* Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/issues/7175) +* repl: Default `useGlobal` to false in CLI REPL. [#5703](https://github.com/nodejs/node/pull/5703) +* Seek legal advice on LICENSE and copyright blocks in code [#3979](https://github.com/nodejs/node/issues/3979) + +### nodejs/LTS + +* Mention odd-number release has eight months support as Current. [#113](https://github.com/nodejs/LTS/issues/113) + +### nodejs/node-eps + +* AsyncWrap public API proposal [#18](https://github.com/nodejs/node-eps/pull/18) + +## Standup + +* Bradley Meck @bmeck (observer/GoDaddy/TC39) + * Trying to gather all stakeholders in ES Module implementations into a meeting + * Back and forth with V8 about details of CJS bridge +* John-David Dalton @jdalton (observer/Lodash/Microsoft) + * Dropped caching from unambiguous JS proposal + * PR to Node EPS repo + * Discussed with V8 (Adam Klein) and Chakra about adding the API, no blockers +* Сковорода Никита Андреевич @ChALkeR (CTC) + * Filed #7475 to backport new Buffer API to 4.x LTS +* Colin Ihrig @cjihrig (CTC) + * Reviewing issues and PRs. Made a couple libuv PRs. +* Evan Lucas @evanlucas (CTC) + * Merged pr to allow passing prompt to readline + * Merged pr that prints experimental warning when using inspector + * Worked on v6.x branch a little +* Jeremiah Senkpiel @Fishrock123 (CTC) + * Was away a bit adjusting to Europe. + * Misc PRs/Issues work. + * Also working to resolve https://github.com/nodejs/node/issues/5426 (ages old timers issue) +* Josh Gavant @joshgav (observer/Microsoft) + * Scheduled next Diag WG meeting (7/13 12 Pacific) (https://github.com/nodejs/diagnostics/issues/60) + * “Inspector Gateway” proposal (https://github.com/nodejs/node/issues/7393) + * Module discussions +* Michael Dawson @mhdawson (CTC) + * Testing problematic PPC machine after move to new node, adding back to regular CI runs + * Working on ABI stable API prototype with Ian/Sampson + * Post mortem work with Richard C + * Misc PR reviews/lands + * Adding linuxOne to master test jobs in CI (since 5.1 landed there) + * LTS, Build WG meetings + * Starting to work on presentations for upcoming conferences +* Brian White @mscdex (CTC) + * Landed a fix for a StringDecoder regression + * Reviewed PRs, commented on issues +* Ali Ijaz Sheikh @ofrobots (CTC) + * Busy with non-Node stuff mostly. +* Rod Vagg @rvagg (CTC) + * Chat with Electron team + * Foundation board meeting + * npm publish bug hunt + * node-gyp release, fix for latest MSVS 2015 release +* Steven R Loomis @srl295 (observer/IBM/ICU) + * regrets for this meeting- nothing to add at this point(hopefully soon) +* Trevor Norris @trevnorris (CTC) + * working on solution for user API for AsyncWrap (?) +* Rich Trott @Trott (CTC) + * child_process fixes + * examining https://node-core-coverage.addaleax.net/ results (thanks, @addaleax!) + * re-certifying flaky tests + +## Minutes + +### child_process: validate fork/execFile arguments [#7399](https://github.com/nodejs/node/pull/7399) + +@trott: Semver-major change requires review. + +@trott: fixing a bug that James filed some time ago - if nonsensical arguments are passed to these methods they silently ignore those arguments. Rich and James think it should throw if you give it garbage. + +@nodejs/ctc: No objections. + +### Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/issues/7175) + +@trevnorris was to work on capturing new errors and handling them. Discovered that all fs methods suffer same issue. Trevor has idea on how to handle it, will submit PR in the next day or two. + +@bzoz understands Windows issues and will address them. + +### buffer: backport --zero-fill-buffers command line option [#5745](https://github.com/nodejs/node/pull/5745) + +See also [#7475](https://github.com/nodejs/node/pull/7475). + +Backport to v4. Was discussed and CTC thought it wasn’t a good idea, but want to revisit now. What was previous issue? @Fishrock123 - another change, possibly security-related, blocked it. + +@rvagg: Same objections as backport to 0.12, should be treated the same. + +@nodejs/ctc: No objections currently. This is relevant to security. + +### repl: Default `useGlobal` to false in CLI REPL. [#5703](https://github.com/nodejs/node/pull/5703) + +* Some discussion in the original issue: https://github.com/nodejs/node/issues/5659#issuecomment-195543607 +* Moving back to GitHub. + +### Mention odd-number release has eight months support as Current. [lts#113](https://github.com/nodejs/LTS/issues/113) + +* Current state is that Current (formerly Stable) branch is supported for **two** months after next release but some people think it’s **three** months. For example, v5 is supported till end of June 2016. But we’d like this to be stated clearly. + +@mhdawson: discussion in last LTS meeting but it’s not in the scope of the LTS WG’s work so it’s up to the CTC. Is it Current+2 or Current+3? + +@nodejs/ctc: Previous Current version is supported for two months after next version is released. + +@rvagg: v5 is still heavily used. + +@Fishrock123: npm metrics also show high usage of v5, not much decline. + +Need to make clear that people need to upgrade. Should we push this harder or adjust to usage pattern? + +@nodejs/ctc: Stick with plan to stop supporting v5 shortly. + +Metrics: https://nodejs.org/metrics/summaries/version.png + + +### AsyncWrap public API proposal [node-eps#18](https://github.com/nodejs/node-eps/pull/18) + +@Fishrock123 - responses have been primarily positive, time for CTC to consider. + +@rvagg - Goal is to raise awareness amongst CTC today, vote on it next week. + +@rvagg - currently marked as experimental. We should associate a message/warning with experimental API usage. EPs are for experimental APIs. + +@trevnorris - AsyncWrap cannot track callbacks from native addons. Also investigating why sometimes messages are dropped (?). + +### replace section 5.1 with unambiguous JavaScript grammar [node-eps#33](https://github.com/nodejs/node-eps/pull/33) + +@jdalton wants to get agreement from Node.js CTC so that he can proceed to browser vendors. + +TC39 may want to add other “goals” for files in addition to module and script such as asm.js, “frozen realms”. + +@rvagg: If we go with `.mjs` we’d have to have extensions for new parse goals too... + +@rvagg: We prefer a spec change in TC39/ES262 or an acknowledgement at least. @jdalton will add that caveat into the PR. + +@Fishrock123: What about avoiding double parsing? +@bmeck: Chakra said maybe, V8 said probably not. @trevnorris did benchmarks and they weren’t too bad. + +`module.root` for fat packages? With .mjs it wasn’t needed, people would include .js and .mjs files; but with new proposal it is needed. However `module.root` isn’t foolproof because people could use it for general redirection/hiding of package internals instead of only for ES6 modules. + +@rvagg: Let’s slate for vote on Wednesday 7/6, those who are unavailable can vote in the issues. + +## Q/A on public fora + +None. + +## Next Meeting + +* AsyncWrap public API proposal [node-eps#18](https://github.com/nodejs/node-eps/pull/18) +* replace section 5.1 with unambiguous JavaScript grammar. +[node-eps#33](https://github.com/nodejs/node-eps/pull/33) + +CTC: 2016-07-06 From fd9b7b4c5ac8ae2e9363154d0f5333222eb28f10 Mon Sep 17 00:00:00 2001 From: Josh Gavant Date: Wed, 6 Jul 2016 14:01:36 -0700 Subject: [PATCH 050/144] doc: add CTC meeting minutes 2016-07-06 PR-URL: https://github.com/nodejs/node/pull/7570 Reviewed-By: James M Snell Reviewed-By: Evan Lucas --- doc/ctc-meetings/2016-07-06.md | 150 +++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 doc/ctc-meetings/2016-07-06.md diff --git a/doc/ctc-meetings/2016-07-06.md b/doc/ctc-meetings/2016-07-06.md new file mode 100644 index 00000000000000..232b83b9c7d6bf --- /dev/null +++ b/doc/ctc-meetings/2016-07-06.md @@ -0,0 +1,150 @@ +# Node Foundation CTC Meeting 2016-07-06 + +## Links + +* **Audio Recording**: TBP +* **GitHub Issue**: https://github.com/nodejs/node/issues/7558 +* **Minutes Google Doc**: +* _Previous Minutes Google Doc: _ + +## Present + +* Сковорода Никита Андреевич @ChALkeR (CTC) +* Colin Ihrig @cjihrig (CTC) +* Evan Lucas @evanlucas (CTC) +* Jeremiah Senkpiel @Fishrock123 (CTC) +* James Snell @jasnell (CTC) +* John-David Dalton @jdalton (observer/Microsoft) +* Josh Gavant @joshgav (observer/Microsoft) +* Michael Dawson @mhdawson (CTC) +* Brian White @mscdex (CTC) +* Alexis Campailla @orangemocha (CTC) +* Shigeki Ohtsu @shigeki (CTC) +* Trevor Norris @trevnorris (CTC) +* Rich Trott @Trott (CTC) + +## Standup + +* Сковорода Никита Андреевич @ChALkeR (CTC) + * Nothing significant. +* Colin Ihrig @cjihrig (CTC) + * Reviewed issues. Reviewed pull requests. Opened a couple PRs +* Evan Lucas @evanlucas (CTC) + * Commented on a few issues, not much else +* Jeremiah Senkpiel @Fishrock123 (CTC) + * v6.3.0 Release, most difficult to date, lots of merge conflicts. + * Various PR / Issue review +* John-David Dalton @jdalton (observer/Microsoft) + * Another round of questions with Chakra dev about Unambiguous JS Grammar confirming difficulty level of API is not significant + * Updated Unambiguous JS Grammar based on feedback +* Josh Gavant @joshgav (observer/Microsoft) + * Out for July 4th holiday. +* Michael Dawson @mhdawson (CTC) + * Added linuxOne to regression tests/watched for issues, all looks good, next step is to add to nightly releases + * Chasing down AIX build breaks test failures + * Continued work on ABI stable module API and scheduling of next WG meeting + * misc PR/Issue reviews/pull requests + * post-mortem work and scheduling of next meeting + * small update to benchmark graphs + * keeping up to date with issues +* Brian White @mscdex (CTC) + * Started the process of rebasing the old js http parser onto master to see how it compares to the current http implementation + * Reviewed PRs, commented on issues +* Alexis Campailla @orangemocha (CTC) + * Nothing to report (was out on vacation) +* Shigeki Ohtsu @shigeki (CTC) + * Reviewed only one PR for crypto doc +* Trevor Norris @trevnorris (CTC) + * Updated AsyncWrap EP + * fs.realpath() deep symlink PR +* Rich Trott @Trott (CTC) + * Onboarded @bzoz + * Fixing test-net-write-slow on FreeBSD (PR #7555) +* James M Snell @jasnell (CTC) + * WHATWG http implementation + * Closing up other business before going on vacation for a week + +## Agenda + +Extracted from **ctc-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. + +### nodejs/node + +* build: drop support for VS 2013 in v7 [#7484](https://github.com/nodejs/node/issues/7484) +* Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/issues/7175) + +### nodejs/node-eps + +* Replace section 5.1 with unambiguous JavaScript grammar. [#33](https://github.com/nodejs/node-eps/pull/33) +* AsyncWrap public API proposal [#18](https://github.com/nodejs/node-eps/pull/18) + +## Previous Meeting + +* New Buffer API backport to v4.x [#7475](https://github.com/nodejs/node/pull/7475) + + * New PR: https://github.com/nodejs/node/pull/7562 + +* child_process: validate fork/execFile arguments [#7399](https://github.com/nodejs/node/pull/7399) +* Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/issues/7175) +* repl: Default `useGlobal` to false in CLI REPL. [#5703](https://github.com/nodejs/node/pull/5703) +* Seek legal advice on LICENSE and copyright blocks in code [#3979](https://github.com/nodejs/node/issues/3979) +* Mention odd-number release has eight months support as Current. [#113](https://github.com/nodejs/LTS/issues/113) +* AsyncWrap public API proposal [#18](https://github.com/nodejs/node-eps/pull/18) + +## Minutes + +### build: drop support for VS 2013 in v7 [#7484](https://github.com/nodejs/node/issues/7484) (@jasnell) + +Consider v6 and v7 separately. All agree on moving to VS 2015 for v7. Only question is v6 prior to LTS. We need more info to make decision on v6. + +If we stay with 2013 for v6 we’ll have to support it for the entire lifetime of v6 LTS. But it needs to still be possible to build native addons with 2013. + +@jasnell - Our recommendation is to build native addons with VS 2015 unless it doesn’t work (e.g. in [node-sass#1283](https://github.com/sass/node-sass/issues/1283). + +@orangemocha - No problem building `node.exe` with VS 2015 in v7. But dropping support for 2013 would break some modules (breaking change) due to ABI incompatibilities, so it might not be appropriate for v6. Need more time to assess impact. + +### Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/issues/7175) + +@trevnorris - fix is working, test in development. Comment further in the PR. + +### Replace section 5.1 with unambiguous JavaScript grammar. [#33](https://github.com/nodejs/node-eps/pull/33) + +@jdalton added line stating explicitly that the .mjs proposal is still possible. + +Vote taken in favor of merging this PR. Alexis officially abstained. + +### AsyncWrap public API proposal [#18](https://github.com/nodejs/node-eps/pull/18) + +See also [#7565](https://github.com/nodejs/node/issues/7565), which questions whether AsyncWrap should exist (from @bnoordhuis). + +@jasnell - Error handling should be addressed. + +@trott - A vote for the EP means “*if* we implement, this is what the JavaScript API will look like” and not necessarily “we intend to implement this.” + +@trevnorris - Correct. Confirm the API, then more work is needed on implementation, e.g. to include info on promises. + +@trevnorris - biggest missing chunk is public C++ API. Trouble is that it requires exposing some things which are not currently in public headers. + +@trevnorris - Goal is to include this as experimental in v6 before LTS. But still waiting on additional hooks into promises from V8. + +@Fishrock123 - AsyncWrap is best bet for CLS across async activities, replaces deprecated domains. + +Vote: 7-8 ayes, 0 opposed, 0 abstentions. + + +## Q/A on public fora + +None. + +## Next Meeting + +* Move to VS 2015 for release build in v6? Is this a breaking change? + +## Upcoming TLP & WG Meetings + +* CTC: 2016-07-13 +* TSC: 2016-07-14 +* Diagnostics: 2016-07-13 +* Post-Mortem: [nodejs/post-mortem#31](https://github.com/nodejs/post-mortem/issues/31) +* LTS: +* Build: From 0094adc0b23c7c07a080f374612fc408d436db29 Mon Sep 17 00:00:00 2001 From: Josh Gavant Date: Thu, 23 Jun 2016 11:02:18 -0700 Subject: [PATCH 051/144] doc: add CTC meeting minutes 2016-06-22 closes #7366 PR-URL: https://github.com/nodejs/node/pull/7390 Reviewed-By: Bradley Farias Reviewed-By: Rod Vagg Reviewed-By: James M Snell --- doc/ctc-meetings/2016-06-22.md | 151 +++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 doc/ctc-meetings/2016-06-22.md diff --git a/doc/ctc-meetings/2016-06-22.md b/doc/ctc-meetings/2016-06-22.md new file mode 100644 index 00000000000000..9e87b13b539fb3 --- /dev/null +++ b/doc/ctc-meetings/2016-06-22.md @@ -0,0 +1,151 @@ +# Node Foundation CTC Meeting 2016-06-22 + +## Links + +* **Audio Recording**: TBP +* **GitHub Issue**: https://github.com/nodejs/node/issues/7366 +* **Minutes Google Doc**: +* _Previous Minutes Google Doc: _ + +## Present + +* Bradley Meck @bmeck (observer/GoDaddy/TC39) +* Chris Dickinson @chrisdickinson (CTC) +* Evan Lucas @evanlucas (CTC) +* James M Snell @jasnell (CTC) +* John-David Dalton @jdalton (observer/Lodash/Microsoft) +* Yuval Brik @jhamhader (observer) +* Josh Gavant @joshgav (observer/Microsoft) +* Michael Dawson @mhdawson (CTC) +* Brian White @mscdex (CTC) +* Ali Ijaz Sheikh @ofrobots (CTC) +* Shigeki Ohtsu @shigeki (CTC) +* Steven R. Loomis @srl295 (observer/IBM/ICU) +* Trevor Norris @trevnorris (CTC) +* Rich Trott @Trott (CTC) + +## Agenda + +Extracted from **ctc-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. + +### nodejs/node + +* Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/issues/7175) + +## Standup + +* Bradley Meck @bmeck (observer/GoDaddy/TC39) + * Need for APM / JIT Cache hooks investigation + * Investigation into VM support for V8 and ES Modules +* Chris Dickinson @chrisdickinson (CTC) + * Keeping track of ES Modules proposals + * tooling gn to be npm installable +* Evan Lucas @evanlucas (CTC) + * working on security fixes + * looking for ways to streamline landing commits +* James M Snell @jasnell (CTC) + * Vacation last week (worked on an experimental http/2 impl) + * Working on WHATWG URL implementation + * Various other performance related and doc PRs + * And a heads up.. Will be on vacation again the 2nd and 3rd weeks of July. +* John-David Dalton @jdalton (observer/Lodash/Microsoft) + * Retooled proposal to simplify it and make it more generic so it will work with things other than just script and module + * Babel now supports export {} and therefore supports Unambiguous Modules proposal + * Pinged some v8 devs to ask about impact there + * Met with TypeScript folks too to discuss things that are a bit out of the scope of Unambiguous JavaScript but still modules + * Initial round of feedback on Unambiguous JavaScript. Will be in JavaScript Weekly tomorrow. +* Josh Gavant @joshgav (observer/Microsoft) + * hacking on inspector and tracing stuff + * es6 modules a bit + * monitoring issues, PRs, etc. +* Michael Dawson @mhdawson (CTC) + * Chasing PPC machine issues + * Chasing new AIX machines (expect this month) + * Contributing to ABI stable module API PoC (NaN examples 1-8 now work) + * Misc reviews/commenting + * misc PRs/lands + * Keeping up with issues +* Brian White @mscdex (CTC) + * Reviewing PRs/issues +* Shigeki Ohtsu @shigeki (CTC) + * Reviewing just one PR for root cert update. +* Steven R. Loomis @srl295 (observer/IBM/ICU) + * helping @jasnell (a little) with https://github.com/nodejs/node/pull/7355 +* Trevor Norris @trevnorris (CTC) + * Additional work on the AsyncWrap EP + * Misc PR reviews +* Rich Trott @Trott (CTC) + * CO: Continuous Onboarding (welcome @RReverser!) + * CI: Investigating and fixing flaky tests as time allows +* Ali Ijaz Sheikh @ofrobots(CTC) + * Working on FFI, and other miscellaneous things. + + +## Minutes + +### Review of last meeting + +* url: return valid file: urls fom url.format() [#7234](https://github.com/nodejs/node/pull/7234) +* http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) +* ES6 Modules + +### fs.realpath + +- https://github.com/nodejs/node/issues/7175 +- https://github.com/nodejs/CTC/issues/9 +- https://github.com/nodejs/node/issues/7192 +- https://github.com/nodejs/node/issues/7044 +- https://github.com/nodejs/node/issues/7294 + +When we made changes to rely on libuv realpath it was a semver-major change which introduced new errors and removed `cache` argument. This broke some ecosystem modules, notably `glob`. Also broke some path-related stuff in Windows. + +We chose libuv realpath because it’s much more performant. + +Options: +- Revert to old behavior. Would lose perf gains. Would be semver-major change. +- Add new method e.g. `realpath2` which uses old behavior. +- **Keep new behavior and add logic in Node to handle new/unexpected errors.** + +@jasnell - We did a semver-major revert for the symlink issue.
+@trevnorris - No need to revert, just handle the errors.
+@jasnell - Do we really know what the errors are so we can be sure we’re handling all of them?
+@trevnorris - we can compare to old impl.
+@jasnell - Add an option to the options object to suppress errors, turn on by default.
+ +**@trevnorris will work on option 3.** + +Post-mortem: https://github.com/nodejs/CTC/issues/9 +- Postpone till Rod is present. +- @jasnell - We didn’t follow typical deprecation path for `cache` parameter change. + + +### ES6 modules + +- https://github.com/bmeck/UnambiguousJavaScriptGrammar + +- Any code with `import` or `export` is a module, otherwise a script. +- `modules.root` aspect removed, so “fat packages” (i.e. incl. both ES6 and CJS) are not addressed. Recommendation is to use one or the other and transpile as needed. Or discuss `modules.root` separately. +- Users can explicitly specify module goal in package.json. This way even if dev removes all `import/export` from their code it’s still treated as a module. +- TC39 could provide a “recommendation” or endorsement supporting this. They may suggest a spec extension. + +@bradleymeck - still need modules.root for fat packages. + +What about bytecode caching? Provide hooks to allow user to handle as desired. That means caching is in userland. Might split this into separate proposal. + +@trevnorris analyzed perf hit of double parsing and found max 25% perf hit. + +In-band detection (from the code itself) is preferable to out-of-band detections (e.g. package.json, file extension). + +CJS and ES6 semantic interoperability: Bradley is working on this, working with WHATWG Loader spec and V8. +- `this` value +- live bindings for getters (get updated values) (?) +- immutability - hooks for APM providers to wrap original functions. To be handled by WHATWG Loader spec. + +**@jdalton - How do we finalize consensus on this?** +- **PR to change [node-eps:/002-es6-modules.md](https://github.com/nodejs/node-eps/blob/master/002-es6-modules.md)** + +### Q/A on public fora +None. + +### Next Meeting +2016-06-29 From a4f0b13e2bfb078dc5ab72061e6c004239903744 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 22 Jul 2016 12:05:27 -0400 Subject: [PATCH 052/144] cluster: support stdio option for workers This commit allows setupMaster() to configure the stdio channels for worker processes. Refs: https://github.com/nodejs/node-v0.x-archive/issues/5727 Refs: https://github.com/nodejs/node/pull/7811 PR-URL: https://github.com/nodejs/node/pull/7838 Reviewed-By: Santiago Gimeno Reviewed-By: James M Snell --- doc/api/cluster.md | 5 +++ lib/cluster.js | 1 + test/parallel/test-cluster-fork-stdio.js | 40 ++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 test/parallel/test-cluster-fork-stdio.js diff --git a/doc/api/cluster.md b/doc/api/cluster.md index 6f0b424e05e083..616be9b59afd14 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -626,6 +626,9 @@ values are `"rr"` and `"none"`. (Default=`process.argv.slice(2)`) * `silent` {Boolean} whether or not to send output to parent's stdio. (Default=`false`) + * `stdio` {Array} Configures the stdio of forked processes. Because the + cluster module relies on IPC to function, this configuration must contain an + `'ipc'` entry. When this option is provided, it overrides `silent`. * `uid` {Number} Sets the user identity of the process. (See setuid(2).) * `gid` {Number} Sets the group identity of the process. (See setgid(2).) @@ -642,6 +645,8 @@ This object is not supposed to be changed or set manually, by you. (Default=`process.argv.slice(2)`) * `silent` {Boolean} whether or not to send output to parent's stdio. (Default=`false`) + * `stdio` {Array} Configures the stdio of forked processes. When this option + is provided, it overrides `silent`. `setupMaster` is used to change the default 'fork' behavior. Once called, the settings will be present in `cluster.settings`. diff --git a/lib/cluster.js b/lib/cluster.js index 5396573c3597a4..ffa0b339ae95ee 100644 --- a/lib/cluster.js +++ b/lib/cluster.js @@ -321,6 +321,7 @@ function masterInit() { env: workerEnv, silent: cluster.settings.silent, execArgv: execArgv, + stdio: cluster.settings.stdio, gid: cluster.settings.gid, uid: cluster.settings.uid }); diff --git a/test/parallel/test-cluster-fork-stdio.js b/test/parallel/test-cluster-fork-stdio.js new file mode 100644 index 00000000000000..1d00e0768e5746 --- /dev/null +++ b/test/parallel/test-cluster-fork-stdio.js @@ -0,0 +1,40 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cluster = require('cluster'); +const net = require('net'); + +if (cluster.isMaster) { + const buf = Buffer.from('foobar'); + + cluster.setupMaster({ + stdio: ['pipe', 'pipe', 'pipe', 'ipc', 'pipe'] + }); + + const worker = cluster.fork(); + const channel = worker.process.stdio[4]; + let response = ''; + + worker.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + })); + + channel.setEncoding('utf8'); + channel.on('data', (data) => { + response += data; + + if (response === buf.toString()) { + worker.disconnect(); + } + }); + channel.write(buf); +} else { + const pipe = new net.Socket({ fd: 4 }); + + pipe.unref(); + pipe.on('data', (data) => { + assert.ok(data instanceof Buffer); + pipe.write(data); + }); +} From 0a07201ca1e637f021d22c06e00e193193eaa3d5 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 25 Jul 2016 09:06:26 +0200 Subject: [PATCH 053/144] util: fix formatting of objects with SIMD enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When SIMD is enabled, `util.format` couldn’t display objects (with at least 1 key) because the formatter function got overridden. PR-URL: https://github.com/nodejs/node/pull/7864 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Michaël Zasso --- lib/util.js | 10 ++++++---- test/parallel/test-util-format.js | 2 ++ test/parallel/test-util-inspect-simd.js | 9 +++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/util.js b/lib/util.js index bb588cf475e236..93313d443f4d05 100644 --- a/lib/util.js +++ b/lib/util.js @@ -487,16 +487,13 @@ function formatValue(ctx, value, recurseTimes) { 'byteOffset', 'buffer'); } - } else if (simdFormatters && - typeof value.constructor === 'function' && - (formatter = simdFormatters.get(value.constructor))) { - braces = ['[', ']']; } else { var promiseInternals = inspectPromise(value); if (promiseInternals) { braces = ['{', '}']; formatter = formatPromise; } else { + let maybeSimdFormatter; if (binding.isMapIterator(value)) { constructor = { name: 'MapIterator' }; braces = ['{', '}']; @@ -507,6 +504,11 @@ function formatValue(ctx, value, recurseTimes) { braces = ['{', '}']; empty = false; formatter = formatCollectionIterator; + } else if (simdFormatters && + typeof constructor === 'function' && + (maybeSimdFormatter = simdFormatters.get(constructor))) { + braces = ['[', ']']; + formatter = maybeSimdFormatter; } else { // Unset the constructor to prevent "Object {...}" for ordinary objects. if (constructor && constructor.name === 'Object') diff --git a/test/parallel/test-util-format.js b/test/parallel/test-util-format.js index f3702ef2f05547..b8977e57b5139c 100644 --- a/test/parallel/test-util-format.js +++ b/test/parallel/test-util-format.js @@ -7,7 +7,9 @@ const symbol = Symbol('foo'); assert.equal(util.format(), ''); assert.equal(util.format(''), ''); assert.equal(util.format([]), '[]'); +assert.equal(util.format([0]), '[ 0 ]'); assert.equal(util.format({}), '{}'); +assert.equal(util.format({foo: 42}), '{ foo: 42 }'); assert.equal(util.format(null), 'null'); assert.equal(util.format(true), 'true'); assert.equal(util.format(false), 'false'); diff --git a/test/parallel/test-util-inspect-simd.js b/test/parallel/test-util-inspect-simd.js index 752ea3d0ce677c..ec4ccc1875a817 100644 --- a/test/parallel/test-util-inspect-simd.js +++ b/test/parallel/test-util-inspect-simd.js @@ -59,3 +59,12 @@ if (typeof SIMD.Uint8x16 === 'function') { inspect(SIMD.Uint8x16()), 'Uint8x16 [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]'); } + +// Tests from test-inspect.js that should not fail with --harmony_simd. +assert.strictEqual(inspect([]), '[]'); +assert.strictEqual(inspect([0]), '[ 0 ]'); +assert.strictEqual(inspect({}), '{}'); +assert.strictEqual(inspect({foo: 42}), '{ foo: 42 }'); +assert.strictEqual(inspect(null), 'null'); +assert.strictEqual(inspect(true), 'true'); +assert.strictEqual(inspect(false), 'false'); From d94063a22bbd70692e0ed8e9016874a645917dd3 Mon Sep 17 00:00:00 2001 From: Santiago Gimeno Date: Sat, 23 Jul 2016 20:40:11 +0200 Subject: [PATCH 054/144] test: fix test-vm-sigint flakiness Set the `SIGUSR2` handler before spawning the child process to make sure the signal is always handled. Fixes: https://github.com/nodejs/node/issues/7767 PR-URL: https://github.com/nodejs/node/pull/7854 Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- test/parallel/test-vm-sigint.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/parallel/test-vm-sigint.js b/test/parallel/test-vm-sigint.js index 2488b0d1c028f6..15d61d3232871a 100644 --- a/test/parallel/test-vm-sigint.js +++ b/test/parallel/test-vm-sigint.js @@ -25,14 +25,14 @@ if (process.argv[2] === 'child') { } process.env.REPL_TEST_PPID = process.pid; -const child = spawn(process.execPath, [ __filename, 'child' ], { - stdio: [null, 'pipe', 'inherit'] -}); - process.on('SIGUSR2', common.mustCall(() => { process.kill(child.pid, 'SIGINT'); })); +const child = spawn(process.execPath, [ __filename, 'child' ], { + stdio: [null, 'pipe', 'inherit'] +}); + child.on('close', common.mustCall((code, signal) => { assert.strictEqual(signal, null); assert.strictEqual(code, 0); From 02b12fe880121841190bcae3c5a8095f9222e419 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 29 Jul 2016 21:41:10 -0700 Subject: [PATCH 055/144] test: improve chained property readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new version of ESLint flags chained properties on multiple lines that were not flagged by the previous version of ESLint. In preparation for turning that feature on, adjust alignment to that expected by the linter. This change happened to be predominantly around assertions using `assert()` and `assert.equal()`. These were changed to `assert.strictEqual()` where possible. PR-URL: https://github.com/nodejs/node/pull/7920 Reviewed-By: Michaël Zasso Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Conflicts: test/parallel/test-readline-interface.js --- test/parallel/test-buffer-includes.js | 80 +++++++---- test/parallel/test-buffer-indexof.js | 128 +++++++++++------- .../test-cluster-worker-forced-exit.js | 20 ++- test/parallel/test-crypto-binary-default.js | 24 ++-- test/parallel/test-crypto-hmac.js | 24 ++-- ...-connections-close-makes-more-available.js | 12 +- test/parallel/test-readline-interface.js | 24 ++-- 7 files changed, 188 insertions(+), 124 deletions(-) diff --git a/test/parallel/test-buffer-includes.js b/test/parallel/test-buffer-includes.js index fe8f4fa69aa8e7..22ba1e6b7e1735 100644 --- a/test/parallel/test-buffer-includes.js +++ b/test/parallel/test-buffer-includes.js @@ -79,44 +79,64 @@ assert(!b.includes(Buffer.from('f'), 6)); assert(!Buffer.from('ff').includes(Buffer.from('f'), 1, 'ucs2')); // test hex encoding -assert( - Buffer.from(b.toString('hex'), 'hex') - .includes('64', 0, 'hex')); -assert( - Buffer.from(b.toString('hex'), 'hex') - .includes(Buffer.from('64', 'hex'), 0, 'hex')); +assert.strictEqual( + Buffer.from(b.toString('hex'), 'hex') + .includes('64', 0, 'hex'), + true +); +assert.strictEqual( + Buffer.from(b.toString('hex'), 'hex') + .includes(Buffer.from('64', 'hex'), 0, 'hex'), + true +); // test base64 encoding -assert( - Buffer.from(b.toString('base64'), 'base64') - .includes('ZA==', 0, 'base64')); -assert( - Buffer.from(b.toString('base64'), 'base64') - .includes(Buffer.from('ZA==', 'base64'), 0, 'base64')); +assert.strictEqual( + Buffer.from(b.toString('base64'), 'base64') + .includes('ZA==', 0, 'base64'), + true +); +assert.strictEqual( + Buffer.from(b.toString('base64'), 'base64') + .includes(Buffer.from('ZA==', 'base64'), 0, 'base64'), + true +); // test ascii encoding -assert( - Buffer.from(b.toString('ascii'), 'ascii') - .includes('d', 0, 'ascii')); -assert( - Buffer.from(b.toString('ascii'), 'ascii') - .includes(Buffer.from('d', 'ascii'), 0, 'ascii')); +assert.strictEqual( + Buffer.from(b.toString('ascii'), 'ascii') + .includes('d', 0, 'ascii'), + true +); +assert.strictEqual( + Buffer.from(b.toString('ascii'), 'ascii') + .includes(Buffer.from('d', 'ascii'), 0, 'ascii'), + true +); // test latin1 encoding -assert( - Buffer.from(b.toString('latin1'), 'latin1') - .includes('d', 0, 'latin1')); -assert( - Buffer.from(b.toString('latin1'), 'latin1') - .includes(Buffer.from('d', 'latin1'), 0, 'latin1')); +assert.strictEqual( + Buffer.from(b.toString('latin1'), 'latin1') + .includes('d', 0, 'latin1'), + true +); +assert.strictEqual( + Buffer.from(b.toString('latin1'), 'latin1') + .includes(Buffer.from('d', 'latin1'), 0, 'latin1'), + true +); // test binary encoding -assert( - Buffer.from(b.toString('binary'), 'binary') - .includes('d', 0, 'binary')); -assert( - Buffer.from(b.toString('binary'), 'binary') - .includes(Buffer.from('d', 'binary'), 0, 'binary')); +assert.strictEqual( + Buffer.from(b.toString('binary'), 'binary') + .includes('d', 0, 'binary'), + true +); +assert.strictEqual( + Buffer.from(b.toString('binary'), 'binary') + .includes(Buffer.from('d', 'binary'), 0, 'binary'), + true +); // test usc2 encoding diff --git a/test/parallel/test-buffer-indexof.js b/test/parallel/test-buffer-indexof.js index 59e969c315ec65..d7598d8b75cbf1 100644 --- a/test/parallel/test-buffer-indexof.js +++ b/test/parallel/test-buffer-indexof.js @@ -79,62 +79,94 @@ assert.equal(b.indexOf(Buffer.from('f'), 6), -1); assert.equal(Buffer.from('ff').indexOf(Buffer.from('f'), 1, 'ucs2'), -1); // test hex encoding -assert.equal( - Buffer.from(b.toString('hex'), 'hex') - .indexOf('64', 0, 'hex'), 3); -assert.equal( - Buffer.from(b.toString('hex'), 'hex') - .indexOf(Buffer.from('64', 'hex'), 0, 'hex'), 3); +assert.strictEqual( + Buffer.from(b.toString('hex'), 'hex') + .indexOf('64', 0, 'hex'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('hex'), 'hex') + .indexOf(Buffer.from('64', 'hex'), 0, 'hex'), + 3 +); // test base64 encoding -assert.equal( - Buffer.from(b.toString('base64'), 'base64') - .indexOf('ZA==', 0, 'base64'), 3); -assert.equal( - Buffer.from(b.toString('base64'), 'base64') - .indexOf(Buffer.from('ZA==', 'base64'), 0, 'base64'), 3); +assert.strictEqual( + Buffer.from(b.toString('base64'), 'base64') + .indexOf('ZA==', 0, 'base64'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('base64'), 'base64') + .indexOf(Buffer.from('ZA==', 'base64'), 0, 'base64'), + 3 +); // test ascii encoding -assert.equal( - Buffer.from(b.toString('ascii'), 'ascii') - .indexOf('d', 0, 'ascii'), 3); -assert.equal( - Buffer.from(b.toString('ascii'), 'ascii') - .indexOf(Buffer.from('d', 'ascii'), 0, 'ascii'), 3); +assert.strictEqual( + Buffer.from(b.toString('ascii'), 'ascii') + .indexOf('d', 0, 'ascii'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('ascii'), 'ascii') + .indexOf(Buffer.from('d', 'ascii'), 0, 'ascii'), + 3 +); // test latin1 encoding -assert.equal( - Buffer.from(b.toString('latin1'), 'latin1') - .indexOf('d', 0, 'latin1'), 3); -assert.equal( - Buffer.from(b.toString('latin1'), 'latin1') - .indexOf(Buffer.from('d', 'latin1'), 0, 'latin1'), 3); -assert.equal( - Buffer.from('aa\u00e8aa', 'latin1') - .indexOf('\u00e8', 'latin1'), 2); -assert.equal( - Buffer.from('\u00e8', 'latin1') - .indexOf('\u00e8', 'latin1'), 0); -assert.equal( - Buffer.from('\u00e8', 'latin1') - .indexOf(Buffer.from('\u00e8', 'latin1'), 'latin1'), 0); +assert.strictEqual( + Buffer.from(b.toString('latin1'), 'latin1') + .indexOf('d', 0, 'latin1'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('latin1'), 'latin1') + .indexOf(Buffer.from('d', 'latin1'), 0, 'latin1'), + 3 +); +assert.strictEqual( + Buffer.from('aa\u00e8aa', 'latin1') + .indexOf('\u00e8', 'latin1'), + 2 +); +assert.strictEqual( + Buffer.from('\u00e8', 'latin1') + .indexOf('\u00e8', 'latin1'), + 0 +); +assert.strictEqual( + Buffer.from('\u00e8', 'latin1') + .indexOf(Buffer.from('\u00e8', 'latin1'), 'latin1'), + 0 +); // test binary encoding -assert.equal( - Buffer.from(b.toString('binary'), 'binary') - .indexOf('d', 0, 'binary'), 3); -assert.equal( - Buffer.from(b.toString('binary'), 'binary') - .indexOf(Buffer.from('d', 'binary'), 0, 'binary'), 3); -assert.equal( - Buffer.from('aa\u00e8aa', 'binary') - .indexOf('\u00e8', 'binary'), 2); -assert.equal( - Buffer.from('\u00e8', 'binary') - .indexOf('\u00e8', 'binary'), 0); -assert.equal( - Buffer.from('\u00e8', 'binary') - .indexOf(Buffer.from('\u00e8', 'binary'), 'binary'), 0); +assert.strictEqual( + Buffer.from(b.toString('binary'), 'binary') + .indexOf('d', 0, 'binary'), + 3 +); +assert.strictEqual( + Buffer.from(b.toString('binary'), 'binary') + .indexOf(Buffer.from('d', 'binary'), 0, 'binary'), + 3 +); +assert.strictEqual( + Buffer.from('aa\u00e8aa', 'binary') + .indexOf('\u00e8', 'binary'), + 2 +); +assert.strictEqual( + Buffer.from('\u00e8', 'binary') + .indexOf('\u00e8', 'binary'), + 0 +); +assert.strictEqual( + Buffer.from('\u00e8', 'binary') + .indexOf(Buffer.from('\u00e8', 'binary'), 'binary'), + 0 +); // test optional offset with passed encoding diff --git a/test/parallel/test-cluster-worker-forced-exit.js b/test/parallel/test-cluster-worker-forced-exit.js index 0592cbfd01ac69..3e1f7905ee50d1 100644 --- a/test/parallel/test-cluster-worker-forced-exit.js +++ b/test/parallel/test-cluster-worker-forced-exit.js @@ -29,20 +29,16 @@ checkForced(); function checkUnforced() { cluster.fork() - .on('online', function() { - this.disconnect(); - }) - .on('exit', common.mustCall(function(status) { - assert.equal(status, SENTINEL); - })); + .on('online', function() { this.disconnect(); }) + .on('exit', common.mustCall(function(status) { + assert.strictEqual(status, SENTINEL); + })); } function checkForced() { cluster.fork() - .on('online', function() { - this.process.disconnect(); - }) - .on('exit', common.mustCall(function(status) { - assert.equal(status, 0); - })); + .on('online', function() { this.process.disconnect(); }) + .on('exit', common.mustCall(function(status) { + assert.strictEqual(status, 0); + })); } diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js index e163c9e4cd65ab..3b3603157786de 100644 --- a/test/parallel/test-crypto-binary-default.js +++ b/test/parallel/test-crypto-binary-default.js @@ -324,19 +324,23 @@ var rfc2202_sha1 = [ for (let i = 0, l = rfc2202_md5.length; i < l; i++) { if (!common.hasFipsCrypto) { - assert.equal(rfc2202_md5[i]['hmac'], - crypto.createHmac('md5', rfc2202_md5[i]['key']) - .update(rfc2202_md5[i]['data']) - .digest('hex'), - 'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202'); + assert.strictEqual( + rfc2202_md5[i]['hmac'], + crypto.createHmac('md5', rfc2202_md5[i]['key']) + .update(rfc2202_md5[i]['data']) + .digest('hex'), + 'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202' + ); } } for (let i = 0, l = rfc2202_sha1.length; i < l; i++) { - assert.equal(rfc2202_sha1[i]['hmac'], - crypto.createHmac('sha1', rfc2202_sha1[i]['key']) - .update(rfc2202_sha1[i]['data']) - .digest('hex'), - 'Test HMAC-SHA1 : Test case ' + (i + 1) + ' rfc 2202'); + assert.strictEqual( + rfc2202_sha1[i]['hmac'], + crypto.createHmac('sha1', rfc2202_sha1[i]['key']) + .update(rfc2202_sha1[i]['data']) + .digest('hex'), + 'Test HMAC-SHA1 : Test case ' + (i + 1) + ' rfc 2202' + ); } // Test hashing diff --git a/test/parallel/test-crypto-hmac.js b/test/parallel/test-crypto-hmac.js index f377d91fd88780..8c2236e6b2ae1f 100644 --- a/test/parallel/test-crypto-hmac.js +++ b/test/parallel/test-crypto-hmac.js @@ -351,17 +351,21 @@ var rfc2202_sha1 = [ if (!common.hasFipsCrypto) { for (let i = 0, l = rfc2202_md5.length; i < l; i++) { - assert.equal(rfc2202_md5[i]['hmac'], - crypto.createHmac('md5', rfc2202_md5[i]['key']) - .update(rfc2202_md5[i]['data']) - .digest('hex'), - 'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202'); + assert.strictEqual( + rfc2202_md5[i]['hmac'], + crypto.createHmac('md5', rfc2202_md5[i]['key']) + .update(rfc2202_md5[i]['data']) + .digest('hex'), + 'Test HMAC-MD5 : Test case ' + (i + 1) + ' rfc 2202' + ); } } for (let i = 0, l = rfc2202_sha1.length; i < l; i++) { - assert.equal(rfc2202_sha1[i]['hmac'], - crypto.createHmac('sha1', rfc2202_sha1[i]['key']) - .update(rfc2202_sha1[i]['data']) - .digest('hex'), - 'Test HMAC-SHA1 : Test case ' + (i + 1) + ' rfc 2202'); + assert.strictEqual( + rfc2202_sha1[i]['hmac'], + crypto.createHmac('sha1', rfc2202_sha1[i]['key']) + .update(rfc2202_sha1[i]['data']) + .digest('hex'), + 'Test HMAC-SHA1 : Test case ' + (i + 1) + ' rfc 2202' + ); } diff --git a/test/parallel/test-net-server-max-connections-close-makes-more-available.js b/test/parallel/test-net-server-max-connections-close-makes-more-available.js index 2f8bee1a8d68d9..fb9831d05b3e50 100644 --- a/test/parallel/test-net-server-max-connections-close-makes-more-available.js +++ b/test/parallel/test-net-server-max-connections-close-makes-more-available.js @@ -69,12 +69,12 @@ server.maxConnections = 1; server.listen(0, function() { createConnection(0) - .then(createConnection.bind(null, 1)) - .then(closeConnection.bind(null, 0)) - .then(createConnection.bind(null, 2)) - .then(createConnection.bind(null, 3)) - .then(server.close.bind(server)) - .then(closeConnection.bind(null, 2)); + .then(createConnection.bind(null, 1)) + .then(closeConnection.bind(null, 0)) + .then(createConnection.bind(null, 2)) + .then(createConnection.bind(null, 3)) + .then(server.close.bind(server)) + .then(closeConnection.bind(null, 2)); }); process.on('exit', function() { diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index 603d08aa7aa130..aa0d6925abb7f1 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -350,14 +350,22 @@ function isWarned(emitter) { assert.equal(readline.getStringWidth('A\ud83c\ude00BC'), 5); // surrogate // check if vt control chars are stripped - assert.equal(readline - .stripVTControlCharacters('\u001b[31m> \u001b[39m'), '> '); - assert.equal(readline - .stripVTControlCharacters('\u001b[31m> \u001b[39m> '), '> > '); - assert.equal(readline - .stripVTControlCharacters('\u001b[31m\u001b[39m'), ''); - assert.equal(readline - .stripVTControlCharacters('> '), '> '); + assert.strictEqual( + readline.stripVTControlCharacters('\u001b[31m> \u001b[39m'), + '> ' + ); + assert.strictEqual( + readline.stripVTControlCharacters('\u001b[31m> \u001b[39m> '), + '> > ' + ); + assert.strictEqual( + readline.stripVTControlCharacters('\u001b[31m\u001b[39m'), + '' + ); + assert.strictEqual( + readline.stripVTControlCharacters('> '), + '> ' + ); assert.equal(readline.getStringWidth('\u001b[31m> \u001b[39m'), 2); assert.equal(readline.getStringWidth('\u001b[31m> \u001b[39m> '), 4); assert.equal(readline.getStringWidth('\u001b[31m\u001b[39m'), 0); From a4394b87450f1f100ac3b8f5e5f5734b38bd9a20 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 2 Aug 2016 09:34:29 +0200 Subject: [PATCH 056/144] build: fix typo in non-essential source file name Depend on src/inspector_agent.h, src/inspector-agent.h does not exist. The typo didn't break the build but it made some of the gyp-based tooling complain. PR-URL: https://github.com/nodejs/node/pull/7945 Reviewed-By: Colin Ihrig Reviewed-By: Evan Lucas --- node.gyp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node.gyp b/node.gyp index 3ba64986a98bb4..a14aa5813243ba 100644 --- a/node.gyp +++ b/node.gyp @@ -319,7 +319,7 @@ 'src/inspector_agent.cc', 'src/inspector_socket.cc', 'src/inspector_socket.h', - 'src/inspector-agent.h', + 'src/inspector_agent.h', ], 'dependencies': [ 'deps/v8_inspector/platform/v8_inspector/v8_inspector.gyp:v8_inspector_stl', From 889c62fec1967eed9485538048e7695742c1ac50 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 2 Aug 2016 09:38:23 +0200 Subject: [PATCH 057/144] build: fix dependency on missing header file Depend on include/ares_rules.h, src/ares_rules.h does not exist. The typo didn't break the build but it made some of the gyp-based tooling complain. PR-URL: https://github.com/nodejs/node/pull/7945 Reviewed-By: Colin Ihrig Reviewed-By: Evan Lucas --- deps/cares/cares.gyp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/cares/cares.gyp b/deps/cares/cares.gyp index 745e38e33d2d6b..158cef39b514a9 100644 --- a/deps/cares/cares.gyp +++ b/deps/cares/cares.gyp @@ -37,6 +37,7 @@ 'sources': [ 'common.gypi', 'include/ares.h', + 'include/ares_rules.h', 'include/ares_version.h', 'include/nameser.h', 'src/ares_cancel.c', @@ -83,7 +84,6 @@ 'src/ares_process.c', 'src/ares_query.c', 'src/ares__read_line.c', - 'src/ares_rules.h', 'src/ares_search.c', 'src/ares_send.c', 'src/ares_setup.h', From f1c50a8c5e934dab33cb83ff616803b49d8cf248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Tue, 19 Jul 2016 21:46:12 +0100 Subject: [PATCH 058/144] win,msi: fix inclusion of translations Reviewed-By: Bartosz Sosnowski PR-URL: https://github.com/nodejs/node/pull/7798 --- tools/msvs/msi/nodemsi.wixproj | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tools/msvs/msi/nodemsi.wixproj b/tools/msvs/msi/nodemsi.wixproj index d21a3cf2327432..892f19040a32dc 100644 --- a/tools/msvs/msi/nodemsi.wixproj +++ b/tools/msvs/msi/nodemsi.wixproj @@ -54,9 +54,12 @@ - - + + @@ -80,9 +83,11 @@ "$(WixToolPath)\torch.exe" -t language "$(TargetDir)en-US\$(TargetFileName)" "$(TargetDir)de-de\$(TargetFileName)" -out "$(TargetDir)transforms\de-de.mst" "$(WixToolPath)\torch.exe" -t language "$(TargetDir)en-US\$(TargetFileName)" "$(TargetDir)it-it\$(TargetFileName)" -out "$(TargetDir)transforms\it-it.mst" + "$(WixToolPath)\torch.exe" -t language "$(TargetDir)en-US\$(TargetFileName)" "$(TargetDir)zh-cn\$(TargetFileName)" -out "$(TargetDir)transforms\zh-cn.mst" cscript.exe "$(WindowsSDK80Path)bin\$(Platform)\WiSubStg.vbs" "$(TargetDir)en-US\$(TargetFileName)" "$(TargetDir)transforms\de-de.mst" 1031 - cscript.exe "$(WindowsSDK80Path)bin\$(Platform)\WiSubStg.vbs" "$(TargetDir)en-US\$(TargetFileName)" "$(TargetDir)transforms\it-it.mst" 1031 - cscript.exe "$(WindowsSDK80Path)bin\$(Platform)\WiLangId.vbs" "$(TargetDir)en-US\$(TargetFileName)" Package 1033,1031 + cscript.exe "$(WindowsSDK80Path)bin\$(Platform)\WiSubStg.vbs" "$(TargetDir)en-US\$(TargetFileName)" "$(TargetDir)transforms\it-it.mst" 1040 + cscript.exe "$(WindowsSDK80Path)bin\$(Platform)\WiSubStg.vbs" "$(TargetDir)en-US\$(TargetFileName)" "$(TargetDir)transforms\zh-cn.mst" 2052 + cscript.exe "$(WindowsSDK80Path)bin\$(Platform)\WiLangId.vbs" "$(TargetDir)en-US\$(TargetFileName)" Package 1031,1033,1040,2052 --> From 48422c240a2da314b793a92a376e5e3c88a7ad47 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Wed, 3 Aug 2016 23:19:39 +0200 Subject: [PATCH 059/144] doc: add @addaleax to the CTC Voted on and approved at CTC meeting https://github.com/nodejs/node/issues/7948 (2016-08-03). PR-URL: https://github.com/nodejs/node/pull/7966 Reviewed-By: Evan Lucas Reviewed-By: Colin Ihrig Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3aabcbcbed97be..ec0ac14eeec574 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,7 @@ information about the governance of the Node.js project, see ### CTC (Core Technical Committee) +* [addaleax](https://github.com/addaleax) - **Anna Henningsen** <anna@addaleax.net> * [bnoordhuis](https://github.com/bnoordhuis) - **Ben Noordhuis** <info@bnoordhuis.nl> * [ChALkeR](https://github.com/ChALkeR) - **Сковорода Никита Андреевич** <chalkerx@gmail.com> * [chrisdickinson](https://github.com/chrisdickinson) - **Chris Dickinson** <christopher.s.dickinson@gmail.com> @@ -175,7 +176,6 @@ information about the governance of the Node.js project, see ### Collaborators -* [addaleax](https://github.com/addaleax) - **Anna Henningsen** <anna@addaleax.net> * [andrasq](https://github.com/andrasq) - **Andras** <andras@kinvey.com> * [AndreasMadsen](https://github.com/AndreasMadsen) - **Andreas Madsen** <amwebdk@gmail.com> * [bengl](https://github.com/bengl) - **Bryan English** <bryan@bryanenglish.com> From 0fbb83a67b12532d1eafef22f6b33fb3a5379ce5 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Wed, 3 Aug 2016 15:34:39 -0700 Subject: [PATCH 060/144] doc: piscisaureus has stepped-down from the CTC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit piscisaureus has voluntarily stepped-down from the CTC PR-URL: https://github.com/nodejs/node/pull/7969 Reviewed-By: Colin Ihrig Reviewed-By: Anna Henningsen Reviewed-By: Michael Dawson Reviewed-By: Сковорода Никита Андреевич --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ec0ac14eeec574..6562bcdb5c46d8 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,6 @@ information about the governance of the Node.js project, see * [mscdex](https://github.com/mscdex) - **Brian White** <mscdex@mscdex.net> * [ofrobots](https://github.com/ofrobots) - **Ali Ijaz Sheikh** <ofrobots@google.com> * [orangemocha](https://github.com/orangemocha) - **Alexis Campailla** <orangemocha@nodejs.org> -* [piscisaureus](https://github.com/piscisaureus) - **Bert Belder** <bertbelder@gmail.com> * [rvagg](https://github.com/rvagg) - **Rod Vagg** <rod@vagg.org> * [shigeki](https://github.com/shigeki) - **Shigeki Ohtsu** <ohtsu@iij.ad.jp> * [trevnorris](https://github.com/trevnorris) - **Trevor Norris** <trev.norris@gmail.com> @@ -210,6 +209,7 @@ information about the governance of the Node.js project, see * [othiym23](https://github.com/othiym23) - **Forrest L Norvell** <ogd@aoaioxxysz.net> * [petkaantonov](https://github.com/petkaantonov) - **Petka Antonov** <petka_antonov@hotmail.com> * [phillipj](https://github.com/phillipj) - **Phillip Johnsen** <johphi@gmail.com> +* [piscisaureus](https://github.com/piscisaureus) - **Bert Belder** <bertbelder@gmail.com> * [pmq20](https://github.com/pmq20) - **Minqi Pan** <pmq2001@gmail.com> * [princejwesley](https://github.com/princejwesley) - **Prince John Wesley** <princejohnwesley@gmail.com> * [qard](https://github.com/qard) - **Stephen Belanger** <admin@stephenbelanger.com> From c72019b75a6c6c5fdccab32b27df612b02ad48c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BA=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=90=D0=BD=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Thu, 14 Jul 2016 12:44:55 +0300 Subject: [PATCH 061/144] doc: convert tabs to spaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert all instances of tab indentation in *.md files to spaces. This affects only three files. PR-URL: https://github.com/nodejs/node/pull/7727 Reviewed-By: Rich Trott Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- doc/changelogs/CHANGELOG_ARCHIVE.md | 38 ++++++++++++++--------------- doc/changelogs/CHANGELOG_V010.md | 16 ++++++------ doc/ctc-meetings/2016-06-15.md | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/doc/changelogs/CHANGELOG_ARCHIVE.md b/doc/changelogs/CHANGELOG_ARCHIVE.md index 1552086ce26775..eb32a8287e7ea8 100644 --- a/doc/changelogs/CHANGELOG_ARCHIVE.md +++ b/doc/changelogs/CHANGELOG_ARCHIVE.md @@ -1314,13 +1314,13 @@ https://github.com/nodejs/node/commit/8b8a7a7f9b41e74e1e810d0330738ad06fc302ec https://github.com/nodejs/node/commit/a72120190a8ffdbcd3d6ad2a2e6ceecd2087111e * npm: Upgrade to 1.1.30 - - Improved 'npm init' - - Fix the 'cb never called' error from 'oudated' and 'update' - - Add --save-bundle|-B config - - Fix isaacs/npm[#2465](https://github.com/joyent/node/issues/2465): Make npm script and windows shims cygwin-aware - - Fix isaacs/npm[#2452](https://github.com/joyent/node/issues/2452) Use --save(-dev|-optional) in npm rm - - `logstream` option to replace removed `logfd` (Rod Vagg) - - Read default descriptions from README.md files + - Improved 'npm init' + - Fix the 'cb never called' error from 'oudated' and 'update' + - Add --save-bundle|-B config + - Fix isaacs/npm[#2465](https://github.com/joyent/node/issues/2465): Make npm script and windows shims cygwin-aware + - Fix isaacs/npm[#2452](https://github.com/joyent/node/issues/2452) Use --save(-dev|-optional) in npm rm + - `logstream` option to replace removed `logfd` (Rod Vagg) + - Read default descriptions from README.md files * Shims to support deprecated ev_* and eio_* methods (Ben Noordhuis) * [#3118](https://github.com/joyent/node/issues/3118) net.Socket: Delay pause/resume until after connect (isaacs) @@ -1381,9 +1381,9 @@ https://github.com/nodejs/node/commit/12a32a48a30182621b3f8e9b9695d1946b53c131 * child_process: new stdio API for .spawn() method (Fedor Indutny) * child_process: spawn().ref() and spawn().unref() (Fedor Indutny) * Upgrade npm to 1.1.25 - - Enable npm link on windows - - Properly remove sh-shim on Windows - - Abstract out registry client and logger + - Enable npm link on windows + - Properly remove sh-shim on Windows + - Abstract out registry client and logger ## 2012.05.28, Version 0.7.9 (unstable) @@ -1981,7 +1981,7 @@ https://github.com/nodejs/node/commit/865b077819a9271a29f982faaef99dc635b57fbc https://github.com/nodejs/node/commit/220e61c1f65bf4db09699fcf6399c0809c0bc446 * Remove cmake build system, support for Cygwin, legacy code base, - process.ENV, process.ARGV, process.memoryUsage().vsize, os.openOSHandle + process.ENV, process.ARGV, process.memoryUsage().vsize, os.openOSHandle * Documentation improvements (Igor Zinkovsky, Bert Belder, Ilya Dmitrichenko, koichik, Maciej Małecki, Guglielmo Ferri, isaacs) @@ -2207,7 +2207,7 @@ https://github.com/nodejs/node/commit/4585330afef44ddfb6a4054bd9b0f190b352628b * Add support for TLS SNI (Fedor Indutny) * New http agent implementation. Off by default the command line flag --use-http2 will enable it. "make test-http2" will run the tests - for the new implementation. (Mikeal Rogers) + for the new implementation. (Mikeal Rogers) * Revert AMD compatibility. (isaacs) * Windows: improvements, child_process support. @@ -2375,7 +2375,7 @@ https://github.com/nodejs/node/commit/7dd22c26e4365698dc3efddf138c4d399cb912c8 * [#983](https://github.com/joyent/node/issues/983) Better JSON.parse error detection in REPL (isaacs) * [#836](https://github.com/joyent/node/issues/836) Agent socket errors bubble up to req only if req exists * [#1041](https://github.com/joyent/node/issues/1041) Fix event listener leak check timing (koichik) -* [#1038](https://github.com/joyent/node/issues/1038) Fix dns.resolve() with 'PTR' throws Error: Unknown type "PTR" +* [#1038](https://github.com/joyent/node/issues/1038) Fix dns.resolve() with 'PTR' throws Error: Unknown type "PTR" (koichik) * [#1073](https://github.com/joyent/node/issues/1073) Share SSL context between server connections (Fedor Indutny) @@ -2389,7 +2389,7 @@ https://github.com/nodejs/node/commit/7dd22c26e4365698dc3efddf138c4d399cb912c8 * Doc improvements * cleartextstream.destroy() should close(2) the socket. Previously was being - mapped to a shutdown(2) syscall. + mapped to a shutdown(2) syscall. * No longer compile out asserts and debug statements in normal build. * Debugger improvements. @@ -2417,16 +2417,16 @@ https://github.com/nodejs/node/commit/58002d56bc79410c5ff397fc0e1ffec0665db38a * Don't error on ENOTCONN from shutdown() [#670](https://github.com/joyent/node/issues/670) * Auto completion of built-in debugger suggests prefix match rather than - partial match. (koichik) + partial match. (koichik) * circular reference in vm modules. [#822](https://github.com/joyent/node/issues/822) (Jakub Lekstan) * http response.readable should be false after 'end' [#867](https://github.com/joyent/node/issues/867) (Abe Fettig) * Implement os.cpus() and os.uptime() on Solaris (Scott McWhirter) * fs.ReadStream: Allow omission of end option for range reads [#801](https://github.com/joyent/node/issues/801) - (Felix Geisendörfer) + (Felix Geisendörfer) * Buffer.write() with UCS-2 should not be write partial char - [#916](https://github.com/joyent/node/issues/916) (koichik) + [#916](https://github.com/joyent/node/issues/916) (koichik) * Pass secureProtocol through on tls.Server creation (Theo Schlossnagle) * TLS use RC4-SHA by default @@ -2467,7 +2467,7 @@ https://github.com/nodejs/node/commit/25122b986a90ba0982697b7abcb0158c302a1019 https://github.com/nodejs/node/commit/c095ce1a1b41ca015758a713283bf1f0bd41e4c4 * Don't decrease server connection counter again if destroy() is called more - than once GH-431 (Andreas Reich, Anders Conbere) + than once GH-431 (Andreas Reich, Anders Conbere) * Documentation improvements (koichik) * Fix bug with setMaxListeners GH-682 @@ -2794,7 +2794,7 @@ https://github.com/nodejs/node/commit/b14dd49222687c12f3e8eac597cff4f2674f84e8 * Set cwd for child processes (Bert Belder) * Tab completion for readline (Trent Mick) * process.title getter/setter for OSX, Linux, Cygwin. - (Rasmus Andersson, Bert Belder) + (Rasmus Andersson, Bert Belder) * Upgrade V8 to 2.3.6 diff --git a/doc/changelogs/CHANGELOG_V010.md b/doc/changelogs/CHANGELOG_V010.md index 7d683746d2e60d..2921c625940940 100644 --- a/doc/changelogs/CHANGELOG_V010.md +++ b/doc/changelogs/CHANGELOG_V010.md @@ -293,14 +293,14 @@ https://github.com/nodejs/node/commit/8d045a30e95602b443eb259a5021d33feb4df079 * uv: Update to v0.10.29 * child_process: properly support optional args (cjihrig) * crypto: Disable autonegotiation for SSLv2/3 by default (Fedor Indutny, - Timothy J Fontaine, Alexis Campailla) - This is a behavior change, by default we will not allow the negotiation to - SSLv2 or SSLv3. If you want this behavior, run Node.js with either - `--enable-ssl2` or `--enable-ssl3` respectively. - This does not change the behavior for users specifically requesting - `SSLv2_method` or `SSLv3_method`. While this behavior is not advised, it is - assumed you know what you're doing since you're specifically asking to use - these methods. + Timothy J Fontaine, Alexis Campailla) + This is a behavior change, by default we will not allow the negotiation to + SSLv2 or SSLv3. If you want this behavior, run Node.js with either + `--enable-ssl2` or `--enable-ssl3` respectively. + This does not change the behavior for users specifically requesting + `SSLv2_method` or `SSLv3_method`. While this behavior is not advised, it is + assumed you know what you're doing since you're specifically asking to use + these methods. ## 2014.09.16, Version 0.10.32 (Stable) diff --git a/doc/ctc-meetings/2016-06-15.md b/doc/ctc-meetings/2016-06-15.md index 4168b3613136fa..9046cdee2ba830 100644 --- a/doc/ctc-meetings/2016-06-15.md +++ b/doc/ctc-meetings/2016-06-15.md @@ -67,7 +67,7 @@ Extracted from **ctc-agenda** labelled issues and pull requests from the **nodej * Keeping up with issues * Brian White @mscdex (CTC) - * Landed some old PRs + * Landed some old PRs * Submitting PRs to fix some regressions * Reviewed PRs and issues From abd0bc052322517fbbbec4194f42e8b8eea3530e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BA=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=90=D0=BD=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Thu, 14 Jul 2016 12:55:30 +0300 Subject: [PATCH 062/144] doc: *.md formatting fixes in the top-level dir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Continuing what a58b48bc3bcf43f7090d4cc914606af68fe55815 did for the doc/ dir, this fixes some formatting issues in the *.md files that are placed directly in the top-level directory. README.md changes are excluded as they are covered by https://github.com/nodejs/node/pull/7971 Refs: https://github.com/nodejs/node/pull/7637 PR-URL: https://github.com/nodejs/node/pull/7727 Reviewed-By: Rich Trott Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- BUILDING.md | 50 ++++++++++++++++++++++++++----------------------- CONTRIBUTING.md | 4 ++-- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 532c478bbb736b..b4a7436cec76c5 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -28,7 +28,7 @@ On FreeBSD and OpenBSD, you may also need: * libexecinfo (FreeBSD and OpenBSD only) -```text +```console $ ./configure $ make $ [sudo] make install @@ -37,7 +37,7 @@ $ [sudo] make install If your Python binary is in a non-standard location or has a non-standard name, run the following instead: -```text +```console $ export PYTHON=/path/to/python $ $PYTHON ./configure $ make @@ -46,13 +46,13 @@ $ [sudo] make install To run the tests: -```text +```console $ make test ``` To run the native module tests: -```text +```console $ make test-addons ``` @@ -61,7 +61,7 @@ To run the npm test suite: *note: to run the suite on node v4 or earlier you must first* *run `make install`* -``` +```console $ make test-npm ``` @@ -69,13 +69,13 @@ To build the documentation: This will build Node.js first (if necessary) and then use it to build the docs: -```text +```console $ make doc ``` If you have an existing Node.js you can build just the docs with: -```text +```console $ NODE=node make doc-only ``` @@ -83,13 +83,13 @@ $ NODE=node make doc-only To read the documentation: -```text +```console $ man doc/node.1 ``` To test if Node.js was built correctly: -``` +```console $ node -e "console.log('Hello from Node.js ' + process.version)" ``` @@ -107,19 +107,19 @@ Prerequisites: [Git for Windows](http://git-scm.com/download/win) includes Git Bash and tools which can be included in the global `PATH`. -```text +```console > vcbuild nosign ``` To run the tests: -```text +```console > vcbuild test ``` To test if Node.js was built correctly: -```text +```console > Release\node -e "console.log('Hello from Node.js', process.version)" ``` @@ -136,7 +136,7 @@ Be sure you have downloaded and extracted [Android NDK] (https://developer.android.com/tools/sdk/ndk/index.html) before in a folder. Then run: -``` +```console $ ./android-configure /path/to/your/android-ndk $ make ``` @@ -165,13 +165,13 @@ Node.js source does not include all locales.) ##### Unix / OS X: -```text +```console $ ./configure --with-intl=full-icu --download=all ``` ##### Windows: -```text +```console > vcbuild full-icu download-all ``` @@ -182,19 +182,19 @@ The `Intl` object will not be available, nor some other APIs such as ##### Unix / OS X: -```text +```console $ ./configure --without-intl ``` ##### Windows: -```text +```console > vcbuild without-intl ``` #### Use existing installed ICU (Unix / OS X only): -```text +```console $ pkg-config --modversion icu-i18n && ./configure --with-intl=system-icu ``` @@ -210,14 +210,18 @@ Download the file named something like `icu4c-**##.#**-src.tgz` (or ##### Unix / OS X -```text -# from an already-unpacked ICU: +From an already-unpacked ICU: +```console $ ./configure --with-intl=[small-icu,full-icu] --with-icu-source=/path/to/icu +``` -# from a local ICU tarball +From a local ICU tarball: +```console $ ./configure --with-intl=[small-icu,full-icu] --with-icu-source=/path/to/icu.tgz +``` -# from a tarball URL +From a tarball URL: +```console $ ./configure --with-intl=full-icu --with-icu-source=http://url/to/icu.tgz ``` @@ -227,7 +231,7 @@ First unpack latest ICU to `deps/icu` [icu4c-**##.#**-src.tgz](http://icu-project.org/download) (or `.zip`) as `deps/icu` (You'll have: `deps/icu/source/...`) -```text +```console > vcbuild full-icu ``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 500e0a79d579a0..ba8ca3da720bbd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -100,7 +100,7 @@ changed and why. Follow these guidelines when writing one: A good commit log can look something like this: -``` +```txt subsystem: explaining the commit in one line Body of commit message is a few lines of text, explaining things @@ -122,7 +122,7 @@ what subsystem (or subsystems) your changes touch. If your patch fixes an open issue, you can add a reference to it at the end of the log. Use the `Fixes:` prefix and the full issue URL. For example: -``` +```txt Fixes: https://github.com/nodejs/node/issues/1337 ``` From 5f12807c46b2ea36918814c2c9a62b3a4965817b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BA=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=90=D0=BD=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Thu, 14 Jul 2016 13:02:45 +0300 Subject: [PATCH 063/144] doc: remove extra indentation in iojs changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes the extra two spaces indentation which was somewhy present in the iojs changelog from v1.8.1 to v3.3.1. iojs changelog was the only file affected. PR-URL: https://github.com/nodejs/node/pull/7727 Reviewed-By: Rich Trott Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- doc/changelogs/CHANGELOG_IOJS.md | 2810 +++++++++++++++--------------- 1 file changed, 1405 insertions(+), 1405 deletions(-) diff --git a/doc/changelogs/CHANGELOG_IOJS.md b/doc/changelogs/CHANGELOG_IOJS.md index 975d046fbcd22d..bef00e45a296ab 100644 --- a/doc/changelogs/CHANGELOG_IOJS.md +++ b/doc/changelogs/CHANGELOG_IOJS.md @@ -67,1416 +67,1416 @@ * [0.10.x](CHANGELOG_V010.md) * [Archive](CHANGELOG_ARCHIVE.md) - - - ## 2015-09-15, io.js Version 3.3.1 @rvagg - - ### Notable changes - - * **buffer**: Fixed a minor errors that was causing crashes (Michaël Zasso) [#2635](https://github.com/nodejs/node/pull/2635), - * **child_process**: Fix error that was causing crashes (Evan Lucas) [#2727](https://github.com/nodejs/node/pull/2727) - * **crypto**: Replace use of rwlocks, unsafe on Windows XP / 2003 (Ben Noordhuis) [#2723](https://github.com/nodejs/node/pull/2723) - * **libuv**: Upgrade from 1.7.3 to 1.7.4 (Saúl Ibarra Corretgé) [#2817](https://github.com/nodejs/node/pull/2817) - * **node**: Fix faulty `process.release.libUrl` on Windows (Rod Vagg) [#2699](https://github.com/nodejs/node/pull/2699) - * **node-gyp**: Float v3.0.3 which has improved support for Node.js and io.js v0.10 to v4+ (Rod Vagg) [#2700](https://github.com/nodejs/node/pull/2700) - * **npm**: Upgrade to version 2.14.3 from 2.13.3, includes a security update, see https://github.com/npm/npm/releases/tag/v2.14.2 for more details, (Kat Marchán) [#2696](https://github.com/nodejs/node/pull/2696). - * **timers**: Improved timer performance from porting the 0.12 implementation, plus minor fixes (Jeremiah Senkpiel) [#2540](https://github.com/nodejs/node/pull/2540), (Julien Gilli) [nodejs/node-v0.x-archive#8751](https://github.com/nodejs/node-v0.x-archive/pull/8751) [nodejs/node-v0.x-archive#8905](https://github.com/nodejs/node-v0.x-archive/pull/8905) - - ### Known issues - - See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. - - * Some uses of computed object shorthand properties are not handled correctly by the current version of V8. e.g. `[{ [prop]: val }]` evaluates to `[{}]`. [#2507](https://github.com/nodejs/node/issues/2507) - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). - * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). - - ### Commits - - * [[`b73ff52fe6`](https://github.com/nodejs/node/commit/b73ff52fe6)] - **bindings**: close after reading module struct (Fedor Indutny) [#2792](https://github.com/nodejs/node/pull/2792) - * [[`aa1140e59a`](https://github.com/nodejs/node/commit/aa1140e59a)] - **buffer**: SlowBuffer only accept valid numeric values (Michaël Zasso) [#2635](https://github.com/nodejs/node/pull/2635) - * [[`574475d56e`](https://github.com/nodejs/node/commit/574475d56e)] - **build**: clean up the generated tap file (Sakthipriyan Vairamani) [#2837](https://github.com/nodejs/node/pull/2837) - * [[`aa0001271e`](https://github.com/nodejs/node/commit/aa0001271e)] - **build**: remote commands on staging in single session (Rod Vagg) [#2717](https://github.com/nodejs/node/pull/2717) - * [[`1428661095`](https://github.com/nodejs/node/commit/1428661095)] - **build**: fix v8_enable_handle_zapping override (Karl Skomski) [#2731](https://github.com/nodejs/node/pull/2731) - * [[`5a51edd718`](https://github.com/nodejs/node/commit/5a51edd718)] - **build**: add --enable-asan with builtin leakcheck (Karl Skomski) [#2376](https://github.com/nodejs/node/pull/2376) - * [[`618caa5de0`](https://github.com/nodejs/node/commit/618caa5de0)] - **child_process**: use stdio.fd even if it is 0 (Evan Lucas) [#2727](https://github.com/nodejs/node/pull/2727) - * [[`7be4e49cb6`](https://github.com/nodejs/node/commit/7be4e49cb6)] - **child_process**: check execFile and fork args (James M Snell) [#2667](https://github.com/nodejs/node/pull/2667) - * [[`7f5d6e72c6`](https://github.com/nodejs/node/commit/7f5d6e72c6)] - **cluster**: allow shared reused dgram sockets (Fedor Indutny) [#2548](https://github.com/nodejs/node/pull/2548) - * [[`e68c7ec498`](https://github.com/nodejs/node/commit/e68c7ec498)] - **contextify**: ignore getters during initialization (Fedor Indutny) [nodejs/io.js#2091](https://github.com/nodejs/io.js/pull/2091) - * [[`610fa964aa`](https://github.com/nodejs/node/commit/610fa964aa)] - **cpplint**: make it possible to run outside git repo (Ben Noordhuis) [#2710](https://github.com/nodejs/node/pull/2710) - * [[`4237373dd7`](https://github.com/nodejs/node/commit/4237373dd7)] - **crypto**: replace rwlocks with simple mutexes (Ben Noordhuis) [#2723](https://github.com/nodejs/node/pull/2723) - * [[`777eb00306`](https://github.com/nodejs/node/commit/777eb00306)] - **deps**: upgraded to node-gyp@3.0.3 in npm (Kat Marchán) [#2822](https://github.com/nodejs/node/pull/2822) - * [[`b729ad384b`](https://github.com/nodejs/node/commit/b729ad384b)] - **deps**: upgrade to npm 2.14.3 (Kat Marchán) [#2822](https://github.com/nodejs/node/pull/2822) - * [[`b09fde761c`](https://github.com/nodejs/node/commit/b09fde761c)] - **deps**: update libuv to version 1.7.4 (Saúl Ibarra Corretgé) [#2817](https://github.com/nodejs/node/pull/2817) - * [[`4cf225daad`](https://github.com/nodejs/node/commit/4cf225daad)] - **deps**: float node-gyp v3.0.0 (Rod Vagg) [#2700](https://github.com/nodejs/node/pull/2700) - * [[`118f48c0f3`](https://github.com/nodejs/node/commit/118f48c0f3)] - **deps**: create .npmrc during npm tests (Kat Marchán) [#2696](https://github.com/nodejs/node/pull/2696) - * [[`b3fee8e6a6`](https://github.com/nodejs/node/commit/b3fee8e6a6)] - **deps**: upgrade to npm 2.14.2 (Kat Marchán) [#2696](https://github.com/nodejs/node/pull/2696) - * [[`4593539b92`](https://github.com/nodejs/node/commit/4593539b92)] - **deps**: backport 75e43a6 from v8 upstream (saper) [#2636](https://github.com/nodejs/node/pull/2636) - * [[`2d1438cfe0`](https://github.com/nodejs/node/commit/2d1438cfe0)] - **doc**: fix broken link in repl.markdown (Danny Nemer) [#2827](https://github.com/nodejs/node/pull/2827) - * [[`9dd9c85a48`](https://github.com/nodejs/node/commit/9dd9c85a48)] - **doc**: fix typos in README (Ionică Bizău) [#2852](https://github.com/nodejs/node/pull/2852) - * [[`476125d403`](https://github.com/nodejs/node/commit/476125d403)] - **doc**: add tunniclm as a collaborator (Mike Tunnicliffe) [#2826](https://github.com/nodejs/node/pull/2826) - * [[`0603a92d48`](https://github.com/nodejs/node/commit/0603a92d48)] - **doc**: fix two doc errors in stream and process (Jeremiah Senkpiel) [#2549](https://github.com/nodejs/node/pull/2549) - * [[`da2902ddfd`](https://github.com/nodejs/node/commit/da2902ddfd)] - **doc**: use "Calls" over "Executes" for consistency (Minwoo Jung) [#2800](https://github.com/nodejs/node/pull/2800) - * [[`5e93bc4fba`](https://github.com/nodejs/node/commit/5e93bc4fba)] - **doc**: use US English for consistency (Anne-Gaelle Colom) [#2784](https://github.com/nodejs/node/pull/2784) - * [[`3ee7fbcefd`](https://github.com/nodejs/node/commit/3ee7fbcefd)] - **doc**: use 3rd person singular for consistency (Anne-Gaelle Colom) [#2765](https://github.com/nodejs/node/pull/2765) - * [[`4fdccb9eb7`](https://github.com/nodejs/node/commit/4fdccb9eb7)] - **doc**: fix comma splice in Assertion Testing doc (Rich Trott) [#2728](https://github.com/nodejs/node/pull/2728) - * [[`28c2d310d6`](https://github.com/nodejs/node/commit/28c2d310d6)] - **doc**: update AUTHORS list (Rod Vagg) - * [[`324c073fb9`](https://github.com/nodejs/node/commit/324c073fb9)] - **doc**: add TSC meeting minutes 2015-09-02 (Rod Vagg) [#2674](https://github.com/nodejs/node/pull/2674) - * [[`8929445686`](https://github.com/nodejs/node/commit/8929445686)] - **doc**: update url doc to account for escaping (Jeremiah Senkpiel) [#2605](https://github.com/nodejs/node/pull/2605) - * [[`512dad6883`](https://github.com/nodejs/node/commit/512dad6883)] - **doc**: reorder collaborators by their usernames (Johan Bergström) [#2322](https://github.com/nodejs/node/pull/2322) - * [[`8372ea2ca5`](https://github.com/nodejs/node/commit/8372ea2ca5)] - **doc,test**: enable recursive file watching in Windows (Sakthipriyan Vairamani) [#2649](https://github.com/nodejs/node/pull/2649) - * [[`daf6c533cc`](https://github.com/nodejs/node/commit/daf6c533cc)] - **events,lib**: don't require EE#listenerCount() (Jeremiah Senkpiel) [#2661](https://github.com/nodejs/node/pull/2661) - * [[`d8371a801e`](https://github.com/nodejs/node/commit/d8371a801e)] - **http_server**: fix resume after socket close (Fedor Indutny) [#2824](https://github.com/nodejs/node/pull/2824) - * [[`7f7d4fdddd`](https://github.com/nodejs/node/commit/7f7d4fdddd)] - **node-gyp**: float 3.0.1, minor fix for download url (Rod Vagg) [#2737](https://github.com/nodejs/node/pull/2737) - * [[`91cee73294`](https://github.com/nodejs/node/commit/91cee73294)] - **src**: use ZCtxt as a source for v8::Isolates (Roman Klauke) [#2547](https://github.com/nodejs/node/pull/2547) - * [[`ac98e13b95`](https://github.com/nodejs/node/commit/ac98e13b95)] - **src**: s/ia32/x86 for process.release.libUrl for win (Rod Vagg) [#2699](https://github.com/nodejs/node/pull/2699) - * [[`ca6c3223e1`](https://github.com/nodejs/node/commit/ca6c3223e1)] - **src**: use standard conform snprintf on windows (Karl Skomski) [#2404](https://github.com/nodejs/node/pull/2404) - * [[`b028978a53`](https://github.com/nodejs/node/commit/b028978a53)] - **src**: fix buffer overflow for long exception lines (Karl Skomski) [#2404](https://github.com/nodejs/node/pull/2404) - * [[`e73eafd7e7`](https://github.com/nodejs/node/commit/e73eafd7e7)] - **src**: fix memory leak in ExternString (Karl Skomski) [#2402](https://github.com/nodejs/node/pull/2402) - * [[`d370306de1`](https://github.com/nodejs/node/commit/d370306de1)] - **src**: only set v8 flags if argc > 1 (Evan Lucas) [#2646](https://github.com/nodejs/node/pull/2646) - * [[`ed087836af`](https://github.com/nodejs/node/commit/ed087836af)] - **streams**: refactor LazyTransform to internal/ (Brendan Ashworth) [#2566](https://github.com/nodejs/node/pull/2566) - * [[`993c22fe0e`](https://github.com/nodejs/node/commit/993c22fe0e)] - **test**: remove disabled test (Rich Trott) [#2841](https://github.com/nodejs/node/pull/2841) - * [[`1474f29d1f`](https://github.com/nodejs/node/commit/1474f29d1f)] - **test**: split up internet dns tests (Rich Trott) [#2802](https://github.com/nodejs/node/pull/2802) - * [[`601a97622b`](https://github.com/nodejs/node/commit/601a97622b)] - **test**: increase dgram timeout for armv6 (Rich Trott) [#2808](https://github.com/nodejs/node/pull/2808) - * [[`1dad19ba81`](https://github.com/nodejs/node/commit/1dad19ba81)] - **test**: remove valid hostname check in test-dns.js (Rich Trott) [#2785](https://github.com/nodejs/node/pull/2785) - * [[`f3d5891a3f`](https://github.com/nodejs/node/commit/f3d5891a3f)] - **test**: expect error for test_lookup_ipv6_hint on FreeBSD (Rich Trott) [#2724](https://github.com/nodejs/node/pull/2724) - * [[`2ffb21baf1`](https://github.com/nodejs/node/commit/2ffb21baf1)] - **test**: fix use of `common` before required (Rod Vagg) [#2685](https://github.com/nodejs/node/pull/2685) - * [[`b2c5479a14`](https://github.com/nodejs/node/commit/b2c5479a14)] - **test**: refactor to eliminate flaky test (Rich Trott) [#2609](https://github.com/nodejs/node/pull/2609) - * [[`fcfd15f8f9`](https://github.com/nodejs/node/commit/fcfd15f8f9)] - **test**: mark eval_messages as flaky (Alexis Campailla) [#2648](https://github.com/nodejs/node/pull/2648) - * [[`1865cad7ae`](https://github.com/nodejs/node/commit/1865cad7ae)] - **test**: mark test-vm-syntax-error-stderr as flaky (João Reis) [#2662](https://github.com/nodejs/node/pull/2662) - * [[`b0014ecd27`](https://github.com/nodejs/node/commit/b0014ecd27)] - **test**: mark test-repl-persistent-history as flaky (João Reis) [#2659](https://github.com/nodejs/node/pull/2659) - * [[`74ff9bc86c`](https://github.com/nodejs/node/commit/74ff9bc86c)] - **timers**: minor _unrefActive fixes and improvements (Jeremiah Senkpiel) [#2540](https://github.com/nodejs/node/pull/2540) - * [[`5d14a6eca7`](https://github.com/nodejs/node/commit/5d14a6eca7)] - **timers**: don't mutate unref list while iterating it (Julien Gilli) [#2540](https://github.com/nodejs/node/pull/2540) - * [[`6e744c58f2`](https://github.com/nodejs/node/commit/6e744c58f2)] - **timers**: Avoid linear scan in _unrefActive. (Julien Gilli) [#2540](https://github.com/nodejs/node/pull/2540) - * [[`07fbf835ad`](https://github.com/nodejs/node/commit/07fbf835ad)] - **tools**: open `test.tap` file in write-binary mode (Sakthipriyan Vairamani) [#2837](https://github.com/nodejs/node/pull/2837) - * [[`6d9198f7f1`](https://github.com/nodejs/node/commit/6d9198f7f1)] - **tools**: add missing tick processor polyfill (Matt Loring) [#2694](https://github.com/nodejs/node/pull/2694) - * [[`7b16597527`](https://github.com/nodejs/node/commit/7b16597527)] - **tools**: fix flakiness in test-tick-processor (Matt Loring) [#2694](https://github.com/nodejs/node/pull/2694) - * [[`ef83029356`](https://github.com/nodejs/node/commit/ef83029356)] - **tools**: remove hyphen in TAP result (Sakthipriyan Vairamani) [#2718](https://github.com/nodejs/node/pull/2718) - * [[`ac45ef9157`](https://github.com/nodejs/node/commit/ac45ef9157)] - **win,msi**: fix documentation shortcut url (Brian White) [#2781](https://github.com/nodejs/node/pull/2781) - - - ## 2015-09-02, Version 3.3.0, @rvagg - - ### Notable changes - - * **build**: Add a `--link-module` option to `configure` that can be used to bundle additional JavaScript modules into a built binary (Bradley Meck) [#2497](https://github.com/nodejs/node/pull/2497) - * **docs**: Merge outstanding doc updates from joyent/node (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * **http_parser**: Significant performance improvement by having `http.Server` consume all initial data from its `net.Socket` and parsing directly without having to enter JavaScript. Any `'data'` listeners on the `net.Socket` will result in the data being "unconsumed" into JavaScript, thereby undoing any performance gains. (Fedor Indutny) [#2355](https://github.com/nodejs/node/pull/2355) - * **libuv**: Upgrade to 1.7.3 (from 1.6.1), see [ChangeLog](https://github.com/libuv/libuv/blob/v1.x/ChangeLog) for details (Saúl Ibarra Corretgé) [#2310](https://github.com/nodejs/node/pull/2310) - * **V8**: Upgrade to 4.4.63.30 (from 4.4.63.26) (Michaël Zasso) [#2482](https://github.com/nodejs/node/pull/2482) - - ### Known issues - - See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. - - * Some uses of computed object shorthand properties are not handled correctly by the current version of V8. e.g. `[{ [prop]: val }]` evaluates to `[{}]`. [#2507](https://github.com/nodejs/node/issues/2507) - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). - * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). - - ### Commits - - * [[`1a531b4e44`](https://github.com/nodejs/node/commit/1a531b4e44)] - **(SEMVER-MINOR)** Introduce --link-module to ./configure (Bradley Meck) [#2497](https://github.com/nodejs/node/pull/2497) - * [[`d2f314c190`](https://github.com/nodejs/node/commit/d2f314c190)] - **build**: fix borked chmod call for release uploads (Rod Vagg) [#2645](https://github.com/nodejs/node/pull/2645) - * [[`3172e9c541`](https://github.com/nodejs/node/commit/3172e9c541)] - **build**: set file permissions before uploading (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) - * [[`a860d7fae1`](https://github.com/nodejs/node/commit/a860d7fae1)] - **build**: change staging directory on new server (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) - * [[`50c0baa8d7`](https://github.com/nodejs/node/commit/50c0baa8d7)] - **build**: rename 'doc' directory to 'docs' for upload (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) - * [[`0a0577cf5f`](https://github.com/nodejs/node/commit/0a0577cf5f)] - **build**: fix bad cherry-pick for vcbuild.bat build-release (Rod Vagg) [#2625](https://github.com/nodejs/node/pull/2625) - * [[`34de90194b`](https://github.com/nodejs/node/commit/34de90194b)] - **build**: only define NODE_V8_OPTIONS if not empty (Evan Lucas) [#2532](https://github.com/nodejs/node/pull/2532) - * [[`944174b189`](https://github.com/nodejs/node/commit/944174b189)] - **build**: make ci test addons in test/addons (Ben Noordhuis) [#2428](https://github.com/nodejs/node/pull/2428) - * [[`e955f9a1b0`](https://github.com/nodejs/node/commit/e955f9a1b0)] - **crypto**: Use OPENSSL_cleanse to shred the data. (Сковорода Никита Андреевич) [#2575](https://github.com/nodejs/node/pull/2575) - * [[`395d736b9d`](https://github.com/nodejs/node/commit/395d736b9d)] - **debugger**: use strict equality comparison (Minwoo Jung) [#2558](https://github.com/nodejs/node/pull/2558) - * [[`1d0e5210a8`](https://github.com/nodejs/node/commit/1d0e5210a8)] - **deps**: upgrade libuv to 1.7.3 (Saúl Ibarra Corretgé) [#2310](https://github.com/nodejs/node/pull/2310) - * [[`34ef53364f`](https://github.com/nodejs/node/commit/34ef53364f)] - **deps**: update V8 to 4.4.63.30 (Michaël Zasso) [#2482](https://github.com/nodejs/node/pull/2482) - * [[`23579a5f4a`](https://github.com/nodejs/node/commit/23579a5f4a)] - **doc**: add TSC meeting minutes 2015-08-12 (Rod Vagg) [#2438](https://github.com/nodejs/node/pull/2438) - * [[`0cc59299a4`](https://github.com/nodejs/node/commit/0cc59299a4)] - **doc**: add TSC meeting minutes 2015-08-26 (Rod Vagg) [#2591](https://github.com/nodejs/node/pull/2591) - * [[`6efa96e33a`](https://github.com/nodejs/node/commit/6efa96e33a)] - **doc**: merge CHANGELOG.md with joyent/node ChangeLog (Minqi Pan) [#2536](https://github.com/nodejs/node/pull/2536) - * [[`f75d54607b`](https://github.com/nodejs/node/commit/f75d54607b)] - **doc**: clarify cluster behaviour with no workers (Jeremiah Senkpiel) [#2606](https://github.com/nodejs/node/pull/2606) - * [[`8936302121`](https://github.com/nodejs/node/commit/8936302121)] - **doc**: minor clarification in buffer.markdown (Сковорода Никита Андреевич) [#2574](https://github.com/nodejs/node/pull/2574) - * [[`0db0e53753`](https://github.com/nodejs/node/commit/0db0e53753)] - **doc**: add @jasnell and @sam-github to release team (Rod Vagg) [#2455](https://github.com/nodejs/node/pull/2455) - * [[`c16e100593`](https://github.com/nodejs/node/commit/c16e100593)] - **doc**: reorg release team to separate section (Rod Vagg) [#2455](https://github.com/nodejs/node/pull/2455) - * [[`e3e00143fd`](https://github.com/nodejs/node/commit/e3e00143fd)] - **doc**: fix bad merge on modules.markdown (James M Snell) - * [[`2f62455880`](https://github.com/nodejs/node/commit/2f62455880)] - **doc**: minor additional corrections and improvements (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`3bd08aac4b`](https://github.com/nodejs/node/commit/3bd08aac4b)] - **doc**: minor grammatical update in crypto.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`f707189370`](https://github.com/nodejs/node/commit/f707189370)] - **doc**: minor grammatical update (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`6c98cf0266`](https://github.com/nodejs/node/commit/6c98cf0266)] - **doc**: remove repeated statement in globals.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`48e6ccf8c2`](https://github.com/nodejs/node/commit/48e6ccf8c2)] - **doc**: remove 'dudes' from documentation (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`b5d68f8076`](https://github.com/nodejs/node/commit/b5d68f8076)] - **doc**: update tense in child_process.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`242e3fe3ba`](https://github.com/nodejs/node/commit/242e3fe3ba)] - **doc**: fixed worker.id type (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`ea9ee15c21`](https://github.com/nodejs/node/commit/ea9ee15c21)] - **doc**: port is optional for socket.bind() (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`0ff6657a50`](https://github.com/nodejs/node/commit/0ff6657a50)] - **doc**: fix minor types and grammar in fs docs (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`94d83c04f2`](https://github.com/nodejs/node/commit/94d83c04f2)] - **doc**: update parameter name in net.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`04111ce40f`](https://github.com/nodejs/node/commit/04111ce40f)] - **doc**: small typo in domain.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`c9fdd1bbbf`](https://github.com/nodejs/node/commit/c9fdd1bbbf)] - **doc**: fixed typo in net.markdown (missing comma) (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`27c07b3f8e`](https://github.com/nodejs/node/commit/27c07b3f8e)] - **doc**: update description of fs.exists in fs.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`52018e73d9`](https://github.com/nodejs/node/commit/52018e73d9)] - **doc**: clarification on the 'close' event (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`f6d3b87a25`](https://github.com/nodejs/node/commit/f6d3b87a25)] - **doc**: improve working in stream.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`b5da89431a`](https://github.com/nodejs/node/commit/b5da89431a)] - **doc**: update path.extname documentation (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`1d4ea609db`](https://github.com/nodejs/node/commit/1d4ea609db)] - **doc**: small clarifications to modules.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`c888985591`](https://github.com/nodejs/node/commit/c888985591)] - **doc**: code style cleanups in repl.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`105b493595`](https://github.com/nodejs/node/commit/105b493595)] - **doc**: correct grammar in cluster.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`51b86ccac7`](https://github.com/nodejs/node/commit/51b86ccac7)] - **doc**: Clarify the module.parent is set once (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) - * [[`d2ffecba2d`](https://github.com/nodejs/node/commit/d2ffecba2d)] - **doc**: add internal modules notice (Jeremiah Senkpiel) [#2523](https://github.com/nodejs/node/pull/2523) - * [[`b36debd5cb`](https://github.com/nodejs/node/commit/b36debd5cb)] - **env**: introduce `KickNextTick` (Fedor Indutny) [#2355](https://github.com/nodejs/node/pull/2355) - * [[`1bc446863f`](https://github.com/nodejs/node/commit/1bc446863f)] - **http_parser**: consume StreamBase instance (Fedor Indutny) [#2355](https://github.com/nodejs/node/pull/2355) - * [[`ce04b735cc`](https://github.com/nodejs/node/commit/ce04b735cc)] - **src**: only memcmp if length > 0 in Buffer::Compare (Karl Skomski) [#2544](https://github.com/nodejs/node/pull/2544) - * [[`31823e37c7`](https://github.com/nodejs/node/commit/31823e37c7)] - **src**: DRY getsockname/getpeername code (Ben Noordhuis) [#956](https://github.com/nodejs/node/pull/956) - * [[`13fd96dda3`](https://github.com/nodejs/node/commit/13fd96dda3)] - **src**: missing Exception::Error in node_http_parser (Jeremiah Senkpiel) [#2550](https://github.com/nodejs/node/pull/2550) - * [[`42e075ae02`](https://github.com/nodejs/node/commit/42e075ae02)] - **test**: improve performance of stringbytes test (Trevor Norris) [#2544](https://github.com/nodejs/node/pull/2544) - * [[`fc726399fd`](https://github.com/nodejs/node/commit/fc726399fd)] - **test**: unmark test-process-argv-0.js as flaky (Rich Trott) [#2613](https://github.com/nodejs/node/pull/2613) - * [[`7727ba1394`](https://github.com/nodejs/node/commit/7727ba1394)] - **test**: lint and refactor to avoid autocrlf issue (Roman Reiss) [#2494](https://github.com/nodejs/node/pull/2494) - * [[`c56aa829f0`](https://github.com/nodejs/node/commit/c56aa829f0)] - **test**: use tmpDir instead of fixturesDir (Sakthipriyan Vairamani) [#2583](https://github.com/nodejs/node/pull/2583) - * [[`5e65181ea4`](https://github.com/nodejs/node/commit/5e65181ea4)] - **test**: handling failure cases properly (Sakthipriyan Vairamani) [#2206](https://github.com/nodejs/node/pull/2206) - * [[`c48b95e847`](https://github.com/nodejs/node/commit/c48b95e847)] - **test**: initial list of flaky tests (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) - * [[`94e88498ba`](https://github.com/nodejs/node/commit/94e88498ba)] - **test**: pass args to test-ci via env variable (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) - * [[`09987c7a1c`](https://github.com/nodejs/node/commit/09987c7a1c)] - **test**: support flaky tests in test-ci (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) - * [[`08b83c8b45`](https://github.com/nodejs/node/commit/08b83c8b45)] - **test**: add test configuration templates (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) - * [[`8f8ab6fa57`](https://github.com/nodejs/node/commit/8f8ab6fa57)] - **test**: runner should return 0 on flaky tests (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) - * [[`0cfd3be9c6`](https://github.com/nodejs/node/commit/0cfd3be9c6)] - **test**: runner support for flaky tests (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) - * [[`3492d2d4c6`](https://github.com/nodejs/node/commit/3492d2d4c6)] - **test**: make test-process-argv-0 robust (Rich Trott) [#2541](https://github.com/nodejs/node/pull/2541) - * [[`a96cc31710`](https://github.com/nodejs/node/commit/a96cc31710)] - **test**: speed up test-child-process-spawnsync.js (Rich Trott) [#2542](https://github.com/nodejs/node/pull/2542) - * [[`856baf4c67`](https://github.com/nodejs/node/commit/856baf4c67)] - **test**: make spawnSync() test robust (Rich Trott) [#2535](https://github.com/nodejs/node/pull/2535) - * [[`3aa6bbb648`](https://github.com/nodejs/node/commit/3aa6bbb648)] - **tools**: update release.sh to work with new website (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) - * [[`f2f0fe45ff`](https://github.com/nodejs/node/commit/f2f0fe45ff)] - **tools**: make add-on scraper print filenames (Ben Noordhuis) [#2428](https://github.com/nodejs/node/pull/2428) - * [[`bb24c4a418`](https://github.com/nodejs/node/commit/bb24c4a418)] - **win,msi**: correct installation path registry keys (João Reis) [#2565](https://github.com/nodejs/node/pull/2565) - * [[`752977b888`](https://github.com/nodejs/node/commit/752977b888)] - **win,msi**: change InstallScope to perMachine (João Reis) [#2565](https://github.com/nodejs/node/pull/2565) - - - ## 2015-08-25, Version 3.2.0, @rvagg - - ### Notable changes - - * **events**: Added `EventEmitter#listenerCount(event)` as a replacement for `EventEmitter.listenerCount(emitter, event)`, which has now been marked as deprecated in the docs. (Sakthipriyan Vairamani) [#2349](https://github.com/nodejs/node/pull/2349) - * **module**: Fixed an error with preloaded modules when the current working directory doesn't exist. (Bradley Meck) [#2353](https://github.com/nodejs/node/pull/2353) - * **node**: Startup time is now about 5% faster when not passing V8 flags. (Evan Lucas) [#2483](https://github.com/nodejs/node/pull/2483) - * **repl**: Tab-completion now works better with arrays. (James M Snell) [#2409](https://github.com/nodejs/node/pull/2409) - * **string_bytes**: Fixed an unaligned write in the handling of UCS2 encoding. (Fedor Indutny) [#2480](https://github.com/nodejs/node/pull/2480) - * **tls**: Added a new `--tls-cipher-list` flag that can be used to override the built-in default cipher list. (James M Snell) [#2412](https://github.com/nodejs/node/pull/2412) _Note: it is suggested you use the built-in cipher list as it has been carefully selected to reflect current security best practices and risk mitigation._ - - ### Known issues - - See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. - - * Some uses of computed object shorthand properties are not handled correctly by the current version of V8. e.g. `[{ [prop]: val }]` evaluates to `[{}]`. [#2507](https://github.com/nodejs/node/issues/2507) - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). - * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). - - ### Commits - - * [[`1cd794f129`](https://github.com/nodejs/node/commit/1cd794f129)] - **buffer**: reapply 07c0667 (Fedor Indutny) [#2487](https://github.com/nodejs/node/pull/2487) - * [[`156781dedd`](https://github.com/nodejs/node/commit/156781dedd)] - **build**: use required platform in android-configure (Evan Lucas) [#2501](https://github.com/nodejs/node/pull/2501) - * [[`77075ec906`](https://github.com/nodejs/node/commit/77075ec906)] - **crypto**: fix mem {de}allocation in ExportChallenge (Karl Skomski) [#2359](https://github.com/nodejs/node/pull/2359) - * [[`cb30414d9e`](https://github.com/nodejs/node/commit/cb30414d9e)] - **doc**: sync CHANGELOG.md from master (Roman Reiss) [#2524](https://github.com/nodejs/node/pull/2524) - * [[`9330f5ef45`](https://github.com/nodejs/node/commit/9330f5ef45)] - **doc**: make the deprecations consistent (Sakthipriyan Vairamani) [#2450](https://github.com/nodejs/node/pull/2450) - * [[`09437e0146`](https://github.com/nodejs/node/commit/09437e0146)] - **doc**: fix comments in tls_wrap.cc and _http_client.js (Minwoo Jung) [#2489](https://github.com/nodejs/node/pull/2489) - * [[`c9867fed29`](https://github.com/nodejs/node/commit/c9867fed29)] - **doc**: document response.finished in http.markdown (hackerjs) [#2414](https://github.com/nodejs/node/pull/2414) - * [[`7f23a83c42`](https://github.com/nodejs/node/commit/7f23a83c42)] - **doc**: update AUTHORS list (Rod Vagg) [#2505](https://github.com/nodejs/node/pull/2505) - * [[`cd0c362f67`](https://github.com/nodejs/node/commit/cd0c362f67)] - **doc**: update AUTHORS list (Rod Vagg) [#2318](https://github.com/nodejs/node/pull/2318) - * [[`2c7b9257ea`](https://github.com/nodejs/node/commit/2c7b9257ea)] - **doc**: add TSC meeting minutes 2015-07-29 (Rod Vagg) [#2437](https://github.com/nodejs/node/pull/2437) - * [[`aaefde793e`](https://github.com/nodejs/node/commit/aaefde793e)] - **doc**: add TSC meeting minutes 2015-08-19 (Rod Vagg) [#2460](https://github.com/nodejs/node/pull/2460) - * [[`51ef9106f5`](https://github.com/nodejs/node/commit/51ef9106f5)] - **doc**: add TSC meeting minutes 2015-06-03 (Rod Vagg) [#2453](https://github.com/nodejs/node/pull/2453) - * [[`7130b4cf1d`](https://github.com/nodejs/node/commit/7130b4cf1d)] - **doc**: fix links to original converged repo (Rod Vagg) [#2454](https://github.com/nodejs/node/pull/2454) - * [[`14f2aee1df`](https://github.com/nodejs/node/commit/14f2aee1df)] - **doc**: fix links to original gh issues for TSC meetings (Rod Vagg) [#2454](https://github.com/nodejs/node/pull/2454) - * [[`87a9ef0a40`](https://github.com/nodejs/node/commit/87a9ef0a40)] - **doc**: add audio recording links to TSC meeting minutes (Rod Vagg) [#2454](https://github.com/nodejs/node/pull/2454) - * [[`f5cf24afbc`](https://github.com/nodejs/node/commit/f5cf24afbc)] - **doc**: add TSC meeting minutes 2015-07-22 (Rod Vagg) [#2436](https://github.com/nodejs/node/pull/2436) - * [[`3f821b96eb`](https://github.com/nodejs/node/commit/3f821b96eb)] - **doc**: fix spelling mistake in node.js comment (Jacob Edelman) [#2391](https://github.com/nodejs/node/pull/2391) - * [[`3e6a6fcdd6`](https://github.com/nodejs/node/commit/3e6a6fcdd6)] - **(SEMVER-MINOR)** **events**: deprecate static listenerCount function (Sakthipriyan Vairamani) [#2349](https://github.com/nodejs/node/pull/2349) - * [[`023386c852`](https://github.com/nodejs/node/commit/023386c852)] - **fs**: replace bad_args macro with concrete error msg (Roman Klauke) [#2495](https://github.com/nodejs/node/pull/2495) - * [[`d1c27b2e29`](https://github.com/nodejs/node/commit/d1c27b2e29)] - **module**: fix module preloading when cwd is ENOENT (Bradley Meck) [#2353](https://github.com/nodejs/node/pull/2353) - * [[`5d7486941b`](https://github.com/nodejs/node/commit/5d7486941b)] - **repl**: filter integer keys from repl tab complete list (James M Snell) [#2409](https://github.com/nodejs/node/pull/2409) - * [[`7f02443a9a`](https://github.com/nodejs/node/commit/7f02443a9a)] - **repl**: dont throw ENOENT on NODE_REPL_HISTORY_FILE (Todd Kennedy) [#2451](https://github.com/nodejs/node/pull/2451) - * [[`56a2ae9cef`](https://github.com/nodejs/node/commit/56a2ae9cef)] - **src**: improve startup time (Evan Lucas) [#2483](https://github.com/nodejs/node/pull/2483) - * [[`14653c7429`](https://github.com/nodejs/node/commit/14653c7429)] - **stream**: rename poorly named function (Ben Noordhuis) [#2479](https://github.com/nodejs/node/pull/2479) - * [[`1c6e014bfa`](https://github.com/nodejs/node/commit/1c6e014bfa)] - **stream**: micro-optimize high water mark calculation (Ben Noordhuis) [#2479](https://github.com/nodejs/node/pull/2479) - * [[`f1f4b4c46d`](https://github.com/nodejs/node/commit/f1f4b4c46d)] - **stream**: fix off-by-factor-16 error in comment (Ben Noordhuis) [#2479](https://github.com/nodejs/node/pull/2479) - * [[`2d3f09bd76`](https://github.com/nodejs/node/commit/2d3f09bd76)] - **stream_base**: various improvements (Fedor Indutny) [#2351](https://github.com/nodejs/node/pull/2351) - * [[`c1ce423b35`](https://github.com/nodejs/node/commit/c1ce423b35)] - **string_bytes**: fix unaligned write in UCS2 (Fedor Indutny) [#2480](https://github.com/nodejs/node/pull/2480) - * [[`e4d0e86165`](https://github.com/nodejs/node/commit/e4d0e86165)] - **test**: refactor test-https-simple.js (Rich Trott) [#2433](https://github.com/nodejs/node/pull/2433) - * [[`0ea5c8d737`](https://github.com/nodejs/node/commit/0ea5c8d737)] - **test**: remove test-timers-first-fire (João Reis) [#2458](https://github.com/nodejs/node/pull/2458) - * [[`536c3d0537`](https://github.com/nodejs/node/commit/536c3d0537)] - **test**: use reserved IP in test-net-connect-timeout (Rich Trott) [#2257](https://github.com/nodejs/node/pull/2257) - * [[`5df06fd8df`](https://github.com/nodejs/node/commit/5df06fd8df)] - **test**: add spaces after keywords (Brendan Ashworth) - * [[`e714b5620e`](https://github.com/nodejs/node/commit/e714b5620e)] - **test**: remove unreachable code (Michaël Zasso) [#2289](https://github.com/nodejs/node/pull/2289) - * [[`3579f3a2a4`](https://github.com/nodejs/node/commit/3579f3a2a4)] - **test**: disallow unreachable code (Michaël Zasso) [#2289](https://github.com/nodejs/node/pull/2289) - * [[`3545e236fc`](https://github.com/nodejs/node/commit/3545e236fc)] - **test**: reduce timeouts in test-net-keepalive (Brendan Ashworth) [#2429](https://github.com/nodejs/node/pull/2429) - * [[`b60e690023`](https://github.com/nodejs/node/commit/b60e690023)] - **test**: improve test-net-server-pause-on-connect (Brendan Ashworth) [#2429](https://github.com/nodejs/node/pull/2429) - * [[`11d1b8fcaf`](https://github.com/nodejs/node/commit/11d1b8fcaf)] - **test**: improve test-net-pingpong (Brendan Ashworth) [#2429](https://github.com/nodejs/node/pull/2429) - * [[`5fef5c6562`](https://github.com/nodejs/node/commit/5fef5c6562)] - **(SEMVER-MINOR)** **tls**: add --tls-cipher-list command line switch (James M Snell) [#2412](https://github.com/nodejs/node/pull/2412) - * [[`d9b70f9cbf`](https://github.com/nodejs/node/commit/d9b70f9cbf)] - **tls**: handle empty cert in checkServerIndentity (Mike Atkins) [#2343](https://github.com/nodejs/node/pull/2343) - * [[`4f8e34c202`](https://github.com/nodejs/node/commit/4f8e34c202)] - **tools**: add license boilerplate to check-imports.sh (James M Snell) [#2386](https://github.com/nodejs/node/pull/2386) - * [[`b76b9197f9`](https://github.com/nodejs/node/commit/b76b9197f9)] - **tools**: enable space-after-keywords in eslint (Brendan Ashworth) - * [[`64a8f30a70`](https://github.com/nodejs/node/commit/64a8f30a70)] - **tools**: fix anchors in generated documents (Sakthipriyan Vairamani) [#2491](https://github.com/nodejs/node/pull/2491) - * [[`22e344ea10`](https://github.com/nodejs/node/commit/22e344ea10)] - **win**: fix custom actions for WiX older than 3.9 (João Reis) [#2365](https://github.com/nodejs/node/pull/2365) - * [[`b5bd3ebfc8`](https://github.com/nodejs/node/commit/b5bd3ebfc8)] - **win**: fix custom actions on Visual Studio != 2013 (Julien Gilli) [#2365](https://github.com/nodejs/node/pull/2365) - - - ## 2015-08-18, Version 3.1.0, @Fishrock123 - - ### Notable changes - - * **buffer**: Fixed a couple large memory leaks (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352). - * **crypto**: - - Fixed a couple of minor memory leaks (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375). - - Signing now checks for OpenSSL errors (Minqi Pan) [#2342](https://github.com/nodejs/node/pull/2342). **Note that this may expose previously hidden errors in user code.** - * **intl**: Intl support using small-icu is now enabled by default in builds (Steven R. Loomis) [#2264](https://github.com/nodejs/node/pull/2264). - - [`String#normalize()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) can now be used for unicode normalization. - - The [`Intl`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl) object and various `String` and `Number` methods are present, but only support the English locale. - - For support of all locales, node must be built with [full-icu](https://github.com/nodejs/node#build-with-full-icu-support-all-locales-supported-by-icu). - * **tls**: Fixed tls throughput being much lower after an incorrect merge (Fedor Indutny) [#2381](https://github.com/nodejs/node/pull/2381). - * **tools**: The v8 tick processor now comes bundled with node (Matt Loring) [#2090](https://github.com/nodejs/node/pull/2090). - - This can be used by producing performance profiling output by running node with `--perf`, then running your appropriate platform's script on the output as found in [tools/v8-prof](https://github.com/nodejs/node/tree/master/tools/v8-prof). - * **util**: `util.inspect(obj)` now prints the constructor name of the object if there is one (Christopher Monsanto) [#1935](https://github.com/nodejs/io.js/pull/1935). - - ### Known issues - - See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). - * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). - - ### Commits - - * [[`3645dc62ed`](https://github.com/nodejs/node/commit/3645dc62ed)] - **build**: work around VS2015 issue in ICU <56 (Steven R. Loomis) [#2283](https://github.com/nodejs/node/pull/2283) - * [[`1f12e03266`](https://github.com/nodejs/node/commit/1f12e03266)] - **(SEMVER-MINOR)** **build**: intl: converge from joyent/node (Steven R. Loomis) [#2264](https://github.com/nodejs/node/pull/2264) - * [[`071640abdd`](https://github.com/nodejs/node/commit/071640abdd)] - **build**: Intl: bump ICU4C from 54 to 55 (Steven R. Loomis) [#2293](https://github.com/nodejs/node/pull/2293) - * [[`07a88b0c8b`](https://github.com/nodejs/node/commit/07a88b0c8b)] - **build**: update manifest to include Windows 10 (Lucien Greathouse) [#2332](https://github.com/nodejs/io.js/pull/2332) - * [[`0bb099f444`](https://github.com/nodejs/node/commit/0bb099f444)] - **build**: expand ~ in install prefix early (Ben Noordhuis) [#2307](https://github.com/nodejs/io.js/pull/2307) - * [[`7fe6dd8f5d`](https://github.com/nodejs/node/commit/7fe6dd8f5d)] - **crypto**: check for OpenSSL errors when signing (Minqi Pan) [#2342](https://github.com/nodejs/node/pull/2342) - * [[`605f6ee904`](https://github.com/nodejs/node/commit/605f6ee904)] - **crypto**: fix memory leak in PBKDF2Request (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) - * [[`ba6eb8af12`](https://github.com/nodejs/node/commit/ba6eb8af12)] - **crypto**: fix memory leak in ECDH::SetPrivateKey (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) - * [[`6a16368611`](https://github.com/nodejs/node/commit/6a16368611)] - **crypto**: fix memory leak in PublicKeyCipher::Cipher (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) - * [[`a760a87803`](https://github.com/nodejs/node/commit/a760a87803)] - **crypto**: fix memory leak in SafeX509ExtPrint (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) - * [[`f45487cd6e`](https://github.com/nodejs/node/commit/f45487cd6e)] - **crypto**: fix memory leak in SetDHParam (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) - * [[`2ff183dd86`](https://github.com/nodejs/node/commit/2ff183dd86)] - **doc**: Update FIPS instructions in README.md (Michael Dawson) [#2278](https://github.com/nodejs/node/pull/2278) - * [[`6483bc2e8f`](https://github.com/nodejs/node/commit/6483bc2e8f)] - **doc**: clarify options for fs.watchFile() (Rich Trott) [#2425](https://github.com/nodejs/node/pull/2425) - * [[`e76822f454`](https://github.com/nodejs/node/commit/e76822f454)] - **doc**: multiple documentation updates cherry picked from v0.12 (James M Snell) [#2302](https://github.com/nodejs/io.js/pull/2302) - * [[`1738c9680b`](https://github.com/nodejs/node/commit/1738c9680b)] - **net**: ensure Socket reported address is current (Ryan Graham) [#2095](https://github.com/nodejs/io.js/pull/2095) - * [[`844d3f0e3e`](https://github.com/nodejs/node/commit/844d3f0e3e)] - **path**: use '===' instead of '==' for comparison (Sam Stites) [#2388](https://github.com/nodejs/node/pull/2388) - * [[`7118b8a882`](https://github.com/nodejs/node/commit/7118b8a882)] - **path**: remove dead code in favor of unit tests (Nathan Woltman) [#2282](https://github.com/nodejs/io.js/pull/2282) - * [[`34f2cfa806`](https://github.com/nodejs/node/commit/34f2cfa806)] - **src**: better error message on failed Buffer malloc (Karl Skomski) [#2422](https://github.com/nodejs/node/pull/2422) - * [[`b196c1da3c`](https://github.com/nodejs/node/commit/b196c1da3c)] - **src**: fix memory leak in DLOpen (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) - * [[`d1307b2995`](https://github.com/nodejs/node/commit/d1307b2995)] - **src**: don't use fopen() in require() fast path (Ben Noordhuis) [#2377](https://github.com/nodejs/node/pull/2377) - * [[`455ec570d1`](https://github.com/nodejs/node/commit/455ec570d1)] - **src**: rename Buffer::Use() to Buffer::New() (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) - * [[`fd63e1ce2b`](https://github.com/nodejs/node/commit/fd63e1ce2b)] - **src**: introduce internal Buffer::Copy() function (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) - * [[`5586ceca13`](https://github.com/nodejs/node/commit/5586ceca13)] - **src**: move internal functions out of node_buffer.h (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) - * [[`bff9bcddb6`](https://github.com/nodejs/node/commit/bff9bcddb6)] - **src**: plug memory leaks (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) - * [[`ccf12df4f3`](https://github.com/nodejs/node/commit/ccf12df4f3)] - **(SEMVER-MINOR)** **src**: add total_available_size to v8 statistics (Roman Klauke) [#2348](https://github.com/nodejs/io.js/pull/2348) - * [[`194eeb841b`](https://github.com/nodejs/node/commit/194eeb841b)] - **test**: drop Isolate::GetCurrent() from addon tests (Ben Noordhuis) [#2427](https://github.com/nodejs/node/pull/2427) - * [[`46cdb2f6e2`](https://github.com/nodejs/node/commit/46cdb2f6e2)] - **test**: lint addon tests (Ben Noordhuis) [#2427](https://github.com/nodejs/node/pull/2427) - * [[`850c794882`](https://github.com/nodejs/node/commit/850c794882)] - **test**: refactor test-fs-watchfile.js (Rich Trott) [#2393](https://github.com/nodejs/node/pull/2393) - * [[`a3160c0a33`](https://github.com/nodejs/node/commit/a3160c0a33)] - **test**: correct spelling of 'childProcess' (muddletoes) [#2389](https://github.com/nodejs/node/pull/2389) - * [[`e51f90d747`](https://github.com/nodejs/node/commit/e51f90d747)] - **test**: option to run a subset of tests (João Reis) [#2260](https://github.com/nodejs/io.js/pull/2260) - * [[`cc46d3bca3`](https://github.com/nodejs/node/commit/cc46d3bca3)] - **test**: clarify dropMembership() call (Rich Trott) [#2062](https://github.com/nodejs/io.js/pull/2062) - * [[`0ee4df9c7a`](https://github.com/nodejs/node/commit/0ee4df9c7a)] - **test**: make listen-fd-cluster/server more robust (Sam Roberts) [#1944](https://github.com/nodejs/io.js/pull/1944) - * [[`cf9ba81398`](https://github.com/nodejs/node/commit/cf9ba81398)] - **test**: address timing issues in simple http tests (Gireesh Punathil) [#2294](https://github.com/nodejs/io.js/pull/2294) - * [[`cbb75c4f86`](https://github.com/nodejs/node/commit/cbb75c4f86)] - **tls**: fix throughput issues after incorrect merge (Fedor Indutny) [#2381](https://github.com/nodejs/node/pull/2381) - * [[`94b765f409`](https://github.com/nodejs/node/commit/94b765f409)] - **tls**: fix check for reused session (Fedor Indutny) [#2312](https://github.com/nodejs/io.js/pull/2312) - * [[`e83a41ad65`](https://github.com/nodejs/node/commit/e83a41ad65)] - **tls**: introduce internal `onticketkeycallback` (Fedor Indutny) [#2312](https://github.com/nodejs/io.js/pull/2312) - * [[`fb0f5d733f`](https://github.com/nodejs/node/commit/fb0f5d733f)] - **(SEMVER-MINOR)** **tools**: run the tick processor without building v8 (Matt Loring) [#2090](https://github.com/nodejs/node/pull/2090) - * [[`7606bdb897`](https://github.com/nodejs/node/commit/7606bdb897)] - **(SEMVER-MINOR)** **util**: display constructor when inspecting objects (Christopher Monsanto) [#1935](https://github.com/nodejs/io.js/pull/1935) - - - ## 2015-08-04, Version 3.0.0, @rvagg - - ### Notable changes - - * **buffer**: - - Due to changes in V8, it has been necessary to reimplement `Buffer` on top of V8's `Uint8Array`. Every effort has been made to minimize the performance impact, however `Buffer` instantiation is measurably slower. Access operations may be faster in some circumstances but the exact performance profile and difference over previous versions will depend on how `Buffer` is used within applications. (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825). - - `Buffer` can now take `ArrayBuffer`s as a constructor argument (Trevor Norris) [#2002](https://github.com/nodejs/node/pull/2002). - - When a single buffer is passed to `Buffer.concat()`, a new, copied `Buffer` object will be returned; previous behavior was to return the original `Buffer` object (Sakthipriyan Vairamani) [#1937](https://github.com/nodejs/node/pull/1937). - * **build**: PPC support has been added to core to allow compiling on pLinux BE and LE (AIX support coming soon) (Michael Dawson) [#2124](https://github.com/nodejs/node/pull/2124). - * **dgram**: If an error occurs within `socket.send()` and a callback has been provided, the error is only passed as the first argument to the callback and not emitted on the `socket` object; previous behavior was to do both (Matteo Collina & Chris Dickinson) [#1796](https://github.com/nodejs/node/pull/1796) - * **freelist**: Deprecate the undocumented `freelist` core module (Sakthipriyan Vairamani) [#2176](https://github.com/nodejs/node/pull/2176). - * **http**: - - Status codes now all use the official [IANA names](http://www.iana.org/assignments/http-status-codes) as per [RFC7231](https://tools.ietf.org/html/rfc7231), e.g. `http.STATUS_CODES[414]` now returns `'URI Too Long'` rather than `'Request-URI Too Large'` (jomo) [#1470](https://github.com/nodejs/node/pull/1470). - - Calling .getName() on an HTTP agent no longer returns a trailing colon, HTTPS agents will no longer return an extra colon near the middle of the string (Brendan Ashworth) [#1617](https://github.com/nodejs/node/pull/1617). - * **node**: - - `NODE_MODULE_VERSION` has been bumped to `45` to reflect the break in ABI (Rod Vagg) [#2096](https://github.com/nodejs/node/pull/2096). - - Introduce a new `process.release` object that contains a `name` property set to `'io.js'` and `sourceUrl`, `headersUrl` and `libUrl` (Windows only) properties containing URLs for the relevant resources; this is intended to be used by node-gyp (Rod Vagg) [#2154](https://github.com/nodejs/node/pull/2154). - - The version of node-gyp bundled with io.js now downloads and uses a tarball of header files from iojs.org rather than the full source for compiling native add-ons; it is hoped this is a temporary floating patch and the change will be upstreamed to node-gyp soon (Rod Vagg) [#2066](https://github.com/nodejs/node/pull/2066). - * **repl**: Persistent history is now enabled by default. The history file is located at ~/.node_repl_history, which can be overridden by the new environment variable `NODE_REPL_HISTORY`. This deprecates the previous `NODE_REPL_HISTORY_FILE` variable. Additionally, the format of the file has been changed to plain text to better handle file corruption. (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224). - * **smalloc**: The `smalloc` module has been removed as it is no longer possible to provide the API due to changes in V8 (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022). - * **tls**: Add `server.getTicketKeys()` and `server.setTicketKeys()` methods for [TLS session key](https://www.ietf.org/rfc/rfc5077.txt) rotation (Fedor Indutny) [#2227](https://github.com/nodejs/node/pull/2227). - * **v8**: Upgraded to 4.4.63.26 - - ES6: Enabled [computed property names](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names) - - ES6: `Array` can now be subclassed in strict mode - - ES6: Implement [rest parameters](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/rest_parameters) in staging, use the `--harmony-rest-parameters` command line flag - - ES6: Implement the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) in staging, use the `--harmony-spreadcalls` command line flag - - Removed `SetIndexedPropertiesToExternalArrayData` and related APIs, forcing a shift to `Buffer` to be reimplemented based on `Uint8Array` - - Introduction of `Maybe` and `MaybeLocal` C++ API for objects which _may_ or _may not_ have a value. - - Added support for PPC - - See also https://github.com/nodejs/node/wiki/Breaking-Changes#300-from-2x for a summary of the breaking changes (SEMVER-MAJOR). - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ### Commits - - * [[`60a974d200`](https://github.com/nodejs/node/commit/60a974d200)] - **buffer**: fix missing null/undefined check (Trevor Norris) [#2195](https://github.com/nodejs/node/pull/2195) - * [[`e6ab2d92bc`](https://github.com/nodejs/node/commit/e6ab2d92bc)] - **buffer**: fix not return on error (Trevor Norris) [#2225](https://github.com/nodejs/node/pull/2225) - * [[`1057d1186b`](https://github.com/nodejs/node/commit/1057d1186b)] - **buffer**: rename internal/buffer_new.js to buffer.js (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) - * [[`4643b8b667`](https://github.com/nodejs/node/commit/4643b8b667)] - **(SEMVER-MINOR)** **buffer**: allow ArrayBuffer as Buffer argument (Trevor Norris) [#2002](https://github.com/nodejs/node/pull/2002) - * [[`e5ada116cd`](https://github.com/nodejs/node/commit/e5ada116cd)] - **buffer**: minor cleanup from rebase (Trevor Norris) [#2003](https://github.com/nodejs/node/pull/2003) - * [[`b625ab4242`](https://github.com/nodejs/node/commit/b625ab4242)] - **buffer**: fix usage of kMaxLength (Trevor Norris) [#2003](https://github.com/nodejs/node/pull/2003) - * [[`eea66e2a7b`](https://github.com/nodejs/node/commit/eea66e2a7b)] - **(SEMVER-MAJOR)** **buffer**: fix case of one buffer passed to concat (Sakthipriyan Vairamani) [#1937](https://github.com/nodejs/node/pull/1937) - * [[`8664084166`](https://github.com/nodejs/node/commit/8664084166)] - **buffer**: make additional changes to native API (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) - * [[`36f78f4c1c`](https://github.com/nodejs/node/commit/36f78f4c1c)] - **buffer**: switch API to return MaybeLocal (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) - * [[`571ec13841`](https://github.com/nodejs/node/commit/571ec13841)] - **buffer**: switch to using Maybe API (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) - * [[`d75f5c8d0e`](https://github.com/nodejs/node/commit/d75f5c8d0e)] - **buffer**: finish implementing FreeCallback (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) - * [[`63da0dfd3a`](https://github.com/nodejs/node/commit/63da0dfd3a)] - **buffer**: implement Uint8Array backed Buffer (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) - * [[`23be6ca189`](https://github.com/nodejs/node/commit/23be6ca189)] - **buffer**: allow ARGS_THIS to accept a name (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) - * [[`971de5e417`](https://github.com/nodejs/node/commit/971de5e417)] - **build**: prepare Windows installer for i18n support (Frederic Hemberger) [#2247](https://github.com/nodejs/node/pull/2247) - * [[`2ba8b23661`](https://github.com/nodejs/node/commit/2ba8b23661)] - **build**: add 'x86' option back in to configure (Rod Vagg) [#2233](https://github.com/nodejs/node/pull/2233) - * [[`b4226e797a`](https://github.com/nodejs/node/commit/b4226e797a)] - **build**: first set of updates to enable PPC support (Michael Dawson) [#2124](https://github.com/nodejs/node/pull/2124) - * [[`24dd016deb`](https://github.com/nodejs/node/commit/24dd016deb)] - **build**: produce symbol map files on windows (Ali Ijaz Sheikh) [#2243](https://github.com/nodejs/node/pull/2243) - * [[`423d8944ce`](https://github.com/nodejs/node/commit/423d8944ce)] - **cluster**: do not unconditionally set --debug-port (cjihrig) [#1949](https://github.com/nodejs/node/pull/1949) - * [[`fa98b97171`](https://github.com/nodejs/node/commit/fa98b97171)] - **cluster**: add handle ref/unref stubs in rr mode (Ben Noordhuis) [#2274](https://github.com/nodejs/node/pull/2274) - * [[`944f68046c`](https://github.com/nodejs/node/commit/944f68046c)] - **crypto**: remove kMaxLength on randomBytes() (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) - * [[`3d3c687012`](https://github.com/nodejs/node/commit/3d3c687012)] - **deps**: update V8 to 4.4.63.26 (Michaël Zasso) [#2220](https://github.com/nodejs/node/pull/2220) - * [[`3aad4fa89a`](https://github.com/nodejs/node/commit/3aad4fa89a)] - **deps**: upgrade v8 to 4.4.63.12 (Ben Noordhuis) [#2092](https://github.com/nodejs/node/pull/2092) - * [[`70d1f32f56`](https://github.com/nodejs/node/commit/70d1f32f56)] - **(SEMVER-MAJOR)** **deps**: update v8 to 4.4.63.9 (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) - * [[`deb7ee93a7`](https://github.com/nodejs/node/commit/deb7ee93a7)] - **deps**: backport 7b24219346 from v8 upstream (Rod Vagg) [#1805](https://github.com/nodejs/node/pull/1805) - * [[`d58e780504`](https://github.com/nodejs/node/commit/d58e780504)] - **(SEMVER-MAJOR)** **deps**: update v8 to 4.3.61.21 (Chris Dickinson) [iojs/io.js#1632](https://github.com/iojs/io.js/pull/1632) - * [[`2a63cf612b`](https://github.com/nodejs/node/commit/2a63cf612b)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`bf63266460`](https://github.com/nodejs/node/commit/bf63266460)] - **deps**: upgrade to npm 2.13.3 (Kat Marchán) [#2284](https://github.com/nodejs/node/pull/2284) - * [[`ef2c8cd4ec`](https://github.com/nodejs/node/commit/ef2c8cd4ec)] - **(SEMVER-MAJOR)** **dgram**: make send cb act as "error" event handler (Matteo Collina) [#1796](https://github.com/nodejs/node/pull/1796) - * [[`3da057fef6`](https://github.com/nodejs/node/commit/3da057fef6)] - **(SEMVER-MAJOR)** **dgram**: make send cb act as "error" event handler (Chris Dickinson) [#1796](https://github.com/nodejs/node/pull/1796) - * [[`df1994fe53`](https://github.com/nodejs/node/commit/df1994fe53)] - ***Revert*** "**dns**: remove AI_V4MAPPED hint flag on FreeBSD" (cjihrig) [iojs/io.js#1555](https://github.com/iojs/io.js/pull/1555) - * [[`1721968b22`](https://github.com/nodejs/node/commit/1721968b22)] - **doc**: document repl persistent history changes (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) - * [[`d12df7f159`](https://github.com/nodejs/node/commit/d12df7f159)] - **doc**: update v8 flags in man page (Michaël Zasso) [iojs/io.js#1701](https://github.com/iojs/io.js/pull/1701) - * [[`d168d01b04`](https://github.com/nodejs/node/commit/d168d01b04)] - **doc**: properly inheriting from EventEmitter (Sakthipriyan Vairamani) [#2168](https://github.com/nodejs/node/pull/2168) - * [[`500f2538cc`](https://github.com/nodejs/node/commit/500f2538cc)] - **doc**: a listener, not "an" listener (Sam Roberts) [#1025](https://github.com/nodejs/node/pull/1025) - * [[`54627a919d`](https://github.com/nodejs/node/commit/54627a919d)] - **doc**: server close event does not have an argument (Sam Roberts) [#1025](https://github.com/nodejs/node/pull/1025) - * [[`ed85c95a9c`](https://github.com/nodejs/node/commit/ed85c95a9c)] - **doc,test**: documents behaviour of non-existent file (Sakthipriyan Vairamani) [#2169](https://github.com/nodejs/node/pull/2169) - * [[`2965442308`](https://github.com/nodejs/node/commit/2965442308)] - **(SEMVER-MAJOR)** **http**: fix agent.getName() and add tests (Brendan Ashworth) [#1617](https://github.com/nodejs/node/pull/1617) - * [[`2d9456e3e6`](https://github.com/nodejs/node/commit/2d9456e3e6)] - **(SEMVER-MAJOR)** **http**: use official IANA Status Codes (jomo) [#1470](https://github.com/nodejs/node/pull/1470) - * [[`11e4249227`](https://github.com/nodejs/node/commit/11e4249227)] - **(SEMVER-MAJOR)** **http_server**: `prefinish` vs `finish` (Fedor Indutny) [#1411](https://github.com/nodejs/node/pull/1411) - * [[`9bc2e26720`](https://github.com/nodejs/node/commit/9bc2e26720)] - **net**: do not set V4MAPPED on FreeBSD (Julien Gilli) [iojs/io.js#1555](https://github.com/iojs/io.js/pull/1555) - * [[`ba9ccf227e`](https://github.com/nodejs/node/commit/ba9ccf227e)] - **node**: remove redundant --use-old-buffer (Rod Vagg) [#2275](https://github.com/nodejs/node/pull/2275) - * [[`ef65321083`](https://github.com/nodejs/node/commit/ef65321083)] - **(SEMVER-MAJOR)** **node**: do not override `message`/`stack` of error (Fedor Indutny) [#2108](https://github.com/nodejs/node/pull/2108) - * [[`9f727f5e03`](https://github.com/nodejs/node/commit/9f727f5e03)] - **node-gyp**: detect RC build with x.y.z-rc.n format (Rod Vagg) [#2171](https://github.com/nodejs/node/pull/2171) - * [[`e52f963632`](https://github.com/nodejs/node/commit/e52f963632)] - **node-gyp**: download header tarball for compile (Rod Vagg) [#2066](https://github.com/nodejs/node/pull/2066) - * [[`902c9ca51d`](https://github.com/nodejs/node/commit/902c9ca51d)] - **node-gyp**: make aware of nightly, next-nightly & rc (Rod Vagg) [#2066](https://github.com/nodejs/node/pull/2066) - * [[`4cffaa3f55`](https://github.com/nodejs/node/commit/4cffaa3f55)] - **(SEMVER-MINOR)** **readline**: allow tabs in input (Rich Trott) [#1761](https://github.com/nodejs/node/pull/1761) - * [[`ed6c249104`](https://github.com/nodejs/node/commit/ed6c249104)] - **(SEMVER-MAJOR)** **repl**: persist history in plain text (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) - * [[`f7d5e4c618`](https://github.com/nodejs/node/commit/f7d5e4c618)] - **(SEMVER-MINOR)** **repl**: default persistence to ~/.node_repl_history (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) - * [[`ea05e760cd`](https://github.com/nodejs/node/commit/ea05e760cd)] - **repl**: don't clobber RegExp.$ properties (Sakthipriyan Vairamani) [#2137](https://github.com/nodejs/node/pull/2137) - * [[`d20093246b`](https://github.com/nodejs/node/commit/d20093246b)] - **src**: disable vector ICs on arm (Michaël Zasso) [#2220](https://github.com/nodejs/node/pull/2220) - * [[`04fd4fad46`](https://github.com/nodejs/node/commit/04fd4fad46)] - **(SEMVER-MINOR)** **src**: introduce process.release object (Rod Vagg) [#2154](https://github.com/nodejs/node/pull/2154) - * [[`9d34bd1147`](https://github.com/nodejs/node/commit/9d34bd1147)] - **src**: increment NODE_MODULE_VERSION to 45 (Rod Vagg) [#2096](https://github.com/nodejs/node/pull/2096) - * [[`ceee8d2807`](https://github.com/nodejs/node/commit/ceee8d2807)] - **test**: add tests for persistent repl history (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) - * [[`8e1a8ffe24`](https://github.com/nodejs/node/commit/8e1a8ffe24)] - **test**: remove two obsolete pummel tests (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) - * [[`ae731ec0fa`](https://github.com/nodejs/node/commit/ae731ec0fa)] - **test**: don't use arguments.callee (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) - * [[`21d31c08e7`](https://github.com/nodejs/node/commit/21d31c08e7)] - **test**: remove obsolete harmony flags (Chris Dickinson) - * [[`64cf71195c`](https://github.com/nodejs/node/commit/64cf71195c)] - **test**: change the hostname to an invalid name (Sakthipriyan Vairamani) [#2287](https://github.com/nodejs/node/pull/2287) - * [[`80a1cf7425`](https://github.com/nodejs/node/commit/80a1cf7425)] - **test**: fix messages and use return to skip tests (Sakthipriyan Vairamani) [#2290](https://github.com/nodejs/node/pull/2290) - * [[`d5ab92bcc1`](https://github.com/nodejs/node/commit/d5ab92bcc1)] - **test**: use common.isWindows consistently (Sakthipriyan Vairamani) [#2269](https://github.com/nodejs/node/pull/2269) - * [[`bc733f7065`](https://github.com/nodejs/node/commit/bc733f7065)] - **test**: fix fs.readFile('/dev/stdin') tests (Ben Noordhuis) [#2265](https://github.com/nodejs/node/pull/2265) - * [[`3cbb5870e5`](https://github.com/nodejs/node/commit/3cbb5870e5)] - **tools**: expose skip output to test runner (Johan Bergström) [#2130](https://github.com/nodejs/node/pull/2130) - * [[`3b021efe11`](https://github.com/nodejs/node/commit/3b021efe11)] - **vm**: fix symbol access (Domenic Denicola) [#1773](https://github.com/nodejs/node/pull/1773) - * [[`7b81e4ba36`](https://github.com/nodejs/node/commit/7b81e4ba36)] - **vm**: remove unnecessary access checks (Domenic Denicola) [#1773](https://github.com/nodejs/node/pull/1773) - * [[`659dadd410`](https://github.com/nodejs/node/commit/659dadd410)] - **vm**: fix property descriptors of sandbox properties (Domenic Denicola) [#1773](https://github.com/nodejs/node/pull/1773) - * [[`9bac1dbae9`](https://github.com/nodejs/node/commit/9bac1dbae9)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) - - - ## 2015-07-28, Version 2.5.0, @cjihrig - - ### Notable changes - - * **https**: TLS sessions in Agent are reused (Fedor Indutny) [#2228](https://github.com/nodejs/node/pull/2228) - * **src**: base64 decoding is now 50% faster (Ben Noordhuis) [#2193](https://github.com/nodejs/node/pull/2193) - * **npm**: Upgraded to v2.13.2, release notes can be found in (Kat Marchán) [#2241](https://github.com/nodejs/node/pull/2241). - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Using multiple REPL instances in parallel may cause some REPL history corruption or loss. [#1634](https://github.com/nodejs/node/issues/1634) - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ### Commits - - * [[`bf2cd225a8`](https://github.com/nodejs/node/commit/bf2cd225a8)] - **process**: resize stderr on SIGWINCH (Jeremiah Senkpiel) [#2231](https://github.com/nodejs/node/pull/2231) - * [[`99d9d7e716`](https://github.com/nodejs/node/commit/99d9d7e716)] - **benchmark**: add remaining path benchmarks & optimize (Nathan Woltman) [#2103](https://github.com/nodejs/node/pull/2103) - * [[`66fc8ca22b`](https://github.com/nodejs/node/commit/66fc8ca22b)] - **(SEMVER-MINOR)** **cluster**: emit 'message' event on cluster master (Sam Roberts) [#861](https://github.com/nodejs/node/pull/861) - * [[`eb35968de7`](https://github.com/nodejs/node/commit/eb35968de7)] - **crypto**: fix legacy SNICallback (Fedor Indutny) [#1720](https://github.com/nodejs/node/pull/1720) - * [[`fef190cea6`](https://github.com/nodejs/node/commit/fef190cea6)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`b73a7465c5`](https://github.com/nodejs/node/commit/b73a7465c5)] - **deps**: upgrade to npm 2.13.2 (Kat Marchán) [#2241](https://github.com/nodejs/node/pull/2241) - * [[`0a7bf81d2f`](https://github.com/nodejs/node/commit/0a7bf81d2f)] - **deps**: update V8 to 4.2.77.21 (Ali Ijaz Sheikh) [#2238](https://github.com/nodejs/node/issues/2238) - * [[`73cdcdd581`](https://github.com/nodejs/node/commit/73cdcdd581)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`04893a736d`](https://github.com/nodejs/node/commit/04893a736d)] - **deps**: upgrade to npm 2.13.1 (Kat Marchán) [#2210](https://github.com/nodejs/node/pull/2210) - * [[`a3c1b9720e`](https://github.com/nodejs/node/commit/a3c1b9720e)] - **doc**: add GPG fingerprint for cjihrig (cjihrig) [#2217](https://github.com/nodejs/node/pull/2217) - * [[`d9f857df3b`](https://github.com/nodejs/node/commit/d9f857df3b)] - **doc**: note about custom inspect functions (Sakthipriyan Vairamani) [#2142](https://github.com/nodejs/node/pull/2142) - * [[`4ef2b5fbfb`](https://github.com/nodejs/node/commit/4ef2b5fbfb)] - **doc**: Replace util.debug with console.error (Yosuke Furukawa) [#2214](https://github.com/nodejs/node/pull/2214) - * [[`b612f085ec`](https://github.com/nodejs/node/commit/b612f085ec)] - **doc**: add joaocgreis as a collaborator (João Reis) [#2208](https://github.com/nodejs/node/pull/2208) - * [[`6b85d5a4b3`](https://github.com/nodejs/node/commit/6b85d5a4b3)] - **doc**: add TSC meeting minutes 2015-07-15 (Rod Vagg) [#2191](https://github.com/nodejs/node/pull/2191) - * [[`c7d8b09162`](https://github.com/nodejs/node/commit/c7d8b09162)] - **doc**: recompile before testing core module changes (Phillip Johnsen) [#2051](https://github.com/nodejs/node/pull/2051) - * [[`9afee6785e`](https://github.com/nodejs/node/commit/9afee6785e)] - **http**: Check this.connection before using it (Sakthipriyan Vairamani) [#2172](https://github.com/nodejs/node/pull/2172) - * [[`2ca5a3db47`](https://github.com/nodejs/node/commit/2ca5a3db47)] - **https**: reuse TLS sessions in Agent (Fedor Indutny) [#2228](https://github.com/nodejs/node/pull/2228) - * [[`fef87fee1d`](https://github.com/nodejs/node/commit/fef87fee1d)] - **(SEMVER-MINOR)** **lib,test**: add freelist deprecation and test (Sakthipriyan Vairamani) [#2176](https://github.com/nodejs/node/pull/2176) - * [[`503b089dd8`](https://github.com/nodejs/node/commit/503b089dd8)] - **net**: don't throw on immediately destroyed socket (Evan Lucas) [#2251](https://github.com/nodejs/node/pull/2251) - * [[`93660c8b8e`](https://github.com/nodejs/node/commit/93660c8b8e)] - **node**: remove bad fn call and check (Trevor Norris) [#2157](https://github.com/nodejs/node/pull/2157) - * [[`afd7e37ee0`](https://github.com/nodejs/node/commit/afd7e37ee0)] - **repl**: better empty line handling (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) - * [[`81ea52aa01`](https://github.com/nodejs/node/commit/81ea52aa01)] - **repl**: improving line continuation handling (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) - * [[`30edb5aee9`](https://github.com/nodejs/node/commit/30edb5aee9)] - **repl**: preventing REPL crash with inherited properties (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) - * [[`77fa385e5d`](https://github.com/nodejs/node/commit/77fa385e5d)] - **repl**: fixing `undefined` in invalid REPL keyword error (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) - * [[`8fd3ce100e`](https://github.com/nodejs/node/commit/8fd3ce100e)] - **src**: make base64 decoding 50% faster (Ben Noordhuis) [#2193](https://github.com/nodejs/node/pull/2193) - * [[`c786d6341d`](https://github.com/nodejs/node/commit/c786d6341d)] - **test**: do not use public IPs for timeout testing (Rich Trott) [#2057](https://github.com/nodejs/node/pull/2057) - * [[`4e78cd71c0`](https://github.com/nodejs/node/commit/4e78cd71c0)] - **test**: skip IPv6 part before testing it (Sakthipriyan Vairamani) [#2226](https://github.com/nodejs/node/pull/2226) - * [[`ac70bc8240`](https://github.com/nodejs/node/commit/ac70bc8240)] - **test**: fix valgrind uninitialized memory warning (Ben Noordhuis) [#2193](https://github.com/nodejs/node/pull/2193) - * [[`ac7d3fa0d9`](https://github.com/nodejs/node/commit/ac7d3fa0d9)] - **test**: add -no_rand_screen to s_client opts on Win (Shigeki Ohtsu) [#2209](https://github.com/nodejs/node/pull/2209) - * [[`79c865a53f`](https://github.com/nodejs/node/commit/79c865a53f)] - **test**: changing process.exit to return while skipping tests (Sakthipriyan Vairamani) [#2109](https://github.com/nodejs/node/pull/2109) - * [[`69298d36cf`](https://github.com/nodejs/node/commit/69298d36cf)] - **test**: formatting skip messages for TAP parsing (Sakthipriyan Vairamani) [#2109](https://github.com/nodejs/node/pull/2109) - * [[`543dabb609`](https://github.com/nodejs/node/commit/543dabb609)] - **timers**: improve Timer.now() performance (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) - * [[`3663b124e6`](https://github.com/nodejs/node/commit/3663b124e6)] - **timers**: remove unused Timer.again() (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) - * [[`bcce5cf9bb`](https://github.com/nodejs/node/commit/bcce5cf9bb)] - **timers**: remove unused Timer.getRepeat() (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) - * [[`f2c83bd202`](https://github.com/nodejs/node/commit/f2c83bd202)] - **timers**: remove unused Timer.setRepeat() (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) - * [[`e11fc67225`](https://github.com/nodejs/node/commit/e11fc67225)] - **(SEMVER-MINOR)** **tls**: add `getTicketKeys()`/`setTicketKeys()` (Fedor Indutny) [#2227](https://github.com/nodejs/node/pull/2227) - * [[`68b06e94e3`](https://github.com/nodejs/node/commit/68b06e94e3)] - **tools**: use local or specified $NODE for test-npm (Jeremiah Senkpiel) [#1984](https://github.com/nodejs/node/pull/1984) - * [[`ab479659c7`](https://github.com/nodejs/node/commit/ab479659c7)] - **util**: delay creation of debug context (Ali Ijaz Sheikh) [#2248](https://github.com/nodejs/node/pull/2248) - * [[`6391f4d2fd`](https://github.com/nodejs/node/commit/6391f4d2fd)] - **util**: removing redundant checks in is* functions (Sakthipriyan Vairamani) [#2179](https://github.com/nodejs/node/pull/2179) - * [[`b148c0dff3`](https://github.com/nodejs/node/commit/b148c0dff3)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) - * [[`f90f1e75bb`](https://github.com/nodejs/node/commit/f90f1e75bb)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) - - - ## 2015-07-17, Version 2.4.0, @Fishrock123 - - ### Notable changes - - * **src**: Added a new `--track-heap-objects` flag to track heap object allocations for heap snapshots (Bradley Meck) [#2135](https://github.com/nodejs/node/pull/2135). - * **readline**: Fixed a freeze that affected the repl if the keypress event handler threw (Alex Kocharin) [#2107](https://github.com/nodejs/node/pull/2107). - * **npm**: Upgraded to v2.13.0, release notes can be found in (Forrest L Norvell) [#2152](https://github.com/nodejs/node/pull/2152). - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ### Commits - - * [[`f95f9ef6ea`](https://github.com/nodejs/node/commit/f95f9ef6ea)] - **build**: always use prefix=/ for tar-headers (Rod Vagg) [#2082](https://github.com/nodejs/node/pull/2082) - * [[`12bc397207`](https://github.com/nodejs/node/commit/12bc397207)] - **build**: run-ci makefile rule (Alexis Campailla) [#2134](https://github.com/nodejs/node/pull/2134) - * [[`84012c99e0`](https://github.com/nodejs/node/commit/84012c99e0)] - **build**: fix vcbuild merge issues (Alexis Campailla) [#2131](https://github.com/nodejs/node/pull/2131) - * [[`47e2c5c828`](https://github.com/nodejs/node/commit/47e2c5c828)] - **build**: bail early if clean is invoked (Johan Bergström) [#2127](https://github.com/nodejs/node/pull/2127) - * [[`5acad6b163`](https://github.com/nodejs/node/commit/5acad6b163)] - **child_process**: fix arguments comments (Roman Reiss) [#2161](https://github.com/nodejs/node/pull/2161) - * [[`3c4121c418`](https://github.com/nodejs/node/commit/3c4121c418)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`938cc757bb`](https://github.com/nodejs/node/commit/938cc757bb)] - **deps**: upgrade to npm 2.13.0 (Forrest L Norvell) [#2152](https://github.com/nodejs/node/pull/2152) - * [[`6f306e0ed2`](https://github.com/nodejs/node/commit/6f306e0ed2)] - **doc**: add targos as a collaborator (Michaël Zasso) [#2200](https://github.com/nodejs/node/pull/2200) - * [[`c019d9a239`](https://github.com/nodejs/node/commit/c019d9a239)] - **doc**: add thefourtheye as a collaborator (Sakthipriyan Vairamani) [#2199](https://github.com/nodejs/node/pull/2199) - * [[`4e92dbc26b`](https://github.com/nodejs/node/commit/4e92dbc26b)] - **doc**: add TSC members from the combined project (Jeremiah Senkpiel) [#2085](https://github.com/nodejs/node/pull/2085) - * [[`6c3aabf455`](https://github.com/nodejs/node/commit/6c3aabf455)] - **doc**: add TSC meeting minutes 2015-07-08 (Rod Vagg) [#2184](https://github.com/nodejs/node/pull/2184) - * [[`30a0d47d51`](https://github.com/nodejs/node/commit/30a0d47d51)] - **doc**: add TSC meeting minutes 2015-07-01 (Rod Vagg) [#2132](https://github.com/nodejs/node/pull/2132) - * [[`23efb05cc3`](https://github.com/nodejs/node/commit/23efb05cc3)] - **doc**: document fs.watchFile behaviour on ENOENT (Brendan Ashworth) [#2093](https://github.com/nodejs/node/pull/2093) - * [[`65963ec26f`](https://github.com/nodejs/node/commit/65963ec26f)] - **doc,test**: empty strings in path module (Sakthipriyan Vairamani) [#2106](https://github.com/nodejs/node/pull/2106) - * [[`0ab81e6f58`](https://github.com/nodejs/node/commit/0ab81e6f58)] - **docs**: link to more up-to-date v8 docs (Jeremiah Senkpiel) [#2196](https://github.com/nodejs/node/pull/2196) - * [[`1afc0c9e86`](https://github.com/nodejs/node/commit/1afc0c9e86)] - **fs**: fix error on bad listener type (Brendan Ashworth) [#2093](https://github.com/nodejs/node/pull/2093) - * [[`2ba84606a6`](https://github.com/nodejs/node/commit/2ba84606a6)] - **path**: assert path.join() arguments equally (Phillip Johnsen) [#2159](https://github.com/nodejs/node/pull/2159) - * [[`bd01603201`](https://github.com/nodejs/node/commit/bd01603201)] - **readline**: fix freeze if `keypress` event throws (Alex Kocharin) [#2107](https://github.com/nodejs/node/pull/2107) - * [[`59f6b5da2a`](https://github.com/nodejs/node/commit/59f6b5da2a)] - **repl**: Prevent crash when tab-completed with Proxy (Sakthipriyan Vairamani) [#2120](https://github.com/nodejs/node/pull/2120) - * [[`cf14a2427c`](https://github.com/nodejs/node/commit/cf14a2427c)] - **(SEMVER-MINOR)** **src**: add --track-heap-objects (Bradley Meck) [#2135](https://github.com/nodejs/node/pull/2135) - * [[`2b4b600660`](https://github.com/nodejs/node/commit/2b4b600660)] - **test**: fix test-debug-port-from-cmdline (João Reis) [#2186](https://github.com/nodejs/node/pull/2186) - * [[`d4ceb16da2`](https://github.com/nodejs/node/commit/d4ceb16da2)] - **test**: properly clean up temp directory (Roman Reiss) [#2164](https://github.com/nodejs/node/pull/2164) - * [[`842eb5b853`](https://github.com/nodejs/node/commit/842eb5b853)] - **test**: add test for dgram.setTTL (Evan Lucas) [#2121](https://github.com/nodejs/node/pull/2121) - * [[`cff7300a57`](https://github.com/nodejs/node/commit/cff7300a57)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) - - - - ## 2015-07-09, Version 2.3.4, @Fishrock123 - - ### Notable changes - - * **openssl**: Upgrade to 1.0.2d, fixes CVE-2015-1793 (Alternate Chains Certificate Forgery) (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141). - * **npm**: Upgraded to v2.12.1, release notes can be found in and (Kat Marchán) [#2112](https://github.com/nodejs/node/pull/2112). - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ### Commits - - * [[`0d15161c24`](https://github.com/nodejs/node/commit/0d15161c24)] - **benchmark**: Add some path benchmarks for #1778 (Nathan Woltman) [#1778](https://github.com/nodejs/node/pull/1778) - * [[`c70e68fa32`](https://github.com/nodejs/node/commit/c70e68fa32)] - **deps**: update deps/openssl/conf/arch/*/opensslconf.h (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) - * [[`ca93f7f2e6`](https://github.com/nodejs/node/commit/ca93f7f2e6)] - **deps**: upgrade openssl sources to 1.0.2d (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) - * [[`b18c841ec1`](https://github.com/nodejs/node/commit/b18c841ec1)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`863cdbdd08`](https://github.com/nodejs/node/commit/863cdbdd08)] - **deps**: upgrade to npm 2.12.1 (Kat Marchán) [#2112](https://github.com/nodejs/node/pull/2112) - * [[`84b3915764`](https://github.com/nodejs/node/commit/84b3915764)] - **doc**: document current release procedure (Rod Vagg) [#2099](https://github.com/nodejs/node/pull/2099) - * [[`46140334cd`](https://github.com/nodejs/node/commit/46140334cd)] - **doc**: update AUTHORS list (Rod Vagg) [#2100](https://github.com/nodejs/node/pull/2100) - * [[`bca53dce76`](https://github.com/nodejs/node/commit/bca53dce76)] - **path**: refactor for performance and consistency (Nathan Woltman) [#1778](https://github.com/nodejs/node/pull/1778) - * [[`6bef15afe7`](https://github.com/nodejs/node/commit/6bef15afe7)] - **src**: remove traceSyncIO property from process (Bradley Meck) [#2143](https://github.com/nodejs/node/pull/2143) - * [[`2ba1740ba1`](https://github.com/nodejs/node/commit/2ba1740ba1)] - **test**: add missing crypto checks (Johan Bergström) [#2129](https://github.com/nodejs/node/pull/2129) - * [[`180fd392ca`](https://github.com/nodejs/node/commit/180fd392ca)] - **test**: refactor test-repl-tab-complete (Sakthipriyan Vairamani) [#2122](https://github.com/nodejs/node/pull/2122) - * [[`fb05c8e27d`](https://github.com/nodejs/node/commit/fb05c8e27d)] - ***Revert*** "**test**: add test for missing `close`/`finish` event" (Fedor Indutny) - * [[`9436a860cb`](https://github.com/nodejs/node/commit/9436a860cb)] - **test**: add test for missing `close`/`finish` event (Mark Plomer) [iojs/io.js#1373](https://github.com/iojs/io.js/pull/1373) - * [[`ee3ce2ed88`](https://github.com/nodejs/node/commit/ee3ce2ed88)] - **tools**: install gdbinit from v8 to $PREFIX/share (Ali Ijaz Sheikh) [#2123](https://github.com/nodejs/node/pull/2123) - * [[`dd523c75da`](https://github.com/nodejs/node/commit/dd523c75da)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) - - - - ## 2015-07-09, Version 1.8.4, @Fishrock123 - - **Maintenance release** - - ### Notable changes - - * **openssl**: Upgrade to 1.0.2d, fixes CVE-2015-1793 (Alternate Chains Certificate Forgery) [#2141](https://github.com/nodejs/node/pull/2141). - - ### Known issues - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) + +## 2015-09-15, io.js Version 3.3.1 @rvagg - ### Commits +### Notable changes + +* **buffer**: Fixed a minor errors that was causing crashes (Michaël Zasso) [#2635](https://github.com/nodejs/node/pull/2635), +* **child_process**: Fix error that was causing crashes (Evan Lucas) [#2727](https://github.com/nodejs/node/pull/2727) +* **crypto**: Replace use of rwlocks, unsafe on Windows XP / 2003 (Ben Noordhuis) [#2723](https://github.com/nodejs/node/pull/2723) +* **libuv**: Upgrade from 1.7.3 to 1.7.4 (Saúl Ibarra Corretgé) [#2817](https://github.com/nodejs/node/pull/2817) +* **node**: Fix faulty `process.release.libUrl` on Windows (Rod Vagg) [#2699](https://github.com/nodejs/node/pull/2699) +* **node-gyp**: Float v3.0.3 which has improved support for Node.js and io.js v0.10 to v4+ (Rod Vagg) [#2700](https://github.com/nodejs/node/pull/2700) +* **npm**: Upgrade to version 2.14.3 from 2.13.3, includes a security update, see https://github.com/npm/npm/releases/tag/v2.14.2 for more details, (Kat Marchán) [#2696](https://github.com/nodejs/node/pull/2696). +* **timers**: Improved timer performance from porting the 0.12 implementation, plus minor fixes (Jeremiah Senkpiel) [#2540](https://github.com/nodejs/node/pull/2540), (Julien Gilli) [nodejs/node-v0.x-archive#8751](https://github.com/nodejs/node-v0.x-archive/pull/8751) [nodejs/node-v0.x-archive#8905](https://github.com/nodejs/node-v0.x-archive/pull/8905) + +### Known issues + +See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. + +* Some uses of computed object shorthand properties are not handled correctly by the current version of V8. e.g. `[{ [prop]: val }]` evaluates to `[{}]`. [#2507](https://github.com/nodejs/node/issues/2507) +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). + +### Commits + +* [[`b73ff52fe6`](https://github.com/nodejs/node/commit/b73ff52fe6)] - **bindings**: close after reading module struct (Fedor Indutny) [#2792](https://github.com/nodejs/node/pull/2792) +* [[`aa1140e59a`](https://github.com/nodejs/node/commit/aa1140e59a)] - **buffer**: SlowBuffer only accept valid numeric values (Michaël Zasso) [#2635](https://github.com/nodejs/node/pull/2635) +* [[`574475d56e`](https://github.com/nodejs/node/commit/574475d56e)] - **build**: clean up the generated tap file (Sakthipriyan Vairamani) [#2837](https://github.com/nodejs/node/pull/2837) +* [[`aa0001271e`](https://github.com/nodejs/node/commit/aa0001271e)] - **build**: remote commands on staging in single session (Rod Vagg) [#2717](https://github.com/nodejs/node/pull/2717) +* [[`1428661095`](https://github.com/nodejs/node/commit/1428661095)] - **build**: fix v8_enable_handle_zapping override (Karl Skomski) [#2731](https://github.com/nodejs/node/pull/2731) +* [[`5a51edd718`](https://github.com/nodejs/node/commit/5a51edd718)] - **build**: add --enable-asan with builtin leakcheck (Karl Skomski) [#2376](https://github.com/nodejs/node/pull/2376) +* [[`618caa5de0`](https://github.com/nodejs/node/commit/618caa5de0)] - **child_process**: use stdio.fd even if it is 0 (Evan Lucas) [#2727](https://github.com/nodejs/node/pull/2727) +* [[`7be4e49cb6`](https://github.com/nodejs/node/commit/7be4e49cb6)] - **child_process**: check execFile and fork args (James M Snell) [#2667](https://github.com/nodejs/node/pull/2667) +* [[`7f5d6e72c6`](https://github.com/nodejs/node/commit/7f5d6e72c6)] - **cluster**: allow shared reused dgram sockets (Fedor Indutny) [#2548](https://github.com/nodejs/node/pull/2548) +* [[`e68c7ec498`](https://github.com/nodejs/node/commit/e68c7ec498)] - **contextify**: ignore getters during initialization (Fedor Indutny) [nodejs/io.js#2091](https://github.com/nodejs/io.js/pull/2091) +* [[`610fa964aa`](https://github.com/nodejs/node/commit/610fa964aa)] - **cpplint**: make it possible to run outside git repo (Ben Noordhuis) [#2710](https://github.com/nodejs/node/pull/2710) +* [[`4237373dd7`](https://github.com/nodejs/node/commit/4237373dd7)] - **crypto**: replace rwlocks with simple mutexes (Ben Noordhuis) [#2723](https://github.com/nodejs/node/pull/2723) +* [[`777eb00306`](https://github.com/nodejs/node/commit/777eb00306)] - **deps**: upgraded to node-gyp@3.0.3 in npm (Kat Marchán) [#2822](https://github.com/nodejs/node/pull/2822) +* [[`b729ad384b`](https://github.com/nodejs/node/commit/b729ad384b)] - **deps**: upgrade to npm 2.14.3 (Kat Marchán) [#2822](https://github.com/nodejs/node/pull/2822) +* [[`b09fde761c`](https://github.com/nodejs/node/commit/b09fde761c)] - **deps**: update libuv to version 1.7.4 (Saúl Ibarra Corretgé) [#2817](https://github.com/nodejs/node/pull/2817) +* [[`4cf225daad`](https://github.com/nodejs/node/commit/4cf225daad)] - **deps**: float node-gyp v3.0.0 (Rod Vagg) [#2700](https://github.com/nodejs/node/pull/2700) +* [[`118f48c0f3`](https://github.com/nodejs/node/commit/118f48c0f3)] - **deps**: create .npmrc during npm tests (Kat Marchán) [#2696](https://github.com/nodejs/node/pull/2696) +* [[`b3fee8e6a6`](https://github.com/nodejs/node/commit/b3fee8e6a6)] - **deps**: upgrade to npm 2.14.2 (Kat Marchán) [#2696](https://github.com/nodejs/node/pull/2696) +* [[`4593539b92`](https://github.com/nodejs/node/commit/4593539b92)] - **deps**: backport 75e43a6 from v8 upstream (saper) [#2636](https://github.com/nodejs/node/pull/2636) +* [[`2d1438cfe0`](https://github.com/nodejs/node/commit/2d1438cfe0)] - **doc**: fix broken link in repl.markdown (Danny Nemer) [#2827](https://github.com/nodejs/node/pull/2827) +* [[`9dd9c85a48`](https://github.com/nodejs/node/commit/9dd9c85a48)] - **doc**: fix typos in README (Ionică Bizău) [#2852](https://github.com/nodejs/node/pull/2852) +* [[`476125d403`](https://github.com/nodejs/node/commit/476125d403)] - **doc**: add tunniclm as a collaborator (Mike Tunnicliffe) [#2826](https://github.com/nodejs/node/pull/2826) +* [[`0603a92d48`](https://github.com/nodejs/node/commit/0603a92d48)] - **doc**: fix two doc errors in stream and process (Jeremiah Senkpiel) [#2549](https://github.com/nodejs/node/pull/2549) +* [[`da2902ddfd`](https://github.com/nodejs/node/commit/da2902ddfd)] - **doc**: use "Calls" over "Executes" for consistency (Minwoo Jung) [#2800](https://github.com/nodejs/node/pull/2800) +* [[`5e93bc4fba`](https://github.com/nodejs/node/commit/5e93bc4fba)] - **doc**: use US English for consistency (Anne-Gaelle Colom) [#2784](https://github.com/nodejs/node/pull/2784) +* [[`3ee7fbcefd`](https://github.com/nodejs/node/commit/3ee7fbcefd)] - **doc**: use 3rd person singular for consistency (Anne-Gaelle Colom) [#2765](https://github.com/nodejs/node/pull/2765) +* [[`4fdccb9eb7`](https://github.com/nodejs/node/commit/4fdccb9eb7)] - **doc**: fix comma splice in Assertion Testing doc (Rich Trott) [#2728](https://github.com/nodejs/node/pull/2728) +* [[`28c2d310d6`](https://github.com/nodejs/node/commit/28c2d310d6)] - **doc**: update AUTHORS list (Rod Vagg) +* [[`324c073fb9`](https://github.com/nodejs/node/commit/324c073fb9)] - **doc**: add TSC meeting minutes 2015-09-02 (Rod Vagg) [#2674](https://github.com/nodejs/node/pull/2674) +* [[`8929445686`](https://github.com/nodejs/node/commit/8929445686)] - **doc**: update url doc to account for escaping (Jeremiah Senkpiel) [#2605](https://github.com/nodejs/node/pull/2605) +* [[`512dad6883`](https://github.com/nodejs/node/commit/512dad6883)] - **doc**: reorder collaborators by their usernames (Johan Bergström) [#2322](https://github.com/nodejs/node/pull/2322) +* [[`8372ea2ca5`](https://github.com/nodejs/node/commit/8372ea2ca5)] - **doc,test**: enable recursive file watching in Windows (Sakthipriyan Vairamani) [#2649](https://github.com/nodejs/node/pull/2649) +* [[`daf6c533cc`](https://github.com/nodejs/node/commit/daf6c533cc)] - **events,lib**: don't require EE#listenerCount() (Jeremiah Senkpiel) [#2661](https://github.com/nodejs/node/pull/2661) +* [[`d8371a801e`](https://github.com/nodejs/node/commit/d8371a801e)] - **http_server**: fix resume after socket close (Fedor Indutny) [#2824](https://github.com/nodejs/node/pull/2824) +* [[`7f7d4fdddd`](https://github.com/nodejs/node/commit/7f7d4fdddd)] - **node-gyp**: float 3.0.1, minor fix for download url (Rod Vagg) [#2737](https://github.com/nodejs/node/pull/2737) +* [[`91cee73294`](https://github.com/nodejs/node/commit/91cee73294)] - **src**: use ZCtxt as a source for v8::Isolates (Roman Klauke) [#2547](https://github.com/nodejs/node/pull/2547) +* [[`ac98e13b95`](https://github.com/nodejs/node/commit/ac98e13b95)] - **src**: s/ia32/x86 for process.release.libUrl for win (Rod Vagg) [#2699](https://github.com/nodejs/node/pull/2699) +* [[`ca6c3223e1`](https://github.com/nodejs/node/commit/ca6c3223e1)] - **src**: use standard conform snprintf on windows (Karl Skomski) [#2404](https://github.com/nodejs/node/pull/2404) +* [[`b028978a53`](https://github.com/nodejs/node/commit/b028978a53)] - **src**: fix buffer overflow for long exception lines (Karl Skomski) [#2404](https://github.com/nodejs/node/pull/2404) +* [[`e73eafd7e7`](https://github.com/nodejs/node/commit/e73eafd7e7)] - **src**: fix memory leak in ExternString (Karl Skomski) [#2402](https://github.com/nodejs/node/pull/2402) +* [[`d370306de1`](https://github.com/nodejs/node/commit/d370306de1)] - **src**: only set v8 flags if argc > 1 (Evan Lucas) [#2646](https://github.com/nodejs/node/pull/2646) +* [[`ed087836af`](https://github.com/nodejs/node/commit/ed087836af)] - **streams**: refactor LazyTransform to internal/ (Brendan Ashworth) [#2566](https://github.com/nodejs/node/pull/2566) +* [[`993c22fe0e`](https://github.com/nodejs/node/commit/993c22fe0e)] - **test**: remove disabled test (Rich Trott) [#2841](https://github.com/nodejs/node/pull/2841) +* [[`1474f29d1f`](https://github.com/nodejs/node/commit/1474f29d1f)] - **test**: split up internet dns tests (Rich Trott) [#2802](https://github.com/nodejs/node/pull/2802) +* [[`601a97622b`](https://github.com/nodejs/node/commit/601a97622b)] - **test**: increase dgram timeout for armv6 (Rich Trott) [#2808](https://github.com/nodejs/node/pull/2808) +* [[`1dad19ba81`](https://github.com/nodejs/node/commit/1dad19ba81)] - **test**: remove valid hostname check in test-dns.js (Rich Trott) [#2785](https://github.com/nodejs/node/pull/2785) +* [[`f3d5891a3f`](https://github.com/nodejs/node/commit/f3d5891a3f)] - **test**: expect error for test_lookup_ipv6_hint on FreeBSD (Rich Trott) [#2724](https://github.com/nodejs/node/pull/2724) +* [[`2ffb21baf1`](https://github.com/nodejs/node/commit/2ffb21baf1)] - **test**: fix use of `common` before required (Rod Vagg) [#2685](https://github.com/nodejs/node/pull/2685) +* [[`b2c5479a14`](https://github.com/nodejs/node/commit/b2c5479a14)] - **test**: refactor to eliminate flaky test (Rich Trott) [#2609](https://github.com/nodejs/node/pull/2609) +* [[`fcfd15f8f9`](https://github.com/nodejs/node/commit/fcfd15f8f9)] - **test**: mark eval_messages as flaky (Alexis Campailla) [#2648](https://github.com/nodejs/node/pull/2648) +* [[`1865cad7ae`](https://github.com/nodejs/node/commit/1865cad7ae)] - **test**: mark test-vm-syntax-error-stderr as flaky (João Reis) [#2662](https://github.com/nodejs/node/pull/2662) +* [[`b0014ecd27`](https://github.com/nodejs/node/commit/b0014ecd27)] - **test**: mark test-repl-persistent-history as flaky (João Reis) [#2659](https://github.com/nodejs/node/pull/2659) +* [[`74ff9bc86c`](https://github.com/nodejs/node/commit/74ff9bc86c)] - **timers**: minor _unrefActive fixes and improvements (Jeremiah Senkpiel) [#2540](https://github.com/nodejs/node/pull/2540) +* [[`5d14a6eca7`](https://github.com/nodejs/node/commit/5d14a6eca7)] - **timers**: don't mutate unref list while iterating it (Julien Gilli) [#2540](https://github.com/nodejs/node/pull/2540) +* [[`6e744c58f2`](https://github.com/nodejs/node/commit/6e744c58f2)] - **timers**: Avoid linear scan in _unrefActive. (Julien Gilli) [#2540](https://github.com/nodejs/node/pull/2540) +* [[`07fbf835ad`](https://github.com/nodejs/node/commit/07fbf835ad)] - **tools**: open `test.tap` file in write-binary mode (Sakthipriyan Vairamani) [#2837](https://github.com/nodejs/node/pull/2837) +* [[`6d9198f7f1`](https://github.com/nodejs/node/commit/6d9198f7f1)] - **tools**: add missing tick processor polyfill (Matt Loring) [#2694](https://github.com/nodejs/node/pull/2694) +* [[`7b16597527`](https://github.com/nodejs/node/commit/7b16597527)] - **tools**: fix flakiness in test-tick-processor (Matt Loring) [#2694](https://github.com/nodejs/node/pull/2694) +* [[`ef83029356`](https://github.com/nodejs/node/commit/ef83029356)] - **tools**: remove hyphen in TAP result (Sakthipriyan Vairamani) [#2718](https://github.com/nodejs/node/pull/2718) +* [[`ac45ef9157`](https://github.com/nodejs/node/commit/ac45ef9157)] - **win,msi**: fix documentation shortcut url (Brian White) [#2781](https://github.com/nodejs/node/pull/2781) + + +## 2015-09-02, Version 3.3.0, @rvagg + +### Notable changes + +* **build**: Add a `--link-module` option to `configure` that can be used to bundle additional JavaScript modules into a built binary (Bradley Meck) [#2497](https://github.com/nodejs/node/pull/2497) +* **docs**: Merge outstanding doc updates from joyent/node (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* **http_parser**: Significant performance improvement by having `http.Server` consume all initial data from its `net.Socket` and parsing directly without having to enter JavaScript. Any `'data'` listeners on the `net.Socket` will result in the data being "unconsumed" into JavaScript, thereby undoing any performance gains. (Fedor Indutny) [#2355](https://github.com/nodejs/node/pull/2355) +* **libuv**: Upgrade to 1.7.3 (from 1.6.1), see [ChangeLog](https://github.com/libuv/libuv/blob/v1.x/ChangeLog) for details (Saúl Ibarra Corretgé) [#2310](https://github.com/nodejs/node/pull/2310) +* **V8**: Upgrade to 4.4.63.30 (from 4.4.63.26) (Michaël Zasso) [#2482](https://github.com/nodejs/node/pull/2482) + +### Known issues + +See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. + +* Some uses of computed object shorthand properties are not handled correctly by the current version of V8. e.g. `[{ [prop]: val }]` evaluates to `[{}]`. [#2507](https://github.com/nodejs/node/issues/2507) +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). + +### Commits + +* [[`1a531b4e44`](https://github.com/nodejs/node/commit/1a531b4e44)] - **(SEMVER-MINOR)** Introduce --link-module to ./configure (Bradley Meck) [#2497](https://github.com/nodejs/node/pull/2497) +* [[`d2f314c190`](https://github.com/nodejs/node/commit/d2f314c190)] - **build**: fix borked chmod call for release uploads (Rod Vagg) [#2645](https://github.com/nodejs/node/pull/2645) +* [[`3172e9c541`](https://github.com/nodejs/node/commit/3172e9c541)] - **build**: set file permissions before uploading (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) +* [[`a860d7fae1`](https://github.com/nodejs/node/commit/a860d7fae1)] - **build**: change staging directory on new server (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) +* [[`50c0baa8d7`](https://github.com/nodejs/node/commit/50c0baa8d7)] - **build**: rename 'doc' directory to 'docs' for upload (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) +* [[`0a0577cf5f`](https://github.com/nodejs/node/commit/0a0577cf5f)] - **build**: fix bad cherry-pick for vcbuild.bat build-release (Rod Vagg) [#2625](https://github.com/nodejs/node/pull/2625) +* [[`34de90194b`](https://github.com/nodejs/node/commit/34de90194b)] - **build**: only define NODE_V8_OPTIONS if not empty (Evan Lucas) [#2532](https://github.com/nodejs/node/pull/2532) +* [[`944174b189`](https://github.com/nodejs/node/commit/944174b189)] - **build**: make ci test addons in test/addons (Ben Noordhuis) [#2428](https://github.com/nodejs/node/pull/2428) +* [[`e955f9a1b0`](https://github.com/nodejs/node/commit/e955f9a1b0)] - **crypto**: Use OPENSSL_cleanse to shred the data. (Сковорода Никита Андреевич) [#2575](https://github.com/nodejs/node/pull/2575) +* [[`395d736b9d`](https://github.com/nodejs/node/commit/395d736b9d)] - **debugger**: use strict equality comparison (Minwoo Jung) [#2558](https://github.com/nodejs/node/pull/2558) +* [[`1d0e5210a8`](https://github.com/nodejs/node/commit/1d0e5210a8)] - **deps**: upgrade libuv to 1.7.3 (Saúl Ibarra Corretgé) [#2310](https://github.com/nodejs/node/pull/2310) +* [[`34ef53364f`](https://github.com/nodejs/node/commit/34ef53364f)] - **deps**: update V8 to 4.4.63.30 (Michaël Zasso) [#2482](https://github.com/nodejs/node/pull/2482) +* [[`23579a5f4a`](https://github.com/nodejs/node/commit/23579a5f4a)] - **doc**: add TSC meeting minutes 2015-08-12 (Rod Vagg) [#2438](https://github.com/nodejs/node/pull/2438) +* [[`0cc59299a4`](https://github.com/nodejs/node/commit/0cc59299a4)] - **doc**: add TSC meeting minutes 2015-08-26 (Rod Vagg) [#2591](https://github.com/nodejs/node/pull/2591) +* [[`6efa96e33a`](https://github.com/nodejs/node/commit/6efa96e33a)] - **doc**: merge CHANGELOG.md with joyent/node ChangeLog (Minqi Pan) [#2536](https://github.com/nodejs/node/pull/2536) +* [[`f75d54607b`](https://github.com/nodejs/node/commit/f75d54607b)] - **doc**: clarify cluster behaviour with no workers (Jeremiah Senkpiel) [#2606](https://github.com/nodejs/node/pull/2606) +* [[`8936302121`](https://github.com/nodejs/node/commit/8936302121)] - **doc**: minor clarification in buffer.markdown (Сковорода Никита Андреевич) [#2574](https://github.com/nodejs/node/pull/2574) +* [[`0db0e53753`](https://github.com/nodejs/node/commit/0db0e53753)] - **doc**: add @jasnell and @sam-github to release team (Rod Vagg) [#2455](https://github.com/nodejs/node/pull/2455) +* [[`c16e100593`](https://github.com/nodejs/node/commit/c16e100593)] - **doc**: reorg release team to separate section (Rod Vagg) [#2455](https://github.com/nodejs/node/pull/2455) +* [[`e3e00143fd`](https://github.com/nodejs/node/commit/e3e00143fd)] - **doc**: fix bad merge on modules.markdown (James M Snell) +* [[`2f62455880`](https://github.com/nodejs/node/commit/2f62455880)] - **doc**: minor additional corrections and improvements (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`3bd08aac4b`](https://github.com/nodejs/node/commit/3bd08aac4b)] - **doc**: minor grammatical update in crypto.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`f707189370`](https://github.com/nodejs/node/commit/f707189370)] - **doc**: minor grammatical update (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`6c98cf0266`](https://github.com/nodejs/node/commit/6c98cf0266)] - **doc**: remove repeated statement in globals.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`48e6ccf8c2`](https://github.com/nodejs/node/commit/48e6ccf8c2)] - **doc**: remove 'dudes' from documentation (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`b5d68f8076`](https://github.com/nodejs/node/commit/b5d68f8076)] - **doc**: update tense in child_process.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`242e3fe3ba`](https://github.com/nodejs/node/commit/242e3fe3ba)] - **doc**: fixed worker.id type (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`ea9ee15c21`](https://github.com/nodejs/node/commit/ea9ee15c21)] - **doc**: port is optional for socket.bind() (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`0ff6657a50`](https://github.com/nodejs/node/commit/0ff6657a50)] - **doc**: fix minor types and grammar in fs docs (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`94d83c04f2`](https://github.com/nodejs/node/commit/94d83c04f2)] - **doc**: update parameter name in net.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`04111ce40f`](https://github.com/nodejs/node/commit/04111ce40f)] - **doc**: small typo in domain.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`c9fdd1bbbf`](https://github.com/nodejs/node/commit/c9fdd1bbbf)] - **doc**: fixed typo in net.markdown (missing comma) (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`27c07b3f8e`](https://github.com/nodejs/node/commit/27c07b3f8e)] - **doc**: update description of fs.exists in fs.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`52018e73d9`](https://github.com/nodejs/node/commit/52018e73d9)] - **doc**: clarification on the 'close' event (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`f6d3b87a25`](https://github.com/nodejs/node/commit/f6d3b87a25)] - **doc**: improve working in stream.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`b5da89431a`](https://github.com/nodejs/node/commit/b5da89431a)] - **doc**: update path.extname documentation (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`1d4ea609db`](https://github.com/nodejs/node/commit/1d4ea609db)] - **doc**: small clarifications to modules.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`c888985591`](https://github.com/nodejs/node/commit/c888985591)] - **doc**: code style cleanups in repl.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`105b493595`](https://github.com/nodejs/node/commit/105b493595)] - **doc**: correct grammar in cluster.markdown (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`51b86ccac7`](https://github.com/nodejs/node/commit/51b86ccac7)] - **doc**: Clarify the module.parent is set once (James M Snell) [#2378](https://github.com/nodejs/node/pull/2378) +* [[`d2ffecba2d`](https://github.com/nodejs/node/commit/d2ffecba2d)] - **doc**: add internal modules notice (Jeremiah Senkpiel) [#2523](https://github.com/nodejs/node/pull/2523) +* [[`b36debd5cb`](https://github.com/nodejs/node/commit/b36debd5cb)] - **env**: introduce `KickNextTick` (Fedor Indutny) [#2355](https://github.com/nodejs/node/pull/2355) +* [[`1bc446863f`](https://github.com/nodejs/node/commit/1bc446863f)] - **http_parser**: consume StreamBase instance (Fedor Indutny) [#2355](https://github.com/nodejs/node/pull/2355) +* [[`ce04b735cc`](https://github.com/nodejs/node/commit/ce04b735cc)] - **src**: only memcmp if length > 0 in Buffer::Compare (Karl Skomski) [#2544](https://github.com/nodejs/node/pull/2544) +* [[`31823e37c7`](https://github.com/nodejs/node/commit/31823e37c7)] - **src**: DRY getsockname/getpeername code (Ben Noordhuis) [#956](https://github.com/nodejs/node/pull/956) +* [[`13fd96dda3`](https://github.com/nodejs/node/commit/13fd96dda3)] - **src**: missing Exception::Error in node_http_parser (Jeremiah Senkpiel) [#2550](https://github.com/nodejs/node/pull/2550) +* [[`42e075ae02`](https://github.com/nodejs/node/commit/42e075ae02)] - **test**: improve performance of stringbytes test (Trevor Norris) [#2544](https://github.com/nodejs/node/pull/2544) +* [[`fc726399fd`](https://github.com/nodejs/node/commit/fc726399fd)] - **test**: unmark test-process-argv-0.js as flaky (Rich Trott) [#2613](https://github.com/nodejs/node/pull/2613) +* [[`7727ba1394`](https://github.com/nodejs/node/commit/7727ba1394)] - **test**: lint and refactor to avoid autocrlf issue (Roman Reiss) [#2494](https://github.com/nodejs/node/pull/2494) +* [[`c56aa829f0`](https://github.com/nodejs/node/commit/c56aa829f0)] - **test**: use tmpDir instead of fixturesDir (Sakthipriyan Vairamani) [#2583](https://github.com/nodejs/node/pull/2583) +* [[`5e65181ea4`](https://github.com/nodejs/node/commit/5e65181ea4)] - **test**: handling failure cases properly (Sakthipriyan Vairamani) [#2206](https://github.com/nodejs/node/pull/2206) +* [[`c48b95e847`](https://github.com/nodejs/node/commit/c48b95e847)] - **test**: initial list of flaky tests (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) +* [[`94e88498ba`](https://github.com/nodejs/node/commit/94e88498ba)] - **test**: pass args to test-ci via env variable (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) +* [[`09987c7a1c`](https://github.com/nodejs/node/commit/09987c7a1c)] - **test**: support flaky tests in test-ci (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) +* [[`08b83c8b45`](https://github.com/nodejs/node/commit/08b83c8b45)] - **test**: add test configuration templates (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) +* [[`8f8ab6fa57`](https://github.com/nodejs/node/commit/8f8ab6fa57)] - **test**: runner should return 0 on flaky tests (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) +* [[`0cfd3be9c6`](https://github.com/nodejs/node/commit/0cfd3be9c6)] - **test**: runner support for flaky tests (Alexis Campailla) [#2424](https://github.com/nodejs/node/pull/2424) +* [[`3492d2d4c6`](https://github.com/nodejs/node/commit/3492d2d4c6)] - **test**: make test-process-argv-0 robust (Rich Trott) [#2541](https://github.com/nodejs/node/pull/2541) +* [[`a96cc31710`](https://github.com/nodejs/node/commit/a96cc31710)] - **test**: speed up test-child-process-spawnsync.js (Rich Trott) [#2542](https://github.com/nodejs/node/pull/2542) +* [[`856baf4c67`](https://github.com/nodejs/node/commit/856baf4c67)] - **test**: make spawnSync() test robust (Rich Trott) [#2535](https://github.com/nodejs/node/pull/2535) +* [[`3aa6bbb648`](https://github.com/nodejs/node/commit/3aa6bbb648)] - **tools**: update release.sh to work with new website (Rod Vagg) [#2623](https://github.com/nodejs/node/pull/2623) +* [[`f2f0fe45ff`](https://github.com/nodejs/node/commit/f2f0fe45ff)] - **tools**: make add-on scraper print filenames (Ben Noordhuis) [#2428](https://github.com/nodejs/node/pull/2428) +* [[`bb24c4a418`](https://github.com/nodejs/node/commit/bb24c4a418)] - **win,msi**: correct installation path registry keys (João Reis) [#2565](https://github.com/nodejs/node/pull/2565) +* [[`752977b888`](https://github.com/nodejs/node/commit/752977b888)] - **win,msi**: change InstallScope to perMachine (João Reis) [#2565](https://github.com/nodejs/node/pull/2565) + + +## 2015-08-25, Version 3.2.0, @rvagg + +### Notable changes + +* **events**: Added `EventEmitter#listenerCount(event)` as a replacement for `EventEmitter.listenerCount(emitter, event)`, which has now been marked as deprecated in the docs. (Sakthipriyan Vairamani) [#2349](https://github.com/nodejs/node/pull/2349) +* **module**: Fixed an error with preloaded modules when the current working directory doesn't exist. (Bradley Meck) [#2353](https://github.com/nodejs/node/pull/2353) +* **node**: Startup time is now about 5% faster when not passing V8 flags. (Evan Lucas) [#2483](https://github.com/nodejs/node/pull/2483) +* **repl**: Tab-completion now works better with arrays. (James M Snell) [#2409](https://github.com/nodejs/node/pull/2409) +* **string_bytes**: Fixed an unaligned write in the handling of UCS2 encoding. (Fedor Indutny) [#2480](https://github.com/nodejs/node/pull/2480) +* **tls**: Added a new `--tls-cipher-list` flag that can be used to override the built-in default cipher list. (James M Snell) [#2412](https://github.com/nodejs/node/pull/2412) _Note: it is suggested you use the built-in cipher list as it has been carefully selected to reflect current security best practices and risk mitigation._ + +### Known issues + +See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. + +* Some uses of computed object shorthand properties are not handled correctly by the current version of V8. e.g. `[{ [prop]: val }]` evaluates to `[{}]`. [#2507](https://github.com/nodejs/node/issues/2507) +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). + +### Commits + +* [[`1cd794f129`](https://github.com/nodejs/node/commit/1cd794f129)] - **buffer**: reapply 07c0667 (Fedor Indutny) [#2487](https://github.com/nodejs/node/pull/2487) +* [[`156781dedd`](https://github.com/nodejs/node/commit/156781dedd)] - **build**: use required platform in android-configure (Evan Lucas) [#2501](https://github.com/nodejs/node/pull/2501) +* [[`77075ec906`](https://github.com/nodejs/node/commit/77075ec906)] - **crypto**: fix mem {de}allocation in ExportChallenge (Karl Skomski) [#2359](https://github.com/nodejs/node/pull/2359) +* [[`cb30414d9e`](https://github.com/nodejs/node/commit/cb30414d9e)] - **doc**: sync CHANGELOG.md from master (Roman Reiss) [#2524](https://github.com/nodejs/node/pull/2524) +* [[`9330f5ef45`](https://github.com/nodejs/node/commit/9330f5ef45)] - **doc**: make the deprecations consistent (Sakthipriyan Vairamani) [#2450](https://github.com/nodejs/node/pull/2450) +* [[`09437e0146`](https://github.com/nodejs/node/commit/09437e0146)] - **doc**: fix comments in tls_wrap.cc and _http_client.js (Minwoo Jung) [#2489](https://github.com/nodejs/node/pull/2489) +* [[`c9867fed29`](https://github.com/nodejs/node/commit/c9867fed29)] - **doc**: document response.finished in http.markdown (hackerjs) [#2414](https://github.com/nodejs/node/pull/2414) +* [[`7f23a83c42`](https://github.com/nodejs/node/commit/7f23a83c42)] - **doc**: update AUTHORS list (Rod Vagg) [#2505](https://github.com/nodejs/node/pull/2505) +* [[`cd0c362f67`](https://github.com/nodejs/node/commit/cd0c362f67)] - **doc**: update AUTHORS list (Rod Vagg) [#2318](https://github.com/nodejs/node/pull/2318) +* [[`2c7b9257ea`](https://github.com/nodejs/node/commit/2c7b9257ea)] - **doc**: add TSC meeting minutes 2015-07-29 (Rod Vagg) [#2437](https://github.com/nodejs/node/pull/2437) +* [[`aaefde793e`](https://github.com/nodejs/node/commit/aaefde793e)] - **doc**: add TSC meeting minutes 2015-08-19 (Rod Vagg) [#2460](https://github.com/nodejs/node/pull/2460) +* [[`51ef9106f5`](https://github.com/nodejs/node/commit/51ef9106f5)] - **doc**: add TSC meeting minutes 2015-06-03 (Rod Vagg) [#2453](https://github.com/nodejs/node/pull/2453) +* [[`7130b4cf1d`](https://github.com/nodejs/node/commit/7130b4cf1d)] - **doc**: fix links to original converged repo (Rod Vagg) [#2454](https://github.com/nodejs/node/pull/2454) +* [[`14f2aee1df`](https://github.com/nodejs/node/commit/14f2aee1df)] - **doc**: fix links to original gh issues for TSC meetings (Rod Vagg) [#2454](https://github.com/nodejs/node/pull/2454) +* [[`87a9ef0a40`](https://github.com/nodejs/node/commit/87a9ef0a40)] - **doc**: add audio recording links to TSC meeting minutes (Rod Vagg) [#2454](https://github.com/nodejs/node/pull/2454) +* [[`f5cf24afbc`](https://github.com/nodejs/node/commit/f5cf24afbc)] - **doc**: add TSC meeting minutes 2015-07-22 (Rod Vagg) [#2436](https://github.com/nodejs/node/pull/2436) +* [[`3f821b96eb`](https://github.com/nodejs/node/commit/3f821b96eb)] - **doc**: fix spelling mistake in node.js comment (Jacob Edelman) [#2391](https://github.com/nodejs/node/pull/2391) +* [[`3e6a6fcdd6`](https://github.com/nodejs/node/commit/3e6a6fcdd6)] - **(SEMVER-MINOR)** **events**: deprecate static listenerCount function (Sakthipriyan Vairamani) [#2349](https://github.com/nodejs/node/pull/2349) +* [[`023386c852`](https://github.com/nodejs/node/commit/023386c852)] - **fs**: replace bad_args macro with concrete error msg (Roman Klauke) [#2495](https://github.com/nodejs/node/pull/2495) +* [[`d1c27b2e29`](https://github.com/nodejs/node/commit/d1c27b2e29)] - **module**: fix module preloading when cwd is ENOENT (Bradley Meck) [#2353](https://github.com/nodejs/node/pull/2353) +* [[`5d7486941b`](https://github.com/nodejs/node/commit/5d7486941b)] - **repl**: filter integer keys from repl tab complete list (James M Snell) [#2409](https://github.com/nodejs/node/pull/2409) +* [[`7f02443a9a`](https://github.com/nodejs/node/commit/7f02443a9a)] - **repl**: dont throw ENOENT on NODE_REPL_HISTORY_FILE (Todd Kennedy) [#2451](https://github.com/nodejs/node/pull/2451) +* [[`56a2ae9cef`](https://github.com/nodejs/node/commit/56a2ae9cef)] - **src**: improve startup time (Evan Lucas) [#2483](https://github.com/nodejs/node/pull/2483) +* [[`14653c7429`](https://github.com/nodejs/node/commit/14653c7429)] - **stream**: rename poorly named function (Ben Noordhuis) [#2479](https://github.com/nodejs/node/pull/2479) +* [[`1c6e014bfa`](https://github.com/nodejs/node/commit/1c6e014bfa)] - **stream**: micro-optimize high water mark calculation (Ben Noordhuis) [#2479](https://github.com/nodejs/node/pull/2479) +* [[`f1f4b4c46d`](https://github.com/nodejs/node/commit/f1f4b4c46d)] - **stream**: fix off-by-factor-16 error in comment (Ben Noordhuis) [#2479](https://github.com/nodejs/node/pull/2479) +* [[`2d3f09bd76`](https://github.com/nodejs/node/commit/2d3f09bd76)] - **stream_base**: various improvements (Fedor Indutny) [#2351](https://github.com/nodejs/node/pull/2351) +* [[`c1ce423b35`](https://github.com/nodejs/node/commit/c1ce423b35)] - **string_bytes**: fix unaligned write in UCS2 (Fedor Indutny) [#2480](https://github.com/nodejs/node/pull/2480) +* [[`e4d0e86165`](https://github.com/nodejs/node/commit/e4d0e86165)] - **test**: refactor test-https-simple.js (Rich Trott) [#2433](https://github.com/nodejs/node/pull/2433) +* [[`0ea5c8d737`](https://github.com/nodejs/node/commit/0ea5c8d737)] - **test**: remove test-timers-first-fire (João Reis) [#2458](https://github.com/nodejs/node/pull/2458) +* [[`536c3d0537`](https://github.com/nodejs/node/commit/536c3d0537)] - **test**: use reserved IP in test-net-connect-timeout (Rich Trott) [#2257](https://github.com/nodejs/node/pull/2257) +* [[`5df06fd8df`](https://github.com/nodejs/node/commit/5df06fd8df)] - **test**: add spaces after keywords (Brendan Ashworth) +* [[`e714b5620e`](https://github.com/nodejs/node/commit/e714b5620e)] - **test**: remove unreachable code (Michaël Zasso) [#2289](https://github.com/nodejs/node/pull/2289) +* [[`3579f3a2a4`](https://github.com/nodejs/node/commit/3579f3a2a4)] - **test**: disallow unreachable code (Michaël Zasso) [#2289](https://github.com/nodejs/node/pull/2289) +* [[`3545e236fc`](https://github.com/nodejs/node/commit/3545e236fc)] - **test**: reduce timeouts in test-net-keepalive (Brendan Ashworth) [#2429](https://github.com/nodejs/node/pull/2429) +* [[`b60e690023`](https://github.com/nodejs/node/commit/b60e690023)] - **test**: improve test-net-server-pause-on-connect (Brendan Ashworth) [#2429](https://github.com/nodejs/node/pull/2429) +* [[`11d1b8fcaf`](https://github.com/nodejs/node/commit/11d1b8fcaf)] - **test**: improve test-net-pingpong (Brendan Ashworth) [#2429](https://github.com/nodejs/node/pull/2429) +* [[`5fef5c6562`](https://github.com/nodejs/node/commit/5fef5c6562)] - **(SEMVER-MINOR)** **tls**: add --tls-cipher-list command line switch (James M Snell) [#2412](https://github.com/nodejs/node/pull/2412) +* [[`d9b70f9cbf`](https://github.com/nodejs/node/commit/d9b70f9cbf)] - **tls**: handle empty cert in checkServerIndentity (Mike Atkins) [#2343](https://github.com/nodejs/node/pull/2343) +* [[`4f8e34c202`](https://github.com/nodejs/node/commit/4f8e34c202)] - **tools**: add license boilerplate to check-imports.sh (James M Snell) [#2386](https://github.com/nodejs/node/pull/2386) +* [[`b76b9197f9`](https://github.com/nodejs/node/commit/b76b9197f9)] - **tools**: enable space-after-keywords in eslint (Brendan Ashworth) +* [[`64a8f30a70`](https://github.com/nodejs/node/commit/64a8f30a70)] - **tools**: fix anchors in generated documents (Sakthipriyan Vairamani) [#2491](https://github.com/nodejs/node/pull/2491) +* [[`22e344ea10`](https://github.com/nodejs/node/commit/22e344ea10)] - **win**: fix custom actions for WiX older than 3.9 (João Reis) [#2365](https://github.com/nodejs/node/pull/2365) +* [[`b5bd3ebfc8`](https://github.com/nodejs/node/commit/b5bd3ebfc8)] - **win**: fix custom actions on Visual Studio != 2013 (Julien Gilli) [#2365](https://github.com/nodejs/node/pull/2365) + + +## 2015-08-18, Version 3.1.0, @Fishrock123 + +### Notable changes + +* **buffer**: Fixed a couple large memory leaks (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352). +* **crypto**: + - Fixed a couple of minor memory leaks (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375). + - Signing now checks for OpenSSL errors (Minqi Pan) [#2342](https://github.com/nodejs/node/pull/2342). **Note that this may expose previously hidden errors in user code.** +* **intl**: Intl support using small-icu is now enabled by default in builds (Steven R. Loomis) [#2264](https://github.com/nodejs/node/pull/2264). + - [`String#normalize()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) can now be used for unicode normalization. + - The [`Intl`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl) object and various `String` and `Number` methods are present, but only support the English locale. + - For support of all locales, node must be built with [full-icu](https://github.com/nodejs/node#build-with-full-icu-support-all-locales-supported-by-icu). +* **tls**: Fixed tls throughput being much lower after an incorrect merge (Fedor Indutny) [#2381](https://github.com/nodejs/node/pull/2381). +* **tools**: The v8 tick processor now comes bundled with node (Matt Loring) [#2090](https://github.com/nodejs/node/pull/2090). + - This can be used by producing performance profiling output by running node with `--perf`, then running your appropriate platform's script on the output as found in [tools/v8-prof](https://github.com/nodejs/node/tree/master/tools/v8-prof). +* **util**: `util.inspect(obj)` now prints the constructor name of the object if there is one (Christopher Monsanto) [#1935](https://github.com/nodejs/io.js/pull/1935). + +### Known issues + +See https://github.com/nodejs/io.js/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/io.js/issues/1264). +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/io.js/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/io.js/issues/760). +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/io.js/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/io.js/issues/1435). + +### Commits + +* [[`3645dc62ed`](https://github.com/nodejs/node/commit/3645dc62ed)] - **build**: work around VS2015 issue in ICU <56 (Steven R. Loomis) [#2283](https://github.com/nodejs/node/pull/2283) +* [[`1f12e03266`](https://github.com/nodejs/node/commit/1f12e03266)] - **(SEMVER-MINOR)** **build**: intl: converge from joyent/node (Steven R. Loomis) [#2264](https://github.com/nodejs/node/pull/2264) +* [[`071640abdd`](https://github.com/nodejs/node/commit/071640abdd)] - **build**: Intl: bump ICU4C from 54 to 55 (Steven R. Loomis) [#2293](https://github.com/nodejs/node/pull/2293) +* [[`07a88b0c8b`](https://github.com/nodejs/node/commit/07a88b0c8b)] - **build**: update manifest to include Windows 10 (Lucien Greathouse) [#2332](https://github.com/nodejs/io.js/pull/2332) +* [[`0bb099f444`](https://github.com/nodejs/node/commit/0bb099f444)] - **build**: expand ~ in install prefix early (Ben Noordhuis) [#2307](https://github.com/nodejs/io.js/pull/2307) +* [[`7fe6dd8f5d`](https://github.com/nodejs/node/commit/7fe6dd8f5d)] - **crypto**: check for OpenSSL errors when signing (Minqi Pan) [#2342](https://github.com/nodejs/node/pull/2342) +* [[`605f6ee904`](https://github.com/nodejs/node/commit/605f6ee904)] - **crypto**: fix memory leak in PBKDF2Request (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) +* [[`ba6eb8af12`](https://github.com/nodejs/node/commit/ba6eb8af12)] - **crypto**: fix memory leak in ECDH::SetPrivateKey (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) +* [[`6a16368611`](https://github.com/nodejs/node/commit/6a16368611)] - **crypto**: fix memory leak in PublicKeyCipher::Cipher (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) +* [[`a760a87803`](https://github.com/nodejs/node/commit/a760a87803)] - **crypto**: fix memory leak in SafeX509ExtPrint (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) +* [[`f45487cd6e`](https://github.com/nodejs/node/commit/f45487cd6e)] - **crypto**: fix memory leak in SetDHParam (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) +* [[`2ff183dd86`](https://github.com/nodejs/node/commit/2ff183dd86)] - **doc**: Update FIPS instructions in README.md (Michael Dawson) [#2278](https://github.com/nodejs/node/pull/2278) +* [[`6483bc2e8f`](https://github.com/nodejs/node/commit/6483bc2e8f)] - **doc**: clarify options for fs.watchFile() (Rich Trott) [#2425](https://github.com/nodejs/node/pull/2425) +* [[`e76822f454`](https://github.com/nodejs/node/commit/e76822f454)] - **doc**: multiple documentation updates cherry picked from v0.12 (James M Snell) [#2302](https://github.com/nodejs/io.js/pull/2302) +* [[`1738c9680b`](https://github.com/nodejs/node/commit/1738c9680b)] - **net**: ensure Socket reported address is current (Ryan Graham) [#2095](https://github.com/nodejs/io.js/pull/2095) +* [[`844d3f0e3e`](https://github.com/nodejs/node/commit/844d3f0e3e)] - **path**: use '===' instead of '==' for comparison (Sam Stites) [#2388](https://github.com/nodejs/node/pull/2388) +* [[`7118b8a882`](https://github.com/nodejs/node/commit/7118b8a882)] - **path**: remove dead code in favor of unit tests (Nathan Woltman) [#2282](https://github.com/nodejs/io.js/pull/2282) +* [[`34f2cfa806`](https://github.com/nodejs/node/commit/34f2cfa806)] - **src**: better error message on failed Buffer malloc (Karl Skomski) [#2422](https://github.com/nodejs/node/pull/2422) +* [[`b196c1da3c`](https://github.com/nodejs/node/commit/b196c1da3c)] - **src**: fix memory leak in DLOpen (Karl Skomski) [#2375](https://github.com/nodejs/node/pull/2375) +* [[`d1307b2995`](https://github.com/nodejs/node/commit/d1307b2995)] - **src**: don't use fopen() in require() fast path (Ben Noordhuis) [#2377](https://github.com/nodejs/node/pull/2377) +* [[`455ec570d1`](https://github.com/nodejs/node/commit/455ec570d1)] - **src**: rename Buffer::Use() to Buffer::New() (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) +* [[`fd63e1ce2b`](https://github.com/nodejs/node/commit/fd63e1ce2b)] - **src**: introduce internal Buffer::Copy() function (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) +* [[`5586ceca13`](https://github.com/nodejs/node/commit/5586ceca13)] - **src**: move internal functions out of node_buffer.h (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) +* [[`bff9bcddb6`](https://github.com/nodejs/node/commit/bff9bcddb6)] - **src**: plug memory leaks (Ben Noordhuis) [#2352](https://github.com/nodejs/node/pull/2352) +* [[`ccf12df4f3`](https://github.com/nodejs/node/commit/ccf12df4f3)] - **(SEMVER-MINOR)** **src**: add total_available_size to v8 statistics (Roman Klauke) [#2348](https://github.com/nodejs/io.js/pull/2348) +* [[`194eeb841b`](https://github.com/nodejs/node/commit/194eeb841b)] - **test**: drop Isolate::GetCurrent() from addon tests (Ben Noordhuis) [#2427](https://github.com/nodejs/node/pull/2427) +* [[`46cdb2f6e2`](https://github.com/nodejs/node/commit/46cdb2f6e2)] - **test**: lint addon tests (Ben Noordhuis) [#2427](https://github.com/nodejs/node/pull/2427) +* [[`850c794882`](https://github.com/nodejs/node/commit/850c794882)] - **test**: refactor test-fs-watchfile.js (Rich Trott) [#2393](https://github.com/nodejs/node/pull/2393) +* [[`a3160c0a33`](https://github.com/nodejs/node/commit/a3160c0a33)] - **test**: correct spelling of 'childProcess' (muddletoes) [#2389](https://github.com/nodejs/node/pull/2389) +* [[`e51f90d747`](https://github.com/nodejs/node/commit/e51f90d747)] - **test**: option to run a subset of tests (João Reis) [#2260](https://github.com/nodejs/io.js/pull/2260) +* [[`cc46d3bca3`](https://github.com/nodejs/node/commit/cc46d3bca3)] - **test**: clarify dropMembership() call (Rich Trott) [#2062](https://github.com/nodejs/io.js/pull/2062) +* [[`0ee4df9c7a`](https://github.com/nodejs/node/commit/0ee4df9c7a)] - **test**: make listen-fd-cluster/server more robust (Sam Roberts) [#1944](https://github.com/nodejs/io.js/pull/1944) +* [[`cf9ba81398`](https://github.com/nodejs/node/commit/cf9ba81398)] - **test**: address timing issues in simple http tests (Gireesh Punathil) [#2294](https://github.com/nodejs/io.js/pull/2294) +* [[`cbb75c4f86`](https://github.com/nodejs/node/commit/cbb75c4f86)] - **tls**: fix throughput issues after incorrect merge (Fedor Indutny) [#2381](https://github.com/nodejs/node/pull/2381) +* [[`94b765f409`](https://github.com/nodejs/node/commit/94b765f409)] - **tls**: fix check for reused session (Fedor Indutny) [#2312](https://github.com/nodejs/io.js/pull/2312) +* [[`e83a41ad65`](https://github.com/nodejs/node/commit/e83a41ad65)] - **tls**: introduce internal `onticketkeycallback` (Fedor Indutny) [#2312](https://github.com/nodejs/io.js/pull/2312) +* [[`fb0f5d733f`](https://github.com/nodejs/node/commit/fb0f5d733f)] - **(SEMVER-MINOR)** **tools**: run the tick processor without building v8 (Matt Loring) [#2090](https://github.com/nodejs/node/pull/2090) +* [[`7606bdb897`](https://github.com/nodejs/node/commit/7606bdb897)] - **(SEMVER-MINOR)** **util**: display constructor when inspecting objects (Christopher Monsanto) [#1935](https://github.com/nodejs/io.js/pull/1935) + + +## 2015-08-04, Version 3.0.0, @rvagg + +### Notable changes + +* **buffer**: + - Due to changes in V8, it has been necessary to reimplement `Buffer` on top of V8's `Uint8Array`. Every effort has been made to minimize the performance impact, however `Buffer` instantiation is measurably slower. Access operations may be faster in some circumstances but the exact performance profile and difference over previous versions will depend on how `Buffer` is used within applications. (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825). + - `Buffer` can now take `ArrayBuffer`s as a constructor argument (Trevor Norris) [#2002](https://github.com/nodejs/node/pull/2002). + - When a single buffer is passed to `Buffer.concat()`, a new, copied `Buffer` object will be returned; previous behavior was to return the original `Buffer` object (Sakthipriyan Vairamani) [#1937](https://github.com/nodejs/node/pull/1937). +* **build**: PPC support has been added to core to allow compiling on pLinux BE and LE (AIX support coming soon) (Michael Dawson) [#2124](https://github.com/nodejs/node/pull/2124). +* **dgram**: If an error occurs within `socket.send()` and a callback has been provided, the error is only passed as the first argument to the callback and not emitted on the `socket` object; previous behavior was to do both (Matteo Collina & Chris Dickinson) [#1796](https://github.com/nodejs/node/pull/1796) +* **freelist**: Deprecate the undocumented `freelist` core module (Sakthipriyan Vairamani) [#2176](https://github.com/nodejs/node/pull/2176). +* **http**: + - Status codes now all use the official [IANA names](http://www.iana.org/assignments/http-status-codes) as per [RFC7231](https://tools.ietf.org/html/rfc7231), e.g. `http.STATUS_CODES[414]` now returns `'URI Too Long'` rather than `'Request-URI Too Large'` (jomo) [#1470](https://github.com/nodejs/node/pull/1470). + - Calling .getName() on an HTTP agent no longer returns a trailing colon, HTTPS agents will no longer return an extra colon near the middle of the string (Brendan Ashworth) [#1617](https://github.com/nodejs/node/pull/1617). +* **node**: + - `NODE_MODULE_VERSION` has been bumped to `45` to reflect the break in ABI (Rod Vagg) [#2096](https://github.com/nodejs/node/pull/2096). + - Introduce a new `process.release` object that contains a `name` property set to `'io.js'` and `sourceUrl`, `headersUrl` and `libUrl` (Windows only) properties containing URLs for the relevant resources; this is intended to be used by node-gyp (Rod Vagg) [#2154](https://github.com/nodejs/node/pull/2154). + - The version of node-gyp bundled with io.js now downloads and uses a tarball of header files from iojs.org rather than the full source for compiling native add-ons; it is hoped this is a temporary floating patch and the change will be upstreamed to node-gyp soon (Rod Vagg) [#2066](https://github.com/nodejs/node/pull/2066). +* **repl**: Persistent history is now enabled by default. The history file is located at ~/.node_repl_history, which can be overridden by the new environment variable `NODE_REPL_HISTORY`. This deprecates the previous `NODE_REPL_HISTORY_FILE` variable. Additionally, the format of the file has been changed to plain text to better handle file corruption. (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224). +* **smalloc**: The `smalloc` module has been removed as it is no longer possible to provide the API due to changes in V8 (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022). +* **tls**: Add `server.getTicketKeys()` and `server.setTicketKeys()` methods for [TLS session key](https://www.ietf.org/rfc/rfc5077.txt) rotation (Fedor Indutny) [#2227](https://github.com/nodejs/node/pull/2227). +* **v8**: Upgraded to 4.4.63.26 + - ES6: Enabled [computed property names](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names) + - ES6: `Array` can now be subclassed in strict mode + - ES6: Implement [rest parameters](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/rest_parameters) in staging, use the `--harmony-rest-parameters` command line flag + - ES6: Implement the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) in staging, use the `--harmony-spreadcalls` command line flag + - Removed `SetIndexedPropertiesToExternalArrayData` and related APIs, forcing a shift to `Buffer` to be reimplemented based on `Uint8Array` + - Introduction of `Maybe` and `MaybeLocal` C++ API for objects which _may_ or _may not_ have a value. + - Added support for PPC + +See also https://github.com/nodejs/node/wiki/Breaking-Changes#300-from-2x for a summary of the breaking changes (SEMVER-MAJOR). + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +### Commits + +* [[`60a974d200`](https://github.com/nodejs/node/commit/60a974d200)] - **buffer**: fix missing null/undefined check (Trevor Norris) [#2195](https://github.com/nodejs/node/pull/2195) +* [[`e6ab2d92bc`](https://github.com/nodejs/node/commit/e6ab2d92bc)] - **buffer**: fix not return on error (Trevor Norris) [#2225](https://github.com/nodejs/node/pull/2225) +* [[`1057d1186b`](https://github.com/nodejs/node/commit/1057d1186b)] - **buffer**: rename internal/buffer_new.js to buffer.js (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) +* [[`4643b8b667`](https://github.com/nodejs/node/commit/4643b8b667)] - **(SEMVER-MINOR)** **buffer**: allow ArrayBuffer as Buffer argument (Trevor Norris) [#2002](https://github.com/nodejs/node/pull/2002) +* [[`e5ada116cd`](https://github.com/nodejs/node/commit/e5ada116cd)] - **buffer**: minor cleanup from rebase (Trevor Norris) [#2003](https://github.com/nodejs/node/pull/2003) +* [[`b625ab4242`](https://github.com/nodejs/node/commit/b625ab4242)] - **buffer**: fix usage of kMaxLength (Trevor Norris) [#2003](https://github.com/nodejs/node/pull/2003) +* [[`eea66e2a7b`](https://github.com/nodejs/node/commit/eea66e2a7b)] - **(SEMVER-MAJOR)** **buffer**: fix case of one buffer passed to concat (Sakthipriyan Vairamani) [#1937](https://github.com/nodejs/node/pull/1937) +* [[`8664084166`](https://github.com/nodejs/node/commit/8664084166)] - **buffer**: make additional changes to native API (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) +* [[`36f78f4c1c`](https://github.com/nodejs/node/commit/36f78f4c1c)] - **buffer**: switch API to return MaybeLocal (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) +* [[`571ec13841`](https://github.com/nodejs/node/commit/571ec13841)] - **buffer**: switch to using Maybe API (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) +* [[`d75f5c8d0e`](https://github.com/nodejs/node/commit/d75f5c8d0e)] - **buffer**: finish implementing FreeCallback (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) +* [[`63da0dfd3a`](https://github.com/nodejs/node/commit/63da0dfd3a)] - **buffer**: implement Uint8Array backed Buffer (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) +* [[`23be6ca189`](https://github.com/nodejs/node/commit/23be6ca189)] - **buffer**: allow ARGS_THIS to accept a name (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) +* [[`971de5e417`](https://github.com/nodejs/node/commit/971de5e417)] - **build**: prepare Windows installer for i18n support (Frederic Hemberger) [#2247](https://github.com/nodejs/node/pull/2247) +* [[`2ba8b23661`](https://github.com/nodejs/node/commit/2ba8b23661)] - **build**: add 'x86' option back in to configure (Rod Vagg) [#2233](https://github.com/nodejs/node/pull/2233) +* [[`b4226e797a`](https://github.com/nodejs/node/commit/b4226e797a)] - **build**: first set of updates to enable PPC support (Michael Dawson) [#2124](https://github.com/nodejs/node/pull/2124) +* [[`24dd016deb`](https://github.com/nodejs/node/commit/24dd016deb)] - **build**: produce symbol map files on windows (Ali Ijaz Sheikh) [#2243](https://github.com/nodejs/node/pull/2243) +* [[`423d8944ce`](https://github.com/nodejs/node/commit/423d8944ce)] - **cluster**: do not unconditionally set --debug-port (cjihrig) [#1949](https://github.com/nodejs/node/pull/1949) +* [[`fa98b97171`](https://github.com/nodejs/node/commit/fa98b97171)] - **cluster**: add handle ref/unref stubs in rr mode (Ben Noordhuis) [#2274](https://github.com/nodejs/node/pull/2274) +* [[`944f68046c`](https://github.com/nodejs/node/commit/944f68046c)] - **crypto**: remove kMaxLength on randomBytes() (Trevor Norris) [#1825](https://github.com/nodejs/node/pull/1825) +* [[`3d3c687012`](https://github.com/nodejs/node/commit/3d3c687012)] - **deps**: update V8 to 4.4.63.26 (Michaël Zasso) [#2220](https://github.com/nodejs/node/pull/2220) +* [[`3aad4fa89a`](https://github.com/nodejs/node/commit/3aad4fa89a)] - **deps**: upgrade v8 to 4.4.63.12 (Ben Noordhuis) [#2092](https://github.com/nodejs/node/pull/2092) +* [[`70d1f32f56`](https://github.com/nodejs/node/commit/70d1f32f56)] - **(SEMVER-MAJOR)** **deps**: update v8 to 4.4.63.9 (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) +* [[`deb7ee93a7`](https://github.com/nodejs/node/commit/deb7ee93a7)] - **deps**: backport 7b24219346 from v8 upstream (Rod Vagg) [#1805](https://github.com/nodejs/node/pull/1805) +* [[`d58e780504`](https://github.com/nodejs/node/commit/d58e780504)] - **(SEMVER-MAJOR)** **deps**: update v8 to 4.3.61.21 (Chris Dickinson) [iojs/io.js#1632](https://github.com/iojs/io.js/pull/1632) +* [[`2a63cf612b`](https://github.com/nodejs/node/commit/2a63cf612b)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`bf63266460`](https://github.com/nodejs/node/commit/bf63266460)] - **deps**: upgrade to npm 2.13.3 (Kat Marchán) [#2284](https://github.com/nodejs/node/pull/2284) +* [[`ef2c8cd4ec`](https://github.com/nodejs/node/commit/ef2c8cd4ec)] - **(SEMVER-MAJOR)** **dgram**: make send cb act as "error" event handler (Matteo Collina) [#1796](https://github.com/nodejs/node/pull/1796) +* [[`3da057fef6`](https://github.com/nodejs/node/commit/3da057fef6)] - **(SEMVER-MAJOR)** **dgram**: make send cb act as "error" event handler (Chris Dickinson) [#1796](https://github.com/nodejs/node/pull/1796) +* [[`df1994fe53`](https://github.com/nodejs/node/commit/df1994fe53)] - ***Revert*** "**dns**: remove AI_V4MAPPED hint flag on FreeBSD" (cjihrig) [iojs/io.js#1555](https://github.com/iojs/io.js/pull/1555) +* [[`1721968b22`](https://github.com/nodejs/node/commit/1721968b22)] - **doc**: document repl persistent history changes (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) +* [[`d12df7f159`](https://github.com/nodejs/node/commit/d12df7f159)] - **doc**: update v8 flags in man page (Michaël Zasso) [iojs/io.js#1701](https://github.com/iojs/io.js/pull/1701) +* [[`d168d01b04`](https://github.com/nodejs/node/commit/d168d01b04)] - **doc**: properly inheriting from EventEmitter (Sakthipriyan Vairamani) [#2168](https://github.com/nodejs/node/pull/2168) +* [[`500f2538cc`](https://github.com/nodejs/node/commit/500f2538cc)] - **doc**: a listener, not "an" listener (Sam Roberts) [#1025](https://github.com/nodejs/node/pull/1025) +* [[`54627a919d`](https://github.com/nodejs/node/commit/54627a919d)] - **doc**: server close event does not have an argument (Sam Roberts) [#1025](https://github.com/nodejs/node/pull/1025) +* [[`ed85c95a9c`](https://github.com/nodejs/node/commit/ed85c95a9c)] - **doc,test**: documents behaviour of non-existent file (Sakthipriyan Vairamani) [#2169](https://github.com/nodejs/node/pull/2169) +* [[`2965442308`](https://github.com/nodejs/node/commit/2965442308)] - **(SEMVER-MAJOR)** **http**: fix agent.getName() and add tests (Brendan Ashworth) [#1617](https://github.com/nodejs/node/pull/1617) +* [[`2d9456e3e6`](https://github.com/nodejs/node/commit/2d9456e3e6)] - **(SEMVER-MAJOR)** **http**: use official IANA Status Codes (jomo) [#1470](https://github.com/nodejs/node/pull/1470) +* [[`11e4249227`](https://github.com/nodejs/node/commit/11e4249227)] - **(SEMVER-MAJOR)** **http_server**: `prefinish` vs `finish` (Fedor Indutny) [#1411](https://github.com/nodejs/node/pull/1411) +* [[`9bc2e26720`](https://github.com/nodejs/node/commit/9bc2e26720)] - **net**: do not set V4MAPPED on FreeBSD (Julien Gilli) [iojs/io.js#1555](https://github.com/iojs/io.js/pull/1555) +* [[`ba9ccf227e`](https://github.com/nodejs/node/commit/ba9ccf227e)] - **node**: remove redundant --use-old-buffer (Rod Vagg) [#2275](https://github.com/nodejs/node/pull/2275) +* [[`ef65321083`](https://github.com/nodejs/node/commit/ef65321083)] - **(SEMVER-MAJOR)** **node**: do not override `message`/`stack` of error (Fedor Indutny) [#2108](https://github.com/nodejs/node/pull/2108) +* [[`9f727f5e03`](https://github.com/nodejs/node/commit/9f727f5e03)] - **node-gyp**: detect RC build with x.y.z-rc.n format (Rod Vagg) [#2171](https://github.com/nodejs/node/pull/2171) +* [[`e52f963632`](https://github.com/nodejs/node/commit/e52f963632)] - **node-gyp**: download header tarball for compile (Rod Vagg) [#2066](https://github.com/nodejs/node/pull/2066) +* [[`902c9ca51d`](https://github.com/nodejs/node/commit/902c9ca51d)] - **node-gyp**: make aware of nightly, next-nightly & rc (Rod Vagg) [#2066](https://github.com/nodejs/node/pull/2066) +* [[`4cffaa3f55`](https://github.com/nodejs/node/commit/4cffaa3f55)] - **(SEMVER-MINOR)** **readline**: allow tabs in input (Rich Trott) [#1761](https://github.com/nodejs/node/pull/1761) +* [[`ed6c249104`](https://github.com/nodejs/node/commit/ed6c249104)] - **(SEMVER-MAJOR)** **repl**: persist history in plain text (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) +* [[`f7d5e4c618`](https://github.com/nodejs/node/commit/f7d5e4c618)] - **(SEMVER-MINOR)** **repl**: default persistence to ~/.node_repl_history (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) +* [[`ea05e760cd`](https://github.com/nodejs/node/commit/ea05e760cd)] - **repl**: don't clobber RegExp.$ properties (Sakthipriyan Vairamani) [#2137](https://github.com/nodejs/node/pull/2137) +* [[`d20093246b`](https://github.com/nodejs/node/commit/d20093246b)] - **src**: disable vector ICs on arm (Michaël Zasso) [#2220](https://github.com/nodejs/node/pull/2220) +* [[`04fd4fad46`](https://github.com/nodejs/node/commit/04fd4fad46)] - **(SEMVER-MINOR)** **src**: introduce process.release object (Rod Vagg) [#2154](https://github.com/nodejs/node/pull/2154) +* [[`9d34bd1147`](https://github.com/nodejs/node/commit/9d34bd1147)] - **src**: increment NODE_MODULE_VERSION to 45 (Rod Vagg) [#2096](https://github.com/nodejs/node/pull/2096) +* [[`ceee8d2807`](https://github.com/nodejs/node/commit/ceee8d2807)] - **test**: add tests for persistent repl history (Jeremiah Senkpiel) [#2224](https://github.com/nodejs/node/pull/2224) +* [[`8e1a8ffe24`](https://github.com/nodejs/node/commit/8e1a8ffe24)] - **test**: remove two obsolete pummel tests (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) +* [[`ae731ec0fa`](https://github.com/nodejs/node/commit/ae731ec0fa)] - **test**: don't use arguments.callee (Ben Noordhuis) [#2022](https://github.com/nodejs/node/pull/2022) +* [[`21d31c08e7`](https://github.com/nodejs/node/commit/21d31c08e7)] - **test**: remove obsolete harmony flags (Chris Dickinson) +* [[`64cf71195c`](https://github.com/nodejs/node/commit/64cf71195c)] - **test**: change the hostname to an invalid name (Sakthipriyan Vairamani) [#2287](https://github.com/nodejs/node/pull/2287) +* [[`80a1cf7425`](https://github.com/nodejs/node/commit/80a1cf7425)] - **test**: fix messages and use return to skip tests (Sakthipriyan Vairamani) [#2290](https://github.com/nodejs/node/pull/2290) +* [[`d5ab92bcc1`](https://github.com/nodejs/node/commit/d5ab92bcc1)] - **test**: use common.isWindows consistently (Sakthipriyan Vairamani) [#2269](https://github.com/nodejs/node/pull/2269) +* [[`bc733f7065`](https://github.com/nodejs/node/commit/bc733f7065)] - **test**: fix fs.readFile('/dev/stdin') tests (Ben Noordhuis) [#2265](https://github.com/nodejs/node/pull/2265) +* [[`3cbb5870e5`](https://github.com/nodejs/node/commit/3cbb5870e5)] - **tools**: expose skip output to test runner (Johan Bergström) [#2130](https://github.com/nodejs/node/pull/2130) +* [[`3b021efe11`](https://github.com/nodejs/node/commit/3b021efe11)] - **vm**: fix symbol access (Domenic Denicola) [#1773](https://github.com/nodejs/node/pull/1773) +* [[`7b81e4ba36`](https://github.com/nodejs/node/commit/7b81e4ba36)] - **vm**: remove unnecessary access checks (Domenic Denicola) [#1773](https://github.com/nodejs/node/pull/1773) +* [[`659dadd410`](https://github.com/nodejs/node/commit/659dadd410)] - **vm**: fix property descriptors of sandbox properties (Domenic Denicola) [#1773](https://github.com/nodejs/node/pull/1773) +* [[`9bac1dbae9`](https://github.com/nodejs/node/commit/9bac1dbae9)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) + + +## 2015-07-28, Version 2.5.0, @cjihrig + +### Notable changes + +* **https**: TLS sessions in Agent are reused (Fedor Indutny) [#2228](https://github.com/nodejs/node/pull/2228) +* **src**: base64 decoding is now 50% faster (Ben Noordhuis) [#2193](https://github.com/nodejs/node/pull/2193) +* **npm**: Upgraded to v2.13.2, release notes can be found in (Kat Marchán) [#2241](https://github.com/nodejs/node/pull/2241). + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Using multiple REPL instances in parallel may cause some REPL history corruption or loss. [#1634](https://github.com/nodejs/node/issues/1634) +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +### Commits + +* [[`bf2cd225a8`](https://github.com/nodejs/node/commit/bf2cd225a8)] - **process**: resize stderr on SIGWINCH (Jeremiah Senkpiel) [#2231](https://github.com/nodejs/node/pull/2231) +* [[`99d9d7e716`](https://github.com/nodejs/node/commit/99d9d7e716)] - **benchmark**: add remaining path benchmarks & optimize (Nathan Woltman) [#2103](https://github.com/nodejs/node/pull/2103) +* [[`66fc8ca22b`](https://github.com/nodejs/node/commit/66fc8ca22b)] - **(SEMVER-MINOR)** **cluster**: emit 'message' event on cluster master (Sam Roberts) [#861](https://github.com/nodejs/node/pull/861) +* [[`eb35968de7`](https://github.com/nodejs/node/commit/eb35968de7)] - **crypto**: fix legacy SNICallback (Fedor Indutny) [#1720](https://github.com/nodejs/node/pull/1720) +* [[`fef190cea6`](https://github.com/nodejs/node/commit/fef190cea6)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`b73a7465c5`](https://github.com/nodejs/node/commit/b73a7465c5)] - **deps**: upgrade to npm 2.13.2 (Kat Marchán) [#2241](https://github.com/nodejs/node/pull/2241) +* [[`0a7bf81d2f`](https://github.com/nodejs/node/commit/0a7bf81d2f)] - **deps**: update V8 to 4.2.77.21 (Ali Ijaz Sheikh) [#2238](https://github.com/nodejs/node/issues/2238) +* [[`73cdcdd581`](https://github.com/nodejs/node/commit/73cdcdd581)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`04893a736d`](https://github.com/nodejs/node/commit/04893a736d)] - **deps**: upgrade to npm 2.13.1 (Kat Marchán) [#2210](https://github.com/nodejs/node/pull/2210) +* [[`a3c1b9720e`](https://github.com/nodejs/node/commit/a3c1b9720e)] - **doc**: add GPG fingerprint for cjihrig (cjihrig) [#2217](https://github.com/nodejs/node/pull/2217) +* [[`d9f857df3b`](https://github.com/nodejs/node/commit/d9f857df3b)] - **doc**: note about custom inspect functions (Sakthipriyan Vairamani) [#2142](https://github.com/nodejs/node/pull/2142) +* [[`4ef2b5fbfb`](https://github.com/nodejs/node/commit/4ef2b5fbfb)] - **doc**: Replace util.debug with console.error (Yosuke Furukawa) [#2214](https://github.com/nodejs/node/pull/2214) +* [[`b612f085ec`](https://github.com/nodejs/node/commit/b612f085ec)] - **doc**: add joaocgreis as a collaborator (João Reis) [#2208](https://github.com/nodejs/node/pull/2208) +* [[`6b85d5a4b3`](https://github.com/nodejs/node/commit/6b85d5a4b3)] - **doc**: add TSC meeting minutes 2015-07-15 (Rod Vagg) [#2191](https://github.com/nodejs/node/pull/2191) +* [[`c7d8b09162`](https://github.com/nodejs/node/commit/c7d8b09162)] - **doc**: recompile before testing core module changes (Phillip Johnsen) [#2051](https://github.com/nodejs/node/pull/2051) +* [[`9afee6785e`](https://github.com/nodejs/node/commit/9afee6785e)] - **http**: Check this.connection before using it (Sakthipriyan Vairamani) [#2172](https://github.com/nodejs/node/pull/2172) +* [[`2ca5a3db47`](https://github.com/nodejs/node/commit/2ca5a3db47)] - **https**: reuse TLS sessions in Agent (Fedor Indutny) [#2228](https://github.com/nodejs/node/pull/2228) +* [[`fef87fee1d`](https://github.com/nodejs/node/commit/fef87fee1d)] - **(SEMVER-MINOR)** **lib,test**: add freelist deprecation and test (Sakthipriyan Vairamani) [#2176](https://github.com/nodejs/node/pull/2176) +* [[`503b089dd8`](https://github.com/nodejs/node/commit/503b089dd8)] - **net**: don't throw on immediately destroyed socket (Evan Lucas) [#2251](https://github.com/nodejs/node/pull/2251) +* [[`93660c8b8e`](https://github.com/nodejs/node/commit/93660c8b8e)] - **node**: remove bad fn call and check (Trevor Norris) [#2157](https://github.com/nodejs/node/pull/2157) +* [[`afd7e37ee0`](https://github.com/nodejs/node/commit/afd7e37ee0)] - **repl**: better empty line handling (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) +* [[`81ea52aa01`](https://github.com/nodejs/node/commit/81ea52aa01)] - **repl**: improving line continuation handling (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) +* [[`30edb5aee9`](https://github.com/nodejs/node/commit/30edb5aee9)] - **repl**: preventing REPL crash with inherited properties (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) +* [[`77fa385e5d`](https://github.com/nodejs/node/commit/77fa385e5d)] - **repl**: fixing `undefined` in invalid REPL keyword error (Sakthipriyan Vairamani) [#2163](https://github.com/nodejs/node/pull/2163) +* [[`8fd3ce100e`](https://github.com/nodejs/node/commit/8fd3ce100e)] - **src**: make base64 decoding 50% faster (Ben Noordhuis) [#2193](https://github.com/nodejs/node/pull/2193) +* [[`c786d6341d`](https://github.com/nodejs/node/commit/c786d6341d)] - **test**: do not use public IPs for timeout testing (Rich Trott) [#2057](https://github.com/nodejs/node/pull/2057) +* [[`4e78cd71c0`](https://github.com/nodejs/node/commit/4e78cd71c0)] - **test**: skip IPv6 part before testing it (Sakthipriyan Vairamani) [#2226](https://github.com/nodejs/node/pull/2226) +* [[`ac70bc8240`](https://github.com/nodejs/node/commit/ac70bc8240)] - **test**: fix valgrind uninitialized memory warning (Ben Noordhuis) [#2193](https://github.com/nodejs/node/pull/2193) +* [[`ac7d3fa0d9`](https://github.com/nodejs/node/commit/ac7d3fa0d9)] - **test**: add -no_rand_screen to s_client opts on Win (Shigeki Ohtsu) [#2209](https://github.com/nodejs/node/pull/2209) +* [[`79c865a53f`](https://github.com/nodejs/node/commit/79c865a53f)] - **test**: changing process.exit to return while skipping tests (Sakthipriyan Vairamani) [#2109](https://github.com/nodejs/node/pull/2109) +* [[`69298d36cf`](https://github.com/nodejs/node/commit/69298d36cf)] - **test**: formatting skip messages for TAP parsing (Sakthipriyan Vairamani) [#2109](https://github.com/nodejs/node/pull/2109) +* [[`543dabb609`](https://github.com/nodejs/node/commit/543dabb609)] - **timers**: improve Timer.now() performance (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) +* [[`3663b124e6`](https://github.com/nodejs/node/commit/3663b124e6)] - **timers**: remove unused Timer.again() (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) +* [[`bcce5cf9bb`](https://github.com/nodejs/node/commit/bcce5cf9bb)] - **timers**: remove unused Timer.getRepeat() (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) +* [[`f2c83bd202`](https://github.com/nodejs/node/commit/f2c83bd202)] - **timers**: remove unused Timer.setRepeat() (Ben Noordhuis) [#2256](https://github.com/nodejs/node/pull/2256) +* [[`e11fc67225`](https://github.com/nodejs/node/commit/e11fc67225)] - **(SEMVER-MINOR)** **tls**: add `getTicketKeys()`/`setTicketKeys()` (Fedor Indutny) [#2227](https://github.com/nodejs/node/pull/2227) +* [[`68b06e94e3`](https://github.com/nodejs/node/commit/68b06e94e3)] - **tools**: use local or specified $NODE for test-npm (Jeremiah Senkpiel) [#1984](https://github.com/nodejs/node/pull/1984) +* [[`ab479659c7`](https://github.com/nodejs/node/commit/ab479659c7)] - **util**: delay creation of debug context (Ali Ijaz Sheikh) [#2248](https://github.com/nodejs/node/pull/2248) +* [[`6391f4d2fd`](https://github.com/nodejs/node/commit/6391f4d2fd)] - **util**: removing redundant checks in is* functions (Sakthipriyan Vairamani) [#2179](https://github.com/nodejs/node/pull/2179) +* [[`b148c0dff3`](https://github.com/nodejs/node/commit/b148c0dff3)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) +* [[`f90f1e75bb`](https://github.com/nodejs/node/commit/f90f1e75bb)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) + + +## 2015-07-17, Version 2.4.0, @Fishrock123 + +### Notable changes + +* **src**: Added a new `--track-heap-objects` flag to track heap object allocations for heap snapshots (Bradley Meck) [#2135](https://github.com/nodejs/node/pull/2135). +* **readline**: Fixed a freeze that affected the repl if the keypress event handler threw (Alex Kocharin) [#2107](https://github.com/nodejs/node/pull/2107). +* **npm**: Upgraded to v2.13.0, release notes can be found in (Forrest L Norvell) [#2152](https://github.com/nodejs/node/pull/2152). + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +### Commits + +* [[`f95f9ef6ea`](https://github.com/nodejs/node/commit/f95f9ef6ea)] - **build**: always use prefix=/ for tar-headers (Rod Vagg) [#2082](https://github.com/nodejs/node/pull/2082) +* [[`12bc397207`](https://github.com/nodejs/node/commit/12bc397207)] - **build**: run-ci makefile rule (Alexis Campailla) [#2134](https://github.com/nodejs/node/pull/2134) +* [[`84012c99e0`](https://github.com/nodejs/node/commit/84012c99e0)] - **build**: fix vcbuild merge issues (Alexis Campailla) [#2131](https://github.com/nodejs/node/pull/2131) +* [[`47e2c5c828`](https://github.com/nodejs/node/commit/47e2c5c828)] - **build**: bail early if clean is invoked (Johan Bergström) [#2127](https://github.com/nodejs/node/pull/2127) +* [[`5acad6b163`](https://github.com/nodejs/node/commit/5acad6b163)] - **child_process**: fix arguments comments (Roman Reiss) [#2161](https://github.com/nodejs/node/pull/2161) +* [[`3c4121c418`](https://github.com/nodejs/node/commit/3c4121c418)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`938cc757bb`](https://github.com/nodejs/node/commit/938cc757bb)] - **deps**: upgrade to npm 2.13.0 (Forrest L Norvell) [#2152](https://github.com/nodejs/node/pull/2152) +* [[`6f306e0ed2`](https://github.com/nodejs/node/commit/6f306e0ed2)] - **doc**: add targos as a collaborator (Michaël Zasso) [#2200](https://github.com/nodejs/node/pull/2200) +* [[`c019d9a239`](https://github.com/nodejs/node/commit/c019d9a239)] - **doc**: add thefourtheye as a collaborator (Sakthipriyan Vairamani) [#2199](https://github.com/nodejs/node/pull/2199) +* [[`4e92dbc26b`](https://github.com/nodejs/node/commit/4e92dbc26b)] - **doc**: add TSC members from the combined project (Jeremiah Senkpiel) [#2085](https://github.com/nodejs/node/pull/2085) +* [[`6c3aabf455`](https://github.com/nodejs/node/commit/6c3aabf455)] - **doc**: add TSC meeting minutes 2015-07-08 (Rod Vagg) [#2184](https://github.com/nodejs/node/pull/2184) +* [[`30a0d47d51`](https://github.com/nodejs/node/commit/30a0d47d51)] - **doc**: add TSC meeting minutes 2015-07-01 (Rod Vagg) [#2132](https://github.com/nodejs/node/pull/2132) +* [[`23efb05cc3`](https://github.com/nodejs/node/commit/23efb05cc3)] - **doc**: document fs.watchFile behaviour on ENOENT (Brendan Ashworth) [#2093](https://github.com/nodejs/node/pull/2093) +* [[`65963ec26f`](https://github.com/nodejs/node/commit/65963ec26f)] - **doc,test**: empty strings in path module (Sakthipriyan Vairamani) [#2106](https://github.com/nodejs/node/pull/2106) +* [[`0ab81e6f58`](https://github.com/nodejs/node/commit/0ab81e6f58)] - **docs**: link to more up-to-date v8 docs (Jeremiah Senkpiel) [#2196](https://github.com/nodejs/node/pull/2196) +* [[`1afc0c9e86`](https://github.com/nodejs/node/commit/1afc0c9e86)] - **fs**: fix error on bad listener type (Brendan Ashworth) [#2093](https://github.com/nodejs/node/pull/2093) +* [[`2ba84606a6`](https://github.com/nodejs/node/commit/2ba84606a6)] - **path**: assert path.join() arguments equally (Phillip Johnsen) [#2159](https://github.com/nodejs/node/pull/2159) +* [[`bd01603201`](https://github.com/nodejs/node/commit/bd01603201)] - **readline**: fix freeze if `keypress` event throws (Alex Kocharin) [#2107](https://github.com/nodejs/node/pull/2107) +* [[`59f6b5da2a`](https://github.com/nodejs/node/commit/59f6b5da2a)] - **repl**: Prevent crash when tab-completed with Proxy (Sakthipriyan Vairamani) [#2120](https://github.com/nodejs/node/pull/2120) +* [[`cf14a2427c`](https://github.com/nodejs/node/commit/cf14a2427c)] - **(SEMVER-MINOR)** **src**: add --track-heap-objects (Bradley Meck) [#2135](https://github.com/nodejs/node/pull/2135) +* [[`2b4b600660`](https://github.com/nodejs/node/commit/2b4b600660)] - **test**: fix test-debug-port-from-cmdline (João Reis) [#2186](https://github.com/nodejs/node/pull/2186) +* [[`d4ceb16da2`](https://github.com/nodejs/node/commit/d4ceb16da2)] - **test**: properly clean up temp directory (Roman Reiss) [#2164](https://github.com/nodejs/node/pull/2164) +* [[`842eb5b853`](https://github.com/nodejs/node/commit/842eb5b853)] - **test**: add test for dgram.setTTL (Evan Lucas) [#2121](https://github.com/nodejs/node/pull/2121) +* [[`cff7300a57`](https://github.com/nodejs/node/commit/cff7300a57)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) + + + +## 2015-07-09, Version 2.3.4, @Fishrock123 + +### Notable changes + +* **openssl**: Upgrade to 1.0.2d, fixes CVE-2015-1793 (Alternate Chains Certificate Forgery) (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141). +* **npm**: Upgraded to v2.12.1, release notes can be found in and (Kat Marchán) [#2112](https://github.com/nodejs/node/pull/2112). + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +### Commits + +* [[`0d15161c24`](https://github.com/nodejs/node/commit/0d15161c24)] - **benchmark**: Add some path benchmarks for #1778 (Nathan Woltman) [#1778](https://github.com/nodejs/node/pull/1778) +* [[`c70e68fa32`](https://github.com/nodejs/node/commit/c70e68fa32)] - **deps**: update deps/openssl/conf/arch/*/opensslconf.h (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) +* [[`ca93f7f2e6`](https://github.com/nodejs/node/commit/ca93f7f2e6)] - **deps**: upgrade openssl sources to 1.0.2d (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) +* [[`b18c841ec1`](https://github.com/nodejs/node/commit/b18c841ec1)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`863cdbdd08`](https://github.com/nodejs/node/commit/863cdbdd08)] - **deps**: upgrade to npm 2.12.1 (Kat Marchán) [#2112](https://github.com/nodejs/node/pull/2112) +* [[`84b3915764`](https://github.com/nodejs/node/commit/84b3915764)] - **doc**: document current release procedure (Rod Vagg) [#2099](https://github.com/nodejs/node/pull/2099) +* [[`46140334cd`](https://github.com/nodejs/node/commit/46140334cd)] - **doc**: update AUTHORS list (Rod Vagg) [#2100](https://github.com/nodejs/node/pull/2100) +* [[`bca53dce76`](https://github.com/nodejs/node/commit/bca53dce76)] - **path**: refactor for performance and consistency (Nathan Woltman) [#1778](https://github.com/nodejs/node/pull/1778) +* [[`6bef15afe7`](https://github.com/nodejs/node/commit/6bef15afe7)] - **src**: remove traceSyncIO property from process (Bradley Meck) [#2143](https://github.com/nodejs/node/pull/2143) +* [[`2ba1740ba1`](https://github.com/nodejs/node/commit/2ba1740ba1)] - **test**: add missing crypto checks (Johan Bergström) [#2129](https://github.com/nodejs/node/pull/2129) +* [[`180fd392ca`](https://github.com/nodejs/node/commit/180fd392ca)] - **test**: refactor test-repl-tab-complete (Sakthipriyan Vairamani) [#2122](https://github.com/nodejs/node/pull/2122) +* [[`fb05c8e27d`](https://github.com/nodejs/node/commit/fb05c8e27d)] - ***Revert*** "**test**: add test for missing `close`/`finish` event" (Fedor Indutny) +* [[`9436a860cb`](https://github.com/nodejs/node/commit/9436a860cb)] - **test**: add test for missing `close`/`finish` event (Mark Plomer) [iojs/io.js#1373](https://github.com/iojs/io.js/pull/1373) +* [[`ee3ce2ed88`](https://github.com/nodejs/node/commit/ee3ce2ed88)] - **tools**: install gdbinit from v8 to $PREFIX/share (Ali Ijaz Sheikh) [#2123](https://github.com/nodejs/node/pull/2123) +* [[`dd523c75da`](https://github.com/nodejs/node/commit/dd523c75da)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) + + + +## 2015-07-09, Version 1.8.4, @Fishrock123 + +**Maintenance release** + +### Notable changes + +* **openssl**: Upgrade to 1.0.2d, fixes CVE-2015-1793 (Alternate Chains Certificate Forgery) [#2141](https://github.com/nodejs/node/pull/2141). + +### Known issues + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). +* readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) + +### Commits + +* [[`52b1230628`](https://github.com/nodejs/node/commit/52b1230628)] - **deps**: update deps/openssl/conf/arch/*/opensslconf.h (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) +* [[`20ff1e2ecb`](https://github.com/nodejs/node/commit/20ff1e2ecb)] - **deps**: upgrade openssl sources to 1.0.2d (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) + + + +## 2015-07-04, Version 2.3.3, @Fishrock123 + +### Notable changes + +* **deps**: Fixed an out-of-band write in utf8 decoder. **This is an important security update** as it can be used to cause a denial of service attack. + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +## Commits + +* [[`030f8045c7`](https://github.com/nodejs/node/commit/030f8045c7)] - **deps**: fix out-of-band write in utf8 decoder (Fedor Indutny) +* [[`0f09b8db28`](https://github.com/nodejs/node/commit/0f09b8db28)] - **doc**: don't recommend domains for error handling (Benjamin Gruenbaum) [#2056](https://github.com/nodejs/node/pull/2056) +* [[`9cd44bb2b6`](https://github.com/nodejs/node/commit/9cd44bb2b6)] - **util**: prepend '(node) ' to deprecation messages (Sakthipriyan Vairamani) [#1892](https://github.com/nodejs/node/pull/1892) + + + +## 2015-07-04, Version 1.8.3, @rvagg + +**Maintenance release** + +## Notable changes + +* **v8**: Fixed an out-of-band write in utf8 decoder. **This is an important security update** as it can be used to cause a denial of service attack. +* **openssl**: Upgrade to 1.0.2b and 1.0.2c, introduces DHE man-in-the-middle protection (Logjam) and fixes malformed ECParameters causing infinite loop (CVE-2015-1788). See the [security advisory](https://www.openssl.org/news/secadv_20150611.txt) for full details. (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) [#1958](https://github.com/nodejs/node/pull/1958) +* **build**: + - Added support for compiling with Microsoft Visual C++ 2015 + - Started building and distributing headers-only tarballs along with binaries + +### Known issues + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). +* readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) + +### Commits + +* [[`d8f260d33b`](https://github.com/nodejs/node/commit/d8f260d33b)] - **build**: add tar-headers target for headers-only tar (Rod Vagg) [#1975](https://github.com/nodejs/node/pull/1975) +* [[`00ba429674`](https://github.com/nodejs/node/commit/00ba429674)] - **build**: update build targets for io.js (Rod Vagg) [#1938](https://github.com/nodejs/node/pull/1938) +* [[`39e2207ff1`](https://github.com/nodejs/node/commit/39e2207ff1)] - **build**: fix cherry-pick ooops, fix comment wording (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) +* [[`561919a67a`](https://github.com/nodejs/node/commit/561919a67a)] - **build**: add MSVS 2015 support (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) +* [[`8e1134c04c`](https://github.com/nodejs/node/commit/8e1134c04c)] - **build**: remove lint from test-ci on windows (Johan Bergström) [#2004](https://github.com/nodejs/node/pull/2004) +* [[`e52e99085e`](https://github.com/nodejs/node/commit/e52e99085e)] - **build**: don't run lint from test-ci (Johan Bergström) [#1965](https://github.com/nodejs/node/pull/1965) +* [[`c5d1ec7fea`](https://github.com/nodejs/node/commit/c5d1ec7fea)] - **build**: simplify execution of built binary (Johan Bergström) [#1955](https://github.com/nodejs/node/pull/1955) +* [[`2ce147551a`](https://github.com/nodejs/node/commit/2ce147551a)] - **build,win**: set env before generating projects (Alexis Campailla) [joyent/node#20109](https://github.com/joyent/node/pull/20109) +* [[`78de5f85f2`](https://github.com/nodejs/node/commit/78de5f85f2)] - **deps**: fix out-of-band write in utf8 decoder (Ben Noordhuis) +* [[`83ee07b6be`](https://github.com/nodejs/node/commit/83ee07b6be)] - **deps**: copy all openssl header files to include dir (Shigeki Ohtsu) [#2016](https://github.com/nodejs/node/pull/2016) +* [[`a97125520d`](https://github.com/nodejs/node/commit/a97125520d)] - **deps**: update UPGRADING.md doc to openssl-1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) +* [[`0e2d068e0b`](https://github.com/nodejs/node/commit/0e2d068e0b)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) +* [[`310b8d1120`](https://github.com/nodejs/node/commit/310b8d1120)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`a472946747`](https://github.com/nodejs/node/commit/a472946747)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) +* [[`b2467e3ebf`](https://github.com/nodejs/node/commit/b2467e3ebf)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) +* [[`e548abb800`](https://github.com/nodejs/node/commit/e548abb800)] - **deps**: upgrade openssl sources to 1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) +* [[`1feaa68e85`](https://github.com/nodejs/node/commit/1feaa68e85)] - **deps**: update asm files for openssl-1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) +* [[`151720fae7`](https://github.com/nodejs/node/commit/151720fae7)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) +* [[`139da6a02a`](https://github.com/nodejs/node/commit/139da6a02a)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`283642827a`](https://github.com/nodejs/node/commit/283642827a)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) +* [[`d593b552de`](https://github.com/nodejs/node/commit/d593b552de)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) +* [[`2a3367a4bd`](https://github.com/nodejs/node/commit/2a3367a4bd)] - **deps**: upgrade openssl sources to 1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) +* [[`5c29c0c519`](https://github.com/nodejs/node/commit/5c29c0c519)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) +* [[`2cd7f73d9f`](https://github.com/nodejs/node/commit/2cd7f73d9f)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) +* [[`c65484a74d`](https://github.com/nodejs/node/commit/c65484a74d)] - **tls**: make server not use DHE in less than 1024bits (Shigeki Ohtsu) [#1739](https://github.com/nodejs/node/pull/1739) +* [[`77f518403f`](https://github.com/nodejs/node/commit/77f518403f)] - **win,node-gyp**: make delay-load hook C89 compliant (Sharat M R) [TooTallNate/node-gyp#616](https://github.com/TooTallNa + + + +## 2015-07-01, Version 2.3.2, @rvagg + +### Notable changes + +* **build**: + - Added support for compiling with Microsoft Visual C++ 2015 + - Started building and distributing headers-only tarballs along with binaries + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +## Commits + +* [[`9180140231`](https://github.com/nodejs/node/commit/9180140231)] - **_stream_wrap**: prevent use after free in TLS (Fedor Indutny) [#1910](https://github.com/nodejs/node/pull/1910) +* [[`05a73c0f25`](https://github.com/nodejs/node/commit/05a73c0f25)] - **benchmark**: make concurrent requests configurable (Rich Trott) [#2068](https://github.com/nodejs/node/pull/2068) +* [[`f52d73352e`](https://github.com/nodejs/node/commit/f52d73352e)] - **benchmark**: fix typo in README (Rich Trott) [#2067](https://github.com/nodejs/node/pull/2067) +* [[`1cd9eeb556`](https://github.com/nodejs/node/commit/1cd9eeb556)] - **buffer**: prevent abort on bad proto (Trevor Norris) [#2012](https://github.com/nodejs/node/pull/2012) +* [[`8350f3a3a2`](https://github.com/nodejs/node/commit/8350f3a3a2)] - **buffer**: optimize Buffer#toString() (Ben Noordhuis) [#2027](https://github.com/nodejs/node/pull/2027) +* [[`628a3ab093`](https://github.com/nodejs/node/commit/628a3ab093)] - **build**: add tar-headers target for headers-only tar (Rod Vagg) [#1975](https://github.com/nodejs/node/pull/1975) +* [[`dcbb9e1da6`](https://github.com/nodejs/node/commit/dcbb9e1da6)] - **build**: update build targets for io.js (Rod Vagg) [#1938](https://github.com/nodejs/node/pull/1938) +* [[`c87c34c242`](https://github.com/nodejs/node/commit/c87c34c242)] - **build**: fix cherry-pick ooops, fix comment wording (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) +* [[`4208dc4fef`](https://github.com/nodejs/node/commit/4208dc4fef)] - **build**: add MSVS 2015 support (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) +* [[`834a365113`](https://github.com/nodejs/node/commit/834a365113)] - **build**: DTrace is enabled by default on darwin (Evan Lucas) [#2019](https://github.com/nodejs/node/pull/2019) +* [[`c0c0d73269`](https://github.com/nodejs/node/commit/c0c0d73269)] - **build,win**: set env before generating projects (Alexis Campailla) [joyent/node#20109](https://github.com/joyent/node/pull/20109) +* [[`9e890fe8b4`](https://github.com/nodejs/node/commit/9e890fe8b4)] - **crypto**: fix VerifyCallback in case of verify error (Shigeki Ohtsu) [#2064](https://github.com/nodejs/node/pull/2064) +* [[`1f371e3988`](https://github.com/nodejs/node/commit/1f371e3988)] - **deps**: copy all openssl header files to include dir (Shigeki Ohtsu) [#2016](https://github.com/nodejs/node/pull/2016) +* [[`c370bd3aea`](https://github.com/nodejs/node/commit/c370bd3aea)] - **doc**: make the abbreviation 1MM clear (Ivan Yan) [#2053](https://github.com/nodejs/node/pull/2053) +* [[`54d5437566`](https://github.com/nodejs/node/commit/54d5437566)] - **doc**: Added sample command to test iojs build (Jimmy Hsu) [#850](https://github.com/nodejs/node/pull/850) +* [[`f1f1b7e597`](https://github.com/nodejs/node/commit/f1f1b7e597)] - **doc**: add TSC meeting minutes 2015-06-17 (Rod Vagg) [#2048](https://github.com/nodejs/node/pull/2048) +* [[`dbd5dc932d`](https://github.com/nodejs/node/commit/dbd5dc932d)] - **doc**: clarify prerequisites in benchmark/README.md (Jeremiah Senkpiel) [#2034](https://github.com/nodejs/node/pull/2034) +* [[`50dbc8e143`](https://github.com/nodejs/node/commit/50dbc8e143)] - **doc**: add TSC meeting minutes 2015-05-27 (Rod Vagg) [#2037](https://github.com/nodejs/node/pull/2037) +* [[`941ad362a7`](https://github.com/nodejs/node/commit/941ad362a7)] - **doc**: archive io.js TC minutes (Rod Vagg) +* [[`644b2eaa89`](https://github.com/nodejs/node/commit/644b2eaa89)] - **doc**: rename tc-meetings to tsc-meetings (Rod Vagg) +* [[`1330ee3b27`](https://github.com/nodejs/node/commit/1330ee3b27)] - **doc**: add TC meeting 2015-05-13 minutes (Rod Vagg) [#1700](https://github.com/nodejs/node/pull/1700) +* [[`392e8fd64e`](https://github.com/nodejs/node/commit/392e8fd64e)] - **doc**: add @shigeki and @mscdex to TC (Rod Vagg) [#2008](https://github.com/nodejs/node/pull/2008) +* [[`af249fa8a1`](https://github.com/nodejs/node/commit/af249fa8a1)] - **net**: wrap connect in nextTick (Evan Lucas) [#2054](https://github.com/nodejs/node/pull/2054) +* [[`7f63449fde`](https://github.com/nodejs/node/commit/7f63449fde)] - **net**: fix debug for dnsopts (Evan Lucas) [#2059](https://github.com/nodejs/node/pull/2059) +* [[`eabed2f518`](https://github.com/nodejs/node/commit/eabed2f518)] - **repl**: remove obsolete TODO (Rich Trott) [#2081](https://github.com/nodejs/node/pull/2081) +* [[`a198c68b56`](https://github.com/nodejs/node/commit/a198c68b56)] - **repl**: make 'Unexpected token' errors recoverable (Julien Gilli) [#2052](https://github.com/nodejs/node/pull/2052) +* [[`d735b2c6ef`](https://github.com/nodejs/node/commit/d735b2c6ef)] - **repl**: fix tab completion for a non-global context (Sangmin Yoon) [#2052](https://github.com/nodejs/node/pull/2052) +* [[`8cee8f54fc`](https://github.com/nodejs/node/commit/8cee8f54fc)] - **src**: nix stdin _readableState.reading manipulation (Chris Dickinson) [#454](https://github.com/nodejs/node/pull/454) +* [[`856c11f8c8`](https://github.com/nodejs/node/commit/856c11f8c8)] - **test**: purge stale disabled tests (Rich Trott) [#2045](https://github.com/nodejs/node/pull/2045) +* [[`4d5089e181`](https://github.com/nodejs/node/commit/4d5089e181)] - **test**: do not swallow OpenSSL support error (Rich Trott) [#2042](https://github.com/nodejs/node/pull/2042) +* [[`06721fe005`](https://github.com/nodejs/node/commit/06721fe005)] - **test**: fix test-repl-tab-complete.js (cjihrig) [#2052](https://github.com/nodejs/node/pull/2052) +* [[`8e9089ac35`](https://github.com/nodejs/node/commit/8e9089ac35)] - **test**: check for error on Windows (Rich Trott) [#2035](https://github.com/nodejs/node/pull/2035) +* [[`776a65ebcd`](https://github.com/nodejs/node/commit/776a65ebcd)] - **test**: remove obsolete TODO comments (Rich Trott) [#2033](https://github.com/nodejs/node/pull/2033) +* [[`bdfeb798ad`](https://github.com/nodejs/node/commit/bdfeb798ad)] - **test**: remove obsolete TODO comments (Rich Trott) [#2032](https://github.com/nodejs/node/pull/2032) +* [[`58e914f9bc`](https://github.com/nodejs/node/commit/58e914f9bc)] - **tools**: fix gyp to work on MacOSX without XCode (Shigeki Ohtsu) [iojs/io.js#1325](https://github.com/iojs/io.js/pull/1325) +* [[`99cbbc0a13`](https://github.com/nodejs/node/commit/99cbbc0a13)] - **tools**: update gyp to 25ed9ac (Ben Noordhuis) [#2074](https://github.com/nodejs/node/pull/2074) +* [[`e3f9335c40`](https://github.com/nodejs/node/commit/e3f9335c40)] - **tools**: re-enable comma-spacing linter rule (Roman Reiss) [#2072](https://github.com/nodejs/node/pull/2072) +* [[`d91e10b3bd`](https://github.com/nodejs/node/commit/d91e10b3bd)] - **tools**: update eslint to 0.24.0 (Roman Reiss) [#2072](https://github.com/nodejs/node/pull/2072) +* [[`6c61ca5325`](https://github.com/nodejs/node/commit/6c61ca5325)] - **url**: fix typo in comment (Rich Trott) [#2071](https://github.com/nodejs/node/pull/2071) +* [[`1a51f0058c`](https://github.com/nodejs/node/commit/1a51f0058c)] - **v8**: cherry-pick JitCodeEvent patch from upstream (Ben Noordhuis) [#2075](https://github.com/nodejs/node/pull/2075) + + + +## 2015-06-23, Version 2.3.1, @rvagg + +### Notable changes + +* **module**: The number of syscalls made during a `require()` have been significantly reduced again (see [#1801](https://github.com/nodejs/node/pull/1801) from v2.2.0 for previous work), which should lead to a performance improvement (Pierre Inglebert) [#1920](https://github.com/nodejs/node/pull/1920). +* **npm**: + * Upgrade to [v2.11.2](https://github.com/npm/npm/releases/tag/v2.11.2) (Rebecca Turner) [#1956](https://github.com/nodejs/node/pull/1956). + * Upgrade to [v2.11.3](https://github.com/npm/npm/releases/tag/v2.11.3) (Forrest L Norvell) [#2018](https://github.com/nodejs/node/pull/2018). +* **zlib**: A bug was discovered where the process would abort if the final part of a zlib decompression results in a buffer that would exceed the maximum length of `0x3fffffff` bytes (~1GiB). This was likely to only occur during buffered decompression (rather than streaming). This is now fixed and will instead result in a thrown `RangeError` (Michaël Zasso) [#1811](https://github.com/nodejs/node/pull/1811). + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +## Commits + +* [[`e56758a5e0`](https://github.com/nodejs/node/commit/e56758a5e0)] - **async-wrap**: add provider id and object info cb (Trevor Norris) [#1896](https://github.com/nodejs/node/pull/1896) +* [[`d5637e67c9`](https://github.com/nodejs/node/commit/d5637e67c9)] - **buffer**: fix cyclic dependency with util (Brendan Ashworth) [#1988](https://github.com/nodejs/node/pull/1988) +* [[`c5353d7c62`](https://github.com/nodejs/node/commit/c5353d7c62)] - **build**: remove lint from test-ci on windows (Johan Bergström) [#2004](https://github.com/nodejs/node/pull/2004) +* [[`c207e8d223`](https://github.com/nodejs/node/commit/c207e8d223)] - **build**: fix pkg-config output parsing in configure (Ben Noordhuis) [#1986](https://github.com/nodejs/node/pull/1986) +* [[`8d8a26e8f7`](https://github.com/nodejs/node/commit/8d8a26e8f7)] - **build**: don't run lint from test-ci (Johan Bergström) [#1965](https://github.com/nodejs/node/pull/1965) +* [[`1ec53c044d`](https://github.com/nodejs/node/commit/1ec53c044d)] - **build**: simplify execution of built binary (Johan Bergström) [#1955](https://github.com/nodejs/node/pull/1955) +* [[`3beb880716`](https://github.com/nodejs/node/commit/3beb880716)] - **crypto**: add cert check to CNNIC Whitelist (Shigeki Ohtsu) [#1895](https://github.com/nodejs/node/pull/1895) +* [[`48c0fb8b1a`](https://github.com/nodejs/node/commit/48c0fb8b1a)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`6a359b1ce9`](https://github.com/nodejs/node/commit/6a359b1ce9)] - **deps**: upgrade to npm 2.11.3 (Forrest L Norvell) [#2018](https://github.com/nodejs/node/pull/2018) +* [[`6aab2f3b9a`](https://github.com/nodejs/node/commit/6aab2f3b9a)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`3e12561b55`](https://github.com/nodejs/node/commit/3e12561b55)] - **deps**: upgrade to npm 2.11.2 (Rebecca Turner) [#1956](https://github.com/nodejs/node/pull/1956) +* [[`8ac50819b6`](https://github.com/nodejs/node/commit/8ac50819b6)] - **doc**: add security section to README.md (Rod Vagg) [#1948](https://github.com/nodejs/node/pull/1948) +* [[`1f93b63b11`](https://github.com/nodejs/node/commit/1f93b63b11)] - **doc**: change the info to the same as in gitconfig (Christian Tellnes) [#2000](https://github.com/nodejs/node/pull/2000) +* [[`0cf94e6856`](https://github.com/nodejs/node/commit/0cf94e6856)] - **doc**: mention CI in Collaborator Guide (Rich Trott) [#1995](https://github.com/nodejs/node/pull/1995) +* [[`7a3006efe4`](https://github.com/nodejs/node/commit/7a3006efe4)] - **doc**: add TOC links to Collaborator Guide (Rich Trott) [#1994](https://github.com/nodejs/node/pull/1994) +* [[`30638b150f`](https://github.com/nodejs/node/commit/30638b150f)] - **doc**: add TSC meeting notes 2015-06-10 (Bert Belder) [#1943](https://github.com/nodejs/node/pull/1943) +* [[`c4ec04136b`](https://github.com/nodejs/node/commit/c4ec04136b)] - **doc**: reformat authors section (Johan Bergström) [#1966](https://github.com/nodejs/node/pull/1966) +* [[`96165f9be2`](https://github.com/nodejs/node/commit/96165f9be2)] - **doc**: minor clarification in the modules API doc. (Сковорода Никита Андреевич) [#1983](https://github.com/nodejs/node/pull/1983) +* [[`5c2707c1b2`](https://github.com/nodejs/node/commit/5c2707c1b2)] - **doc**: benchmark/README.md copyedit (Rich Trott) [#1970](https://github.com/nodejs/node/pull/1970) +* [[`74fdf732d0`](https://github.com/nodejs/node/commit/74fdf732d0)] - **doc**: copyedit COLLABORATOR_GUIDE.md (Rich Trott) [#1964](https://github.com/nodejs/node/pull/1964) +* [[`5fe6e83640`](https://github.com/nodejs/node/commit/5fe6e83640)] - **doc**: copyedit GOVERNANCE.md (Rich Trott) [#1963](https://github.com/nodejs/node/pull/1963) +* [[`428526544c`](https://github.com/nodejs/node/commit/428526544c)] - **doc**: add ChALkeR as collaborator (Сковорода Никита Андреевич) [#1927](https://github.com/nodejs/node/pull/1927) +* [[`5dfe0d5d61`](https://github.com/nodejs/node/commit/5dfe0d5d61)] - **doc**: remove irrelevant SEMVER-MINOR & MAJOR (Rod Vagg) +* [[`fb8811d95e`](https://github.com/nodejs/node/commit/fb8811d95e)] - **lib,test**: fix whitespace issues (Roman Reiss) [#1971](https://github.com/nodejs/node/pull/1971) +* [[`a4f4909f3d`](https://github.com/nodejs/node/commit/a4f4909f3d)] - **module**: fix stat with long paths on Windows (Michaël Zasso) [#2013](https://github.com/nodejs/node/pull/2013) +* [[`a71ee93afe`](https://github.com/nodejs/node/commit/a71ee93afe)] - **module**: reduce syscalls during require search (Pierre Inglebert) [#1920](https://github.com/nodejs/node/pull/1920) +* [[`671e64ac73`](https://github.com/nodejs/node/commit/671e64ac73)] - **module**: allow long paths for require on Windows (Michaël Zasso) +* [[`061342a500`](https://github.com/nodejs/node/commit/061342a500)] - **net**: Defer reading until listeners could be added (James Hartig) [#1496](https://github.com/nodejs/node/pull/1496) +* [[`5d2b846d11`](https://github.com/nodejs/node/commit/5d2b846d11)] - **test**: assert tmp and fixture dirs different (Rich Trott) [#2015](https://github.com/nodejs/node/pull/2015) +* [[`b0990ef45d`](https://github.com/nodejs/node/commit/b0990ef45d)] - **test**: confirm symlink (Rich Trott) [#2014](https://github.com/nodejs/node/pull/2014) +* [[`3ba4f71fc4`](https://github.com/nodejs/node/commit/3ba4f71fc4)] - **test**: check result as early as possible (Rich Trott) [#2007](https://github.com/nodejs/node/pull/2007) +* [[`0abcf44d6b`](https://github.com/nodejs/node/commit/0abcf44d6b)] - **test**: add Buffer slice UTF-8 test (Rich Trott) [#1989](https://github.com/nodejs/node/pull/1989) +* [[`88c1831ff4`](https://github.com/nodejs/node/commit/88c1831ff4)] - **test**: tmpdir creation failures should fail tests (Rich Trott) [#1976](https://github.com/nodejs/node/pull/1976) +* [[`52a822d944`](https://github.com/nodejs/node/commit/52a822d944)] - **test**: fix test-cluster-worker-disconnect (Santiago Gimeno) [#1919](https://github.com/nodejs/node/pull/1919) +* [[`7c79490bfb`](https://github.com/nodejs/node/commit/7c79490bfb)] - **test**: only refresh tmpDir for tests that need it (Rich Trott) [#1954](https://github.com/nodejs/node/pull/1954) +* [[`88d7904c0b`](https://github.com/nodejs/node/commit/88d7904c0b)] - **test**: remove test repetition (Rich Trott) [#1874](https://github.com/nodejs/node/pull/1874) +* [[`91dfb5e094`](https://github.com/nodejs/node/commit/91dfb5e094)] - **tools**: make test-npm work without global npm (Jeremiah Senkpiel) [#1926](https://github.com/nodejs/node/pull/1926) +* [[`3777f41562`](https://github.com/nodejs/node/commit/3777f41562)] - **tools**: enable whitespace related rules in eslint (Roman Reiss) [#1971](https://github.com/nodejs/node/pull/1971) +* [[`626432d843`](https://github.com/nodejs/node/commit/626432d843)] - **util**: dont repeat isBuffer (Brendan Ashworth) [#1988](https://github.com/nodejs/node/pull/1988) +* [[`1d79f572f1`](https://github.com/nodejs/node/commit/1d79f572f1)] - **util**: move deprecate() to internal module (Brendan Ashworth) [#1988](https://github.com/nodejs/node/pull/1988) +* [[`4b4b1760b5`](https://github.com/nodejs/node/commit/4b4b1760b5)] - **v8**: cherry-pick uclibc build patch from upstream (Ben Noordhuis) [#1974](https://github.com/nodejs/node/pull/1974) +* [[`5d0cee46bb`](https://github.com/nodejs/node/commit/5d0cee46bb)] - **vm**: remove unnecessary HandleScopes (Ben Noordhuis) [#2001](https://github.com/nodejs/node/pull/2001) +* [[`0ecf9457b5`](https://github.com/nodejs/node/commit/0ecf9457b5)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) +* [[`953b3e75e8`](https://github.com/nodejs/node/commit/953b3e75e8)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) +* [[`3806d875d3`](https://github.com/nodejs/node/commit/3806d875d3)] - **zlib**: prevent uncaught exception in zlibBuffer (Michaël Zasso) [#1811](https://github.com/nodejs/node/pull/1811) + + + +## 2015-06-13, Version 2.3.0, @rvagg + +### Notable changes + +* **libuv**: Upgraded to 1.6.0 and 1.6.1, see [full ChangeLog](https://github.com/libuv/libuv/blob/60e515d9e6f3d86c0eedad583805201f32ea3aed/ChangeLog#L1-L36) for details. (Saúl Ibarra Corretgé) [#1905](https://github.com/nodejs/node/pull/1905) [#1889](https://github.com/nodejs/node/pull/1889). Highlights include: + - Fix TTY becoming blocked on OS X + - Fix UDP send callbacks to not to be synchronous + - Add `uv_os_homedir()` (exposed as `os.homedir()`, see below) +* **npm**: See full [release notes](https://github.com/npm/npm/releases/tag/v2.11.1) for details. (Kat Marchán) [#1899](https://github.com/nodejs/node/pull/1899). Highlight: + - Use GIT_SSH_COMMAND (available as of Git 2.3) +* **openssl**: + - Upgrade to 1.0.2b and 1.0.2c, introduces DHE man-in-the-middle protection (Logjam) and fixes malformed ECParameters causing infinite loop (CVE-2015-1788). See the [security advisory](https://www.openssl.org/news/secadv_20150611.txt) for full details. (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) [#1958](https://github.com/nodejs/node/pull/1958) + - Support [FIPS](https://en.wikipedia.org/wiki/Federal_Information_Processing_Standards) mode of OpenSSL, see [README](https://github.com/nodejs/node#building-iojs-with-fips-compliant-openssl) for instructions. (Fedor Indutny) [#1890](https://github.com/nodejs/node/pull/1890) +* **os**: Add `os.homedir()` method. (Colin Ihrig) [#1791](https://github.com/nodejs/node/pull/1791) +* **smalloc**: Deprecate whole module. (Vladimir Kurchatkin) [#1822](https://github.com/nodejs/node/pull/1822) +* Add new collaborators: + - Alex Kocharin ([@rlidwka](https://github.com/rlidwka)) + - Christopher Monsanto ([@monsanto](https://github.com/monsanto)) + - Ali Ijaz Sheikh ([@ofrobots](https://github.com/ofrobots)) + - Oleg Elifantiev ([@Olegas](https://github.com/Olegas)) + - Domenic Denicola ([@domenic](https://github.com/domenic)) + - Rich Trott ([@Trott](https://github.com/Trott)) + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +## Commits + +* [[`9c0a1b8cfc`](https://github.com/nodejs/node/commit/9c0a1b8cfc)] - **cluster**: wait on servers closing before disconnect (Oleg Elifantiev) [#1400](https://github.com/nodejs/node/pull/1400) +* [[`0f68377f69`](https://github.com/nodejs/node/commit/0f68377f69)] - **crypto**: support FIPS mode of OpenSSL (Fedor Indutny) [#1890](https://github.com/nodejs/node/pull/1890) +* [[`38d1afc24d`](https://github.com/nodejs/node/commit/38d1afc24d)] - **(SEMVER-MINOR)** **crypto**: add getCurves() to get supported ECs (Brian White) [#1914](https://github.com/nodejs/node/pull/1914) +* [[`a4dbf45b59`](https://github.com/nodejs/node/commit/a4dbf45b59)] - **crypto**: update root certificates (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) +* [[`81029c639a`](https://github.com/nodejs/node/commit/81029c639a)] - **debugger**: improve ESRCH error message (Jackson Tian) [#1863](https://github.com/nodejs/node/pull/1863) +* [[`2a7fd0ad32`](https://github.com/nodejs/node/commit/2a7fd0ad32)] - **deps**: update UPGRADING.md doc to openssl-1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) +* [[`6b3df929e0`](https://github.com/nodejs/node/commit/6b3df929e0)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) +* [[`664a659696`](https://github.com/nodejs/node/commit/664a659696)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`42a8de2ac6`](https://github.com/nodejs/node/commit/42a8de2ac6)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) +* [[`c66c3d9fa3`](https://github.com/nodejs/node/commit/c66c3d9fa3)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) +* [[`86737cf0a0`](https://github.com/nodejs/node/commit/86737cf0a0)] - **deps**: upgrade openssl sources to 1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) +* [[`94804969b7`](https://github.com/nodejs/node/commit/94804969b7)] - **deps**: update asm files for openssl-1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) +* [[`38444915e0`](https://github.com/nodejs/node/commit/38444915e0)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) +* [[`f62b613252`](https://github.com/nodejs/node/commit/f62b613252)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`f624d0122c`](https://github.com/nodejs/node/commit/f624d0122c)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) +* [[`dcd67cc8d7`](https://github.com/nodejs/node/commit/dcd67cc8d7)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) +* [[`c21b24decf`](https://github.com/nodejs/node/commit/c21b24decf)] - **deps**: upgrade openssl sources to 1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) +* [[`2dc819b09a`](https://github.com/nodejs/node/commit/2dc819b09a)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`f41b7f12b5`](https://github.com/nodejs/node/commit/f41b7f12b5)] - **deps**: upgrade to npm 2.11.1 (Kat Marchán) [#1899](https://github.com/nodejs/node/pull/1899) +* [[`a5bd466440`](https://github.com/nodejs/node/commit/a5bd466440)] - **deps**: update libuv to version 1.6.1 (Saúl Ibarra Corretgé) [#1905](https://github.com/nodejs/node/pull/1905) +* [[`aa33db3238`](https://github.com/nodejs/node/commit/aa33db3238)] - **deps**: update libuv to version 1.6.0 (Saúl Ibarra Corretgé) [#1889](https://github.com/nodejs/node/pull/1889) +* [[`0ee497f0b4`](https://github.com/nodejs/node/commit/0ee497f0b4)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`b5cd2f0986`](https://github.com/nodejs/node/commit/b5cd2f0986)] - **dgram**: partially revert 18d457b (Saúl Ibarra Corretgé) [#1889](https://github.com/nodejs/node/pull/1889) +* [[`a3cc43d0a4`](https://github.com/nodejs/node/commit/a3cc43d0a4)] - **doc**: add Trott as collaborator (Rich Trott) [#1962](https://github.com/nodejs/node/pull/1962) +* [[`cf5020fc02`](https://github.com/nodejs/node/commit/cf5020fc02)] - **doc**: add domenic as collaborator (Domenic Denicola) [#1942](https://github.com/nodejs/node/pull/1942) +* [[`11ed5f31ab`](https://github.com/nodejs/node/commit/11ed5f31ab)] - **doc**: add Olegas as collaborator (Oleg Elifantiev) [#1930](https://github.com/nodejs/node/pull/1930) +* [[`f500e1833b`](https://github.com/nodejs/node/commit/f500e1833b)] - **doc**: add ofrobots as collaborator (Ali Ijaz Sheikh) +* [[`717724611a`](https://github.com/nodejs/node/commit/717724611a)] - **doc**: add monsanto as collaborator (Christopher Monsanto) [#1932](https://github.com/nodejs/node/pull/1932) +* [[`7192b6688c`](https://github.com/nodejs/node/commit/7192b6688c)] - **doc**: add rlidwka as collaborator (Alex Kocharin) [#1929](https://github.com/nodejs/node/pull/1929) +* [[`9f3a03f0d4`](https://github.com/nodejs/node/commit/9f3a03f0d4)] - **doc**: add references to crypto.getCurves() (Roman Reiss) [#1918](https://github.com/nodejs/node/pull/1918) +* [[`ff39ecb914`](https://github.com/nodejs/node/commit/ff39ecb914)] - **doc**: remove comma splice (Rich Trott) [#1900](https://github.com/nodejs/node/pull/1900) +* [[`deb8b87dc9`](https://github.com/nodejs/node/commit/deb8b87dc9)] - **doc**: add note about available ECC curves (Ryan Petschek) [#1913](https://github.com/nodejs/node/pull/1913) +* [[`89a5b9040e`](https://github.com/nodejs/node/commit/89a5b9040e)] - **doc**: fix http.IncomingMessage.socket documentation (Сковорода Никита Андреевич) [#1867](https://github.com/nodejs/node/pull/1867) +* [[`d29034b34b`](https://github.com/nodejs/node/commit/d29034b34b)] - **doc**: adjust changelog to clarify `client` revert (Rod Vagg) [#1859](https://github.com/nodejs/node/pull/1859) +* [[`a79dece8ad`](https://github.com/nodejs/node/commit/a79dece8ad)] - **docs**: add return value for sync fs functions (Tyler Anton) [#1770](https://github.com/nodejs/node/pull/1770) +* [[`1cb72c14c4`](https://github.com/nodejs/node/commit/1cb72c14c4)] - **docs**: delete unused/duplicate css files (Robert Kowalski) [#1770](https://github.com/nodejs/node/pull/1770) +* [[`53a4eb3198`](https://github.com/nodejs/node/commit/53a4eb3198)] - **fs**: make SyncWriteStream non-enumerable (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) +* [[`a011c3243f`](https://github.com/nodejs/node/commit/a011c3243f)] - **fs**: minor refactoring (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) +* [[`8841132f30`](https://github.com/nodejs/node/commit/8841132f30)] - **fs**: remove inStatWatchers and use Map for lookup (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) +* [[`67a11b9bcc`](https://github.com/nodejs/node/commit/67a11b9bcc)] - **fs**: removing unnecessary nullCheckCallNT (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) +* [[`09f2a67bd8`](https://github.com/nodejs/node/commit/09f2a67bd8)] - **fs**: improve error message descriptions (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) +* [[`2dcef83b5f`](https://github.com/nodejs/node/commit/2dcef83b5f)] - **fs**: use `kMaxLength` from binding (Vladimir Kurchatkin) [#1903](https://github.com/nodejs/node/pull/1903) +* [[`353e26e3c7`](https://github.com/nodejs/node/commit/353e26e3c7)] - **(SEMVER-MINOR)** **fs**: Add string encoding option for Stream method (Yosuke Furukawa) [#1845](https://github.com/nodejs/node/pull/1845) +* [[`8357c5084b`](https://github.com/nodejs/node/commit/8357c5084b)] - **fs**: set encoding on fs.createWriteStream (Yosuke Furukawa) [#1844](https://github.com/nodejs/node/pull/1844) +* [[`02c345020a`](https://github.com/nodejs/node/commit/02c345020a)] - **gitignore**: don't ignore the debug npm module (Kat Marchán) [#1908](https://github.com/nodejs/node/pull/1908) +* [[`b5b8ff117c`](https://github.com/nodejs/node/commit/b5b8ff117c)] - **lib**: don't use global Buffer (Roman Reiss) [#1794](https://github.com/nodejs/node/pull/1794) +* [[`a251657058`](https://github.com/nodejs/node/commit/a251657058)] - **node**: mark promises as handled as soon as possible (Vladimir Kurchatkin) [#1952](https://github.com/nodejs/node/pull/1952) +* [[`2eb170874a`](https://github.com/nodejs/node/commit/2eb170874a)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) +* [[`a130132c8f`](https://github.com/nodejs/node/commit/a130132c8f)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) +* [[`6e78e5feaa`](https://github.com/nodejs/node/commit/6e78e5feaa)] - **(SEMVER-MINOR)** **os**: add homedir() (cjihrig) [#1791](https://github.com/nodejs/node/pull/1791) +* [[`d9e250295b`](https://github.com/nodejs/node/commit/d9e250295b)] - ***Revert*** "**readline**: allow tabs in input" (Jeremiah Senkpiel) [#1961](https://github.com/nodejs/node/pull/1961) +* [[`4b3d493c4b`](https://github.com/nodejs/node/commit/4b3d493c4b)] - **readline**: allow tabs in input (Rich Trott) [#1761](https://github.com/nodejs/node/pull/1761) +* [[`6d95f4ff92`](https://github.com/nodejs/node/commit/6d95f4ff92)] - **(SEMVER-MINOR)** **smalloc**: deprecate whole module (Vladimir Kurchatkin) [#1822](https://github.com/nodejs/node/pull/1822) +* [[`8c71a9241d`](https://github.com/nodejs/node/commit/8c71a9241d)] - **src**: hide InitializeICUDirectory symbol (Ben Noordhuis) [#1815](https://github.com/nodejs/node/pull/1815) +* [[`5b6f575c1f`](https://github.com/nodejs/node/commit/5b6f575c1f)] - ***Revert*** "**src**: add getopt option parser" (Evan Lucas) [#1862](https://github.com/nodejs/node/pull/1862) +* [[`c0e7bf2d8c`](https://github.com/nodejs/node/commit/c0e7bf2d8c)] - **src**: add getopt option parser (Evan Lucas) [#1804](https://github.com/nodejs/node/pull/1804) +* [[`8ea6844d26`](https://github.com/nodejs/node/commit/8ea6844d26)] - **test**: add test for failed save in REPL (Rich Trott) [#1818](https://github.com/nodejs/node/pull/1818) +* [[`03ce84dfa1`](https://github.com/nodejs/node/commit/03ce84dfa1)] - **test**: fix cluster-worker-wait-server-close races (Sam Roberts) [#1953](https://github.com/nodejs/node/pull/1953) +* [[`a6b8ee19b8`](https://github.com/nodejs/node/commit/a6b8ee19b8)] - **test**: create temp dir in common.js (Rich Trott) [#1877](https://github.com/nodejs/node/pull/1877) +* [[`ff8202c6f4`](https://github.com/nodejs/node/commit/ff8202c6f4)] - **test**: fix undeclared variable access (Roman Reiss) [#1794](https://github.com/nodejs/node/pull/1794) +* [[`d9ddd7d345`](https://github.com/nodejs/node/commit/d9ddd7d345)] - **test**: remove TODO comment (Rich Trott) [#1820](https://github.com/nodejs/node/pull/1820) +* [[`6537fd4b55`](https://github.com/nodejs/node/commit/6537fd4b55)] - **test**: remove TODO (Rich Trott) [#1875](https://github.com/nodejs/node/pull/1875) +* [[`a804026c9b`](https://github.com/nodejs/node/commit/a804026c9b)] - **test**: fix broken FreeBSD test (Santiago Gimeno) [#1881](https://github.com/nodejs/node/pull/1881) +* [[`43a82f8a71`](https://github.com/nodejs/node/commit/43a82f8a71)] - **test**: fix test-sync-io-option (Evan Lucas) [#1840](https://github.com/nodejs/node/pull/1840) +* [[`4ed25f664d`](https://github.com/nodejs/node/commit/4ed25f664d)] - **test**: add -no_rand_screen for tls-server-verify (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`4cf323d23d`](https://github.com/nodejs/node/commit/4cf323d23d)] - **test**: kill child in tls-server-verify for speed up (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`e6ccdcc1fe`](https://github.com/nodejs/node/commit/e6ccdcc1fe)] - **test**: improve console output of tls-server-verify (João Reis) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`975e5956f0`](https://github.com/nodejs/node/commit/975e5956f0)] - **test**: run tls-server-verify servers in parallel (João Reis) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`b18604ba2c`](https://github.com/nodejs/node/commit/b18604ba2c)] - **test**: running tls-server-verify clients in parallel (João Reis) [#1836](https://github.com/nodejs/node/pull/1836) +* [[`f78c722df5`](https://github.com/nodejs/node/commit/f78c722df5)] - **test**: remove hardwired references to 'iojs' (Rod Vagg) [#1882](https://github.com/nodejs/node/pull/1882) +* [[`bd99e8de8e`](https://github.com/nodejs/node/commit/bd99e8de8e)] - **test**: more test coverage for maxConnections (Rich Trott) [#1855](https://github.com/nodejs/node/pull/1855) +* [[`b9267189a5`](https://github.com/nodejs/node/commit/b9267189a5)] - **test**: fix test-child-process-stdout-flush-exit (Santiago Gimeno) [#1868](https://github.com/nodejs/node/pull/1868) +* [[`d20f018dcf`](https://github.com/nodejs/node/commit/d20f018dcf)] - **test**: loosen condition to detect infinite loop (Yosuke Furukawa) [#1857](https://github.com/nodejs/node/pull/1857) +* [[`e0e96acc6f`](https://github.com/nodejs/node/commit/e0e96acc6f)] - **test**: remove smalloc add-on test (Ben Noordhuis) [#1835](https://github.com/nodejs/node/pull/1835) +* [[`8704c58fc4`](https://github.com/nodejs/node/commit/8704c58fc4)] - **test**: remove unneeded comment task (Rich Trott) [#1858](https://github.com/nodejs/node/pull/1858) +* [[`8732977536`](https://github.com/nodejs/node/commit/8732977536)] - **tls**: fix references to undefined `cb` (Fedor Indutny) [#1951](https://github.com/nodejs/node/pull/1951) +* [[`75930bb38c`](https://github.com/nodejs/node/commit/75930bb38c)] - **tls**: prevent use-after-free (Fedor Indutny) [#1702](https://github.com/nodejs/node/pull/1702) +* [[`5795e835a1`](https://github.com/nodejs/node/commit/5795e835a1)] - **tls**: emit errors on close whilst async action (Fedor Indutny) [#1702](https://github.com/nodejs/node/pull/1702) +* [[`59d9734e21`](https://github.com/nodejs/node/commit/59d9734e21)] - **tls_wrap**: invoke queued callbacks in DestroySSL (Fedor Indutny) [#1702](https://github.com/nodejs/node/pull/1702) +* [[`6e4d30286d`](https://github.com/nodejs/node/commit/6e4d30286d)] - **tools**: enable/add additional eslint rules (Roman Reiss) [#1794](https://github.com/nodejs/node/pull/1794) +* [[`098354a9f8`](https://github.com/nodejs/node/commit/098354a9f8)] - **tools**: update certdata.txt (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) +* [[`a2d921d6a0`](https://github.com/nodejs/node/commit/a2d921d6a0)] - **tools**: customize mk-ca-bundle.pl (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) +* [[`5be9efca40`](https://github.com/nodejs/node/commit/5be9efca40)] - **tools**: update mk-ca-bundle.pl to HEAD of upstream (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) +* [[`1baba0580d`](https://github.com/nodejs/node/commit/1baba0580d)] - **tools**: Fix copying contents of deps/npm (thefourtheye) [#1853](https://github.com/nodejs/node/pull/1853) +* [[`628845b816`](https://github.com/nodejs/node/commit/628845b816)] - **(SEMVER-MINOR)** **util**: introduce `printDeprecationMessage` function (Vladimir Kurchatkin) [#1822](https://github.com/nodejs/node/pull/1822) +* [[`91d0a8b19c`](https://github.com/nodejs/node/commit/91d0a8b19c)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) + + + +## 2015-06-01, Version 2.2.1, @rvagg + +### Notable changes + +* **http**: Reverts the move of the `client` property of `IncomingMessage` to its prototype. Although undocumented, this property was used and assumed to be an "own property" in the wild, most notably by [request](https://github.com/request/request) which is used by npm. (Michaël Zasso) [#1852](https://github.com/nodejs/node/pull/1852). + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +### Commits + +* [[`c5a1009903`](https://github.com/nodejs/node/commit/c5a1009903)] - **build**: avoid passing empty strings to build flags (Johan Bergström) [#1789](https://github.com/nodejs/node/pull/1789) +* [[`5d83401086`](https://github.com/nodejs/node/commit/5d83401086)] - **doc**: put SEMVER-MINOR on pre-load module fix 2.2.0 (Rod Vagg) +* [[`4d6b768e5d`](https://github.com/nodejs/node/commit/4d6b768e5d)] - **http**: revert deprecation of client property (Michaël Zasso) [#1852](https://github.com/nodejs/node/pull/1852) + + + +## 2015-05-31, Version 2.2.0, @rvagg + +### Notable changes + +* **node**: Speed-up `require()` by replacing usage of `fs.statSync()` and `fs.readFileSync()` with internal variants that are faster for this use-case and do not create as many objects for the garbage collector to clean up. The primary two benefits are: significant increase in application start-up time on typical applications and better start-up time for the debugger by eliminating almost all of the thousands of exception events. (Ben Noordhuis) [#1801](https://github.com/nodejs/node/pull/1801). +* **node**: Resolution of pre-load modules (`-r` or `--require`) now follows the standard `require()` rules rather than just resolving paths, so you can now pre-load modules in node_modules. (Ali Ijaz Sheikh) [#1812](https://github.com/nodejs/node/pull/1812). +* **npm**: Upgraded npm to v2.11.0. New hooks for `preversion`, `version`, and `postversion` lifecycle events, some SPDX-related license changes and license file inclusions. See the [release notes](https://github.com/npm/npm/releases/tag/v2.11.0) for full details. + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +### Commits + +* [[`a77c330c32`](https://github.com/nodejs/node/commit/a77c330c32)] - **(SEMVER-MINOR)** **child_process**: expose ChildProcess constructor (Evan Lucas) [#1760](https://github.com/nodejs/node/pull/1760) +* [[`3a1bc067d4`](https://github.com/nodejs/node/commit/3a1bc067d4)] - ***Revert*** "**core**: set PROVIDER type as Persistent class id" (Ben Noordhuis) [#1827](https://github.com/nodejs/node/pull/1827) +* [[`f9fd554500`](https://github.com/nodejs/node/commit/f9fd554500)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`c1afa53648`](https://github.com/nodejs/node/commit/c1afa53648)] - **deps**: upgrade npm to 2.11.0 (Forrest L Norvell) [iojs/io.js#1829](https://github.com/iojs/io.js/pull/1829) +* [[`ff794498e7`](https://github.com/nodejs/node/commit/ff794498e7)] - **doc**: `fs.*File()` also accept encoding strings (Rich Trott) [#1806](https://github.com/nodejs/node/pull/1806) +* [[`98649fd31a`](https://github.com/nodejs/node/commit/98649fd31a)] - **doc**: add documentation for AtExit hook (Steve Sharp) [#1014](https://github.com/nodejs/node/pull/1014) +* [[`eb1856dfd1`](https://github.com/nodejs/node/commit/eb1856dfd1)] - **doc**: clarify stability of fs.watch and relatives (Rich Trott) [#1775](https://github.com/nodejs/node/pull/1775) +* [[`a74c2c9458`](https://github.com/nodejs/node/commit/a74c2c9458)] - **doc**: state url decoding behavior (Josh Gummersall) [#1731](https://github.com/nodejs/node/pull/1731) +* [[`ba76a9d872`](https://github.com/nodejs/node/commit/ba76a9d872)] - **doc**: remove bad semver-major entry from CHANGELOG (Rod Vagg) [#1782](https://github.com/nodejs/node/pull/1782) +* [[`a6a3f8c78d`](https://github.com/nodejs/node/commit/a6a3f8c78d)] - **doc**: fix changelog s/2.0.3/2.1.0 (Rod Vagg) +* [[`2c686fd3ce`](https://github.com/nodejs/node/commit/2c686fd3ce)] - **http**: flush stored header (Vladimir Kurchatkin) [#1695](https://github.com/nodejs/node/pull/1695) +* [[`1eec5f091a`](https://github.com/nodejs/node/commit/1eec5f091a)] - **http**: simplify code and remove unused properties (Brian White) [#1572](https://github.com/nodejs/node/pull/1572) +* [[`1bbf8d0720`](https://github.com/nodejs/node/commit/1bbf8d0720)] - **lib**: speed up require(), phase 2 (Ben Noordhuis) [#1801](https://github.com/nodejs/node/pull/1801) +* [[`b14fd1a720`](https://github.com/nodejs/node/commit/b14fd1a720)] - **lib**: speed up require(), phase 1 (Ben Noordhuis) [#1801](https://github.com/nodejs/node/pull/1801) +* [[`5abd4ac079`](https://github.com/nodejs/node/commit/5abd4ac079)] - **lib**: simplify nextTick() usage (Brian White) [#1612](https://github.com/nodejs/node/pull/1612) +* [[`5759722cfa`](https://github.com/nodejs/node/commit/5759722cfa)] - **(SEMVER-MINOR)** **src**: fix module search path for preload modules (Ali Ijaz Sheikh) [#1812](https://github.com/nodejs/node/pull/1812) +* [[`a65762cab6`](https://github.com/nodejs/node/commit/a65762cab6)] - **src**: remove old code (Brendan Ashworth) [#1819](https://github.com/nodejs/node/pull/1819) +* [[`93a44d5228`](https://github.com/nodejs/node/commit/93a44d5228)] - **src**: fix deferred events not working with -e (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) +* [[`8059393934`](https://github.com/nodejs/node/commit/8059393934)] - **test**: check error type from net.Server.listen() (Rich Trott) [#1821](https://github.com/nodejs/node/pull/1821) +* [[`4e90c82cdb`](https://github.com/nodejs/node/commit/4e90c82cdb)] - **test**: add heap profiler add-on regression test (Ben Noordhuis) [#1828](https://github.com/nodejs/node/pull/1828) +* [[`6dfca71af0`](https://github.com/nodejs/node/commit/6dfca71af0)] - **test**: don't lint autogenerated test/addons/doc-*/ (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) +* [[`c2b8b30836`](https://github.com/nodejs/node/commit/c2b8b30836)] - **test**: remove stray copyright notices (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) +* [[`280fb01daf`](https://github.com/nodejs/node/commit/280fb01daf)] - **test**: fix deprecation warning in addons test (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) +* [[`8606793999`](https://github.com/nodejs/node/commit/8606793999)] - **tools**: pass constant to logger instead of string (Johan Bergström) [#1842](https://github.com/nodejs/node/pull/1842) +* [[`fbd2b59716`](https://github.com/nodejs/node/commit/fbd2b59716)] - **tools**: add objectLiteralShorthandProperties to .eslintrc (Evan Lucas) [#1760](https://github.com/nodejs/node/pull/1760) +* [[`53e98cc1b4`](https://github.com/nodejs/node/commit/53e98cc1b4)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1763](https://github.com/nodejs/node/pull/1763) + + +## 2015-05-24, Version 2.1.0, @rvagg + +### Notable changes + +* **crypto**: Diffie-Hellman key exchange (DHE) parameters (`'dhparams'`) must now be 1024 bits or longer or an error will be thrown. A warning will also be printed to the console if you supply less than 2048 bits. See https://weakdh.org/ for further context on this security concern. (Shigeki Ohtsu) [#1739](https://github.com/nodejs/node/pull/1739). +* **node**: A new `--trace-sync-io` command line flag will print a warning and a stack trace whenever a synchronous API is used. This can be used to track down synchronous calls that may be slowing down an application. (Trevor Norris) [#1707](https://github.com/nodejs/node/pull/1707). +* **node**: To allow for chaining of methods, the `setTimeout()`, `setKeepAlive()`, `setNoDelay()`, `ref()` and `unref()` methods used in `'net'`, `'dgram'`, `'http'`, `'https'` and `'tls'` now return the current instance instead of `undefined` (Roman Reiss & Evan Lucas) [#1699](https://github.com/nodejs/node/pull/1699) [#1768](https://github.com/nodejs/node/pull/1768) [#1779](https://github.com/nodejs/node/pull/1779). +* **npm**: Upgraded to v2.10.1, release notes can be found in and . +* **util**: A significant speed-up (in the order of 35%) for the common-case of a single string argument to `util.format()`, used by `console.log()` (Сковорода Никита Андреевич) [#1749](https://github.com/nodejs/node/pull/1749). + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +### Commits + +* [[`9da168b71f`](https://github.com/nodejs/node/commit/9da168b71f)] - **buffer**: optimize Buffer.byteLength (Brendan Ashworth) [#1713](https://github.com/nodejs/node/pull/1713) +* [[`2b1c01c2cc`](https://github.com/nodejs/node/commit/2b1c01c2cc)] - **build**: refactor pkg-config for shared libraries (Johan Bergström) [#1603](https://github.com/nodejs/node/pull/1603) +* [[`3c44100558`](https://github.com/nodejs/node/commit/3c44100558)] - **core**: set PROVIDER type as Persistent class id (Trevor Norris) [#1730](https://github.com/nodejs/node/pull/1730) +* [[`c1de6d249e`](https://github.com/nodejs/node/commit/c1de6d249e)] - **(SEMVER-MINOR)** **core**: implement runtime flag to trace sync io (Trevor Norris) [#1707](https://github.com/nodejs/node/pull/1707) +* [[`9e7099fa4e`](https://github.com/nodejs/node/commit/9e7099fa4e)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) +* [[`c54d057598`](https://github.com/nodejs/node/commit/c54d057598)] - **deps**: upgrade to npm 2.10.1 (Rebecca Turner) [#1763](https://github.com/nodejs/node/pull/1763) +* [[`367ffd167d`](https://github.com/nodejs/node/commit/367ffd167d)] - **doc**: update AUTHORS list (Rod Vagg) [#1776](https://github.com/nodejs/node/pull/1776) +* [[`2bb2f06b3e`](https://github.com/nodejs/node/commit/2bb2f06b3e)] - **doc**: fix typo in CONTRIBUTING.md (Rich Trott) [#1755](https://github.com/nodejs/node/pull/1755) +* [[`515afc6367`](https://github.com/nodejs/node/commit/515afc6367)] - **doc**: path is ignored in url.format (Maurice Butler) [#1753](https://github.com/nodejs/node/pull/1753) +* [[`f0a8bc3f84`](https://github.com/nodejs/node/commit/f0a8bc3f84)] - **doc**: fix spelling in CHANGELOG (Felipe Batista) +* [[`86dd244d9b`](https://github.com/nodejs/node/commit/86dd244d9b)] - **doc**: add notes to child_process.fork() and .exec() (Rich Trott) [#1718](https://github.com/nodejs/node/pull/1718) +* [[`066274794c`](https://github.com/nodejs/node/commit/066274794c)] - **doc**: update links from iojs/io.js to nodejs/io.js (Frederic Hemberger) [#1715](https://github.com/nodejs/node/pull/1715) +* [[`cb381fe3e0`](https://github.com/nodejs/node/commit/cb381fe3e0)] - **(SEMVER-MINOR)** **net**: return this from setNoDelay and setKeepAlive (Roman Reiss) [#1779](https://github.com/nodejs/node/pull/1779) +* [[`85d9983009`](https://github.com/nodejs/node/commit/85d9983009)] - **net**: persist net.Socket options before connect (Evan Lucas) [#1518](https://github.com/nodejs/node/pull/1518) +* [[`39dde3222e`](https://github.com/nodejs/node/commit/39dde3222e)] - **(SEMVER-MINOR)** **net,dgram**: return this from ref and unref methods (Roman Reiss) [#1768](https://github.com/nodejs/node/pull/1768) +* [[`5773438913`](https://github.com/nodejs/node/commit/5773438913)] - **test**: fix jslint error (Michaël Zasso) [#1743](https://github.com/nodejs/node/pull/1743) +* [[`867631986f`](https://github.com/nodejs/node/commit/867631986f)] - **test**: fix test-sync-io-option (Santiago Gimeno) [#1734](https://github.com/nodejs/node/pull/1734) +* [[`f29762f4dd`](https://github.com/nodejs/node/commit/f29762f4dd)] - **test**: enable linting for tests (Roman Reiss) [#1721](https://github.com/nodejs/node/pull/1721) +* [[`2a71f02988`](https://github.com/nodejs/node/commit/2a71f02988)] - **tls**: emit errors happening before handshake finish (Malte-Thorben Bruns) [#1769](https://github.com/nodejs/node/pull/1769) +* [[`80342f649d`](https://github.com/nodejs/node/commit/80342f649d)] - **tls**: use `.destroy(err)` instead of destroy+emit (Fedor Indutny) [#1711](https://github.com/nodejs/node/pull/1711) +* [[`9b35be5810`](https://github.com/nodejs/node/commit/9b35be5810)] - **tls**: make server not use DHE in less than 1024bits (Shigeki Ohtsu) [#1739](https://github.com/nodejs/node/pull/1739) +* [[`214d02040e`](https://github.com/nodejs/node/commit/214d02040e)] - **util**: speed up common case of formatting string (Сковорода Никита Андреевич) [#1749](https://github.com/nodejs/node/pull/1749) +* [[`d144e96fbf`](https://github.com/nodejs/node/commit/d144e96fbf)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1763](https://github.com/nodejs/node/pull/1763) +* [[`0d6d3dda95`](https://github.com/nodejs/node/commit/0d6d3dda95)] - **win,node-gyp**: make delay-load hook C89 compliant (Sharat M R) [TooTallNate/node-gyp#616](https://github.com/TooTallNate/node-gyp/pull/616) + + +## 2015-05-17, Version 1.8.2, @rvagg + +**Maintenance release** + +## Notable changes + +* **crypto**: significantly reduced memory usage for TLS (Fedor Indutny & Сковорода Никита Андреевич) [#1529](https://github.com/nodejs/node/pull/1529) +* **npm**: Upgrade npm to 2.9.0. See the [v2.8.4](https://github.com/npm/npm/releases/tag/v2.8.4) and [v2.9.0](https://github.com/npm/npm/releases/tag/v2.9.0) release notes for details. Summary: + - Add support for default author field to make `npm init -y` work without user-input (@othiym23) [npm/npm/d8eee6cf9d](https://github.com/npm/npm/commit/d8eee6cf9d2ff7aca68dfaed2de76824a3e0d9 + - Include local modules in `npm outdated` and `npm update` (@ArnaudRinquin) [npm/npm#7426](https://github.com/npm/npm/issues/7426) + - The prefix used before the version number on `npm version` is now configurable via `tag-version-prefix` (@kkragenbrink) [npm/npm#8014](https://github.com/npm/npm/issues/8014) + +### Known issues + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). +* readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) + +### Commits + +* [[`5404cbc745`](https://github.com/nodejs/node/commit/5404cbc745)] - **buffer**: fix copy() segfault with zero arguments (Trevor Norris) [nodejs/node#1520](https://github.com/nodejs/node/pull/1520) +* [[`65dd10e9c0`](https://github.com/nodejs/node/commit/65dd10e9c0)] - **build**: remove -J from test-ci (Rod Vagg) [nodejs/node#1544](https://github.com/nodejs/node/pull/1544) +* [[`74060bb60e`](https://github.com/nodejs/node/commit/74060bb60e)] - **crypto**: track external memory for SSL structures (Fedor Indutny) [nodejs/node#1529](https://github.com/nodejs/node/pull/1529) +* [[`f10f379240`](https://github.com/nodejs/node/commit/f10f379240)] - **deps**: make node-gyp work with io.js (cjihrig) [nodejs/node#990](https://github.com/nodejs/node/pull/990) +* [[`ba0e744c2c`](https://github.com/nodejs/node/commit/ba0e744c2c)] - **deps**: upgrade npm to 2.9.0 (Forrest L Norvell) [nodejs/node#1583](https://github.com/nodejs/node/pull/1583) +* [[`b3a7da1091`](https://github.com/nodejs/node/commit/b3a7da1091)] - **deps**: update http_parser to 2.5.0 (Fedor Indutny) [nodejs/node#1517](https://github.com/nodejs/node/pull/1517) +* [[`4030545af6`](https://github.com/nodejs/node/commit/4030545af6)] - **fs**: validate fd on fs.write (Julian Duque) [#1553](https://github.com/nodejs/node/pull/1553) +* [[`898d423820`](https://github.com/nodejs/node/commit/898d423820)] - **string_decoder**: don't cache Buffer.isEncoding (Brian White) [nodejs/node#1548](https://github.com/nodejs/node/pull/1548) +* [[`32a6dbcf23`](https://github.com/nodejs/node/commit/32a6dbcf23)] - **test**: extend timeouts for ARMv6 (Rod Vagg) [nodejs/node#1554](https://github.com/nodejs/node/pull/1554) +* [[`5896fe5cd3`](https://github.com/nodejs/node/commit/5896fe5cd3)] - **test**: adjust Makefile/test-ci, add to vcbuild.bat (Rod Vagg) [nodejs/node#1530](https://github.com/nodejs/node/pull/1530) +* [[`b72e4bc596`](https://github.com/nodejs/node/commit/b72e4bc596)] - **tls**: destroy singleUse context immediately (Fedor Indutny) [nodejs/node#1529](https://github.com/nodejs/node/pull/1529) +* [[`1cfc455dc5`](https://github.com/nodejs/node/commit/1cfc455dc5)] - **tls**: zero SSL_CTX freelist for a singleUse socket (Fedor Indutny) [nodejs/node#1529](https://github.com/nodejs/node/pull/1529) +* [[`7ada680519`](https://github.com/nodejs/node/commit/7ada680519)] - **tls**: destroy SSL once it is out of use (Fedor Indutny) [nodejs/node#1529](https://github.com/nodejs/node/pull/1529) +* [[`71274b0263`](https://github.com/nodejs/node/commit/71274b0263)] - **tls_wrap**: use localhost if options.host is empty (Guilherme Souza) [nodejs/node#1493](https://github.com/nodejs/node/pull/1493) +* [[`0eb74a8b6c`](https://github.com/nodejs/node/commit/0eb74a8b6c)] - **win,node-gyp**: optionally allow node.exe/iojs.exe to be renamed (Bert Belder) [nodejs/node#1266](https://github.com/nodejs/node/pull/1266) + + +## 2015-05-15, Version 2.0.2, @Fishrock123 + +### Notable changes + +* **win,node-gyp**: the delay-load hook for windows addons has now been correctly enabled by default, it had wrongly defaulted to off in the release version of 2.0.0 (Bert Belder) [#1433](https://github.com/nodejs/node/pull/1433) +* **os**: `tmpdir()`'s trailing slash stripping has been refined to fix an issue when the temp directory is at '/'. Also considers which slash is used by the operating system. (cjihrig) [#1673](https://github.com/nodejs/node/pull/1673) +* **tls**: default ciphers have been updated to use gcm and aes128 (Mike MacCana) [#1660](https://github.com/nodejs/node/pull/1660) +* **build**: v8 snapshots have been re-enabled by default as suggested by the v8 team, since prior security issues have been resolved. This should give some perf improvements to both startup and vm context creation. (Trevor Norris) [#1663](https://github.com/nodejs/node/pull/1663) +* **src**: fixed preload modules not working when other flags were used before `--require` (Yosuke Furukawa) [#1694](https://github.com/nodejs/node/pull/1694) +* **dgram**: fixed `send()`'s callback not being asynchronous (Yosuke Furukawa) [#1313](https://github.com/nodejs/node/pull/1313) +* **readline**: emitKeys now keeps buffering data until it has enough to parse. This fixes an issue with parsing split escapes. (Alex Kocharin) [#1601](https://github.com/nodejs/node/pull/1601) +* **cluster**: works now properly emit 'disconnect' to `cluser.worker` (Oleg Elifantiev) [#1386](https://github.com/nodejs/node/pull/1386) +* **events**: uncaught errors now provide some context (Evan Lucas) [#1654](https://github.com/nodejs/node/pull/1654) + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). + +### Commits + +* [[`8a0e5295b4`](https://github.com/nodejs/node/commit/8a0e5295b4)] - **build**: use backslashes for paths on windows (Johan Bergström) [#1698](https://github.com/nodejs/node/pull/1698) +* [[`20c9a52227`](https://github.com/nodejs/node/commit/20c9a52227)] - **build**: move --with-intl to intl optgroup (Johan Bergström) [#1680](https://github.com/nodejs/node/pull/1680) +* [[`36cdc7c8ac`](https://github.com/nodejs/node/commit/36cdc7c8ac)] - **build**: re-enable V8 snapshots (Trevor Norris) [#1663](https://github.com/nodejs/node/pull/1663) +* [[`5883a59b21`](https://github.com/nodejs/node/commit/5883a59b21)] - **cluster**: disconnect event not emitted correctly (Oleg Elifantiev) [#1386](https://github.com/nodejs/node/pull/1386) +* [[`0f850f7ae7`](https://github.com/nodejs/node/commit/0f850f7ae7)] - **deps**: provide TXT chunk info in c-ares (Fedor Indutny) +* [[`7e1c0e75ed`](https://github.com/nodejs/node/commit/7e1c0e75ed)] - **deps**: sync with upstream bagder/c-ares@bba4dc5 (Ben Noordhuis) [#1678](https://github.com/nodejs/node/pull/1678) +* [[`18d457bd34`](https://github.com/nodejs/node/commit/18d457bd34)] - **dgram**: call send callback asynchronously (Yosuke Furukawa) [#1313](https://github.com/nodejs/node/pull/1313) +* [[`8b9a1537ad`](https://github.com/nodejs/node/commit/8b9a1537ad)] - **events**: provide better error message for unhandled error (Evan Lucas) [#1654](https://github.com/nodejs/node/pull/1654) +* [[`19ffb5cf1c`](https://github.com/nodejs/node/commit/19ffb5cf1c)] - **lib**: fix eslint styles (Yosuke Furukawa) [#1539](https://github.com/nodejs/node/pull/1539) +* [[`76937051f8`](https://github.com/nodejs/node/commit/76937051f8)] - **os**: refine tmpdir() trailing slash stripping (cjihrig) [#1673](https://github.com/nodejs/node/pull/1673) +* [[`aed6bce906`](https://github.com/nodejs/node/commit/aed6bce906)] - **readline**: turn emitKeys into a streaming parser (Alex Kocharin) [#1601](https://github.com/nodejs/node/pull/1601) +* [[`0a461e5360`](https://github.com/nodejs/node/commit/0a461e5360)] - **src**: fix preload when used with prior flags (Yosuke Furukawa) [#1694](https://github.com/nodejs/node/pull/1694) +* [[`931a0d4634`](https://github.com/nodejs/node/commit/931a0d4634)] - **src**: add type check to v8.setFlagsFromString() (Roman Klauke) [#1652](https://github.com/nodejs/node/pull/1652) +* [[`08d08668c9`](https://github.com/nodejs/node/commit/08d08668c9)] - **src,deps**: replace LoadLibrary by LoadLibraryW (Cheng Zhao) [#226](https://github.com/nodejs/node/pull/226) +* [[`4e2f999a62`](https://github.com/nodejs/node/commit/4e2f999a62)] - **test**: fix infinite loop detection (Yosuke Furukawa) [#1681](https://github.com/nodejs/node/pull/1681) +* [[`5755fc099f`](https://github.com/nodejs/node/commit/5755fc099f)] - **tls**: update default ciphers to use gcm and aes128 (Mike MacCana) [#1660](https://github.com/nodejs/node/pull/1660) +* [[`966acb9916`](https://github.com/nodejs/node/commit/966acb9916)] - **tools**: remove closure_linter to eslint on windows (Yosuke Furukawa) [#1685](https://github.com/nodejs/node/pull/1685) +* [[`c58264e58b`](https://github.com/nodejs/node/commit/c58264e58b)] - **tools**: make eslint work on subdirectories (Roman Reiss) [#1686](https://github.com/nodejs/node/pull/1686) +* [[`0b21ab13b7`](https://github.com/nodejs/node/commit/0b21ab13b7)] - **tools**: refactor `make test-npm` into test-npm.sh (Jeremiah Senkpiel) [#1662](https://github.com/nodejs/node/pull/1662) +* [[`f07b3b600b`](https://github.com/nodejs/node/commit/f07b3b600b)] - **tools**: set eslint comma-spacing to 'warn' (Roman Reiss) [#1672](https://github.com/nodejs/node/pull/1672) +* [[`f9dd34d301`](https://github.com/nodejs/node/commit/f9dd34d301)] - **tools**: replace closure-linter with eslint (Yosuke Furukawa) [#1539](https://github.com/nodejs/node/pull/1539) +* [[`64d3210c98`](https://github.com/nodejs/node/commit/64d3210c98)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1667](https://github.com/nodejs/node/issues/1667) + + +## 2015-05-07, Version 2.0.1, @rvagg + +### Notable changes + +* **async_wrap**: (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) + - it is now possible to filter by providers + - bit flags have been removed and replaced with method calls on the binding object + - _note that this is an unstable API so feature additions and breaking changes won't change io.js semver_ +* **libuv**: resolves numerous io.js issues: + - [#862](https://github.com/nodejs/node/issues/862) prevent spawning child processes with invalid stdio file descriptors + - [#1397](https://github.com/nodejs/node/issues/1397) fix EPERM error with fs.access(W_OK) on Windows + - [#1621](https://github.com/nodejs/node/issues/1621) build errors associated with the bundled libuv + - [#1512](https://github.com/nodejs/node/issues/1512) should properly fix Windows termination errors +* **addons**: the `NODE_DEPRECATED` macro was causing problems when compiling addons with older compilers, this should now be resolved (Ben Noordhuis) [#1626](https://github.com/nodejs/node/pull/1626) +* **V8**: upgrade V8 from 4.2.77.18 to 4.2.77.20 with minor fixes, including a bug preventing builds on FreeBSD + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). +* readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) + +### Commits + +* [[`7dde95a8bd`](https://github.com/nodejs/node/commit/7dde95a8bd)] - **async-wrap**: remove before/after calls in init (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) +* [[`bd42ba056a`](https://github.com/nodejs/node/commit/bd42ba056a)] - **async-wrap**: set flags using functions (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) +* [[`4b2c786449`](https://github.com/nodejs/node/commit/4b2c786449)] - **async-wrap**: pass PROVIDER as first arg to init (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) +* [[`84bf609fd2`](https://github.com/nodejs/node/commit/84bf609fd2)] - **async-wrap**: don't call init callback unnecessarily (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) +* [[`04cc03b029`](https://github.com/nodejs/node/commit/04cc03b029)] - **deps**: update libuv to 1.5.0 (Saúl Ibarra Corretgé) [#1646](https://github.com/nodejs/node/pull/1646) +* [[`b16d9c28e8`](https://github.com/nodejs/node/commit/b16d9c28e8)] - **deps**: upgrade v8 to 4.2.77.20 (Ben Noordhuis) [#1639](https://github.com/nodejs/node/pull/1639) +* [[`9ec3109272`](https://github.com/nodejs/node/commit/9ec3109272)] - **doc**: add TC meeting 2015-04-29 minutes (Rod Vagg) [#1585](https://github.com/nodejs/node/pull/1585) +* [[`2c7206254c`](https://github.com/nodejs/node/commit/2c7206254c)] - **doc**: fix typo in readme.md (AQNOUCH Mohammed) [#1643](https://github.com/nodejs/node/pull/1643) +* [[`71dc7152ee`](https://github.com/nodejs/node/commit/71dc7152ee)] - **doc**: fix PR link in CHANGELOG (Brian White) [#1624](https://github.com/nodejs/node/pull/1624) +* [[`b97b96d05a`](https://github.com/nodejs/node/commit/b97b96d05a)] - **install**: fix NameError (thefourtheye) [#1628](https://github.com/nodejs/node/pull/1628) +* [[`6ccbe75384`](https://github.com/nodejs/node/commit/6ccbe75384)] - **js_stream**: fix buffer index in DoWrite (Shigeki Ohtsu) [#1635](https://github.com/nodejs/node/pull/1635) +* [[`c43855c49c`](https://github.com/nodejs/node/commit/c43855c49c)] - **src**: export the ParseEncoding function on Windows (Ivan Kozik) [#1596](https://github.com/nodejs/node/pull/1596) +* [[`8315b22390`](https://github.com/nodejs/node/commit/8315b22390)] - **src**: fix pedantic cpplint whitespace warnings (Ben Noordhuis) [#1640](https://github.com/nodejs/node/pull/1640) +* [[`b712af79a7`](https://github.com/nodejs/node/commit/b712af79a7)] - **src**: fix NODE_DEPRECATED macro with old compilers (Ben Noordhuis) [#1626](https://github.com/nodejs/node/pull/1626) +* [[`2ed10f1349`](https://github.com/nodejs/node/commit/2ed10f1349)] - **src**: fix minor inefficiency in Buffer::New() call (Ben Noordhuis) [#1577](https://github.com/nodejs/node/pull/1577) +* [[`f696c9efab`](https://github.com/nodejs/node/commit/f696c9efab)] - **src**: fix deprecated use of Buffer::New() (Ben Noordhuis) [#1577](https://github.com/nodejs/node/pull/1577) +* [[`0c8f13df8f`](https://github.com/nodejs/node/commit/0c8f13df8f)] - **tools**: remove unused GuessWordSize function (thefourtheye) [#1638](https://github.com/nodejs/node/pull/1638) + + +## 2015-05-04, Version 2.0.0, @rvagg + +### Breaking changes + +Full details at https://github.com/nodejs/node/wiki/Breaking-Changes#200-from-1x + +* V8 upgrade to 4.2, minor changes to C++ API +* `os.tmpdir()` is now cross-platform consistent and no longer returns a path with a trailing slash on any platform +* While not a *breaking change* the 'smalloc' module has been deprecated in anticipation of it becoming unsupportable with a future upgrade to V8 4.4. See [#1451](https://github.com/nodejs/node/issues/1451) for further information. + +_Note: a new version of the 'url' module was reverted prior to release as it was decided the potential for breakage across the npm ecosystem was too great and that more compatibility work needed to be done before releasing it. See [#1602](https://github.com/nodejs/node/pull/1602) for further information._ + +### Notable changes + +* **crypto**: significantly reduced memory usage for TLS (Fedor Indutny & Сковорода Никита Андреевич) [#1529](https://github.com/nodejs/node/pull/1529) +* **net**: `socket.connect()` now accepts a `'lookup'` option for a custom DNS resolution mechanism, defaults to `dns.lookup()` (Evan Lucas) [#1505](https://github.com/nodejs/node/pull/1505) +* **npm**: Upgrade npm to 2.9.0. See the [v2.8.4](https://github.com/npm/npm/releases/tag/v2.8.4) and [v2.9.0](https://github.com/npm/npm/releases/tag/v2.9.0) release notes for details. Notable items: + - Add support for default author field to make `npm init -y` work without user-input (@othiym23) [npm/npm/d8eee6cf9d](https://github.com/npm/npm/commit/d8eee6cf9d2ff7aca68dfaed2de76824a3e0d9af) + - Include local modules in `npm outdated` and `npm update` (@ArnaudRinquin) [npm/npm#7426](https://github.com/npm/npm/issues/7426) + - The prefix used before the version number on `npm version` is now configurable via `tag-version-prefix` (@kkragenbrink) [npm/npm#8014](https://github.com/npm/npm/issues/8014) +* **os**: `os.tmpdir()` is now cross-platform consistent and will no longer returns a path with a trailing slash on any platform (Christian Tellnes) [#747](https://github.com/nodejs/node/pull/747) +* **process**: + - `process.nextTick()` performance has been improved by between 2-42% across the benchmark suite, notable because this is heavily used across core (Brian White) [#1571](https://github.com/nodejs/node/pull/1571) + - New `process.geteuid()`, `process.seteuid(id)`, `process.getegid()` and `process.setegid(id)` methods allow you to get and set effective UID and GID of the process (Evan Lucas) [#1536](https://github.com/nodejs/node/pull/1536) +* **repl**: + - REPL history can be persisted across sessions if the `NODE_REPL_HISTORY_FILE` environment variable is set to a user accessible file, `NODE_REPL_HISTORY_SIZE` can set the maximum history size and defaults to `1000` (Chris Dickinson) [#1513](https://github.com/nodejs/node/pull/1513) + - The REPL can be placed in to one of three modes using the `NODE_REPL_MODE` environment variable: `sloppy`, `strict` or `magic` (default); the new `magic` mode will automatically run "strict mode only" statements in strict mode (Chris Dickinson) [#1513](https://github.com/nodejs/node/pull/1513) +* **smalloc**: the 'smalloc' module has been deprecated due to changes coming in V8 4.4 that will render it unusable +* **util**: add Promise, Map and Set inspection support (Christopher Monsanto) [#1471](https://github.com/nodejs/node/pull/1471) +* **V8**: upgrade to 4.2.77.18, see the [ChangeLog](https://chromium.googlesource.com/v8/v8/+/refs/heads/4.2.77/ChangeLog) for full details. Notable items: + - Classes have moved out of staging; the `class` keyword is now usable in strict mode without flags + - Object literal enhancements have moved out of staging; shorthand method and property syntax is now usable (`{ method() { }, property }`) + - Rest parameters (`function(...args) {}`) are implemented in staging behind the `--harmony-rest-parameters` flag + - Computed property names (`{['foo'+'bar']:'bam'}`) are implemented in staging behind the `--harmony-computed-property-names` flag + - Unicode escapes (`'\u{xxxx}'`) are implemented in staging behind the `--harmony_unicode` flag and the `--harmony_unicode_regexps` flag for use in regular expressions +* **Windows**: + - Random process termination on Windows fixed (Fedor Indutny) [#1512](https://github.com/nodejs/node/issues/1512) / [#1563](https://github.com/nodejs/node/pull/1563) + - The delay-load hook introduced to fix issues with process naming (iojs.exe / node.exe) has been made opt-out for native add-ons. Native add-ons should include `'win_delay_load_hook': 'false'` in their binding.gyp to disable this feature if they experience problems . (Bert Belder) [#1433](https://github.com/nodejs/node/pull/1433) +* **Governance**: + - Rod Vagg (@rvagg) was added to the Technical Committee (TC) + - Jeremiah Senkpiel (@Fishrock123) was added to the Technical Committee (TC) + +### Known issues + +See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). +* readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) + +### Commits - * [[`52b1230628`](https://github.com/nodejs/node/commit/52b1230628)] - **deps**: update deps/openssl/conf/arch/*/opensslconf.h (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) - * [[`20ff1e2ecb`](https://github.com/nodejs/node/commit/20ff1e2ecb)] - **deps**: upgrade openssl sources to 1.0.2d (Shigeki Ohtsu) [#2141](https://github.com/nodejs/node/pull/2141) +* [[`5404cbc745`](https://github.com/nodejs/node/commit/5404cbc745)] - **buffer**: fix copy() segfault with zero arguments (Trevor Norris) [#1520](https://github.com/nodejs/node/pull/1520) +* [[`3d3083b91f`](https://github.com/nodejs/node/commit/3d3083b91f)] - **buffer**: little improve for Buffer.concat method (Jackson Tian) [#1437](https://github.com/nodejs/node/pull/1437) +* [[`e67542ae17`](https://github.com/nodejs/node/commit/e67542ae17)] - **build**: disable -Og when building with clang (Ben Noordhuis) [#1609](https://github.com/nodejs/node/pull/1609) +* [[`78f4b038f8`](https://github.com/nodejs/node/commit/78f4b038f8)] - **build**: turn on debug-safe optimizations with -Og (Ben Noordhuis) [#1569](https://github.com/nodejs/node/pull/1569) +* [[`a5dcff827a`](https://github.com/nodejs/node/commit/a5dcff827a)] - **build**: Use option groups in configure output (Johan Bergström) [#1533](https://github.com/nodejs/node/pull/1533) +* [[`2a3c8c187e`](https://github.com/nodejs/node/commit/2a3c8c187e)] - **build**: remove -J from test-ci (Rod Vagg) [#1544](https://github.com/nodejs/node/pull/1544) +* [[`e6874dd0f9`](https://github.com/nodejs/node/commit/e6874dd0f9)] - **crypto**: track external memory for SSL structures (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) +* [[`935c9d3fa7`](https://github.com/nodejs/node/commit/935c9d3fa7)] - **deps**: make node-gyp work with io.js (cjihrig) [#990](https://github.com/nodejs/node/pull/990) +* [[`56e4255382`](https://github.com/nodejs/node/commit/56e4255382)] - **deps**: upgrade npm to 2.9.0 (Forrest L Norvell) [#1573](https://github.com/nodejs/node/pull/1573) +* [[`509b59ea7c`](https://github.com/nodejs/node/commit/509b59ea7c)] - **deps**: enable v8 postmortem debugging again (Ben Noordhuis) [#1232](https://github.com/nodejs/node/pull/1232) +* [[`01652c7709`](https://github.com/nodejs/node/commit/01652c7709)] - **deps**: upgrade v8 to 4.2.77.18 (Chris Dickinson) [#1506](https://github.com/nodejs/node/pull/1506) +* [[`01e6632d70`](https://github.com/nodejs/node/commit/01e6632d70)] - **deps**: upgrade v8 to 4.2.77.15 (Ben Noordhuis) [#1399](https://github.com/nodejs/node/pull/1399) +* [[`db4ded5903`](https://github.com/nodejs/node/commit/db4ded5903)] - **deps**: enable v8 postmortem debugging again (Ben Noordhuis) [#1232](https://github.com/nodejs/node/pull/1232) +* [[`36cd5fb9d2`](https://github.com/nodejs/node/commit/36cd5fb9d2)] - **(SEMVER-MAJOR)** **deps**: upgrade v8 to 4.2.77.13 (Ben Noordhuis) [#1232](https://github.com/nodejs/node/pull/1232) +* [[`b3a7da1091`](https://github.com/nodejs/node/commit/b3a7da1091)] - **deps**: update http_parser to 2.5.0 (Fedor Indutny) [#1517](https://github.com/nodejs/node/pull/1517) +* [[`ac1fb39ce8`](https://github.com/nodejs/node/commit/ac1fb39ce8)] - **doc**: add rvagg to the TC (Rod Vagg) [#1613](https://github.com/nodejs/node/pull/1613) +* [[`dacc1fa35c`](https://github.com/nodejs/node/commit/dacc1fa35c)] - **doc**: update AUTHORS list (Rod Vagg) [#1586](https://github.com/nodejs/node/pull/1586) +* [[`2a3a1909ab`](https://github.com/nodejs/node/commit/2a3a1909ab)] - **doc**: add require() lines to child.stdio example (Nick Raienko) [#1504](https://github.com/nodejs/node/pull/1504) +* [[`02388dbf40`](https://github.com/nodejs/node/commit/02388dbf40)] - **doc**: fix some cross-references (Alexander Gromnitsky) [#1584](https://github.com/nodejs/node/pull/1584) +* [[`57c4cc26e2`](https://github.com/nodejs/node/commit/57c4cc26e2)] - **doc**: add TC meeting 2015-04-22 minutes (Rod Vagg) [#1556](https://github.com/nodejs/node/pull/1556) +* [[`b4ad5d7050`](https://github.com/nodejs/node/commit/b4ad5d7050)] - **doc**: improve http.request and https.request opts (Roman Reiss) [#1551](https://github.com/nodejs/node/pull/1551) +* [[`7dc8eec0a6`](https://github.com/nodejs/node/commit/7dc8eec0a6)] - **doc**: deprecate smalloc module (Ben Noordhuis) [#1566](https://github.com/nodejs/node/pull/1566) +* [[`1bcdf46ca7`](https://github.com/nodejs/node/commit/1bcdf46ca7)] - **doc**: add TC meeting 2015-04-15 minutes (Rod Vagg) [#1498](https://github.com/nodejs/node/pull/1498) +* [[`391cae3595`](https://github.com/nodejs/node/commit/391cae3595)] - **doc**: Add Known issues to v1.7.0/1.7.1 CHANGELOG (Yosuke Furukawa) [#1473](https://github.com/nodejs/node/pull/1473) +* [[`e55fdc47a7`](https://github.com/nodejs/node/commit/e55fdc47a7)] - **doc**: fix util.deprecate example (Nick Raienko) [#1535](https://github.com/nodejs/node/pull/1535) +* [[`5178f93bc0`](https://github.com/nodejs/node/commit/5178f93bc0)] - **doc**: Add Addon API (NAN) to working group list (Julian Duque) [#1523](https://github.com/nodejs/node/pull/1523) +* [[`f3cc50f811`](https://github.com/nodejs/node/commit/f3cc50f811)] - **doc**: add TC meeting 2015-04-08 minutes (Rod Vagg) [#1497](https://github.com/nodejs/node/pull/1497) +* [[`bb254b533b`](https://github.com/nodejs/node/commit/bb254b533b)] - **doc**: update branch to master (Roman Reiss) [#1511](https://github.com/nodejs/node/pull/1511) +* [[`22aafa5597`](https://github.com/nodejs/node/commit/22aafa5597)] - **doc**: add Fishrock123 to the TC (Jeremiah Senkpiel) [#1507](https://github.com/nodejs/node/pull/1507) +* [[`b16a328ede`](https://github.com/nodejs/node/commit/b16a328ede)] - **doc**: add spaces to child.kill example (Nick Raienko) [#1503](https://github.com/nodejs/node/pull/1503) +* [[`26327757f8`](https://github.com/nodejs/node/commit/26327757f8)] - **doc**: update AUTHORS list (Rod Vagg) [#1476](https://github.com/nodejs/node/pull/1476) +* [[`f9c681cf62`](https://github.com/nodejs/node/commit/f9c681cf62)] - **fs**: validate fd on fs.write (Julian Duque) [#1553](https://github.com/nodejs/node/pull/1553) +* [[`801b47acc5`](https://github.com/nodejs/node/commit/801b47acc5)] - **gitignore**: ignore xcode workspaces and projects (Roman Klauke) [#1562](https://github.com/nodejs/node/pull/1562) +* [[`d5ce47e433`](https://github.com/nodejs/node/commit/d5ce47e433)] - **(SEMVER-MINOR)** **lib**: deprecate the smalloc module (Ben Noordhuis) [#1564](https://github.com/nodejs/node/pull/1564) +* [[`7384ca83f9`](https://github.com/nodejs/node/commit/7384ca83f9)] - **module**: remove '' from Module.globalPaths (Chris Yip) [#1488](https://github.com/nodejs/node/pull/1488) +* [[`b4f5898395`](https://github.com/nodejs/node/commit/b4f5898395)] - **net**: ensure Write/ShutdownWrap references handle (Fedor Indutny) [#1590](https://github.com/nodejs/node/pull/1590) +* [[`4abe2fa1cf`](https://github.com/nodejs/node/commit/4abe2fa1cf)] - **(SEMVER-MINOR)** **net**: add lookup option to Socket.prototype.connect (Evan Lucas) [#1505](https://github.com/nodejs/node/pull/1505) +* [[`1bef717476`](https://github.com/nodejs/node/commit/1bef717476)] - **(SEMVER-MINOR)** **net**: cleanup connect logic (Evan Lucas) [#1505](https://github.com/nodejs/node/pull/1505) +* [[`c7782c0af8`](https://github.com/nodejs/node/commit/c7782c0af8)] - **node**: improve nextTick performance (Brian White) [#1571](https://github.com/nodejs/node/pull/1571) +* [[`b57cc51d8d`](https://github.com/nodejs/node/commit/b57cc51d8d)] - **(SEMVER-MAJOR)** **os**: remove trailing slash from os.tmpdir() (Christian Tellnes) [#747](https://github.com/nodejs/node/pull/747) +* [[`ca219b00d1`](https://github.com/nodejs/node/commit/ca219b00d1)] - **repl**: fix for a+ fd clearing the file on read (Chris Dickinson) [#1605](https://github.com/nodejs/node/pull/1605) +* [[`051d482b15`](https://github.com/nodejs/node/commit/051d482b15)] - **repl**: fix \_debugger by properly proxying repl (Chris Dickinson) [#1605](https://github.com/nodejs/node/pull/1605) +* [[`2e2fce0502`](https://github.com/nodejs/node/commit/2e2fce0502)] - **repl**: fix persistent history and env variable name (Roman Reiss) [#1593](https://github.com/nodejs/node/pull/1593) +* [[`ea5195ccaf`](https://github.com/nodejs/node/commit/ea5195ccaf)] - **repl**: do not save history for non-terminal repl (Fedor Indutny) [#1575](https://github.com/nodejs/node/pull/1575) +* [[`0450ce7db2`](https://github.com/nodejs/node/commit/0450ce7db2)] - **repl**: add mode detection, cli persistent history (Chris Dickinson) [#1513](https://github.com/nodejs/node/pull/1513) +* [[`af9fe3bbc7`](https://github.com/nodejs/node/commit/af9fe3bbc7)] - **(SEMVER-MAJOR)** **src**: bump NODE_MODULE_VERSION due to V8 API (Rod Vagg) [#1532](https://github.com/nodejs/node/pull/1532) +* [[`279f6116aa`](https://github.com/nodejs/node/commit/279f6116aa)] - **src**: fix -Wmissing-field-initializers warning (Ben Noordhuis) [#1606](https://github.com/nodejs/node/pull/1606) +* [[`73062521a4`](https://github.com/nodejs/node/commit/73062521a4)] - **src**: deprecate smalloc public functions (Ben Noordhuis) [#1565](https://github.com/nodejs/node/pull/1565) +* [[`ccb199af17`](https://github.com/nodejs/node/commit/ccb199af17)] - **src**: fix deprecation warnings (Ben Noordhuis) [#1565](https://github.com/nodejs/node/pull/1565) +* [[`609fa0de03`](https://github.com/nodejs/node/commit/609fa0de03)] - **src**: fix NODE_DEPRECATED macro (Ben Noordhuis) [#1565](https://github.com/nodejs/node/pull/1565) +* [[`3c92ca2b5c`](https://github.com/nodejs/node/commit/3c92ca2b5c)] - **(SEMVER-MINOR)** **src**: add ability to get/set effective uid/gid (Evan Lucas) [#1536](https://github.com/nodejs/node/pull/1536) +* [[`30b7349176`](https://github.com/nodejs/node/commit/30b7349176)] - **stream_base**: dispatch reqs in the stream impl (Fedor Indutny) [#1563](https://github.com/nodejs/node/pull/1563) +* [[`0fa6c4a6fc`](https://github.com/nodejs/node/commit/0fa6c4a6fc)] - **string_decoder**: don't cache Buffer.isEncoding (Brian White) [#1548](https://github.com/nodejs/node/pull/1548) +* [[`f9b226c1c1`](https://github.com/nodejs/node/commit/f9b226c1c1)] - **test**: extend timeouts for ARMv6 (Rod Vagg) [#1554](https://github.com/nodejs/node/pull/1554) +* [[`bfae8236b1`](https://github.com/nodejs/node/commit/bfae8236b1)] - **test**: fix test-net-dns-custom-lookup test assertion (Evan Lucas) [#1531](https://github.com/nodejs/node/pull/1531) +* [[`547213913b`](https://github.com/nodejs/node/commit/547213913b)] - **test**: adjust Makefile/test-ci, add to vcbuild.bat (Rod Vagg) [#1530](https://github.com/nodejs/node/pull/1530) +* [[`550c2638c0`](https://github.com/nodejs/node/commit/550c2638c0)] - **tls**: use `SSL_set_cert_cb` for async SNI/OCSP (Fedor Indutny) [#1464](https://github.com/nodejs/node/pull/1464) +* [[`1787416376`](https://github.com/nodejs/node/commit/1787416376)] - **tls**: destroy singleUse context immediately (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) +* [[`2684c902c4`](https://github.com/nodejs/node/commit/2684c902c4)] - **tls**: zero SSL_CTX freelist for a singleUse socket (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) +* [[`2d241b3b82`](https://github.com/nodejs/node/commit/2d241b3b82)] - **tls**: destroy SSL once it is out of use (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) +* [[`f7620fb96d`](https://github.com/nodejs/node/commit/f7620fb96d)] - **tls_wrap**: Unlink TLSWrap and SecureContext objects (Сковорода Никита Андреевич) [#1580](https://github.com/nodejs/node/pull/1580) +* [[`a7d74633f2`](https://github.com/nodejs/node/commit/a7d74633f2)] - **tls_wrap**: use localhost if options.host is empty (Guilherme Souza) [#1493](https://github.com/nodejs/node/pull/1493) +* [[`702997c1f0`](https://github.com/nodejs/node/commit/702997c1f0)] - ***Revert*** "**url**: significantly improve the performance of the url module" (Rod Vagg) [#1602](https://github.com/nodejs/node/pull/1602) +* [[`0daed24883`](https://github.com/nodejs/node/commit/0daed24883)] - ***Revert*** "**url**: delete href cache on all setter code paths" (Rod Vagg) [#1602](https://github.com/nodejs/node/pull/1602) +* [[`0f39ef4ca1`](https://github.com/nodejs/node/commit/0f39ef4ca1)] - ***Revert*** "**url**: fix treatment of some values as non-empty" (Rod Vagg) [#1602](https://github.com/nodejs/node/pull/1602) +* [[`66877216bd`](https://github.com/nodejs/node/commit/66877216bd)] - **url**: fix treatment of some values as non-empty (Petka Antonov) [#1589](https://github.com/nodejs/node/pull/1589) +* [[`dbdd81a91b`](https://github.com/nodejs/node/commit/dbdd81a91b)] - **url**: delete href cache on all setter code paths (Petka Antonov) [#1589](https://github.com/nodejs/node/pull/1589) +* [[`3fd7fc429c`](https://github.com/nodejs/node/commit/3fd7fc429c)] - **url**: significantly improve the performance of the url module (Petka Antonov) [#1561](https://github.com/nodejs/node/pull/1561) +* [[`bf7ac08dd0`](https://github.com/nodejs/node/commit/bf7ac08dd0)] - **util**: add Map and Set inspection support (Christopher Monsanto) [#1471](https://github.com/nodejs/node/pull/1471) +* [[`30e83d2e84`](https://github.com/nodejs/node/commit/30e83d2e84)] - **win,node-gyp**: optionally allow node.exe/iojs.exe to be renamed (Bert Belder) [#1266](https://github.com/nodejs/node/pull/1266) +* [[`3bda6cbfa4`](https://github.com/nodejs/node/commit/3bda6cbfa4)] - **(SEMVER-MAJOR)** **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1433](https://github.com/nodejs/node/pull/1433) + + + +## 2015-04-20, Version 1.8.1, @chrisdickinson +### Notable changes + +* **NOTICE**: Skipped v1.8.0 due to problems with release tooling. + See [#1436](https://github.com/nodejs/node/issues/1436) for details. +* **build**: Support for building io.js as a static library (Marat Abdullin) [#1341](https://github.com/nodejs/node/pull/1341) +* **deps**: Upgrade openssl to 1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) + * Users should see performance improvements when using the crypto API. + See [here](https://github.com/nodejs/node/wiki/Crypto-Performance-Notes-for-OpenSSL-1.0.2a-on-iojs-v1.8.0) + for details. +* **npm**: Upgrade npm to 2.8.3. See the [release notes](https://github.com/npm/npm/releases/tag/v2.8.3) for details. Includes improved git support. Summary: + * [`387f889`](https://github.com/npm/npm/commit/387f889c0e8fb617d9cc9a42ed0a3ec49424ab5d) + [#7961](https://github.com/npm/npm/issues/7961) Ensure that hosted git SSH + URLs always have a valid protocol when stored in `resolved` fields in + `npm-shrinkwrap.json`. ([@othiym23](https://github.com/othiym23)) + * [`394c2f5`](https://github.com/npm/npm/commit/394c2f5a1227232c0baf42fbba1402aafe0d6ffb) + Switch the order in which hosted Git providers are checked to `git:`, + `git+https:`, then `git+ssh:` (from `git:`, `git+ssh:`, then `git+https:`) in + an effort to go from most to least likely to succeed, to make for less + confusing error message. ([@othiym23](https://github.com/othiym23)) + * [`431c3bf`](https://github.com/npm/npm/commit/431c3bf6cdec50f9f0c735f478cb2f3f337d3313) + [#7699](https://github.com/npm/npm/issues/7699) `npm-registry-client@6.3.2`: + Don't send body with HTTP GET requests when logging in. + ([@smikes](https://github.com/smikes)) + * [`15efe12`](https://github.com/npm/npm/commit/15efe124753257728a0ddc64074fa5a4b9c2eb30) + [#7872](https://github.com/npm/npm/issues/7872) Use the new version of + `hosted-git-info` to pass along credentials embedded in git URLs. Test it. + Test it a lot. ([@othiym23](https://github.com/othiym23)) + * [`b027319`](https://github.com/npm/npm/commit/b0273190c71eba14395ddfdd1d9f7ba625297523) + [#7920](https://github.com/npm/npm/issues/7920) Scoped packages with + `peerDependencies` were installing the `peerDependencies` into the wrong + directory. ([@ewie](https://github.com/ewie)) + * [`6b0f588`](https://github.com/npm/npm/commit/6b0f58877f37df9904490ffbaaad33862bd36dce) + [#7867](https://github.com/npm/npm/issues/7867) Use git shorthand and git + URLs as presented by user. Support new `hosted-git-info` shortcut syntax. + Save shorthand in `package.json`. Try cloning via `git:`, `git+ssh:`, and + `git+https:`, in that order, when supported by the underlying hosting + provider. ([@othiym23](https://github.com/othiym23)) +* **src**: Allow multiple arguments to be passed to process.nextTick (Trevor Norris) [#1077](https://github.com/nodejs/node/pull/1077) +* **module**: The interaction of `require('.')` with `NODE_PATH` has been restored and deprecated. This functionality +will be removed at a later point. (Roman Reiss) [#1363](https://github.com/nodejs/node/pull/1363) + +### Known issues + +* Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). +* Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) +* `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). +* readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) + +### Commits - - ## 2015-07-04, Version 2.3.3, @Fishrock123 - - ### Notable changes - - * **deps**: Fixed an out-of-band write in utf8 decoder. **This is an important security update** as it can be used to cause a denial of service attack. - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760). - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ## Commits - - * [[`030f8045c7`](https://github.com/nodejs/node/commit/030f8045c7)] - **deps**: fix out-of-band write in utf8 decoder (Fedor Indutny) - * [[`0f09b8db28`](https://github.com/nodejs/node/commit/0f09b8db28)] - **doc**: don't recommend domains for error handling (Benjamin Gruenbaum) [#2056](https://github.com/nodejs/node/pull/2056) - * [[`9cd44bb2b6`](https://github.com/nodejs/node/commit/9cd44bb2b6)] - **util**: prepend '(node) ' to deprecation messages (Sakthipriyan Vairamani) [#1892](https://github.com/nodejs/node/pull/1892) - - - - ## 2015-07-04, Version 1.8.3, @rvagg - - **Maintenance release** - - ## Notable changes - - * **v8**: Fixed an out-of-band write in utf8 decoder. **This is an important security update** as it can be used to cause a denial of service attack. - * **openssl**: Upgrade to 1.0.2b and 1.0.2c, introduces DHE man-in-the-middle protection (Logjam) and fixes malformed ECParameters causing infinite loop (CVE-2015-1788). See the [security advisory](https://www.openssl.org/news/secadv_20150611.txt) for full details. (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) [#1958](https://github.com/nodejs/node/pull/1958) - * **build**: - - Added support for compiling with Microsoft Visual C++ 2015 - - Started building and distributing headers-only tarballs along with binaries - - ### Known issues - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) - - ### Commits - - * [[`d8f260d33b`](https://github.com/nodejs/node/commit/d8f260d33b)] - **build**: add tar-headers target for headers-only tar (Rod Vagg) [#1975](https://github.com/nodejs/node/pull/1975) - * [[`00ba429674`](https://github.com/nodejs/node/commit/00ba429674)] - **build**: update build targets for io.js (Rod Vagg) [#1938](https://github.com/nodejs/node/pull/1938) - * [[`39e2207ff1`](https://github.com/nodejs/node/commit/39e2207ff1)] - **build**: fix cherry-pick ooops, fix comment wording (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) - * [[`561919a67a`](https://github.com/nodejs/node/commit/561919a67a)] - **build**: add MSVS 2015 support (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) - * [[`8e1134c04c`](https://github.com/nodejs/node/commit/8e1134c04c)] - **build**: remove lint from test-ci on windows (Johan Bergström) [#2004](https://github.com/nodejs/node/pull/2004) - * [[`e52e99085e`](https://github.com/nodejs/node/commit/e52e99085e)] - **build**: don't run lint from test-ci (Johan Bergström) [#1965](https://github.com/nodejs/node/pull/1965) - * [[`c5d1ec7fea`](https://github.com/nodejs/node/commit/c5d1ec7fea)] - **build**: simplify execution of built binary (Johan Bergström) [#1955](https://github.com/nodejs/node/pull/1955) - * [[`2ce147551a`](https://github.com/nodejs/node/commit/2ce147551a)] - **build,win**: set env before generating projects (Alexis Campailla) [joyent/node#20109](https://github.com/joyent/node/pull/20109) - * [[`78de5f85f2`](https://github.com/nodejs/node/commit/78de5f85f2)] - **deps**: fix out-of-band write in utf8 decoder (Ben Noordhuis) - * [[`83ee07b6be`](https://github.com/nodejs/node/commit/83ee07b6be)] - **deps**: copy all openssl header files to include dir (Shigeki Ohtsu) [#2016](https://github.com/nodejs/node/pull/2016) - * [[`a97125520d`](https://github.com/nodejs/node/commit/a97125520d)] - **deps**: update UPGRADING.md doc to openssl-1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) - * [[`0e2d068e0b`](https://github.com/nodejs/node/commit/0e2d068e0b)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) - * [[`310b8d1120`](https://github.com/nodejs/node/commit/310b8d1120)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`a472946747`](https://github.com/nodejs/node/commit/a472946747)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) - * [[`b2467e3ebf`](https://github.com/nodejs/node/commit/b2467e3ebf)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) - * [[`e548abb800`](https://github.com/nodejs/node/commit/e548abb800)] - **deps**: upgrade openssl sources to 1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) - * [[`1feaa68e85`](https://github.com/nodejs/node/commit/1feaa68e85)] - **deps**: update asm files for openssl-1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) - * [[`151720fae7`](https://github.com/nodejs/node/commit/151720fae7)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) - * [[`139da6a02a`](https://github.com/nodejs/node/commit/139da6a02a)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`283642827a`](https://github.com/nodejs/node/commit/283642827a)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) - * [[`d593b552de`](https://github.com/nodejs/node/commit/d593b552de)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) - * [[`2a3367a4bd`](https://github.com/nodejs/node/commit/2a3367a4bd)] - **deps**: upgrade openssl sources to 1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) - * [[`5c29c0c519`](https://github.com/nodejs/node/commit/5c29c0c519)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) - * [[`2cd7f73d9f`](https://github.com/nodejs/node/commit/2cd7f73d9f)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [nodejs/node#1389](https://github.com/nodejs/node/pull/1389) - * [[`c65484a74d`](https://github.com/nodejs/node/commit/c65484a74d)] - **tls**: make server not use DHE in less than 1024bits (Shigeki Ohtsu) [#1739](https://github.com/nodejs/node/pull/1739) - * [[`77f518403f`](https://github.com/nodejs/node/commit/77f518403f)] - **win,node-gyp**: make delay-load hook C89 compliant (Sharat M R) [TooTallNate/node-gyp#616](https://github.com/TooTallNa - - - - ## 2015-07-01, Version 2.3.2, @rvagg - - ### Notable changes - - * **build**: - - Added support for compiling with Microsoft Visual C++ 2015 - - Started building and distributing headers-only tarballs along with binaries - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ## Commits - - * [[`9180140231`](https://github.com/nodejs/node/commit/9180140231)] - **_stream_wrap**: prevent use after free in TLS (Fedor Indutny) [#1910](https://github.com/nodejs/node/pull/1910) - * [[`05a73c0f25`](https://github.com/nodejs/node/commit/05a73c0f25)] - **benchmark**: make concurrent requests configurable (Rich Trott) [#2068](https://github.com/nodejs/node/pull/2068) - * [[`f52d73352e`](https://github.com/nodejs/node/commit/f52d73352e)] - **benchmark**: fix typo in README (Rich Trott) [#2067](https://github.com/nodejs/node/pull/2067) - * [[`1cd9eeb556`](https://github.com/nodejs/node/commit/1cd9eeb556)] - **buffer**: prevent abort on bad proto (Trevor Norris) [#2012](https://github.com/nodejs/node/pull/2012) - * [[`8350f3a3a2`](https://github.com/nodejs/node/commit/8350f3a3a2)] - **buffer**: optimize Buffer#toString() (Ben Noordhuis) [#2027](https://github.com/nodejs/node/pull/2027) - * [[`628a3ab093`](https://github.com/nodejs/node/commit/628a3ab093)] - **build**: add tar-headers target for headers-only tar (Rod Vagg) [#1975](https://github.com/nodejs/node/pull/1975) - * [[`dcbb9e1da6`](https://github.com/nodejs/node/commit/dcbb9e1da6)] - **build**: update build targets for io.js (Rod Vagg) [#1938](https://github.com/nodejs/node/pull/1938) - * [[`c87c34c242`](https://github.com/nodejs/node/commit/c87c34c242)] - **build**: fix cherry-pick ooops, fix comment wording (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) - * [[`4208dc4fef`](https://github.com/nodejs/node/commit/4208dc4fef)] - **build**: add MSVS 2015 support (Rod Vagg) [#2036](https://github.com/nodejs/node/pull/2036) - * [[`834a365113`](https://github.com/nodejs/node/commit/834a365113)] - **build**: DTrace is enabled by default on darwin (Evan Lucas) [#2019](https://github.com/nodejs/node/pull/2019) - * [[`c0c0d73269`](https://github.com/nodejs/node/commit/c0c0d73269)] - **build,win**: set env before generating projects (Alexis Campailla) [joyent/node#20109](https://github.com/joyent/node/pull/20109) - * [[`9e890fe8b4`](https://github.com/nodejs/node/commit/9e890fe8b4)] - **crypto**: fix VerifyCallback in case of verify error (Shigeki Ohtsu) [#2064](https://github.com/nodejs/node/pull/2064) - * [[`1f371e3988`](https://github.com/nodejs/node/commit/1f371e3988)] - **deps**: copy all openssl header files to include dir (Shigeki Ohtsu) [#2016](https://github.com/nodejs/node/pull/2016) - * [[`c370bd3aea`](https://github.com/nodejs/node/commit/c370bd3aea)] - **doc**: make the abbreviation 1MM clear (Ivan Yan) [#2053](https://github.com/nodejs/node/pull/2053) - * [[`54d5437566`](https://github.com/nodejs/node/commit/54d5437566)] - **doc**: Added sample command to test iojs build (Jimmy Hsu) [#850](https://github.com/nodejs/node/pull/850) - * [[`f1f1b7e597`](https://github.com/nodejs/node/commit/f1f1b7e597)] - **doc**: add TSC meeting minutes 2015-06-17 (Rod Vagg) [#2048](https://github.com/nodejs/node/pull/2048) - * [[`dbd5dc932d`](https://github.com/nodejs/node/commit/dbd5dc932d)] - **doc**: clarify prerequisites in benchmark/README.md (Jeremiah Senkpiel) [#2034](https://github.com/nodejs/node/pull/2034) - * [[`50dbc8e143`](https://github.com/nodejs/node/commit/50dbc8e143)] - **doc**: add TSC meeting minutes 2015-05-27 (Rod Vagg) [#2037](https://github.com/nodejs/node/pull/2037) - * [[`941ad362a7`](https://github.com/nodejs/node/commit/941ad362a7)] - **doc**: archive io.js TC minutes (Rod Vagg) - * [[`644b2eaa89`](https://github.com/nodejs/node/commit/644b2eaa89)] - **doc**: rename tc-meetings to tsc-meetings (Rod Vagg) - * [[`1330ee3b27`](https://github.com/nodejs/node/commit/1330ee3b27)] - **doc**: add TC meeting 2015-05-13 minutes (Rod Vagg) [#1700](https://github.com/nodejs/node/pull/1700) - * [[`392e8fd64e`](https://github.com/nodejs/node/commit/392e8fd64e)] - **doc**: add @shigeki and @mscdex to TC (Rod Vagg) [#2008](https://github.com/nodejs/node/pull/2008) - * [[`af249fa8a1`](https://github.com/nodejs/node/commit/af249fa8a1)] - **net**: wrap connect in nextTick (Evan Lucas) [#2054](https://github.com/nodejs/node/pull/2054) - * [[`7f63449fde`](https://github.com/nodejs/node/commit/7f63449fde)] - **net**: fix debug for dnsopts (Evan Lucas) [#2059](https://github.com/nodejs/node/pull/2059) - * [[`eabed2f518`](https://github.com/nodejs/node/commit/eabed2f518)] - **repl**: remove obsolete TODO (Rich Trott) [#2081](https://github.com/nodejs/node/pull/2081) - * [[`a198c68b56`](https://github.com/nodejs/node/commit/a198c68b56)] - **repl**: make 'Unexpected token' errors recoverable (Julien Gilli) [#2052](https://github.com/nodejs/node/pull/2052) - * [[`d735b2c6ef`](https://github.com/nodejs/node/commit/d735b2c6ef)] - **repl**: fix tab completion for a non-global context (Sangmin Yoon) [#2052](https://github.com/nodejs/node/pull/2052) - * [[`8cee8f54fc`](https://github.com/nodejs/node/commit/8cee8f54fc)] - **src**: nix stdin _readableState.reading manipulation (Chris Dickinson) [#454](https://github.com/nodejs/node/pull/454) - * [[`856c11f8c8`](https://github.com/nodejs/node/commit/856c11f8c8)] - **test**: purge stale disabled tests (Rich Trott) [#2045](https://github.com/nodejs/node/pull/2045) - * [[`4d5089e181`](https://github.com/nodejs/node/commit/4d5089e181)] - **test**: do not swallow OpenSSL support error (Rich Trott) [#2042](https://github.com/nodejs/node/pull/2042) - * [[`06721fe005`](https://github.com/nodejs/node/commit/06721fe005)] - **test**: fix test-repl-tab-complete.js (cjihrig) [#2052](https://github.com/nodejs/node/pull/2052) - * [[`8e9089ac35`](https://github.com/nodejs/node/commit/8e9089ac35)] - **test**: check for error on Windows (Rich Trott) [#2035](https://github.com/nodejs/node/pull/2035) - * [[`776a65ebcd`](https://github.com/nodejs/node/commit/776a65ebcd)] - **test**: remove obsolete TODO comments (Rich Trott) [#2033](https://github.com/nodejs/node/pull/2033) - * [[`bdfeb798ad`](https://github.com/nodejs/node/commit/bdfeb798ad)] - **test**: remove obsolete TODO comments (Rich Trott) [#2032](https://github.com/nodejs/node/pull/2032) - * [[`58e914f9bc`](https://github.com/nodejs/node/commit/58e914f9bc)] - **tools**: fix gyp to work on MacOSX without XCode (Shigeki Ohtsu) [iojs/io.js#1325](https://github.com/iojs/io.js/pull/1325) - * [[`99cbbc0a13`](https://github.com/nodejs/node/commit/99cbbc0a13)] - **tools**: update gyp to 25ed9ac (Ben Noordhuis) [#2074](https://github.com/nodejs/node/pull/2074) - * [[`e3f9335c40`](https://github.com/nodejs/node/commit/e3f9335c40)] - **tools**: re-enable comma-spacing linter rule (Roman Reiss) [#2072](https://github.com/nodejs/node/pull/2072) - * [[`d91e10b3bd`](https://github.com/nodejs/node/commit/d91e10b3bd)] - **tools**: update eslint to 0.24.0 (Roman Reiss) [#2072](https://github.com/nodejs/node/pull/2072) - * [[`6c61ca5325`](https://github.com/nodejs/node/commit/6c61ca5325)] - **url**: fix typo in comment (Rich Trott) [#2071](https://github.com/nodejs/node/pull/2071) - * [[`1a51f0058c`](https://github.com/nodejs/node/commit/1a51f0058c)] - **v8**: cherry-pick JitCodeEvent patch from upstream (Ben Noordhuis) [#2075](https://github.com/nodejs/node/pull/2075) - - - - ## 2015-06-23, Version 2.3.1, @rvagg - - ### Notable changes - - * **module**: The number of syscalls made during a `require()` have been significantly reduced again (see [#1801](https://github.com/nodejs/node/pull/1801) from v2.2.0 for previous work), which should lead to a performance improvement (Pierre Inglebert) [#1920](https://github.com/nodejs/node/pull/1920). - * **npm**: - * Upgrade to [v2.11.2](https://github.com/npm/npm/releases/tag/v2.11.2) (Rebecca Turner) [#1956](https://github.com/nodejs/node/pull/1956). - * Upgrade to [v2.11.3](https://github.com/npm/npm/releases/tag/v2.11.3) (Forrest L Norvell) [#2018](https://github.com/nodejs/node/pull/2018). - * **zlib**: A bug was discovered where the process would abort if the final part of a zlib decompression results in a buffer that would exceed the maximum length of `0x3fffffff` bytes (~1GiB). This was likely to only occur during buffered decompression (rather than streaming). This is now fixed and will instead result in a thrown `RangeError` (Michaël Zasso) [#1811](https://github.com/nodejs/node/pull/1811). - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ## Commits - - * [[`e56758a5e0`](https://github.com/nodejs/node/commit/e56758a5e0)] - **async-wrap**: add provider id and object info cb (Trevor Norris) [#1896](https://github.com/nodejs/node/pull/1896) - * [[`d5637e67c9`](https://github.com/nodejs/node/commit/d5637e67c9)] - **buffer**: fix cyclic dependency with util (Brendan Ashworth) [#1988](https://github.com/nodejs/node/pull/1988) - * [[`c5353d7c62`](https://github.com/nodejs/node/commit/c5353d7c62)] - **build**: remove lint from test-ci on windows (Johan Bergström) [#2004](https://github.com/nodejs/node/pull/2004) - * [[`c207e8d223`](https://github.com/nodejs/node/commit/c207e8d223)] - **build**: fix pkg-config output parsing in configure (Ben Noordhuis) [#1986](https://github.com/nodejs/node/pull/1986) - * [[`8d8a26e8f7`](https://github.com/nodejs/node/commit/8d8a26e8f7)] - **build**: don't run lint from test-ci (Johan Bergström) [#1965](https://github.com/nodejs/node/pull/1965) - * [[`1ec53c044d`](https://github.com/nodejs/node/commit/1ec53c044d)] - **build**: simplify execution of built binary (Johan Bergström) [#1955](https://github.com/nodejs/node/pull/1955) - * [[`3beb880716`](https://github.com/nodejs/node/commit/3beb880716)] - **crypto**: add cert check to CNNIC Whitelist (Shigeki Ohtsu) [#1895](https://github.com/nodejs/node/pull/1895) - * [[`48c0fb8b1a`](https://github.com/nodejs/node/commit/48c0fb8b1a)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`6a359b1ce9`](https://github.com/nodejs/node/commit/6a359b1ce9)] - **deps**: upgrade to npm 2.11.3 (Forrest L Norvell) [#2018](https://github.com/nodejs/node/pull/2018) - * [[`6aab2f3b9a`](https://github.com/nodejs/node/commit/6aab2f3b9a)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`3e12561b55`](https://github.com/nodejs/node/commit/3e12561b55)] - **deps**: upgrade to npm 2.11.2 (Rebecca Turner) [#1956](https://github.com/nodejs/node/pull/1956) - * [[`8ac50819b6`](https://github.com/nodejs/node/commit/8ac50819b6)] - **doc**: add security section to README.md (Rod Vagg) [#1948](https://github.com/nodejs/node/pull/1948) - * [[`1f93b63b11`](https://github.com/nodejs/node/commit/1f93b63b11)] - **doc**: change the info to the same as in gitconfig (Christian Tellnes) [#2000](https://github.com/nodejs/node/pull/2000) - * [[`0cf94e6856`](https://github.com/nodejs/node/commit/0cf94e6856)] - **doc**: mention CI in Collaborator Guide (Rich Trott) [#1995](https://github.com/nodejs/node/pull/1995) - * [[`7a3006efe4`](https://github.com/nodejs/node/commit/7a3006efe4)] - **doc**: add TOC links to Collaborator Guide (Rich Trott) [#1994](https://github.com/nodejs/node/pull/1994) - * [[`30638b150f`](https://github.com/nodejs/node/commit/30638b150f)] - **doc**: add TSC meeting notes 2015-06-10 (Bert Belder) [#1943](https://github.com/nodejs/node/pull/1943) - * [[`c4ec04136b`](https://github.com/nodejs/node/commit/c4ec04136b)] - **doc**: reformat authors section (Johan Bergström) [#1966](https://github.com/nodejs/node/pull/1966) - * [[`96165f9be2`](https://github.com/nodejs/node/commit/96165f9be2)] - **doc**: minor clarification in the modules API doc. (Сковорода Никита Андреевич) [#1983](https://github.com/nodejs/node/pull/1983) - * [[`5c2707c1b2`](https://github.com/nodejs/node/commit/5c2707c1b2)] - **doc**: benchmark/README.md copyedit (Rich Trott) [#1970](https://github.com/nodejs/node/pull/1970) - * [[`74fdf732d0`](https://github.com/nodejs/node/commit/74fdf732d0)] - **doc**: copyedit COLLABORATOR_GUIDE.md (Rich Trott) [#1964](https://github.com/nodejs/node/pull/1964) - * [[`5fe6e83640`](https://github.com/nodejs/node/commit/5fe6e83640)] - **doc**: copyedit GOVERNANCE.md (Rich Trott) [#1963](https://github.com/nodejs/node/pull/1963) - * [[`428526544c`](https://github.com/nodejs/node/commit/428526544c)] - **doc**: add ChALkeR as collaborator (Сковорода Никита Андреевич) [#1927](https://github.com/nodejs/node/pull/1927) - * [[`5dfe0d5d61`](https://github.com/nodejs/node/commit/5dfe0d5d61)] - **doc**: remove irrelevant SEMVER-MINOR & MAJOR (Rod Vagg) - * [[`fb8811d95e`](https://github.com/nodejs/node/commit/fb8811d95e)] - **lib,test**: fix whitespace issues (Roman Reiss) [#1971](https://github.com/nodejs/node/pull/1971) - * [[`a4f4909f3d`](https://github.com/nodejs/node/commit/a4f4909f3d)] - **module**: fix stat with long paths on Windows (Michaël Zasso) [#2013](https://github.com/nodejs/node/pull/2013) - * [[`a71ee93afe`](https://github.com/nodejs/node/commit/a71ee93afe)] - **module**: reduce syscalls during require search (Pierre Inglebert) [#1920](https://github.com/nodejs/node/pull/1920) - * [[`671e64ac73`](https://github.com/nodejs/node/commit/671e64ac73)] - **module**: allow long paths for require on Windows (Michaël Zasso) - * [[`061342a500`](https://github.com/nodejs/node/commit/061342a500)] - **net**: Defer reading until listeners could be added (James Hartig) [#1496](https://github.com/nodejs/node/pull/1496) - * [[`5d2b846d11`](https://github.com/nodejs/node/commit/5d2b846d11)] - **test**: assert tmp and fixture dirs different (Rich Trott) [#2015](https://github.com/nodejs/node/pull/2015) - * [[`b0990ef45d`](https://github.com/nodejs/node/commit/b0990ef45d)] - **test**: confirm symlink (Rich Trott) [#2014](https://github.com/nodejs/node/pull/2014) - * [[`3ba4f71fc4`](https://github.com/nodejs/node/commit/3ba4f71fc4)] - **test**: check result as early as possible (Rich Trott) [#2007](https://github.com/nodejs/node/pull/2007) - * [[`0abcf44d6b`](https://github.com/nodejs/node/commit/0abcf44d6b)] - **test**: add Buffer slice UTF-8 test (Rich Trott) [#1989](https://github.com/nodejs/node/pull/1989) - * [[`88c1831ff4`](https://github.com/nodejs/node/commit/88c1831ff4)] - **test**: tmpdir creation failures should fail tests (Rich Trott) [#1976](https://github.com/nodejs/node/pull/1976) - * [[`52a822d944`](https://github.com/nodejs/node/commit/52a822d944)] - **test**: fix test-cluster-worker-disconnect (Santiago Gimeno) [#1919](https://github.com/nodejs/node/pull/1919) - * [[`7c79490bfb`](https://github.com/nodejs/node/commit/7c79490bfb)] - **test**: only refresh tmpDir for tests that need it (Rich Trott) [#1954](https://github.com/nodejs/node/pull/1954) - * [[`88d7904c0b`](https://github.com/nodejs/node/commit/88d7904c0b)] - **test**: remove test repetition (Rich Trott) [#1874](https://github.com/nodejs/node/pull/1874) - * [[`91dfb5e094`](https://github.com/nodejs/node/commit/91dfb5e094)] - **tools**: make test-npm work without global npm (Jeremiah Senkpiel) [#1926](https://github.com/nodejs/node/pull/1926) - * [[`3777f41562`](https://github.com/nodejs/node/commit/3777f41562)] - **tools**: enable whitespace related rules in eslint (Roman Reiss) [#1971](https://github.com/nodejs/node/pull/1971) - * [[`626432d843`](https://github.com/nodejs/node/commit/626432d843)] - **util**: dont repeat isBuffer (Brendan Ashworth) [#1988](https://github.com/nodejs/node/pull/1988) - * [[`1d79f572f1`](https://github.com/nodejs/node/commit/1d79f572f1)] - **util**: move deprecate() to internal module (Brendan Ashworth) [#1988](https://github.com/nodejs/node/pull/1988) - * [[`4b4b1760b5`](https://github.com/nodejs/node/commit/4b4b1760b5)] - **v8**: cherry-pick uclibc build patch from upstream (Ben Noordhuis) [#1974](https://github.com/nodejs/node/pull/1974) - * [[`5d0cee46bb`](https://github.com/nodejs/node/commit/5d0cee46bb)] - **vm**: remove unnecessary HandleScopes (Ben Noordhuis) [#2001](https://github.com/nodejs/node/pull/2001) - * [[`0ecf9457b5`](https://github.com/nodejs/node/commit/0ecf9457b5)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) - * [[`953b3e75e8`](https://github.com/nodejs/node/commit/953b3e75e8)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) - * [[`3806d875d3`](https://github.com/nodejs/node/commit/3806d875d3)] - **zlib**: prevent uncaught exception in zlibBuffer (Michaël Zasso) [#1811](https://github.com/nodejs/node/pull/1811) - - - - ## 2015-06-13, Version 2.3.0, @rvagg - - ### Notable changes - - * **libuv**: Upgraded to 1.6.0 and 1.6.1, see [full ChangeLog](https://github.com/libuv/libuv/blob/60e515d9e6f3d86c0eedad583805201f32ea3aed/ChangeLog#L1-L36) for details. (Saúl Ibarra Corretgé) [#1905](https://github.com/nodejs/node/pull/1905) [#1889](https://github.com/nodejs/node/pull/1889). Highlights include: - - Fix TTY becoming blocked on OS X - - Fix UDP send callbacks to not to be synchronous - - Add `uv_os_homedir()` (exposed as `os.homedir()`, see below) - * **npm**: See full [release notes](https://github.com/npm/npm/releases/tag/v2.11.1) for details. (Kat Marchán) [#1899](https://github.com/nodejs/node/pull/1899). Highlight: - - Use GIT_SSH_COMMAND (available as of Git 2.3) - * **openssl**: - - Upgrade to 1.0.2b and 1.0.2c, introduces DHE man-in-the-middle protection (Logjam) and fixes malformed ECParameters causing infinite loop (CVE-2015-1788). See the [security advisory](https://www.openssl.org/news/secadv_20150611.txt) for full details. (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) [#1958](https://github.com/nodejs/node/pull/1958) - - Support [FIPS](https://en.wikipedia.org/wiki/Federal_Information_Processing_Standards) mode of OpenSSL, see [README](https://github.com/nodejs/node#building-iojs-with-fips-compliant-openssl) for instructions. (Fedor Indutny) [#1890](https://github.com/nodejs/node/pull/1890) - * **os**: Add `os.homedir()` method. (Colin Ihrig) [#1791](https://github.com/nodejs/node/pull/1791) - * **smalloc**: Deprecate whole module. (Vladimir Kurchatkin) [#1822](https://github.com/nodejs/node/pull/1822) - * Add new collaborators: - - Alex Kocharin ([@rlidwka](https://github.com/rlidwka)) - - Christopher Monsanto ([@monsanto](https://github.com/monsanto)) - - Ali Ijaz Sheikh ([@ofrobots](https://github.com/ofrobots)) - - Oleg Elifantiev ([@Olegas](https://github.com/Olegas)) - - Domenic Denicola ([@domenic](https://github.com/domenic)) - - Rich Trott ([@Trott](https://github.com/Trott)) - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ## Commits - - * [[`9c0a1b8cfc`](https://github.com/nodejs/node/commit/9c0a1b8cfc)] - **cluster**: wait on servers closing before disconnect (Oleg Elifantiev) [#1400](https://github.com/nodejs/node/pull/1400) - * [[`0f68377f69`](https://github.com/nodejs/node/commit/0f68377f69)] - **crypto**: support FIPS mode of OpenSSL (Fedor Indutny) [#1890](https://github.com/nodejs/node/pull/1890) - * [[`38d1afc24d`](https://github.com/nodejs/node/commit/38d1afc24d)] - **(SEMVER-MINOR)** **crypto**: add getCurves() to get supported ECs (Brian White) [#1914](https://github.com/nodejs/node/pull/1914) - * [[`a4dbf45b59`](https://github.com/nodejs/node/commit/a4dbf45b59)] - **crypto**: update root certificates (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) - * [[`81029c639a`](https://github.com/nodejs/node/commit/81029c639a)] - **debugger**: improve ESRCH error message (Jackson Tian) [#1863](https://github.com/nodejs/node/pull/1863) - * [[`2a7fd0ad32`](https://github.com/nodejs/node/commit/2a7fd0ad32)] - **deps**: update UPGRADING.md doc to openssl-1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) - * [[`6b3df929e0`](https://github.com/nodejs/node/commit/6b3df929e0)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) - * [[`664a659696`](https://github.com/nodejs/node/commit/664a659696)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`42a8de2ac6`](https://github.com/nodejs/node/commit/42a8de2ac6)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) - * [[`c66c3d9fa3`](https://github.com/nodejs/node/commit/c66c3d9fa3)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) - * [[`86737cf0a0`](https://github.com/nodejs/node/commit/86737cf0a0)] - **deps**: upgrade openssl sources to 1.0.2c (Shigeki Ohtsu) [#1958](https://github.com/nodejs/node/pull/1958) - * [[`94804969b7`](https://github.com/nodejs/node/commit/94804969b7)] - **deps**: update asm files for openssl-1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) - * [[`38444915e0`](https://github.com/nodejs/node/commit/38444915e0)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) - * [[`f62b613252`](https://github.com/nodejs/node/commit/f62b613252)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`f624d0122c`](https://github.com/nodejs/node/commit/f624d0122c)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) - * [[`dcd67cc8d7`](https://github.com/nodejs/node/commit/dcd67cc8d7)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) - * [[`c21b24decf`](https://github.com/nodejs/node/commit/c21b24decf)] - **deps**: upgrade openssl sources to 1.0.2b (Shigeki Ohtsu) [#1950](https://github.com/nodejs/node/pull/1950) - * [[`2dc819b09a`](https://github.com/nodejs/node/commit/2dc819b09a)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`f41b7f12b5`](https://github.com/nodejs/node/commit/f41b7f12b5)] - **deps**: upgrade to npm 2.11.1 (Kat Marchán) [#1899](https://github.com/nodejs/node/pull/1899) - * [[`a5bd466440`](https://github.com/nodejs/node/commit/a5bd466440)] - **deps**: update libuv to version 1.6.1 (Saúl Ibarra Corretgé) [#1905](https://github.com/nodejs/node/pull/1905) - * [[`aa33db3238`](https://github.com/nodejs/node/commit/aa33db3238)] - **deps**: update libuv to version 1.6.0 (Saúl Ibarra Corretgé) [#1889](https://github.com/nodejs/node/pull/1889) - * [[`0ee497f0b4`](https://github.com/nodejs/node/commit/0ee497f0b4)] - **deps**: add -no_rand_screen to openssl s_client (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`b5cd2f0986`](https://github.com/nodejs/node/commit/b5cd2f0986)] - **dgram**: partially revert 18d457b (Saúl Ibarra Corretgé) [#1889](https://github.com/nodejs/node/pull/1889) - * [[`a3cc43d0a4`](https://github.com/nodejs/node/commit/a3cc43d0a4)] - **doc**: add Trott as collaborator (Rich Trott) [#1962](https://github.com/nodejs/node/pull/1962) - * [[`cf5020fc02`](https://github.com/nodejs/node/commit/cf5020fc02)] - **doc**: add domenic as collaborator (Domenic Denicola) [#1942](https://github.com/nodejs/node/pull/1942) - * [[`11ed5f31ab`](https://github.com/nodejs/node/commit/11ed5f31ab)] - **doc**: add Olegas as collaborator (Oleg Elifantiev) [#1930](https://github.com/nodejs/node/pull/1930) - * [[`f500e1833b`](https://github.com/nodejs/node/commit/f500e1833b)] - **doc**: add ofrobots as collaborator (Ali Ijaz Sheikh) - * [[`717724611a`](https://github.com/nodejs/node/commit/717724611a)] - **doc**: add monsanto as collaborator (Christopher Monsanto) [#1932](https://github.com/nodejs/node/pull/1932) - * [[`7192b6688c`](https://github.com/nodejs/node/commit/7192b6688c)] - **doc**: add rlidwka as collaborator (Alex Kocharin) [#1929](https://github.com/nodejs/node/pull/1929) - * [[`9f3a03f0d4`](https://github.com/nodejs/node/commit/9f3a03f0d4)] - **doc**: add references to crypto.getCurves() (Roman Reiss) [#1918](https://github.com/nodejs/node/pull/1918) - * [[`ff39ecb914`](https://github.com/nodejs/node/commit/ff39ecb914)] - **doc**: remove comma splice (Rich Trott) [#1900](https://github.com/nodejs/node/pull/1900) - * [[`deb8b87dc9`](https://github.com/nodejs/node/commit/deb8b87dc9)] - **doc**: add note about available ECC curves (Ryan Petschek) [#1913](https://github.com/nodejs/node/pull/1913) - * [[`89a5b9040e`](https://github.com/nodejs/node/commit/89a5b9040e)] - **doc**: fix http.IncomingMessage.socket documentation (Сковорода Никита Андреевич) [#1867](https://github.com/nodejs/node/pull/1867) - * [[`d29034b34b`](https://github.com/nodejs/node/commit/d29034b34b)] - **doc**: adjust changelog to clarify `client` revert (Rod Vagg) [#1859](https://github.com/nodejs/node/pull/1859) - * [[`a79dece8ad`](https://github.com/nodejs/node/commit/a79dece8ad)] - **docs**: add return value for sync fs functions (Tyler Anton) [#1770](https://github.com/nodejs/node/pull/1770) - * [[`1cb72c14c4`](https://github.com/nodejs/node/commit/1cb72c14c4)] - **docs**: delete unused/duplicate css files (Robert Kowalski) [#1770](https://github.com/nodejs/node/pull/1770) - * [[`53a4eb3198`](https://github.com/nodejs/node/commit/53a4eb3198)] - **fs**: make SyncWriteStream non-enumerable (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) - * [[`a011c3243f`](https://github.com/nodejs/node/commit/a011c3243f)] - **fs**: minor refactoring (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) - * [[`8841132f30`](https://github.com/nodejs/node/commit/8841132f30)] - **fs**: remove inStatWatchers and use Map for lookup (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) - * [[`67a11b9bcc`](https://github.com/nodejs/node/commit/67a11b9bcc)] - **fs**: removing unnecessary nullCheckCallNT (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) - * [[`09f2a67bd8`](https://github.com/nodejs/node/commit/09f2a67bd8)] - **fs**: improve error message descriptions (Sakthipriyan Vairamani) [#1870](https://github.com/nodejs/node/pull/1870) - * [[`2dcef83b5f`](https://github.com/nodejs/node/commit/2dcef83b5f)] - **fs**: use `kMaxLength` from binding (Vladimir Kurchatkin) [#1903](https://github.com/nodejs/node/pull/1903) - * [[`353e26e3c7`](https://github.com/nodejs/node/commit/353e26e3c7)] - **(SEMVER-MINOR)** **fs**: Add string encoding option for Stream method (Yosuke Furukawa) [#1845](https://github.com/nodejs/node/pull/1845) - * [[`8357c5084b`](https://github.com/nodejs/node/commit/8357c5084b)] - **fs**: set encoding on fs.createWriteStream (Yosuke Furukawa) [#1844](https://github.com/nodejs/node/pull/1844) - * [[`02c345020a`](https://github.com/nodejs/node/commit/02c345020a)] - **gitignore**: don't ignore the debug npm module (Kat Marchán) [#1908](https://github.com/nodejs/node/pull/1908) - * [[`b5b8ff117c`](https://github.com/nodejs/node/commit/b5b8ff117c)] - **lib**: don't use global Buffer (Roman Reiss) [#1794](https://github.com/nodejs/node/pull/1794) - * [[`a251657058`](https://github.com/nodejs/node/commit/a251657058)] - **node**: mark promises as handled as soon as possible (Vladimir Kurchatkin) [#1952](https://github.com/nodejs/node/pull/1952) - * [[`2eb170874a`](https://github.com/nodejs/node/commit/2eb170874a)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) - * [[`a130132c8f`](https://github.com/nodejs/node/commit/a130132c8f)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [iojs/io.js#1389](https://github.com/iojs/io.js/pull/1389) - * [[`6e78e5feaa`](https://github.com/nodejs/node/commit/6e78e5feaa)] - **(SEMVER-MINOR)** **os**: add homedir() (cjihrig) [#1791](https://github.com/nodejs/node/pull/1791) - * [[`d9e250295b`](https://github.com/nodejs/node/commit/d9e250295b)] - ***Revert*** "**readline**: allow tabs in input" (Jeremiah Senkpiel) [#1961](https://github.com/nodejs/node/pull/1961) - * [[`4b3d493c4b`](https://github.com/nodejs/node/commit/4b3d493c4b)] - **readline**: allow tabs in input (Rich Trott) [#1761](https://github.com/nodejs/node/pull/1761) - * [[`6d95f4ff92`](https://github.com/nodejs/node/commit/6d95f4ff92)] - **(SEMVER-MINOR)** **smalloc**: deprecate whole module (Vladimir Kurchatkin) [#1822](https://github.com/nodejs/node/pull/1822) - * [[`8c71a9241d`](https://github.com/nodejs/node/commit/8c71a9241d)] - **src**: hide InitializeICUDirectory symbol (Ben Noordhuis) [#1815](https://github.com/nodejs/node/pull/1815) - * [[`5b6f575c1f`](https://github.com/nodejs/node/commit/5b6f575c1f)] - ***Revert*** "**src**: add getopt option parser" (Evan Lucas) [#1862](https://github.com/nodejs/node/pull/1862) - * [[`c0e7bf2d8c`](https://github.com/nodejs/node/commit/c0e7bf2d8c)] - **src**: add getopt option parser (Evan Lucas) [#1804](https://github.com/nodejs/node/pull/1804) - * [[`8ea6844d26`](https://github.com/nodejs/node/commit/8ea6844d26)] - **test**: add test for failed save in REPL (Rich Trott) [#1818](https://github.com/nodejs/node/pull/1818) - * [[`03ce84dfa1`](https://github.com/nodejs/node/commit/03ce84dfa1)] - **test**: fix cluster-worker-wait-server-close races (Sam Roberts) [#1953](https://github.com/nodejs/node/pull/1953) - * [[`a6b8ee19b8`](https://github.com/nodejs/node/commit/a6b8ee19b8)] - **test**: create temp dir in common.js (Rich Trott) [#1877](https://github.com/nodejs/node/pull/1877) - * [[`ff8202c6f4`](https://github.com/nodejs/node/commit/ff8202c6f4)] - **test**: fix undeclared variable access (Roman Reiss) [#1794](https://github.com/nodejs/node/pull/1794) - * [[`d9ddd7d345`](https://github.com/nodejs/node/commit/d9ddd7d345)] - **test**: remove TODO comment (Rich Trott) [#1820](https://github.com/nodejs/node/pull/1820) - * [[`6537fd4b55`](https://github.com/nodejs/node/commit/6537fd4b55)] - **test**: remove TODO (Rich Trott) [#1875](https://github.com/nodejs/node/pull/1875) - * [[`a804026c9b`](https://github.com/nodejs/node/commit/a804026c9b)] - **test**: fix broken FreeBSD test (Santiago Gimeno) [#1881](https://github.com/nodejs/node/pull/1881) - * [[`43a82f8a71`](https://github.com/nodejs/node/commit/43a82f8a71)] - **test**: fix test-sync-io-option (Evan Lucas) [#1840](https://github.com/nodejs/node/pull/1840) - * [[`4ed25f664d`](https://github.com/nodejs/node/commit/4ed25f664d)] - **test**: add -no_rand_screen for tls-server-verify (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`4cf323d23d`](https://github.com/nodejs/node/commit/4cf323d23d)] - **test**: kill child in tls-server-verify for speed up (Shigeki Ohtsu) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`e6ccdcc1fe`](https://github.com/nodejs/node/commit/e6ccdcc1fe)] - **test**: improve console output of tls-server-verify (João Reis) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`975e5956f0`](https://github.com/nodejs/node/commit/975e5956f0)] - **test**: run tls-server-verify servers in parallel (João Reis) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`b18604ba2c`](https://github.com/nodejs/node/commit/b18604ba2c)] - **test**: running tls-server-verify clients in parallel (João Reis) [#1836](https://github.com/nodejs/node/pull/1836) - * [[`f78c722df5`](https://github.com/nodejs/node/commit/f78c722df5)] - **test**: remove hardwired references to 'iojs' (Rod Vagg) [#1882](https://github.com/nodejs/node/pull/1882) - * [[`bd99e8de8e`](https://github.com/nodejs/node/commit/bd99e8de8e)] - **test**: more test coverage for maxConnections (Rich Trott) [#1855](https://github.com/nodejs/node/pull/1855) - * [[`b9267189a5`](https://github.com/nodejs/node/commit/b9267189a5)] - **test**: fix test-child-process-stdout-flush-exit (Santiago Gimeno) [#1868](https://github.com/nodejs/node/pull/1868) - * [[`d20f018dcf`](https://github.com/nodejs/node/commit/d20f018dcf)] - **test**: loosen condition to detect infinite loop (Yosuke Furukawa) [#1857](https://github.com/nodejs/node/pull/1857) - * [[`e0e96acc6f`](https://github.com/nodejs/node/commit/e0e96acc6f)] - **test**: remove smalloc add-on test (Ben Noordhuis) [#1835](https://github.com/nodejs/node/pull/1835) - * [[`8704c58fc4`](https://github.com/nodejs/node/commit/8704c58fc4)] - **test**: remove unneeded comment task (Rich Trott) [#1858](https://github.com/nodejs/node/pull/1858) - * [[`8732977536`](https://github.com/nodejs/node/commit/8732977536)] - **tls**: fix references to undefined `cb` (Fedor Indutny) [#1951](https://github.com/nodejs/node/pull/1951) - * [[`75930bb38c`](https://github.com/nodejs/node/commit/75930bb38c)] - **tls**: prevent use-after-free (Fedor Indutny) [#1702](https://github.com/nodejs/node/pull/1702) - * [[`5795e835a1`](https://github.com/nodejs/node/commit/5795e835a1)] - **tls**: emit errors on close whilst async action (Fedor Indutny) [#1702](https://github.com/nodejs/node/pull/1702) - * [[`59d9734e21`](https://github.com/nodejs/node/commit/59d9734e21)] - **tls_wrap**: invoke queued callbacks in DestroySSL (Fedor Indutny) [#1702](https://github.com/nodejs/node/pull/1702) - * [[`6e4d30286d`](https://github.com/nodejs/node/commit/6e4d30286d)] - **tools**: enable/add additional eslint rules (Roman Reiss) [#1794](https://github.com/nodejs/node/pull/1794) - * [[`098354a9f8`](https://github.com/nodejs/node/commit/098354a9f8)] - **tools**: update certdata.txt (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) - * [[`a2d921d6a0`](https://github.com/nodejs/node/commit/a2d921d6a0)] - **tools**: customize mk-ca-bundle.pl (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) - * [[`5be9efca40`](https://github.com/nodejs/node/commit/5be9efca40)] - **tools**: update mk-ca-bundle.pl to HEAD of upstream (Ben Noordhuis) [#1833](https://github.com/nodejs/node/pull/1833) - * [[`1baba0580d`](https://github.com/nodejs/node/commit/1baba0580d)] - **tools**: Fix copying contents of deps/npm (thefourtheye) [#1853](https://github.com/nodejs/node/pull/1853) - * [[`628845b816`](https://github.com/nodejs/node/commit/628845b816)] - **(SEMVER-MINOR)** **util**: introduce `printDeprecationMessage` function (Vladimir Kurchatkin) [#1822](https://github.com/nodejs/node/pull/1822) - * [[`91d0a8b19c`](https://github.com/nodejs/node/commit/91d0a8b19c)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [iojs/io.js#1433](https://github.com/iojs/io.js/pull/1433) - - - - ## 2015-06-01, Version 2.2.1, @rvagg - - ### Notable changes - - * **http**: Reverts the move of the `client` property of `IncomingMessage` to its prototype. Although undocumented, this property was used and assumed to be an "own property" in the wild, most notably by [request](https://github.com/request/request) which is used by npm. (Michaël Zasso) [#1852](https://github.com/nodejs/node/pull/1852). - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ### Commits - - * [[`c5a1009903`](https://github.com/nodejs/node/commit/c5a1009903)] - **build**: avoid passing empty strings to build flags (Johan Bergström) [#1789](https://github.com/nodejs/node/pull/1789) - * [[`5d83401086`](https://github.com/nodejs/node/commit/5d83401086)] - **doc**: put SEMVER-MINOR on pre-load module fix 2.2.0 (Rod Vagg) - * [[`4d6b768e5d`](https://github.com/nodejs/node/commit/4d6b768e5d)] - **http**: revert deprecation of client property (Michaël Zasso) [#1852](https://github.com/nodejs/node/pull/1852) - - - - ## 2015-05-31, Version 2.2.0, @rvagg - - ### Notable changes - - * **node**: Speed-up `require()` by replacing usage of `fs.statSync()` and `fs.readFileSync()` with internal variants that are faster for this use-case and do not create as many objects for the garbage collector to clean up. The primary two benefits are: significant increase in application start-up time on typical applications and better start-up time for the debugger by eliminating almost all of the thousands of exception events. (Ben Noordhuis) [#1801](https://github.com/nodejs/node/pull/1801). - * **node**: Resolution of pre-load modules (`-r` or `--require`) now follows the standard `require()` rules rather than just resolving paths, so you can now pre-load modules in node_modules. (Ali Ijaz Sheikh) [#1812](https://github.com/nodejs/node/pull/1812). - * **npm**: Upgraded npm to v2.11.0. New hooks for `preversion`, `version`, and `postversion` lifecycle events, some SPDX-related license changes and license file inclusions. See the [release notes](https://github.com/npm/npm/releases/tag/v2.11.0) for full details. - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ### Commits - - * [[`a77c330c32`](https://github.com/nodejs/node/commit/a77c330c32)] - **(SEMVER-MINOR)** **child_process**: expose ChildProcess constructor (Evan Lucas) [#1760](https://github.com/nodejs/node/pull/1760) - * [[`3a1bc067d4`](https://github.com/nodejs/node/commit/3a1bc067d4)] - ***Revert*** "**core**: set PROVIDER type as Persistent class id" (Ben Noordhuis) [#1827](https://github.com/nodejs/node/pull/1827) - * [[`f9fd554500`](https://github.com/nodejs/node/commit/f9fd554500)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`c1afa53648`](https://github.com/nodejs/node/commit/c1afa53648)] - **deps**: upgrade npm to 2.11.0 (Forrest L Norvell) [iojs/io.js#1829](https://github.com/iojs/io.js/pull/1829) - * [[`ff794498e7`](https://github.com/nodejs/node/commit/ff794498e7)] - **doc**: `fs.*File()` also accept encoding strings (Rich Trott) [#1806](https://github.com/nodejs/node/pull/1806) - * [[`98649fd31a`](https://github.com/nodejs/node/commit/98649fd31a)] - **doc**: add documentation for AtExit hook (Steve Sharp) [#1014](https://github.com/nodejs/node/pull/1014) - * [[`eb1856dfd1`](https://github.com/nodejs/node/commit/eb1856dfd1)] - **doc**: clarify stability of fs.watch and relatives (Rich Trott) [#1775](https://github.com/nodejs/node/pull/1775) - * [[`a74c2c9458`](https://github.com/nodejs/node/commit/a74c2c9458)] - **doc**: state url decoding behavior (Josh Gummersall) [#1731](https://github.com/nodejs/node/pull/1731) - * [[`ba76a9d872`](https://github.com/nodejs/node/commit/ba76a9d872)] - **doc**: remove bad semver-major entry from CHANGELOG (Rod Vagg) [#1782](https://github.com/nodejs/node/pull/1782) - * [[`a6a3f8c78d`](https://github.com/nodejs/node/commit/a6a3f8c78d)] - **doc**: fix changelog s/2.0.3/2.1.0 (Rod Vagg) - * [[`2c686fd3ce`](https://github.com/nodejs/node/commit/2c686fd3ce)] - **http**: flush stored header (Vladimir Kurchatkin) [#1695](https://github.com/nodejs/node/pull/1695) - * [[`1eec5f091a`](https://github.com/nodejs/node/commit/1eec5f091a)] - **http**: simplify code and remove unused properties (Brian White) [#1572](https://github.com/nodejs/node/pull/1572) - * [[`1bbf8d0720`](https://github.com/nodejs/node/commit/1bbf8d0720)] - **lib**: speed up require(), phase 2 (Ben Noordhuis) [#1801](https://github.com/nodejs/node/pull/1801) - * [[`b14fd1a720`](https://github.com/nodejs/node/commit/b14fd1a720)] - **lib**: speed up require(), phase 1 (Ben Noordhuis) [#1801](https://github.com/nodejs/node/pull/1801) - * [[`5abd4ac079`](https://github.com/nodejs/node/commit/5abd4ac079)] - **lib**: simplify nextTick() usage (Brian White) [#1612](https://github.com/nodejs/node/pull/1612) - * [[`5759722cfa`](https://github.com/nodejs/node/commit/5759722cfa)] - **(SEMVER-MINOR)** **src**: fix module search path for preload modules (Ali Ijaz Sheikh) [#1812](https://github.com/nodejs/node/pull/1812) - * [[`a65762cab6`](https://github.com/nodejs/node/commit/a65762cab6)] - **src**: remove old code (Brendan Ashworth) [#1819](https://github.com/nodejs/node/pull/1819) - * [[`93a44d5228`](https://github.com/nodejs/node/commit/93a44d5228)] - **src**: fix deferred events not working with -e (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) - * [[`8059393934`](https://github.com/nodejs/node/commit/8059393934)] - **test**: check error type from net.Server.listen() (Rich Trott) [#1821](https://github.com/nodejs/node/pull/1821) - * [[`4e90c82cdb`](https://github.com/nodejs/node/commit/4e90c82cdb)] - **test**: add heap profiler add-on regression test (Ben Noordhuis) [#1828](https://github.com/nodejs/node/pull/1828) - * [[`6dfca71af0`](https://github.com/nodejs/node/commit/6dfca71af0)] - **test**: don't lint autogenerated test/addons/doc-*/ (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) - * [[`c2b8b30836`](https://github.com/nodejs/node/commit/c2b8b30836)] - **test**: remove stray copyright notices (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) - * [[`280fb01daf`](https://github.com/nodejs/node/commit/280fb01daf)] - **test**: fix deprecation warning in addons test (Ben Noordhuis) [#1793](https://github.com/nodejs/node/pull/1793) - * [[`8606793999`](https://github.com/nodejs/node/commit/8606793999)] - **tools**: pass constant to logger instead of string (Johan Bergström) [#1842](https://github.com/nodejs/node/pull/1842) - * [[`fbd2b59716`](https://github.com/nodejs/node/commit/fbd2b59716)] - **tools**: add objectLiteralShorthandProperties to .eslintrc (Evan Lucas) [#1760](https://github.com/nodejs/node/pull/1760) - * [[`53e98cc1b4`](https://github.com/nodejs/node/commit/53e98cc1b4)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1763](https://github.com/nodejs/node/pull/1763) - - - ## 2015-05-24, Version 2.1.0, @rvagg - - ### Notable changes - - * **crypto**: Diffie-Hellman key exchange (DHE) parameters (`'dhparams'`) must now be 1024 bits or longer or an error will be thrown. A warning will also be printed to the console if you supply less than 2048 bits. See https://weakdh.org/ for further context on this security concern. (Shigeki Ohtsu) [#1739](https://github.com/nodejs/node/pull/1739). - * **node**: A new `--trace-sync-io` command line flag will print a warning and a stack trace whenever a synchronous API is used. This can be used to track down synchronous calls that may be slowing down an application. (Trevor Norris) [#1707](https://github.com/nodejs/node/pull/1707). - * **node**: To allow for chaining of methods, the `setTimeout()`, `setKeepAlive()`, `setNoDelay()`, `ref()` and `unref()` methods used in `'net'`, `'dgram'`, `'http'`, `'https'` and `'tls'` now return the current instance instead of `undefined` (Roman Reiss & Evan Lucas) [#1699](https://github.com/nodejs/node/pull/1699) [#1768](https://github.com/nodejs/node/pull/1768) [#1779](https://github.com/nodejs/node/pull/1779). - * **npm**: Upgraded to v2.10.1, release notes can be found in and . - * **util**: A significant speed-up (in the order of 35%) for the common-case of a single string argument to `util.format()`, used by `console.log()` (Сковорода Никита Андреевич) [#1749](https://github.com/nodejs/node/pull/1749). - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ### Commits - - * [[`9da168b71f`](https://github.com/nodejs/node/commit/9da168b71f)] - **buffer**: optimize Buffer.byteLength (Brendan Ashworth) [#1713](https://github.com/nodejs/node/pull/1713) - * [[`2b1c01c2cc`](https://github.com/nodejs/node/commit/2b1c01c2cc)] - **build**: refactor pkg-config for shared libraries (Johan Bergström) [#1603](https://github.com/nodejs/node/pull/1603) - * [[`3c44100558`](https://github.com/nodejs/node/commit/3c44100558)] - **core**: set PROVIDER type as Persistent class id (Trevor Norris) [#1730](https://github.com/nodejs/node/pull/1730) - * [[`c1de6d249e`](https://github.com/nodejs/node/commit/c1de6d249e)] - **(SEMVER-MINOR)** **core**: implement runtime flag to trace sync io (Trevor Norris) [#1707](https://github.com/nodejs/node/pull/1707) - * [[`9e7099fa4e`](https://github.com/nodejs/node/commit/9e7099fa4e)] - **deps**: make node-gyp work with io.js (cjihrig) [iojs/io.js#990](https://github.com/iojs/io.js/pull/990) - * [[`c54d057598`](https://github.com/nodejs/node/commit/c54d057598)] - **deps**: upgrade to npm 2.10.1 (Rebecca Turner) [#1763](https://github.com/nodejs/node/pull/1763) - * [[`367ffd167d`](https://github.com/nodejs/node/commit/367ffd167d)] - **doc**: update AUTHORS list (Rod Vagg) [#1776](https://github.com/nodejs/node/pull/1776) - * [[`2bb2f06b3e`](https://github.com/nodejs/node/commit/2bb2f06b3e)] - **doc**: fix typo in CONTRIBUTING.md (Rich Trott) [#1755](https://github.com/nodejs/node/pull/1755) - * [[`515afc6367`](https://github.com/nodejs/node/commit/515afc6367)] - **doc**: path is ignored in url.format (Maurice Butler) [#1753](https://github.com/nodejs/node/pull/1753) - * [[`f0a8bc3f84`](https://github.com/nodejs/node/commit/f0a8bc3f84)] - **doc**: fix spelling in CHANGELOG (Felipe Batista) - * [[`86dd244d9b`](https://github.com/nodejs/node/commit/86dd244d9b)] - **doc**: add notes to child_process.fork() and .exec() (Rich Trott) [#1718](https://github.com/nodejs/node/pull/1718) - * [[`066274794c`](https://github.com/nodejs/node/commit/066274794c)] - **doc**: update links from iojs/io.js to nodejs/io.js (Frederic Hemberger) [#1715](https://github.com/nodejs/node/pull/1715) - * [[`cb381fe3e0`](https://github.com/nodejs/node/commit/cb381fe3e0)] - **(SEMVER-MINOR)** **net**: return this from setNoDelay and setKeepAlive (Roman Reiss) [#1779](https://github.com/nodejs/node/pull/1779) - * [[`85d9983009`](https://github.com/nodejs/node/commit/85d9983009)] - **net**: persist net.Socket options before connect (Evan Lucas) [#1518](https://github.com/nodejs/node/pull/1518) - * [[`39dde3222e`](https://github.com/nodejs/node/commit/39dde3222e)] - **(SEMVER-MINOR)** **net,dgram**: return this from ref and unref methods (Roman Reiss) [#1768](https://github.com/nodejs/node/pull/1768) - * [[`5773438913`](https://github.com/nodejs/node/commit/5773438913)] - **test**: fix jslint error (Michaël Zasso) [#1743](https://github.com/nodejs/node/pull/1743) - * [[`867631986f`](https://github.com/nodejs/node/commit/867631986f)] - **test**: fix test-sync-io-option (Santiago Gimeno) [#1734](https://github.com/nodejs/node/pull/1734) - * [[`f29762f4dd`](https://github.com/nodejs/node/commit/f29762f4dd)] - **test**: enable linting for tests (Roman Reiss) [#1721](https://github.com/nodejs/node/pull/1721) - * [[`2a71f02988`](https://github.com/nodejs/node/commit/2a71f02988)] - **tls**: emit errors happening before handshake finish (Malte-Thorben Bruns) [#1769](https://github.com/nodejs/node/pull/1769) - * [[`80342f649d`](https://github.com/nodejs/node/commit/80342f649d)] - **tls**: use `.destroy(err)` instead of destroy+emit (Fedor Indutny) [#1711](https://github.com/nodejs/node/pull/1711) - * [[`9b35be5810`](https://github.com/nodejs/node/commit/9b35be5810)] - **tls**: make server not use DHE in less than 1024bits (Shigeki Ohtsu) [#1739](https://github.com/nodejs/node/pull/1739) - * [[`214d02040e`](https://github.com/nodejs/node/commit/214d02040e)] - **util**: speed up common case of formatting string (Сковорода Никита Андреевич) [#1749](https://github.com/nodejs/node/pull/1749) - * [[`d144e96fbf`](https://github.com/nodejs/node/commit/d144e96fbf)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1763](https://github.com/nodejs/node/pull/1763) - * [[`0d6d3dda95`](https://github.com/nodejs/node/commit/0d6d3dda95)] - **win,node-gyp**: make delay-load hook C89 compliant (Sharat M R) [TooTallNate/node-gyp#616](https://github.com/TooTallNate/node-gyp/pull/616) - - - ## 2015-05-17, Version 1.8.2, @rvagg - - **Maintenance release** - - ## Notable changes - - * **crypto**: significantly reduced memory usage for TLS (Fedor Indutny & Сковорода Никита Андреевич) [#1529](https://github.com/nodejs/node/pull/1529) - * **npm**: Upgrade npm to 2.9.0. See the [v2.8.4](https://github.com/npm/npm/releases/tag/v2.8.4) and [v2.9.0](https://github.com/npm/npm/releases/tag/v2.9.0) release notes for details. Summary: - - Add support for default author field to make `npm init -y` work without user-input (@othiym23) [npm/npm/d8eee6cf9d](https://github.com/npm/npm/commit/d8eee6cf9d2ff7aca68dfaed2de76824a3e0d9 - - Include local modules in `npm outdated` and `npm update` (@ArnaudRinquin) [npm/npm#7426](https://github.com/npm/npm/issues/7426) - - The prefix used before the version number on `npm version` is now configurable via `tag-version-prefix` (@kkragenbrink) [npm/npm#8014](https://github.com/npm/npm/issues/8014) - - ### Known issues - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) - - ### Commits - - * [[`5404cbc745`](https://github.com/nodejs/node/commit/5404cbc745)] - **buffer**: fix copy() segfault with zero arguments (Trevor Norris) [nodejs/node#1520](https://github.com/nodejs/node/pull/1520) - * [[`65dd10e9c0`](https://github.com/nodejs/node/commit/65dd10e9c0)] - **build**: remove -J from test-ci (Rod Vagg) [nodejs/node#1544](https://github.com/nodejs/node/pull/1544) - * [[`74060bb60e`](https://github.com/nodejs/node/commit/74060bb60e)] - **crypto**: track external memory for SSL structures (Fedor Indutny) [nodejs/node#1529](https://github.com/nodejs/node/pull/1529) - * [[`f10f379240`](https://github.com/nodejs/node/commit/f10f379240)] - **deps**: make node-gyp work with io.js (cjihrig) [nodejs/node#990](https://github.com/nodejs/node/pull/990) - * [[`ba0e744c2c`](https://github.com/nodejs/node/commit/ba0e744c2c)] - **deps**: upgrade npm to 2.9.0 (Forrest L Norvell) [nodejs/node#1583](https://github.com/nodejs/node/pull/1583) - * [[`b3a7da1091`](https://github.com/nodejs/node/commit/b3a7da1091)] - **deps**: update http_parser to 2.5.0 (Fedor Indutny) [nodejs/node#1517](https://github.com/nodejs/node/pull/1517) - * [[`4030545af6`](https://github.com/nodejs/node/commit/4030545af6)] - **fs**: validate fd on fs.write (Julian Duque) [#1553](https://github.com/nodejs/node/pull/1553) - * [[`898d423820`](https://github.com/nodejs/node/commit/898d423820)] - **string_decoder**: don't cache Buffer.isEncoding (Brian White) [nodejs/node#1548](https://github.com/nodejs/node/pull/1548) - * [[`32a6dbcf23`](https://github.com/nodejs/node/commit/32a6dbcf23)] - **test**: extend timeouts for ARMv6 (Rod Vagg) [nodejs/node#1554](https://github.com/nodejs/node/pull/1554) - * [[`5896fe5cd3`](https://github.com/nodejs/node/commit/5896fe5cd3)] - **test**: adjust Makefile/test-ci, add to vcbuild.bat (Rod Vagg) [nodejs/node#1530](https://github.com/nodejs/node/pull/1530) - * [[`b72e4bc596`](https://github.com/nodejs/node/commit/b72e4bc596)] - **tls**: destroy singleUse context immediately (Fedor Indutny) [nodejs/node#1529](https://github.com/nodejs/node/pull/1529) - * [[`1cfc455dc5`](https://github.com/nodejs/node/commit/1cfc455dc5)] - **tls**: zero SSL_CTX freelist for a singleUse socket (Fedor Indutny) [nodejs/node#1529](https://github.com/nodejs/node/pull/1529) - * [[`7ada680519`](https://github.com/nodejs/node/commit/7ada680519)] - **tls**: destroy SSL once it is out of use (Fedor Indutny) [nodejs/node#1529](https://github.com/nodejs/node/pull/1529) - * [[`71274b0263`](https://github.com/nodejs/node/commit/71274b0263)] - **tls_wrap**: use localhost if options.host is empty (Guilherme Souza) [nodejs/node#1493](https://github.com/nodejs/node/pull/1493) - * [[`0eb74a8b6c`](https://github.com/nodejs/node/commit/0eb74a8b6c)] - **win,node-gyp**: optionally allow node.exe/iojs.exe to be renamed (Bert Belder) [nodejs/node#1266](https://github.com/nodejs/node/pull/1266) - - - ## 2015-05-15, Version 2.0.2, @Fishrock123 - - ### Notable changes - - * **win,node-gyp**: the delay-load hook for windows addons has now been correctly enabled by default, it had wrongly defaulted to off in the release version of 2.0.0 (Bert Belder) [#1433](https://github.com/nodejs/node/pull/1433) - * **os**: `tmpdir()`'s trailing slash stripping has been refined to fix an issue when the temp directory is at '/'. Also considers which slash is used by the operating system. (cjihrig) [#1673](https://github.com/nodejs/node/pull/1673) - * **tls**: default ciphers have been updated to use gcm and aes128 (Mike MacCana) [#1660](https://github.com/nodejs/node/pull/1660) - * **build**: v8 snapshots have been re-enabled by default as suggested by the v8 team, since prior security issues have been resolved. This should give some perf improvements to both startup and vm context creation. (Trevor Norris) [#1663](https://github.com/nodejs/node/pull/1663) - * **src**: fixed preload modules not working when other flags were used before `--require` (Yosuke Furukawa) [#1694](https://github.com/nodejs/node/pull/1694) - * **dgram**: fixed `send()`'s callback not being asynchronous (Yosuke Furukawa) [#1313](https://github.com/nodejs/node/pull/1313) - * **readline**: emitKeys now keeps buffering data until it has enough to parse. This fixes an issue with parsing split escapes. (Alex Kocharin) [#1601](https://github.com/nodejs/node/pull/1601) - * **cluster**: works now properly emit 'disconnect' to `cluser.worker` (Oleg Elifantiev) [#1386](https://github.com/nodejs/node/pull/1386) - * **events**: uncaught errors now provide some context (Evan Lucas) [#1654](https://github.com/nodejs/node/pull/1654) - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - - ### Commits - - * [[`8a0e5295b4`](https://github.com/nodejs/node/commit/8a0e5295b4)] - **build**: use backslashes for paths on windows (Johan Bergström) [#1698](https://github.com/nodejs/node/pull/1698) - * [[`20c9a52227`](https://github.com/nodejs/node/commit/20c9a52227)] - **build**: move --with-intl to intl optgroup (Johan Bergström) [#1680](https://github.com/nodejs/node/pull/1680) - * [[`36cdc7c8ac`](https://github.com/nodejs/node/commit/36cdc7c8ac)] - **build**: re-enable V8 snapshots (Trevor Norris) [#1663](https://github.com/nodejs/node/pull/1663) - * [[`5883a59b21`](https://github.com/nodejs/node/commit/5883a59b21)] - **cluster**: disconnect event not emitted correctly (Oleg Elifantiev) [#1386](https://github.com/nodejs/node/pull/1386) - * [[`0f850f7ae7`](https://github.com/nodejs/node/commit/0f850f7ae7)] - **deps**: provide TXT chunk info in c-ares (Fedor Indutny) - * [[`7e1c0e75ed`](https://github.com/nodejs/node/commit/7e1c0e75ed)] - **deps**: sync with upstream bagder/c-ares@bba4dc5 (Ben Noordhuis) [#1678](https://github.com/nodejs/node/pull/1678) - * [[`18d457bd34`](https://github.com/nodejs/node/commit/18d457bd34)] - **dgram**: call send callback asynchronously (Yosuke Furukawa) [#1313](https://github.com/nodejs/node/pull/1313) - * [[`8b9a1537ad`](https://github.com/nodejs/node/commit/8b9a1537ad)] - **events**: provide better error message for unhandled error (Evan Lucas) [#1654](https://github.com/nodejs/node/pull/1654) - * [[`19ffb5cf1c`](https://github.com/nodejs/node/commit/19ffb5cf1c)] - **lib**: fix eslint styles (Yosuke Furukawa) [#1539](https://github.com/nodejs/node/pull/1539) - * [[`76937051f8`](https://github.com/nodejs/node/commit/76937051f8)] - **os**: refine tmpdir() trailing slash stripping (cjihrig) [#1673](https://github.com/nodejs/node/pull/1673) - * [[`aed6bce906`](https://github.com/nodejs/node/commit/aed6bce906)] - **readline**: turn emitKeys into a streaming parser (Alex Kocharin) [#1601](https://github.com/nodejs/node/pull/1601) - * [[`0a461e5360`](https://github.com/nodejs/node/commit/0a461e5360)] - **src**: fix preload when used with prior flags (Yosuke Furukawa) [#1694](https://github.com/nodejs/node/pull/1694) - * [[`931a0d4634`](https://github.com/nodejs/node/commit/931a0d4634)] - **src**: add type check to v8.setFlagsFromString() (Roman Klauke) [#1652](https://github.com/nodejs/node/pull/1652) - * [[`08d08668c9`](https://github.com/nodejs/node/commit/08d08668c9)] - **src,deps**: replace LoadLibrary by LoadLibraryW (Cheng Zhao) [#226](https://github.com/nodejs/node/pull/226) - * [[`4e2f999a62`](https://github.com/nodejs/node/commit/4e2f999a62)] - **test**: fix infinite loop detection (Yosuke Furukawa) [#1681](https://github.com/nodejs/node/pull/1681) - * [[`5755fc099f`](https://github.com/nodejs/node/commit/5755fc099f)] - **tls**: update default ciphers to use gcm and aes128 (Mike MacCana) [#1660](https://github.com/nodejs/node/pull/1660) - * [[`966acb9916`](https://github.com/nodejs/node/commit/966acb9916)] - **tools**: remove closure_linter to eslint on windows (Yosuke Furukawa) [#1685](https://github.com/nodejs/node/pull/1685) - * [[`c58264e58b`](https://github.com/nodejs/node/commit/c58264e58b)] - **tools**: make eslint work on subdirectories (Roman Reiss) [#1686](https://github.com/nodejs/node/pull/1686) - * [[`0b21ab13b7`](https://github.com/nodejs/node/commit/0b21ab13b7)] - **tools**: refactor `make test-npm` into test-npm.sh (Jeremiah Senkpiel) [#1662](https://github.com/nodejs/node/pull/1662) - * [[`f07b3b600b`](https://github.com/nodejs/node/commit/f07b3b600b)] - **tools**: set eslint comma-spacing to 'warn' (Roman Reiss) [#1672](https://github.com/nodejs/node/pull/1672) - * [[`f9dd34d301`](https://github.com/nodejs/node/commit/f9dd34d301)] - **tools**: replace closure-linter with eslint (Yosuke Furukawa) [#1539](https://github.com/nodejs/node/pull/1539) - * [[`64d3210c98`](https://github.com/nodejs/node/commit/64d3210c98)] - **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1667](https://github.com/nodejs/node/issues/1667) - - - ## 2015-05-07, Version 2.0.1, @rvagg - - ### Notable changes - - * **async_wrap**: (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) - - it is now possible to filter by providers - - bit flags have been removed and replaced with method calls on the binding object - - _note that this is an unstable API so feature additions and breaking changes won't change io.js semver_ - * **libuv**: resolves numerous io.js issues: - - [#862](https://github.com/nodejs/node/issues/862) prevent spawning child processes with invalid stdio file descriptors - - [#1397](https://github.com/nodejs/node/issues/1397) fix EPERM error with fs.access(W_OK) on Windows - - [#1621](https://github.com/nodejs/node/issues/1621) build errors associated with the bundled libuv - - [#1512](https://github.com/nodejs/node/issues/1512) should properly fix Windows termination errors - * **addons**: the `NODE_DEPRECATED` macro was causing problems when compiling addons with older compilers, this should now be resolved (Ben Noordhuis) [#1626](https://github.com/nodejs/node/pull/1626) - * **V8**: upgrade V8 from 4.2.77.18 to 4.2.77.20 with minor fixes, including a bug preventing builds on FreeBSD - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) - - ### Commits - - * [[`7dde95a8bd`](https://github.com/nodejs/node/commit/7dde95a8bd)] - **async-wrap**: remove before/after calls in init (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) - * [[`bd42ba056a`](https://github.com/nodejs/node/commit/bd42ba056a)] - **async-wrap**: set flags using functions (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) - * [[`4b2c786449`](https://github.com/nodejs/node/commit/4b2c786449)] - **async-wrap**: pass PROVIDER as first arg to init (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) - * [[`84bf609fd2`](https://github.com/nodejs/node/commit/84bf609fd2)] - **async-wrap**: don't call init callback unnecessarily (Trevor Norris) [#1614](https://github.com/nodejs/node/pull/1614) - * [[`04cc03b029`](https://github.com/nodejs/node/commit/04cc03b029)] - **deps**: update libuv to 1.5.0 (Saúl Ibarra Corretgé) [#1646](https://github.com/nodejs/node/pull/1646) - * [[`b16d9c28e8`](https://github.com/nodejs/node/commit/b16d9c28e8)] - **deps**: upgrade v8 to 4.2.77.20 (Ben Noordhuis) [#1639](https://github.com/nodejs/node/pull/1639) - * [[`9ec3109272`](https://github.com/nodejs/node/commit/9ec3109272)] - **doc**: add TC meeting 2015-04-29 minutes (Rod Vagg) [#1585](https://github.com/nodejs/node/pull/1585) - * [[`2c7206254c`](https://github.com/nodejs/node/commit/2c7206254c)] - **doc**: fix typo in readme.md (AQNOUCH Mohammed) [#1643](https://github.com/nodejs/node/pull/1643) - * [[`71dc7152ee`](https://github.com/nodejs/node/commit/71dc7152ee)] - **doc**: fix PR link in CHANGELOG (Brian White) [#1624](https://github.com/nodejs/node/pull/1624) - * [[`b97b96d05a`](https://github.com/nodejs/node/commit/b97b96d05a)] - **install**: fix NameError (thefourtheye) [#1628](https://github.com/nodejs/node/pull/1628) - * [[`6ccbe75384`](https://github.com/nodejs/node/commit/6ccbe75384)] - **js_stream**: fix buffer index in DoWrite (Shigeki Ohtsu) [#1635](https://github.com/nodejs/node/pull/1635) - * [[`c43855c49c`](https://github.com/nodejs/node/commit/c43855c49c)] - **src**: export the ParseEncoding function on Windows (Ivan Kozik) [#1596](https://github.com/nodejs/node/pull/1596) - * [[`8315b22390`](https://github.com/nodejs/node/commit/8315b22390)] - **src**: fix pedantic cpplint whitespace warnings (Ben Noordhuis) [#1640](https://github.com/nodejs/node/pull/1640) - * [[`b712af79a7`](https://github.com/nodejs/node/commit/b712af79a7)] - **src**: fix NODE_DEPRECATED macro with old compilers (Ben Noordhuis) [#1626](https://github.com/nodejs/node/pull/1626) - * [[`2ed10f1349`](https://github.com/nodejs/node/commit/2ed10f1349)] - **src**: fix minor inefficiency in Buffer::New() call (Ben Noordhuis) [#1577](https://github.com/nodejs/node/pull/1577) - * [[`f696c9efab`](https://github.com/nodejs/node/commit/f696c9efab)] - **src**: fix deprecated use of Buffer::New() (Ben Noordhuis) [#1577](https://github.com/nodejs/node/pull/1577) - * [[`0c8f13df8f`](https://github.com/nodejs/node/commit/0c8f13df8f)] - **tools**: remove unused GuessWordSize function (thefourtheye) [#1638](https://github.com/nodejs/node/pull/1638) - - - ## 2015-05-04, Version 2.0.0, @rvagg - - ### Breaking changes - - Full details at https://github.com/nodejs/node/wiki/Breaking-Changes#200-from-1x - - * V8 upgrade to 4.2, minor changes to C++ API - * `os.tmpdir()` is now cross-platform consistent and no longer returns a path with a trailing slash on any platform - * While not a *breaking change* the 'smalloc' module has been deprecated in anticipation of it becoming unsupportable with a future upgrade to V8 4.4. See [#1451](https://github.com/nodejs/node/issues/1451) for further information. - - _Note: a new version of the 'url' module was reverted prior to release as it was decided the potential for breakage across the npm ecosystem was too great and that more compatibility work needed to be done before releasing it. See [#1602](https://github.com/nodejs/node/pull/1602) for further information._ - - ### Notable changes - - * **crypto**: significantly reduced memory usage for TLS (Fedor Indutny & Сковорода Никита Андреевич) [#1529](https://github.com/nodejs/node/pull/1529) - * **net**: `socket.connect()` now accepts a `'lookup'` option for a custom DNS resolution mechanism, defaults to `dns.lookup()` (Evan Lucas) [#1505](https://github.com/nodejs/node/pull/1505) - * **npm**: Upgrade npm to 2.9.0. See the [v2.8.4](https://github.com/npm/npm/releases/tag/v2.8.4) and [v2.9.0](https://github.com/npm/npm/releases/tag/v2.9.0) release notes for details. Notable items: - - Add support for default author field to make `npm init -y` work without user-input (@othiym23) [npm/npm/d8eee6cf9d](https://github.com/npm/npm/commit/d8eee6cf9d2ff7aca68dfaed2de76824a3e0d9af) - - Include local modules in `npm outdated` and `npm update` (@ArnaudRinquin) [npm/npm#7426](https://github.com/npm/npm/issues/7426) - - The prefix used before the version number on `npm version` is now configurable via `tag-version-prefix` (@kkragenbrink) [npm/npm#8014](https://github.com/npm/npm/issues/8014) - * **os**: `os.tmpdir()` is now cross-platform consistent and will no longer returns a path with a trailing slash on any platform (Christian Tellnes) [#747](https://github.com/nodejs/node/pull/747) - * **process**: - - `process.nextTick()` performance has been improved by between 2-42% across the benchmark suite, notable because this is heavily used across core (Brian White) [#1571](https://github.com/nodejs/node/pull/1571) - - New `process.geteuid()`, `process.seteuid(id)`, `process.getegid()` and `process.setegid(id)` methods allow you to get and set effective UID and GID of the process (Evan Lucas) [#1536](https://github.com/nodejs/node/pull/1536) - * **repl**: - - REPL history can be persisted across sessions if the `NODE_REPL_HISTORY_FILE` environment variable is set to a user accessible file, `NODE_REPL_HISTORY_SIZE` can set the maximum history size and defaults to `1000` (Chris Dickinson) [#1513](https://github.com/nodejs/node/pull/1513) - - The REPL can be placed in to one of three modes using the `NODE_REPL_MODE` environment variable: `sloppy`, `strict` or `magic` (default); the new `magic` mode will automatically run "strict mode only" statements in strict mode (Chris Dickinson) [#1513](https://github.com/nodejs/node/pull/1513) - * **smalloc**: the 'smalloc' module has been deprecated due to changes coming in V8 4.4 that will render it unusable - * **util**: add Promise, Map and Set inspection support (Christopher Monsanto) [#1471](https://github.com/nodejs/node/pull/1471) - * **V8**: upgrade to 4.2.77.18, see the [ChangeLog](https://chromium.googlesource.com/v8/v8/+/refs/heads/4.2.77/ChangeLog) for full details. Notable items: - - Classes have moved out of staging; the `class` keyword is now usable in strict mode without flags - - Object literal enhancements have moved out of staging; shorthand method and property syntax is now usable (`{ method() { }, property }`) - - Rest parameters (`function(...args) {}`) are implemented in staging behind the `--harmony-rest-parameters` flag - - Computed property names (`{['foo'+'bar']:'bam'}`) are implemented in staging behind the `--harmony-computed-property-names` flag - - Unicode escapes (`'\u{xxxx}'`) are implemented in staging behind the `--harmony_unicode` flag and the `--harmony_unicode_regexps` flag for use in regular expressions - * **Windows**: - - Random process termination on Windows fixed (Fedor Indutny) [#1512](https://github.com/nodejs/node/issues/1512) / [#1563](https://github.com/nodejs/node/pull/1563) - - The delay-load hook introduced to fix issues with process naming (iojs.exe / node.exe) has been made opt-out for native add-ons. Native add-ons should include `'win_delay_load_hook': 'false'` in their binding.gyp to disable this feature if they experience problems . (Bert Belder) [#1433](https://github.com/nodejs/node/pull/1433) - * **Governance**: - - Rod Vagg (@rvagg) was added to the Technical Committee (TC) - - Jeremiah Senkpiel (@Fishrock123) was added to the Technical Committee (TC) - - ### Known issues - - See https://github.com/nodejs/node/labels/confirmed-bug for complete and current list of known issues. - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) - - ### Commits - - * [[`5404cbc745`](https://github.com/nodejs/node/commit/5404cbc745)] - **buffer**: fix copy() segfault with zero arguments (Trevor Norris) [#1520](https://github.com/nodejs/node/pull/1520) - * [[`3d3083b91f`](https://github.com/nodejs/node/commit/3d3083b91f)] - **buffer**: little improve for Buffer.concat method (Jackson Tian) [#1437](https://github.com/nodejs/node/pull/1437) - * [[`e67542ae17`](https://github.com/nodejs/node/commit/e67542ae17)] - **build**: disable -Og when building with clang (Ben Noordhuis) [#1609](https://github.com/nodejs/node/pull/1609) - * [[`78f4b038f8`](https://github.com/nodejs/node/commit/78f4b038f8)] - **build**: turn on debug-safe optimizations with -Og (Ben Noordhuis) [#1569](https://github.com/nodejs/node/pull/1569) - * [[`a5dcff827a`](https://github.com/nodejs/node/commit/a5dcff827a)] - **build**: Use option groups in configure output (Johan Bergström) [#1533](https://github.com/nodejs/node/pull/1533) - * [[`2a3c8c187e`](https://github.com/nodejs/node/commit/2a3c8c187e)] - **build**: remove -J from test-ci (Rod Vagg) [#1544](https://github.com/nodejs/node/pull/1544) - * [[`e6874dd0f9`](https://github.com/nodejs/node/commit/e6874dd0f9)] - **crypto**: track external memory for SSL structures (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) - * [[`935c9d3fa7`](https://github.com/nodejs/node/commit/935c9d3fa7)] - **deps**: make node-gyp work with io.js (cjihrig) [#990](https://github.com/nodejs/node/pull/990) - * [[`56e4255382`](https://github.com/nodejs/node/commit/56e4255382)] - **deps**: upgrade npm to 2.9.0 (Forrest L Norvell) [#1573](https://github.com/nodejs/node/pull/1573) - * [[`509b59ea7c`](https://github.com/nodejs/node/commit/509b59ea7c)] - **deps**: enable v8 postmortem debugging again (Ben Noordhuis) [#1232](https://github.com/nodejs/node/pull/1232) - * [[`01652c7709`](https://github.com/nodejs/node/commit/01652c7709)] - **deps**: upgrade v8 to 4.2.77.18 (Chris Dickinson) [#1506](https://github.com/nodejs/node/pull/1506) - * [[`01e6632d70`](https://github.com/nodejs/node/commit/01e6632d70)] - **deps**: upgrade v8 to 4.2.77.15 (Ben Noordhuis) [#1399](https://github.com/nodejs/node/pull/1399) - * [[`db4ded5903`](https://github.com/nodejs/node/commit/db4ded5903)] - **deps**: enable v8 postmortem debugging again (Ben Noordhuis) [#1232](https://github.com/nodejs/node/pull/1232) - * [[`36cd5fb9d2`](https://github.com/nodejs/node/commit/36cd5fb9d2)] - **(SEMVER-MAJOR)** **deps**: upgrade v8 to 4.2.77.13 (Ben Noordhuis) [#1232](https://github.com/nodejs/node/pull/1232) - * [[`b3a7da1091`](https://github.com/nodejs/node/commit/b3a7da1091)] - **deps**: update http_parser to 2.5.0 (Fedor Indutny) [#1517](https://github.com/nodejs/node/pull/1517) - * [[`ac1fb39ce8`](https://github.com/nodejs/node/commit/ac1fb39ce8)] - **doc**: add rvagg to the TC (Rod Vagg) [#1613](https://github.com/nodejs/node/pull/1613) - * [[`dacc1fa35c`](https://github.com/nodejs/node/commit/dacc1fa35c)] - **doc**: update AUTHORS list (Rod Vagg) [#1586](https://github.com/nodejs/node/pull/1586) - * [[`2a3a1909ab`](https://github.com/nodejs/node/commit/2a3a1909ab)] - **doc**: add require() lines to child.stdio example (Nick Raienko) [#1504](https://github.com/nodejs/node/pull/1504) - * [[`02388dbf40`](https://github.com/nodejs/node/commit/02388dbf40)] - **doc**: fix some cross-references (Alexander Gromnitsky) [#1584](https://github.com/nodejs/node/pull/1584) - * [[`57c4cc26e2`](https://github.com/nodejs/node/commit/57c4cc26e2)] - **doc**: add TC meeting 2015-04-22 minutes (Rod Vagg) [#1556](https://github.com/nodejs/node/pull/1556) - * [[`b4ad5d7050`](https://github.com/nodejs/node/commit/b4ad5d7050)] - **doc**: improve http.request and https.request opts (Roman Reiss) [#1551](https://github.com/nodejs/node/pull/1551) - * [[`7dc8eec0a6`](https://github.com/nodejs/node/commit/7dc8eec0a6)] - **doc**: deprecate smalloc module (Ben Noordhuis) [#1566](https://github.com/nodejs/node/pull/1566) - * [[`1bcdf46ca7`](https://github.com/nodejs/node/commit/1bcdf46ca7)] - **doc**: add TC meeting 2015-04-15 minutes (Rod Vagg) [#1498](https://github.com/nodejs/node/pull/1498) - * [[`391cae3595`](https://github.com/nodejs/node/commit/391cae3595)] - **doc**: Add Known issues to v1.7.0/1.7.1 CHANGELOG (Yosuke Furukawa) [#1473](https://github.com/nodejs/node/pull/1473) - * [[`e55fdc47a7`](https://github.com/nodejs/node/commit/e55fdc47a7)] - **doc**: fix util.deprecate example (Nick Raienko) [#1535](https://github.com/nodejs/node/pull/1535) - * [[`5178f93bc0`](https://github.com/nodejs/node/commit/5178f93bc0)] - **doc**: Add Addon API (NAN) to working group list (Julian Duque) [#1523](https://github.com/nodejs/node/pull/1523) - * [[`f3cc50f811`](https://github.com/nodejs/node/commit/f3cc50f811)] - **doc**: add TC meeting 2015-04-08 minutes (Rod Vagg) [#1497](https://github.com/nodejs/node/pull/1497) - * [[`bb254b533b`](https://github.com/nodejs/node/commit/bb254b533b)] - **doc**: update branch to master (Roman Reiss) [#1511](https://github.com/nodejs/node/pull/1511) - * [[`22aafa5597`](https://github.com/nodejs/node/commit/22aafa5597)] - **doc**: add Fishrock123 to the TC (Jeremiah Senkpiel) [#1507](https://github.com/nodejs/node/pull/1507) - * [[`b16a328ede`](https://github.com/nodejs/node/commit/b16a328ede)] - **doc**: add spaces to child.kill example (Nick Raienko) [#1503](https://github.com/nodejs/node/pull/1503) - * [[`26327757f8`](https://github.com/nodejs/node/commit/26327757f8)] - **doc**: update AUTHORS list (Rod Vagg) [#1476](https://github.com/nodejs/node/pull/1476) - * [[`f9c681cf62`](https://github.com/nodejs/node/commit/f9c681cf62)] - **fs**: validate fd on fs.write (Julian Duque) [#1553](https://github.com/nodejs/node/pull/1553) - * [[`801b47acc5`](https://github.com/nodejs/node/commit/801b47acc5)] - **gitignore**: ignore xcode workspaces and projects (Roman Klauke) [#1562](https://github.com/nodejs/node/pull/1562) - * [[`d5ce47e433`](https://github.com/nodejs/node/commit/d5ce47e433)] - **(SEMVER-MINOR)** **lib**: deprecate the smalloc module (Ben Noordhuis) [#1564](https://github.com/nodejs/node/pull/1564) - * [[`7384ca83f9`](https://github.com/nodejs/node/commit/7384ca83f9)] - **module**: remove '' from Module.globalPaths (Chris Yip) [#1488](https://github.com/nodejs/node/pull/1488) - * [[`b4f5898395`](https://github.com/nodejs/node/commit/b4f5898395)] - **net**: ensure Write/ShutdownWrap references handle (Fedor Indutny) [#1590](https://github.com/nodejs/node/pull/1590) - * [[`4abe2fa1cf`](https://github.com/nodejs/node/commit/4abe2fa1cf)] - **(SEMVER-MINOR)** **net**: add lookup option to Socket.prototype.connect (Evan Lucas) [#1505](https://github.com/nodejs/node/pull/1505) - * [[`1bef717476`](https://github.com/nodejs/node/commit/1bef717476)] - **(SEMVER-MINOR)** **net**: cleanup connect logic (Evan Lucas) [#1505](https://github.com/nodejs/node/pull/1505) - * [[`c7782c0af8`](https://github.com/nodejs/node/commit/c7782c0af8)] - **node**: improve nextTick performance (Brian White) [#1571](https://github.com/nodejs/node/pull/1571) - * [[`b57cc51d8d`](https://github.com/nodejs/node/commit/b57cc51d8d)] - **(SEMVER-MAJOR)** **os**: remove trailing slash from os.tmpdir() (Christian Tellnes) [#747](https://github.com/nodejs/node/pull/747) - * [[`ca219b00d1`](https://github.com/nodejs/node/commit/ca219b00d1)] - **repl**: fix for a+ fd clearing the file on read (Chris Dickinson) [#1605](https://github.com/nodejs/node/pull/1605) - * [[`051d482b15`](https://github.com/nodejs/node/commit/051d482b15)] - **repl**: fix \_debugger by properly proxying repl (Chris Dickinson) [#1605](https://github.com/nodejs/node/pull/1605) - * [[`2e2fce0502`](https://github.com/nodejs/node/commit/2e2fce0502)] - **repl**: fix persistent history and env variable name (Roman Reiss) [#1593](https://github.com/nodejs/node/pull/1593) - * [[`ea5195ccaf`](https://github.com/nodejs/node/commit/ea5195ccaf)] - **repl**: do not save history for non-terminal repl (Fedor Indutny) [#1575](https://github.com/nodejs/node/pull/1575) - * [[`0450ce7db2`](https://github.com/nodejs/node/commit/0450ce7db2)] - **repl**: add mode detection, cli persistent history (Chris Dickinson) [#1513](https://github.com/nodejs/node/pull/1513) - * [[`af9fe3bbc7`](https://github.com/nodejs/node/commit/af9fe3bbc7)] - **(SEMVER-MAJOR)** **src**: bump NODE_MODULE_VERSION due to V8 API (Rod Vagg) [#1532](https://github.com/nodejs/node/pull/1532) - * [[`279f6116aa`](https://github.com/nodejs/node/commit/279f6116aa)] - **src**: fix -Wmissing-field-initializers warning (Ben Noordhuis) [#1606](https://github.com/nodejs/node/pull/1606) - * [[`73062521a4`](https://github.com/nodejs/node/commit/73062521a4)] - **src**: deprecate smalloc public functions (Ben Noordhuis) [#1565](https://github.com/nodejs/node/pull/1565) - * [[`ccb199af17`](https://github.com/nodejs/node/commit/ccb199af17)] - **src**: fix deprecation warnings (Ben Noordhuis) [#1565](https://github.com/nodejs/node/pull/1565) - * [[`609fa0de03`](https://github.com/nodejs/node/commit/609fa0de03)] - **src**: fix NODE_DEPRECATED macro (Ben Noordhuis) [#1565](https://github.com/nodejs/node/pull/1565) - * [[`3c92ca2b5c`](https://github.com/nodejs/node/commit/3c92ca2b5c)] - **(SEMVER-MINOR)** **src**: add ability to get/set effective uid/gid (Evan Lucas) [#1536](https://github.com/nodejs/node/pull/1536) - * [[`30b7349176`](https://github.com/nodejs/node/commit/30b7349176)] - **stream_base**: dispatch reqs in the stream impl (Fedor Indutny) [#1563](https://github.com/nodejs/node/pull/1563) - * [[`0fa6c4a6fc`](https://github.com/nodejs/node/commit/0fa6c4a6fc)] - **string_decoder**: don't cache Buffer.isEncoding (Brian White) [#1548](https://github.com/nodejs/node/pull/1548) - * [[`f9b226c1c1`](https://github.com/nodejs/node/commit/f9b226c1c1)] - **test**: extend timeouts for ARMv6 (Rod Vagg) [#1554](https://github.com/nodejs/node/pull/1554) - * [[`bfae8236b1`](https://github.com/nodejs/node/commit/bfae8236b1)] - **test**: fix test-net-dns-custom-lookup test assertion (Evan Lucas) [#1531](https://github.com/nodejs/node/pull/1531) - * [[`547213913b`](https://github.com/nodejs/node/commit/547213913b)] - **test**: adjust Makefile/test-ci, add to vcbuild.bat (Rod Vagg) [#1530](https://github.com/nodejs/node/pull/1530) - * [[`550c2638c0`](https://github.com/nodejs/node/commit/550c2638c0)] - **tls**: use `SSL_set_cert_cb` for async SNI/OCSP (Fedor Indutny) [#1464](https://github.com/nodejs/node/pull/1464) - * [[`1787416376`](https://github.com/nodejs/node/commit/1787416376)] - **tls**: destroy singleUse context immediately (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) - * [[`2684c902c4`](https://github.com/nodejs/node/commit/2684c902c4)] - **tls**: zero SSL_CTX freelist for a singleUse socket (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) - * [[`2d241b3b82`](https://github.com/nodejs/node/commit/2d241b3b82)] - **tls**: destroy SSL once it is out of use (Fedor Indutny) [#1529](https://github.com/nodejs/node/pull/1529) - * [[`f7620fb96d`](https://github.com/nodejs/node/commit/f7620fb96d)] - **tls_wrap**: Unlink TLSWrap and SecureContext objects (Сковорода Никита Андреевич) [#1580](https://github.com/nodejs/node/pull/1580) - * [[`a7d74633f2`](https://github.com/nodejs/node/commit/a7d74633f2)] - **tls_wrap**: use localhost if options.host is empty (Guilherme Souza) [#1493](https://github.com/nodejs/node/pull/1493) - * [[`702997c1f0`](https://github.com/nodejs/node/commit/702997c1f0)] - ***Revert*** "**url**: significantly improve the performance of the url module" (Rod Vagg) [#1602](https://github.com/nodejs/node/pull/1602) - * [[`0daed24883`](https://github.com/nodejs/node/commit/0daed24883)] - ***Revert*** "**url**: delete href cache on all setter code paths" (Rod Vagg) [#1602](https://github.com/nodejs/node/pull/1602) - * [[`0f39ef4ca1`](https://github.com/nodejs/node/commit/0f39ef4ca1)] - ***Revert*** "**url**: fix treatment of some values as non-empty" (Rod Vagg) [#1602](https://github.com/nodejs/node/pull/1602) - * [[`66877216bd`](https://github.com/nodejs/node/commit/66877216bd)] - **url**: fix treatment of some values as non-empty (Petka Antonov) [#1589](https://github.com/nodejs/node/pull/1589) - * [[`dbdd81a91b`](https://github.com/nodejs/node/commit/dbdd81a91b)] - **url**: delete href cache on all setter code paths (Petka Antonov) [#1589](https://github.com/nodejs/node/pull/1589) - * [[`3fd7fc429c`](https://github.com/nodejs/node/commit/3fd7fc429c)] - **url**: significantly improve the performance of the url module (Petka Antonov) [#1561](https://github.com/nodejs/node/pull/1561) - * [[`bf7ac08dd0`](https://github.com/nodejs/node/commit/bf7ac08dd0)] - **util**: add Map and Set inspection support (Christopher Monsanto) [#1471](https://github.com/nodejs/node/pull/1471) - * [[`30e83d2e84`](https://github.com/nodejs/node/commit/30e83d2e84)] - **win,node-gyp**: optionally allow node.exe/iojs.exe to be renamed (Bert Belder) [#1266](https://github.com/nodejs/node/pull/1266) - * [[`3bda6cbfa4`](https://github.com/nodejs/node/commit/3bda6cbfa4)] - **(SEMVER-MAJOR)** **win,node-gyp**: enable delay-load hook by default (Bert Belder) [#1433](https://github.com/nodejs/node/pull/1433) - - - - ## 2015-04-20, Version 1.8.1, @chrisdickinson - - ### Notable changes - - * **NOTICE**: Skipped v1.8.0 due to problems with release tooling. - See [#1436](https://github.com/nodejs/node/issues/1436) for details. - * **build**: Support for building io.js as a static library (Marat Abdullin) [#1341](https://github.com/nodejs/node/pull/1341) - * **deps**: Upgrade openssl to 1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * Users should see performance improvements when using the crypto API. - See [here](https://github.com/nodejs/node/wiki/Crypto-Performance-Notes-for-OpenSSL-1.0.2a-on-iojs-v1.8.0) - for details. - * **npm**: Upgrade npm to 2.8.3. See the [release notes](https://github.com/npm/npm/releases/tag/v2.8.3) for details. Includes improved git support. Summary: - * [`387f889`](https://github.com/npm/npm/commit/387f889c0e8fb617d9cc9a42ed0a3ec49424ab5d) - [#7961](https://github.com/npm/npm/issues/7961) Ensure that hosted git SSH - URLs always have a valid protocol when stored in `resolved` fields in - `npm-shrinkwrap.json`. ([@othiym23](https://github.com/othiym23)) - * [`394c2f5`](https://github.com/npm/npm/commit/394c2f5a1227232c0baf42fbba1402aafe0d6ffb) - Switch the order in which hosted Git providers are checked to `git:`, - `git+https:`, then `git+ssh:` (from `git:`, `git+ssh:`, then `git+https:`) in - an effort to go from most to least likely to succeed, to make for less - confusing error message. ([@othiym23](https://github.com/othiym23)) - * [`431c3bf`](https://github.com/npm/npm/commit/431c3bf6cdec50f9f0c735f478cb2f3f337d3313) - [#7699](https://github.com/npm/npm/issues/7699) `npm-registry-client@6.3.2`: - Don't send body with HTTP GET requests when logging in. - ([@smikes](https://github.com/smikes)) - * [`15efe12`](https://github.com/npm/npm/commit/15efe124753257728a0ddc64074fa5a4b9c2eb30) - [#7872](https://github.com/npm/npm/issues/7872) Use the new version of - `hosted-git-info` to pass along credentials embedded in git URLs. Test it. - Test it a lot. ([@othiym23](https://github.com/othiym23)) - * [`b027319`](https://github.com/npm/npm/commit/b0273190c71eba14395ddfdd1d9f7ba625297523) - [#7920](https://github.com/npm/npm/issues/7920) Scoped packages with - `peerDependencies` were installing the `peerDependencies` into the wrong - directory. ([@ewie](https://github.com/ewie)) - * [`6b0f588`](https://github.com/npm/npm/commit/6b0f58877f37df9904490ffbaaad33862bd36dce) - [#7867](https://github.com/npm/npm/issues/7867) Use git shorthand and git - URLs as presented by user. Support new `hosted-git-info` shortcut syntax. - Save shorthand in `package.json`. Try cloning via `git:`, `git+ssh:`, and - `git+https:`, in that order, when supported by the underlying hosting - provider. ([@othiym23](https://github.com/othiym23)) - * **src**: Allow multiple arguments to be passed to process.nextTick (Trevor Norris) [#1077](https://github.com/nodejs/node/pull/1077) - * **module**: The interaction of `require('.')` with `NODE_PATH` has been restored and deprecated. This functionality - will be removed at a later point. (Roman Reiss) [#1363](https://github.com/nodejs/node/pull/1363) - - ### Known issues - - * Some problems with unreferenced timers running during `beforeExit` are still to be resolved. See [#1264](https://github.com/nodejs/node/issues/1264). - * Surrogate pair in REPL can freeze terminal [#690](https://github.com/nodejs/node/issues/690) - * `process.send()` is not synchronous as the docs suggest, a regression introduced in 1.0.2, see [#760](https://github.com/nodejs/node/issues/760) and fix in [#774](https://github.com/nodejs/node/issues/774) - * Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion [#894](https://github.com/nodejs/node/issues/894) - * `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). - * readline: split escapes are processed incorrectly, see [#1403](https://github.com/nodejs/node/issues/1403) - - ### Commits - - * [[`53ed89d927`](https://github.com/nodejs/node/commit/53ed89d927)] - ***Revert*** "**build**: use %PYTHON% instead of python" (Rod Vagg) [#1475](https://github.com/nodejs/node/pull/1475) - * [[`2b744b0ab7`](https://github.com/nodejs/node/commit/2b744b0ab7)] - **src**: revert NODE_MODULE_VERSION to 43 (Chris Dickinson) [#1460](https://github.com/nodejs/node/pull/1460) - * [[`431673ebd1`](https://github.com/nodejs/node/commit/431673ebd1)] - **buffer**: fast-case for empty string in byteLength (Jackson Tian) [#1441](https://github.com/nodejs/node/pull/1441) - * [[`1b22bad35f`](https://github.com/nodejs/node/commit/1b22bad35f)] - **build**: fix logic for shared library flags (Jeremiah Senkpiel) [#1454](https://github.com/nodejs/node/pull/1454) - * [[`91943a99d5`](https://github.com/nodejs/node/commit/91943a99d5)] - **build**: use %PYTHON% instead of python (Rod Vagg) [#1444](https://github.com/nodejs/node/pull/1444) - * [[`c7769d417b`](https://github.com/nodejs/node/commit/c7769d417b)] - **build**: Expose xz compression level (Johan Bergström) [#1428](https://github.com/nodejs/node/pull/1428) - * [[`a530b2baf1`](https://github.com/nodejs/node/commit/a530b2baf1)] - **build**: fix error message in configure (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`92dfb794f9`](https://github.com/nodejs/node/commit/92dfb794f9)] - **build**: enable ssl support on arm64 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`7de0dcde83`](https://github.com/nodejs/node/commit/7de0dcde83)] - **deps**: make node-gyp work with io.js (cjihrig) [#990](https://github.com/nodejs/node/pull/990) - * [[`4870213f9e`](https://github.com/nodejs/node/commit/4870213f9e)] - **deps**: upgrade npm to 2.8.3 (Forrest L Norvell) - * [[`49bb7ded2c`](https://github.com/nodejs/node/commit/49bb7ded2c)] - **deps**: fix git case sensitivity issue in npm (Chris Dickinson) [#1456](https://github.com/nodejs/node/pull/1456) - * [[`4830b4bce8`](https://github.com/nodejs/node/commit/4830b4bce8)] - **deps**: add docs to upgrade openssl (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`11bec72c87`](https://github.com/nodejs/node/commit/11bec72c87)] - **deps**: update asm files for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`53924d8ebe`](https://github.com/nodejs/node/commit/53924d8ebe)] - **deps**: update asm Makefile for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`418e839456`](https://github.com/nodejs/node/commit/418e839456)] - **deps**: update openssl.gyp/gypi for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`02f12ab666`](https://github.com/nodejs/node/commit/02f12ab666)] - **deps**: update opensslconf.h for 1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`eb7a23595f`](https://github.com/nodejs/node/commit/eb7a23595f)] - **deps**: add x32 and arm64 support for opensslconf.h (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`033a663127`](https://github.com/nodejs/node/commit/033a663127)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`ae8831f240`](https://github.com/nodejs/node/commit/ae8831f240)] - **deps**: backport openssl patch of alt cert chains 1 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`71316c46d9`](https://github.com/nodejs/node/commit/71316c46d9)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`d293a4f096`](https://github.com/nodejs/node/commit/d293a4f096)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`e4872d7405`](https://github.com/nodejs/node/commit/e4872d7405)] - **deps**: upgrade openssl to 1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`a1c9ef3142`](https://github.com/nodejs/node/commit/a1c9ef3142)] - **deps, build**: add support older assembler (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`76f219c128`](https://github.com/nodejs/node/commit/76f219c128)] - **doc**: Document forced pushing with git (Johan Bergström) [#1420](https://github.com/nodejs/node/pull/1420) - * [[`12e51d56c1`](https://github.com/nodejs/node/commit/12e51d56c1)] - **doc**: add Addon API WG (Rod Vagg) [#1226](https://github.com/nodejs/node/pull/1226) - * [[`7956a13dad`](https://github.com/nodejs/node/commit/7956a13dad)] - **http**: logically respect maxSockets (fengmk2) [#1242](https://github.com/nodejs/node/pull/1242) - * [[`5b844e140b`](https://github.com/nodejs/node/commit/5b844e140b)] - **module**: fix style (Roman Reiss) [#1453](https://github.com/nodejs/node/pull/1453) - * [[`3ad82c335d`](https://github.com/nodejs/node/commit/3ad82c335d)] - **(SEMVER-MINOR)** **module**: handle NODE_PATH in require('.') (Roman Reiss) [#1363](https://github.com/nodejs/node/pull/1363) - * [[`cd60ff0328`](https://github.com/nodejs/node/commit/cd60ff0328)] - **net**: add fd into listen2 debug info (Jackson Tian) [#1442](https://github.com/nodejs/node/pull/1442) - * [[`10e31ba56c`](https://github.com/nodejs/node/commit/10e31ba56c)] - **(SEMVER-MINOR)** **node**: allow multiple arguments passed to nextTick (Trevor Norris) [#1077](https://github.com/nodejs/node/pull/1077) - * [[`116c54692a`](https://github.com/nodejs/node/commit/116c54692a)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`62f5f4cec9`](https://github.com/nodejs/node/commit/62f5f4cec9)] - **src**: remove duplicate byteLength from Buffer (Jackson Tian) [#1438](https://github.com/nodejs/node/pull/1438) - * [[`51d0808c90`](https://github.com/nodejs/node/commit/51d0808c90)] - **stream**: remove duplicated expression (Yazhong Liu) [#1444](https://github.com/nodejs/node/pull/1444) - * [[`deb9d23d7b`](https://github.com/nodejs/node/commit/deb9d23d7b)] - **test**: fix error message check for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) - * [[`ca8c9ec2c8`](https://github.com/nodejs/node/commit/ca8c9ec2c8)] - **win,node-gyp**: optionally allow node.exe/iojs.exe to be renamed (Bert Belder) [#1266](https://github.com/nodejs/node/pull/1266) +* [[`53ed89d927`](https://github.com/nodejs/node/commit/53ed89d927)] - ***Revert*** "**build**: use %PYTHON% instead of python" (Rod Vagg) [#1475](https://github.com/nodejs/node/pull/1475) +* [[`2b744b0ab7`](https://github.com/nodejs/node/commit/2b744b0ab7)] - **src**: revert NODE_MODULE_VERSION to 43 (Chris Dickinson) [#1460](https://github.com/nodejs/node/pull/1460) +* [[`431673ebd1`](https://github.com/nodejs/node/commit/431673ebd1)] - **buffer**: fast-case for empty string in byteLength (Jackson Tian) [#1441](https://github.com/nodejs/node/pull/1441) +* [[`1b22bad35f`](https://github.com/nodejs/node/commit/1b22bad35f)] - **build**: fix logic for shared library flags (Jeremiah Senkpiel) [#1454](https://github.com/nodejs/node/pull/1454) +* [[`91943a99d5`](https://github.com/nodejs/node/commit/91943a99d5)] - **build**: use %PYTHON% instead of python (Rod Vagg) [#1444](https://github.com/nodejs/node/pull/1444) +* [[`c7769d417b`](https://github.com/nodejs/node/commit/c7769d417b)] - **build**: Expose xz compression level (Johan Bergström) [#1428](https://github.com/nodejs/node/pull/1428) +* [[`a530b2baf1`](https://github.com/nodejs/node/commit/a530b2baf1)] - **build**: fix error message in configure (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`92dfb794f9`](https://github.com/nodejs/node/commit/92dfb794f9)] - **build**: enable ssl support on arm64 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`7de0dcde83`](https://github.com/nodejs/node/commit/7de0dcde83)] - **deps**: make node-gyp work with io.js (cjihrig) [#990](https://github.com/nodejs/node/pull/990) +* [[`4870213f9e`](https://github.com/nodejs/node/commit/4870213f9e)] - **deps**: upgrade npm to 2.8.3 (Forrest L Norvell) +* [[`49bb7ded2c`](https://github.com/nodejs/node/commit/49bb7ded2c)] - **deps**: fix git case sensitivity issue in npm (Chris Dickinson) [#1456](https://github.com/nodejs/node/pull/1456) +* [[`4830b4bce8`](https://github.com/nodejs/node/commit/4830b4bce8)] - **deps**: add docs to upgrade openssl (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`11bec72c87`](https://github.com/nodejs/node/commit/11bec72c87)] - **deps**: update asm files for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`53924d8ebe`](https://github.com/nodejs/node/commit/53924d8ebe)] - **deps**: update asm Makefile for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`418e839456`](https://github.com/nodejs/node/commit/418e839456)] - **deps**: update openssl.gyp/gypi for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`02f12ab666`](https://github.com/nodejs/node/commit/02f12ab666)] - **deps**: update opensslconf.h for 1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`eb7a23595f`](https://github.com/nodejs/node/commit/eb7a23595f)] - **deps**: add x32 and arm64 support for opensslconf.h (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`033a663127`](https://github.com/nodejs/node/commit/033a663127)] - **deps**: replace all headers in openssl (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`ae8831f240`](https://github.com/nodejs/node/commit/ae8831f240)] - **deps**: backport openssl patch of alt cert chains 1 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`71316c46d9`](https://github.com/nodejs/node/commit/71316c46d9)] - **deps**: fix asm build error of openssl in x86_win32 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`d293a4f096`](https://github.com/nodejs/node/commit/d293a4f096)] - **deps**: fix openssl assembly error on ia32 win32 (Fedor Indutny) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`e4872d7405`](https://github.com/nodejs/node/commit/e4872d7405)] - **deps**: upgrade openssl to 1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`a1c9ef3142`](https://github.com/nodejs/node/commit/a1c9ef3142)] - **deps, build**: add support older assembler (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`76f219c128`](https://github.com/nodejs/node/commit/76f219c128)] - **doc**: Document forced pushing with git (Johan Bergström) [#1420](https://github.com/nodejs/node/pull/1420) +* [[`12e51d56c1`](https://github.com/nodejs/node/commit/12e51d56c1)] - **doc**: add Addon API WG (Rod Vagg) [#1226](https://github.com/nodejs/node/pull/1226) +* [[`7956a13dad`](https://github.com/nodejs/node/commit/7956a13dad)] - **http**: logically respect maxSockets (fengmk2) [#1242](https://github.com/nodejs/node/pull/1242) +* [[`5b844e140b`](https://github.com/nodejs/node/commit/5b844e140b)] - **module**: fix style (Roman Reiss) [#1453](https://github.com/nodejs/node/pull/1453) +* [[`3ad82c335d`](https://github.com/nodejs/node/commit/3ad82c335d)] - **(SEMVER-MINOR)** **module**: handle NODE_PATH in require('.') (Roman Reiss) [#1363](https://github.com/nodejs/node/pull/1363) +* [[`cd60ff0328`](https://github.com/nodejs/node/commit/cd60ff0328)] - **net**: add fd into listen2 debug info (Jackson Tian) [#1442](https://github.com/nodejs/node/pull/1442) +* [[`10e31ba56c`](https://github.com/nodejs/node/commit/10e31ba56c)] - **(SEMVER-MINOR)** **node**: allow multiple arguments passed to nextTick (Trevor Norris) [#1077](https://github.com/nodejs/node/pull/1077) +* [[`116c54692a`](https://github.com/nodejs/node/commit/116c54692a)] - **openssl**: fix keypress requirement in apps on win32 (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`62f5f4cec9`](https://github.com/nodejs/node/commit/62f5f4cec9)] - **src**: remove duplicate byteLength from Buffer (Jackson Tian) [#1438](https://github.com/nodejs/node/pull/1438) +* [[`51d0808c90`](https://github.com/nodejs/node/commit/51d0808c90)] - **stream**: remove duplicated expression (Yazhong Liu) [#1444](https://github.com/nodejs/node/pull/1444) +* [[`deb9d23d7b`](https://github.com/nodejs/node/commit/deb9d23d7b)] - **test**: fix error message check for openssl-1.0.2a (Shigeki Ohtsu) [#1389](https://github.com/nodejs/node/pull/1389) +* [[`ca8c9ec2c8`](https://github.com/nodejs/node/commit/ca8c9ec2c8)] - **win,node-gyp**: optionally allow node.exe/iojs.exe to be renamed (Bert Belder) [#1266](https://github.com/nodejs/node/pull/1266) ## 2015-04-14, Version 1.7.1, @rvagg From df35ae62466e9072a78bbed3672365516d024985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BA=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=90=D0=BD=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Thu, 4 Aug 2016 06:15:52 +0300 Subject: [PATCH 064/144] doc: fix minor formatting issue in 0.10 changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This splits one huge commit description into paragraphs, which supposedly was the intended behavior there. PR-URL: https://github.com/nodejs/node/pull/7727 Reviewed-By: Rich Trott Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- doc/changelogs/CHANGELOG_V010.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/changelogs/CHANGELOG_V010.md b/doc/changelogs/CHANGELOG_V010.md index 2921c625940940..a81d589d7c55ac 100644 --- a/doc/changelogs/CHANGELOG_V010.md +++ b/doc/changelogs/CHANGELOG_V010.md @@ -294,9 +294,11 @@ https://github.com/nodejs/node/commit/8d045a30e95602b443eb259a5021d33feb4df079 * child_process: properly support optional args (cjihrig) * crypto: Disable autonegotiation for SSLv2/3 by default (Fedor Indutny, Timothy J Fontaine, Alexis Campailla) + This is a behavior change, by default we will not allow the negotiation to SSLv2 or SSLv3. If you want this behavior, run Node.js with either `--enable-ssl2` or `--enable-ssl3` respectively. + This does not change the behavior for users specifically requesting `SSLv2_method` or `SSLv3_method`. While this behavior is not advised, it is assumed you know what you're doing since you're specifically asking to use From 295d1ea016c4d66322a9c2fd6540fea3df19b8a6 Mon Sep 17 00:00:00 2001 From: vladimir Date: Tue, 12 Jul 2016 23:09:12 +0200 Subject: [PATCH 065/144] util: support classes in util.deprecate() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Classes cannot be instantiated without new, but util.deprecate() uses Function.prototype.apply(). This commit uses new.target to detect constructor calls, allowing classes to be deprecated. PR-URL: https://github.com/nodejs/node/pull/7690 Reviewed-By: Colin Ihrig Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- doc/api/util.md | 2 +- lib/internal/util.js | 9 +++++++ test/fixtures/deprecated-userland-class.js | 12 ++++++++++ test/fixtures/deprecated-userland-subclass.js | 19 +++++++++++++++ test/sequential/test-deprecation-flags.js | 24 ++++++++++++++++--- 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/deprecated-userland-class.js create mode 100644 test/fixtures/deprecated-userland-subclass.js diff --git a/doc/api/util.md b/doc/api/util.md index 34c68393332a5d..6f011929a239dc 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -46,7 +46,7 @@ environment variable. For example: `NODE_DEBUG=fs,net,tls`. ## util.deprecate(function, string) -The `util.deprecate()` method wraps the given `function` in such a way that +The `util.deprecate()` method wraps the given `function` or class in such a way that it is marked as deprecated. ```js diff --git a/lib/internal/util.js b/lib/internal/util.js index 6f2af0efb42af2..d231b41a2f1dc9 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -57,9 +57,18 @@ exports._deprecate = function(fn, msg) { var warned = false; function deprecated() { warned = exports.printDeprecationMessage(msg, warned, deprecated); + if (new.target) { + return Reflect.construct(fn, arguments, new.target); + } return fn.apply(this, arguments); } + // The wrapper will keep the same prototype as fn to maintain prototype chain + Object.setPrototypeOf(deprecated, fn); + if (fn.prototype) { + Object.setPrototypeOf(deprecated.prototype, fn.prototype); + } + return deprecated; }; diff --git a/test/fixtures/deprecated-userland-class.js b/test/fixtures/deprecated-userland-class.js new file mode 100644 index 00000000000000..867bbbf2aeea4f --- /dev/null +++ b/test/fixtures/deprecated-userland-class.js @@ -0,0 +1,12 @@ +const util = require('util'); +const assert = require('assert'); + +class deprecatedClass { +} + +const deprecated = util.deprecate(deprecatedClass, 'deprecatedClass is deprecated.'); + +const instance = new deprecated(); + +assert(instance instanceof deprecated); +assert(instance instanceof deprecatedClass); diff --git a/test/fixtures/deprecated-userland-subclass.js b/test/fixtures/deprecated-userland-subclass.js new file mode 100644 index 00000000000000..2df374ad7d1b8d --- /dev/null +++ b/test/fixtures/deprecated-userland-subclass.js @@ -0,0 +1,19 @@ +const util = require('util'); +const assert = require('assert'); + +class deprecatedClass { +} + +const deprecated = util.deprecate(deprecatedClass, 'deprecatedClass is deprecated.'); + +class subclass extends deprecated { + constructor() { + super(); + } +} + +const instance = new subclass(); + +assert(instance instanceof subclass); +assert(instance instanceof deprecated); +assert(instance instanceof deprecatedClass); diff --git a/test/sequential/test-deprecation-flags.js b/test/sequential/test-deprecation-flags.js index bbb5ecb7002ac2..e9f5ee673d23bd 100644 --- a/test/sequential/test-deprecation-flags.js +++ b/test/sequential/test-deprecation-flags.js @@ -5,8 +5,14 @@ const execFile = require('child_process').execFile; const depmod = require.resolve(common.fixturesDir + '/deprecated.js'); const node = process.execPath; -const depUserland = - require.resolve(common.fixturesDir + '/deprecated-userland-function.js'); +const depUserlandFunction = + require.resolve(common.fixturesDir + '/deprecated-userland-function.js'); + +const depUserlandClass = + require.resolve(common.fixturesDir + '/deprecated-userland-class.js'); + +const depUserlandSubClass = + require.resolve(common.fixturesDir + '/deprecated-userland-subclass.js'); const normal = [depmod]; const noDep = ['--no-deprecation', depmod]; @@ -39,10 +45,22 @@ execFile(node, traceDep, function(er, stdout, stderr) { console.log('trace ok'); }); -execFile(node, [depUserland], function(er, stdout, stderr) { +execFile(node, [depUserlandFunction], function(er, stdout, stderr) { console.error('normal: testing deprecated userland function'); assert.equal(er, null); assert.equal(stdout, ''); assert(/deprecatedFunction is deprecated/.test(stderr)); console.error('normal: ok'); }); + +execFile(node, [depUserlandClass], function(er, stdout, stderr) { + assert.strictEqual(er, null); + assert.strictEqual(stdout, ''); + assert(/deprecatedClass is deprecated/.test(stderr)); +}); + +execFile(node, [depUserlandSubClass], function(er, stdout, stderr) { + assert.strictEqual(er, null); + assert.strictEqual(stdout, ''); + assert(/deprecatedClass is deprecated/.test(stderr)); +}); From 27f92efaeecda28e762ab57bc5fe966069cdb9dc Mon Sep 17 00:00:00 2001 From: yorkie Date: Tue, 2 Aug 2016 01:31:28 +0800 Subject: [PATCH 066/144] doctool: improve the title of pages in doc PR-URL: https://github.com/nodejs/node/pull/7939 Reviewed-By: James M Snell Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott Reviewed-By: Roman Reiss --- doc/template.html | 2 +- tools/doc/html.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/template.html b/doc/template.html index 71e3a21e1d4d5c..af680645d15080 100644 --- a/doc/template.html +++ b/doc/template.html @@ -2,7 +2,7 @@ - __SECTION__ Node.js __VERSION__ Manual & Documentation + __SECTION__ | Node.js __VERSION__ Documentation diff --git a/tools/doc/html.js b/tools/doc/html.js index 769d601e26c800..75d5f085311601 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -118,7 +118,7 @@ function render(opts, cb) { template = template.replace(/__ID__/g, id); template = template.replace(/__FILENAME__/g, filename); - template = template.replace(/__SECTION__/g, section); + template = template.replace(/__SECTION__/g, section || 'Index'); template = template.replace(/__VERSION__/g, nodeVersion); template = template.replace(/__TOC__/g, toc); template = template.replace( From 1ab796fa961e606567b501ee7b584faa52cd8959 Mon Sep 17 00:00:00 2001 From: Franziska Hinkelmann Date: Thu, 28 Jul 2016 11:52:16 +0200 Subject: [PATCH 067/144] src: do not copy on failing setProperty() In vm, the setter interceptor should not copy a value onto the sandbox, if setting it on the global object will fail. It will fail if we are in strict mode and set a value without declaring it. Fixes: https://github.com/nodejs/node/issues/5344 PR-URL: https://github.com/nodejs/node/pull/7908 Reviewed-By: Ali Ijaz Sheikh Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- src/node_contextify.cc | 14 +++++++++++++- test/parallel/test-vm-strict-mode.js | 27 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-vm-strict-mode.js diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 7ec03c10f7743a..95911be7e708e6 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -380,7 +380,19 @@ class ContextifyContext { if (ctx->context_.IsEmpty()) return; - ctx->sandbox()->Set(property, value); + bool is_declared = + ctx->global_proxy()->HasRealNamedProperty(ctx->context(), + property).FromJust(); + bool is_contextual_store = ctx->global_proxy() != args.This(); + + bool set_property_will_throw = + args.ShouldThrowOnError() && + !is_declared && + is_contextual_store; + + if (!set_property_will_throw) { + ctx->sandbox()->Set(property, value); + } } diff --git a/test/parallel/test-vm-strict-mode.js b/test/parallel/test-vm-strict-mode.js new file mode 100644 index 00000000000000..f3820d8aead6af --- /dev/null +++ b/test/parallel/test-vm-strict-mode.js @@ -0,0 +1,27 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const vm = require('vm'); +const ctx = vm.createContext(); + +// Test strict mode inside a vm script, i.e., using an undefined variable +// throws a ReferenceError. Also check that variables +// that are not successfully set in the vm, must not be set +// on the sandboxed context. + +vm.runInContext('w = 1;', ctx); +assert.strictEqual(1, ctx.w); + +assert.throws(function() { vm.runInContext('"use strict"; x = 1;', ctx); }, + /ReferenceError: x is not defined/); +assert.strictEqual(undefined, ctx.x); + +vm.runInContext('"use strict"; var y = 1;', ctx); +assert.strictEqual(1, ctx.y); + +vm.runInContext('"use strict"; this.z = 1;', ctx); +assert.strictEqual(1, ctx.z); + +// w has been defined +vm.runInContext('"use strict"; w = 2;', ctx); +assert.strictEqual(2, ctx.w); From c934f51aa46532ae9dddbcae448f061547a01fce Mon Sep 17 00:00:00 2001 From: hugnosis Date: Wed, 20 Jul 2016 15:45:43 +0900 Subject: [PATCH 068/144] doc: fix default encoding mention in crypto.md The default encoding for crypto methods was changed in v6.0.0 with v4.x keeping a default of binary. PR-URL: https://github.com/nodejs/node/pull/7805 Reviewed-By: Claudio Rodriguez Reviewed-By: James M Snell --- doc/api/crypto.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 1c4e825d4e29fb..2ee17ae0378a1d 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -913,7 +913,7 @@ recent OpenSSL releases, `openssl list-cipher-algorithms` will display the available cipher algorithms. The `key` is the raw key used by the `algorithm` and `iv` is an -[initialization vector][]. Both arguments must be `'latin1'` encoded strings or +[initialization vector][]. Both arguments must be `'utf8'` encoded strings or [buffers][`Buffer`]. ### crypto.createCredentials(details) @@ -968,7 +968,7 @@ recent OpenSSL releases, `openssl list-cipher-algorithms` will display the available cipher algorithms. The `key` is the raw key used by the `algorithm` and `iv` is an -[initialization vector][]. Both arguments must be `'latin1'` encoded strings or +[initialization vector][]. Both arguments must be `'utf8'` encoded strings or [buffers][`Buffer`]. ### crypto.createDiffieHellman(prime[, prime_encoding][, generator][, generator_encoding]) From e116cf96a0e3fb4ef61239ec4e50b05c9ea6c715 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 16 Jul 2016 00:35:38 +0200 Subject: [PATCH 069/144] doc: use blockquotes for Stability: markers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use blockquotes instead of code blocks for stability markers in the docs. Doing that: - Makes the makers appear correctly when viewed e.g. on github. - Allows remark-lint rules like `no-undefined-references` to work properly (https://github.com/nodejs/node/pull/7729). PR-URL: https://github.com/nodejs/node/pull/7757 Reviewed-By: James M Snell Reviewed-By: Сковорода Никита Андреевич Reviewed-By: Michaël Zasso Reviewed-By: Roman Reiss Conflicts: doc/api/punycode.md --- doc/api/assert.md | 2 +- doc/api/buffer.md | 24 ++++++++++----------- doc/api/child_process.md | 2 +- doc/api/cluster.md | 4 ++-- doc/api/console.md | 2 +- doc/api/crypto.md | 6 +++--- doc/api/debugger.md | 2 +- doc/api/dgram.md | 2 +- doc/api/dns.md | 2 +- doc/api/documentation.md | 2 +- doc/api/domain.md | 6 +++--- doc/api/events.md | 4 ++-- doc/api/fs.md | 8 +++---- doc/api/globals.md | 2 +- doc/api/http.md | 4 ++-- doc/api/https.md | 2 +- doc/api/modules.md | 2 +- doc/api/net.md | 4 ++-- doc/api/os.md | 2 +- doc/api/path.md | 2 +- doc/api/punycode.md | 7 ++++++- doc/api/querystring.md | 2 +- doc/api/readline.md | 2 +- doc/api/repl.md | 4 ++-- doc/api/stream.md | 2 +- doc/api/string_decoder.md | 2 +- doc/api/timers.md | 2 +- doc/api/tls.md | 8 +++---- doc/api/tty.md | 2 +- doc/api/url.md | 2 +- doc/api/util.md | 44 +++++++++++++++++++-------------------- doc/api/vm.md | 2 +- doc/api/zlib.md | 2 +- tools/doc/README.md | 2 +- tools/doc/html.js | 22 +++++++++++++++++--- tools/doc/json.js | 26 +++++++++++++++++------ 36 files changed, 125 insertions(+), 90 deletions(-) diff --git a/doc/api/assert.md b/doc/api/assert.md index d5fd7c26995781..f1f8238b0f96e7 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -1,6 +1,6 @@ # Assert - Stability: 3 - Locked +> Stability: 3 - Locked The `assert` module provides a simple set of assertion tests that can be used to test invariants. The module is intended for internal use by Node.js, but can be diff --git a/doc/api/buffer.md b/doc/api/buffer.md index ebce7fc4ba30c3..9533324c15f441 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -1,6 +1,6 @@ # Buffer - Stability: 2 - Stable +> Stability: 2 - Stable Prior to the introduction of [`TypedArray`] in ECMAScript 2015 (ES6), the JavaScript language had no mechanism for reading or manipulating streams @@ -300,7 +300,7 @@ It can be constructed in a variety of ways. deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use [`Buffer.from(array)`] instead. +> Stability: 0 - Deprecated: Use [`Buffer.from(array)`] instead. * `array` {Array} An array of bytes to copy from @@ -318,7 +318,7 @@ const buf = new Buffer([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]); deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use [`Buffer.from(buffer)`] instead. +> Stability: 0 - Deprecated: Use [`Buffer.from(buffer)`] instead. * `buffer` {Buffer} An existing `Buffer` to copy data from @@ -344,9 +344,9 @@ console.log(buf2.toString()); deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use - [`Buffer.from(arrayBuffer[, byteOffset [, length]])`][`Buffer.from(arrayBuffer)`] - instead. +> Stability: 0 - Deprecated: Use +> [`Buffer.from(arrayBuffer[, byteOffset [, length]])`][`Buffer.from(arrayBuffer)`] +> instead. * `arrayBuffer` {ArrayBuffer} The `.buffer` property of a [`TypedArray`] or [`ArrayBuffer`] @@ -387,8 +387,8 @@ console.log(buf); deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use [`Buffer.alloc()`] instead (also see - [`Buffer.allocUnsafe()`]). +> Stability: 0 - Deprecated: Use [`Buffer.alloc()`] instead (also see +> [`Buffer.allocUnsafe()`]). * `size` {Integer} The desired length of the new `Buffer` @@ -420,8 +420,8 @@ console.log(buf); deprecated: v6.0.0 --> - Stability: 0 - Deprecated: - Use [`Buffer.from(string[, encoding])`][`Buffer.from(string)`] instead. +> Stability: 0 - Deprecated: +> Use [`Buffer.from(string[, encoding])`][`Buffer.from(string)`] instead. * `string` {String} String to encode * `encoding` {String} The encoding of `string`. **Default:** `'utf8'` @@ -2309,7 +2309,7 @@ On 64-bit architectures, this value is `(2^31)-1` (~2GB). deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use [`Buffer.allocUnsafeSlow()`] instead. +> Stability: 0 - Deprecated: Use [`Buffer.allocUnsafeSlow()`] instead. Returns an un-pooled `Buffer`. @@ -2349,7 +2349,7 @@ has observed undue memory retention in their applications. deprecated: v6.0.0 --> - Stability: 0 - Deprecated: Use [`Buffer.allocUnsafeSlow()`] instead. +> Stability: 0 - Deprecated: Use [`Buffer.allocUnsafeSlow()`] instead. * `size` {Integer} The desired length of the new `SlowBuffer` diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 708511e0470016..ab140bc65fadf0 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -1,6 +1,6 @@ # Child Process - Stability: 2 - Stable +> Stability: 2 - Stable The `child_process` module provides the ability to spawn child processes in a manner that is similar, but not identical, to popen(3). This capability diff --git a/doc/api/cluster.md b/doc/api/cluster.md index 616be9b59afd14..a865ff4691ead8 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -1,6 +1,6 @@ # Cluster - Stability: 2 - Stable +> Stability: 2 - Stable A single instance of Node.js runs in a single thread. To take advantage of multi-core systems the user will sometimes want to launch a cluster of Node.js @@ -395,7 +395,7 @@ if (cluster.isMaster) { ### worker.suicide - Stability: 0 - Deprecated: Use [`worker.exitedAfterDisconnect`][] instead. +> Stability: 0 - Deprecated: Use [`worker.exitedAfterDisconnect`][] instead. An alias to [`worker.exitedAfterDisconnect`][]. diff --git a/doc/api/console.md b/doc/api/console.md index 70e325178abe74..74850c0c2e0c9f 100644 --- a/doc/api/console.md +++ b/doc/api/console.md @@ -1,6 +1,6 @@ # Console - Stability: 2 - Stable +> Stability: 2 - Stable The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 2ee17ae0378a1d..1d4b451be0d682 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1,6 +1,6 @@ # Crypto - Stability: 2 - Stable +> Stability: 2 - Stable The `crypto` module provides cryptographic functionality that includes a set of wrappers for OpenSSL's hash, HMAC, cipher, decipher, sign and verify functions. @@ -510,7 +510,7 @@ public point (key) is also generated and set in the ECDH object. ### ecdh.setPublicKey(public_key[, encoding]) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated Sets the EC Diffie-Hellman public key. Key encoding can be `'latin1'`, `'hex'` or `'base64'`. If `encoding` is provided `public_key` is expected to @@ -918,7 +918,7 @@ The `key` is the raw key used by the `algorithm` and `iv` is an ### crypto.createCredentials(details) - Stability: 0 - Deprecated: Use [`tls.createSecureContext()`][] instead. +> Stability: 0 - Deprecated: Use [`tls.createSecureContext()`][] instead. The `crypto.createCredentials()` method is a deprecated alias for creating and returning a `tls.SecureContext` object. The `crypto.createCredentials()` diff --git a/doc/api/debugger.md b/doc/api/debugger.md index d146292f2d704e..acffe65cbaac38 100644 --- a/doc/api/debugger.md +++ b/doc/api/debugger.md @@ -1,6 +1,6 @@ # Debugger - Stability: 2 - Stable +> Stability: 2 - Stable diff --git a/doc/api/dgram.md b/doc/api/dgram.md index 1a5cce0b91e150..91d6f749334219 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -1,6 +1,6 @@ # UDP / Datagram Sockets - Stability: 2 - Stable +> Stability: 2 - Stable diff --git a/doc/api/dns.md b/doc/api/dns.md index 7192be9a861999..775d288a54b9e3 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -1,6 +1,6 @@ # DNS - Stability: 2 - Stable +> Stability: 2 - Stable The `dns` module contains functions belonging to two different categories: diff --git a/doc/api/documentation.md b/doc/api/documentation.md index 1acb21a8969fa2..38ede72cf6c338 100644 --- a/doc/api/documentation.md +++ b/doc/api/documentation.md @@ -64,7 +64,7 @@ Please do not suggest API changes in this area; they will be refused. ## JSON Output - Stability: 1 - Experimental +> Stability: 1 - Experimental Every HTML file in the markdown has a corresponding JSON file with the same data. diff --git a/doc/api/domain.md b/doc/api/domain.md index c556e2533c0be3..2fe7e2c39af718 100644 --- a/doc/api/domain.md +++ b/doc/api/domain.md @@ -1,6 +1,6 @@ # Domain - Stability: 0 - Deprecated +> Stability: 0 - Deprecated **This module is pending deprecation**. Once a replacement API has been finalized, this module will be fully deprecated. Most end users should @@ -436,8 +436,8 @@ without exiting the domain. ### domain.dispose() - Stability: 0 - Deprecated. Please recover from failed IO actions - explicitly via error event handlers set on the domain. +> Stability: 0 - Deprecated. Please recover from failed IO actions +> explicitly via error event handlers set on the domain. Once `dispose` has been called, the domain will no longer be used by callbacks bound into the domain via `run`, `bind`, or `intercept`, and a `'dispose'` event diff --git a/doc/api/events.md b/doc/api/events.md index 0e2d49543954c7..32198fa5194f9c 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -1,6 +1,6 @@ # Events - Stability: 2 - Stable +> Stability: 2 - Stable @@ -222,7 +222,7 @@ The `'removeListener'` event is emitted *after* the `listener` is removed. ### EventEmitter.listenerCount(emitter, eventName) - Stability: 0 - Deprecated: Use [`emitter.listenerCount()`][] instead. +> Stability: 0 - Deprecated: Use [`emitter.listenerCount()`][] instead. A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`. diff --git a/doc/api/fs.md b/doc/api/fs.md index 0c84c44b58ee31..1984b5642e305b 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1,6 +1,6 @@ # File System - Stability: 2 - Stable +> Stability: 2 - Stable @@ -584,7 +584,7 @@ added: v0.0.2 deprecated: v1.0.0 --> - Stability: 0 - Deprecated: Use [`fs.stat()`][] or [`fs.access()`][] instead. +> Stability: 0 - Deprecated: Use [`fs.stat()`][] or [`fs.access()`][] instead. * `path` {String | Buffer} * `callback` {Function} @@ -610,8 +610,8 @@ added: v0.1.21 deprecated: v1.0.0 --> - Stability: 0 - Deprecated: Use [`fs.statSync()`][] or [`fs.accessSync()`][] - instead. +> Stability: 0 - Deprecated: Use [`fs.statSync()`][] or [`fs.accessSync()`][] +> instead. * `path` {String | Buffer} diff --git a/doc/api/globals.md b/doc/api/globals.md index 7db4fbe1aaae00..63fbf64f6e3d25 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -155,7 +155,7 @@ Error. ### require.extensions - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * {Object} diff --git a/doc/api/http.md b/doc/api/http.md index 606f79f39576de..8bd8da55701b16 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -1,6 +1,6 @@ # HTTP - Stability: 2 - Stable +> Stability: 2 - Stable To use the HTTP server and client one must `require('http')`. @@ -1331,7 +1331,7 @@ added: v0.1.13 deprecated: v0.3.6 --> - Stability: 0 - Deprecated: Use [`http.request()`][] instead. +> Stability: 0 - Deprecated: Use [`http.request()`][] instead. Constructs a new HTTP client. `port` and `host` refer to the server to be connected to. diff --git a/doc/api/https.md b/doc/api/https.md index af1516a494c966..bc0e4114c39761 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -1,6 +1,6 @@ # HTTPS - Stability: 2 - Stable +> Stability: 2 - Stable HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a separate module. diff --git a/doc/api/modules.md b/doc/api/modules.md index 7528e1004229e3..3cba97a9763eeb 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -1,6 +1,6 @@ # Modules - Stability: 3 - Locked +> Stability: 3 - Locked diff --git a/doc/api/net.md b/doc/api/net.md index e3160ff4616487..18090093ea038d 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -1,6 +1,6 @@ # net - Stability: 2 - Stable +> Stability: 2 - Stable The `net` module provides you with an asynchronous network wrapper. It contains functions for creating both servers and clients (called streams). You can include @@ -98,7 +98,7 @@ added: v0.2.0 deprecated: v0.9.7 --> - Stability: 0 - Deprecated: Use [`server.getConnections()`][] instead. +> Stability: 0 - Deprecated: Use [`server.getConnections()`][] instead. The number of concurrent connections on the server. diff --git a/doc/api/os.md b/doc/api/os.md index 8a9c00971a15a8..98390bb387c313 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -1,6 +1,6 @@ # OS - Stability: 2 - Stable +> Stability: 2 - Stable The `os` module provides a number of operating system-related utility methods. It can be accessed using: diff --git a/doc/api/path.md b/doc/api/path.md index d977173596b8de..6617f0e9e76b62 100644 --- a/doc/api/path.md +++ b/doc/api/path.md @@ -1,6 +1,6 @@ # Path - Stability: 2 - Stable +> Stability: 2 - Stable The `path` module provides utilities for working with file and directory paths. It can be accessed using: diff --git a/doc/api/punycode.md b/doc/api/punycode.md index d34b3fdf2a1fa2..18809370145abd 100644 --- a/doc/api/punycode.md +++ b/doc/api/punycode.md @@ -1,6 +1,11 @@ # punycode - Stability: 2 - Stable +> Stability: 0 - Deprecated + +**The version of the punycode module bundled in Node.js is being deprecated**. +In a future major version of Node.js this module will be removed. Users +currently depending on the `punycode` module should switch to using the +userland-provided [Punycode.js][] module instead. The `punycode` module is a bundled version of the [Punycode.js][] module. It can be accessed using: diff --git a/doc/api/querystring.md b/doc/api/querystring.md index 9b87e76f6499a1..1a3732445e27e5 100644 --- a/doc/api/querystring.md +++ b/doc/api/querystring.md @@ -1,6 +1,6 @@ # Query String - Stability: 2 - Stable +> Stability: 2 - Stable diff --git a/doc/api/readline.md b/doc/api/readline.md index 9025f6fe7da821..c01397d57108b6 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -1,6 +1,6 @@ # Readline - Stability: 2 - Stable +> Stability: 2 - Stable The `readline` module provides an interface for reading data from a [Readable][] stream (such as [`process.stdin`]) one line at a time. It can be accessed using: diff --git a/doc/api/repl.md b/doc/api/repl.md index 5499f4dacb5462..c4cc092ab29f24 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -1,6 +1,6 @@ # REPL - Stability: 2 - Stable +> Stability: 2 - Stable The `repl` module provides a Read-Eval-Print-Loop (REPL) implementation that is available both as a standalone program or includable in other applications. @@ -444,7 +444,7 @@ added: v2.0.0 deprecated: v3.0.0 --> - Stability: 0 - Deprecated: Use `NODE_REPL_HISTORY` instead. +> Stability: 0 - Deprecated: Use `NODE_REPL_HISTORY` instead. Previously in Node.js/io.js v2.x, REPL history was controlled by using a `NODE_REPL_HISTORY_FILE` environment variable, and the history was saved in JSON diff --git a/doc/api/stream.md b/doc/api/stream.md index 36a624dede6b54..16644f8e2257c8 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1,6 +1,6 @@ # Stream - Stability: 2 - Stable +> Stability: 2 - Stable A stream is an abstract interface for working with streaming data in Node.js. The `stream` module provides a base API that makes it easy to build objects diff --git a/doc/api/string_decoder.md b/doc/api/string_decoder.md index 6bd5a57502b82c..b557ffab9725b0 100644 --- a/doc/api/string_decoder.md +++ b/doc/api/string_decoder.md @@ -1,6 +1,6 @@ # StringDecoder - Stability: 2 - Stable +> Stability: 2 - Stable The `string_decoder` module provides an API for decoding `Buffer` objects into strings in a manner that preserves encoded multi-byte UTF-8 and UTF-16 diff --git a/doc/api/timers.md b/doc/api/timers.md index a311edd744ef1a..cd10f4f13565f6 100644 --- a/doc/api/timers.md +++ b/doc/api/timers.md @@ -1,6 +1,6 @@ # Timers - Stability: 3 - Locked +> Stability: 3 - Locked The `timer` module exposes a global API for scheduling functions to be called at some future period of time. Because the timer functions are diff --git a/doc/api/tls.md b/doc/api/tls.md index a0ece6e58cca63..7feaff2acb2731 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -1,6 +1,6 @@ # TLS (SSL) - Stability: 2 - Stable +> Stability: 2 - Stable The `tls` module provides an implementation of the Transport Layer Security (TLS) and Secure Socket Layer (SSL) protocols that is built on top of OpenSSL. @@ -1153,7 +1153,7 @@ added: v0.3.4 deprecated: v0.11.3 --> - Stability: 0 - Deprecated: Use [`tls.TLSSocket`][] instead. +> Stability: 0 - Deprecated: Use [`tls.TLSSocket`][] instead. The `tls.CryptoStream` class represents a stream of encrypted data. This class has been deprecated and should no longer be used. @@ -1174,7 +1174,7 @@ added: v0.3.2 deprecated: v0.11.3 --> - Stability: 0 - Deprecated: Use [`tls.TLSSocket`][] instead. +> Stability: 0 - Deprecated: Use [`tls.TLSSocket`][] instead. Returned by [`tls.createSecurePair()`][]. @@ -1197,7 +1197,7 @@ added: v0.3.2 deprecated: v0.11.3 --> - Stability: 0 - Deprecated: Use [`tls.TLSSocket`][] instead. +> Stability: 0 - Deprecated: Use [`tls.TLSSocket`][] instead. * `context` {Object} A secure context object as returned by `tls.createSecureContext()` diff --git a/doc/api/tty.md b/doc/api/tty.md index 372f29b6ce058d..f9be1fc4ffd3e5 100644 --- a/doc/api/tty.md +++ b/doc/api/tty.md @@ -1,6 +1,6 @@ # TTY - Stability: 2 - Stable +> Stability: 2 - Stable The `tty` module provides the `tty.ReadStream` and `tty.WriteStream` classes. In most cases, it will not be necessary or possible to use this module directly. diff --git a/doc/api/url.md b/doc/api/url.md index 76b0a3794d5bf6..023697803dd0e3 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -1,6 +1,6 @@ # URL - Stability: 2 - Stable +> Stability: 2 - Stable The `url` module provides utilities for URL resolution and parsing. It can be accessed using: diff --git a/doc/api/util.md b/doc/api/util.md index 6f011929a239dc..c6c31d77590957 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -1,6 +1,6 @@ # util - Stability: 2 - Stable +> Stability: 2 - Stable The `util` module is primarily designed to support the needs of Node.js' own internal APIs. However, many of the utilities are useful for application and @@ -278,7 +278,7 @@ applications and modules should be updated to find alternative approaches. ### util.debug(string) - Stability: 0 - Deprecated: Use [`console.error()`][] instead. +> Stability: 0 - Deprecated: Use [`console.error()`][] instead. * `string` {string} The message to print to `stderr` @@ -286,7 +286,7 @@ Deprecated predecessor of `console.error`. ### util.error([...]) - Stability: 0 - Deprecated: Use [`console.error()`][] instead. +> Stability: 0 - Deprecated: Use [`console.error()`][] instead. * `string` {string} The message to print to `stderr` @@ -294,7 +294,7 @@ Deprecated predecessor of `console.error`. ### util.isArray(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -315,7 +315,7 @@ util.isArray({}); ### util.isBoolean(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -334,7 +334,7 @@ util.isBoolean(false); ### util.isBuffer(object) - Stability: 0 - Deprecated: Use [`Buffer.isBuffer()`][] instead. +> Stability: 0 - Deprecated: Use [`Buffer.isBuffer()`][] instead. * `object` {any} @@ -353,7 +353,7 @@ util.isBuffer(Buffer.from('hello world')); ### util.isDate(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -372,7 +372,7 @@ util.isDate({}); ### util.isError(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -407,7 +407,7 @@ util.isError(obj); ### util.isFunction(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -430,7 +430,7 @@ util.isFunction(Bar); ### util.isNull(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -450,7 +450,7 @@ util.isNull(null); ### util.isNullOrUndefined(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -470,7 +470,7 @@ util.isNullOrUndefined(null); ### util.isNumber(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -491,7 +491,7 @@ util.isNumber(NaN); ### util.isObject(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -513,7 +513,7 @@ util.isObject(function(){}); ### util.isPrimitive(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -545,7 +545,7 @@ util.isPrimitive(new Date()); ### util.isRegExp(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -564,7 +564,7 @@ util.isRegExp({}); ### util.isString(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -585,7 +585,7 @@ util.isString(5); ### util.isSymbol(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -604,7 +604,7 @@ util.isSymbol(Symbol('foo')); ### util.isUndefined(object) - Stability: 0 - Deprecated +> Stability: 0 - Deprecated * `object` {any} @@ -624,7 +624,7 @@ util.isUndefined(null); ### util.log(string) - Stability: 0 - Deprecated: Use a third party module instead. +> Stability: 0 - Deprecated: Use a third party module instead. * `string` {string} @@ -639,19 +639,19 @@ util.log('Timestamped message.'); ### util.print([...]) - Stability: 0 - Deprecated: Use [`console.log()`][] instead. +> Stability: 0 - Deprecated: Use [`console.log()`][] instead. Deprecated predecessor of `console.log`. ### util.puts([...]) - Stability: 0 - Deprecated: Use [`console.log()`][] instead. +> Stability: 0 - Deprecated: Use [`console.log()`][] instead. Deprecated predecessor of `console.log`. ### util._extend(obj) - Stability: 0 - Deprecated: Use [`Object.assign()`] instead. +> Stability: 0 - Deprecated: Use [`Object.assign()`] instead. The `util._extend()` method was never intended to be used outside of internal Node.js modules. The community found and used it anyway. diff --git a/doc/api/vm.md b/doc/api/vm.md index c6290f1e93b76d..7d4cd9eaf5eae4 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -1,6 +1,6 @@ # Executing JavaScript - Stability: 2 - Stable +> Stability: 2 - Stable diff --git a/doc/api/zlib.md b/doc/api/zlib.md index 7463b25a400175..8ce911f4321f32 100644 --- a/doc/api/zlib.md +++ b/doc/api/zlib.md @@ -1,6 +1,6 @@ # Zlib - Stability: 2 - Stable +> Stability: 2 - Stable The `zlib` module provides compression functionality implemented using Gzip and Deflate/Inflate. It can be accessed using: diff --git a/tools/doc/README.md b/tools/doc/README.md index 1620d6c25acbc9..e472c712dc0a52 100644 --- a/tools/doc/README.md +++ b/tools/doc/README.md @@ -10,7 +10,7 @@ Each type of heading has a description block. added: v0.10.0 --> - Stability: 3 - Stable + > Stability: 3 - Stable description and examples. diff --git a/tools/doc/html.js b/tools/doc/html.js index 75d5f085311601..30bc3b5caae303 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -150,15 +150,31 @@ function parseText(lexed) { // lists that come right after a heading are what we're after. function parseLists(input) { var state = null; + var savedState = []; var depth = 0; var output = []; output.links = input.links; input.forEach(function(tok) { - if (tok.type === 'code' && tok.text.match(/Stability:.*/g)) { - tok.text = parseAPIHeader(tok.text); - output.push({ type: 'html', text: tok.text }); + if (tok.type === 'blockquote_start') { + savedState.push(state); + state = 'MAYBE_STABILITY_BQ'; return; } + if (tok.type === 'blockquote_end' && state === 'MAYBE_STABILITY_BQ') { + state = savedState.pop(); + return; + } + if ((tok.type === 'paragraph' && state === 'MAYBE_STABILITY_BQ') || + tok.type === 'code') { + if (tok.text.match(/Stability:.*/g)) { + tok.text = parseAPIHeader(tok.text); + output.push({ type: 'html', text: tok.text }); + return; + } else if (state === 'MAYBE_STABILITY_BQ') { + output.push({ type: 'blockquote_start' }); + state = savedState.pop(); + } + } if (state === null || (state === 'AFTERHEADING' && tok.type === 'heading')) { if (tok.type === 'heading') { diff --git a/tools/doc/json.js b/tools/doc/json.js index 33bde6515b1235..f5bce301056a48 100644 --- a/tools/doc/json.js +++ b/tools/doc/json.js @@ -82,19 +82,19 @@ function doJSON(input, filename, cb) { // Immediately after a heading, we can expect the following // - // { type: 'code', text: 'Stability: ...' }, + // { type: 'blockquote_start' } + // { type: 'paragraph', text: 'Stability: ...' }, + // { type: 'blockquote_end' } // // a list: starting with list_start, ending with list_end, // maybe containing other nested lists in each item. // - // If one of these isnt' found, then anything that comes between + // If one of these isn't found, then anything that comes between // here and the next heading should be parsed as the desc. var stability; if (state === 'AFTERHEADING') { - if (type === 'code' && - (stability = text.match(/^Stability: ([0-5])(?:\s*-\s*)?(.*)$/))) { - current.stability = parseInt(stability[1], 10); - current.stabilityText = stability[2].trim(); + if (type === 'blockquote_start') { + state = 'AFTERHEADING_BLOCKQUOTE'; return; } else if (type === 'list_start' && !tok.ordered) { state = 'AFTERHEADING_LIST'; @@ -129,6 +129,20 @@ function doJSON(input, filename, cb) { return; } + if (state === 'AFTERHEADING_BLOCKQUOTE') { + if (type === 'blockquote_end') { + state = 'AFTERHEADING'; + return; + } + + if (type === 'paragraph' && + (stability = text.match(/^Stability: ([0-5])(?:\s*-\s*)?(.*)$/))) { + current.stability = parseInt(stability[1], 10); + current.stabilityText = stability[2].trim(); + return; + } + } + current.desc = current.desc || []; current.desc.push(tok); From 5cc4b0ed1586c0c79d21b92f7ceac9a8239f8fa7 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Tue, 2 Aug 2016 21:07:53 -0700 Subject: [PATCH 070/144] meta: clarify process for breaking changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://github.com/nodejs/node/issues/7848 PR-URL: https://github.com/nodejs/node/pull/7955 Reviewed-By: James M Snell Reviewed-By: Сковорода Никита Андреевич Reviewed-By: Julien Gilli Reviewed-By: Anna Henningsen Reviewed-By: Brian White Reviewed-By: Michael Dawson --- COLLABORATOR_GUIDE.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 90d73e80e9679b..2bab2e203145f0 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -60,12 +60,20 @@ and work schedules. Trivial changes (e.g. those which fix minor bugs or improve performance without affecting API or causing other wide-reaching impact) may be landed after a shorter delay. -Where there is no disagreement amongst Collaborators, a pull request -may be landed given appropriate review. Where there is discussion +For non-breaking changes, if there is no disagreement amongst Collaborators, a +pull request may be landed given appropriate review. Where there is discussion amongst Collaborators, consensus should be sought if possible. The lack of consensus may indicate the need to elevate discussion to the CTC for resolution (see below). +Breaking changes (that is, pull requests that require an increase in the +major version number, known as `semver-major` changes) must be elevated for +review by the CTC. This does not necessarily mean that the PR must be put onto +the CTC meeting agenda. If multiple CTC members approve (`LGTM`) the PR and no +Collaborators oppose the PR, it can be landed. Where there is disagreement among +CTC members or objections from one or more Collaborators, `semver-major` pull +requests should be put on the CTC meeting agenda. + All bugfixes require a test case which demonstrates the defect. The test should *fail* before the change, and *pass* after the change. From 3d1a06451a254a729b968db9da350eb9b52a0e86 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 22 Jul 2016 21:40:27 -0400 Subject: [PATCH 071/144] doc: use `git-secure-tag` for release tags `git-secure-tag` recursively constructs an SHA-512 digest out of the git tree, and puts the hash from the tree's root into the tag annotation. This hash provides better integrity guarantees than the default SHA-1 merkle tree that git uses. Fix: #7579 PR-URL: https://github.com/nodejs/node/pull/7603 Reviewed-By: Rod Vagg Reviewed-By: James M Snell Reviewed-By: Evan Lucas --- doc/releases.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/releases.md b/doc/releases.md index b5e57d1251747c..25cdb56a4791de 100644 --- a/doc/releases.md +++ b/doc/releases.md @@ -216,10 +216,16 @@ Once you have produced builds that you're happy with, create a new tag. By waiti Tag summaries have a predictable format, look at a recent tag to see, `git tag -v v6.0.0`. The message should look something like `2016-04-26 Node.js v6.0.0 (Current) Release`. +Install `git-secure-tag` npm module: + +```console +$ npm install -g git-secure-tag +``` + Create a tag using the following command: ```sh -$ git tag -sm 'YYYY-MM-DD Node.js vx.y.z (Release Type) Release' +$ git secure-tag -sm 'YYYY-MM-DD Node.js vx.y.z (Release Type) Release' ``` The tag **must** be signed using the GPG key that's listed for you on the project README. From db3a7e83eba8776ea65a1fec9b7ceb99397115e8 Mon Sep 17 00:00:00 2001 From: yorkie Date: Wed, 3 Aug 2016 00:28:38 +0800 Subject: [PATCH 072/144] http: specify _implicitHeader in OutgoingMessage PR-URL: https://github.com/nodejs/node/pull/7949 Reviewed-By: Rich Trott Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- lib/_http_outgoing.js | 3 +++ test/parallel/test-http-outgoing-proto.js | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 test/parallel/test-http-outgoing-proto.js diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index 0dc2d07e7a5e4e..f3adc9bd930567 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -413,6 +413,9 @@ OutgoingMessage.prototype._renderHeaders = function() { return headers; }; +OutgoingMessage.prototype._implicitHeader = function() { + throw new Error('_implicitHeader() method is not implemented'); +}; Object.defineProperty(OutgoingMessage.prototype, 'headersSent', { configurable: true, diff --git a/test/parallel/test-http-outgoing-proto.js b/test/parallel/test-http-outgoing-proto.js new file mode 100644 index 00000000000000..738e1d2c8cfe4e --- /dev/null +++ b/test/parallel/test-http-outgoing-proto.js @@ -0,0 +1,14 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +const http = require('http'); +const OutgoingMessage = http.OutgoingMessage; +const ClientRequest = http.ClientRequest; +const ServerResponse = http.ServerResponse; + +assert.throws(OutgoingMessage.prototype._implicitHeader); +assert.strictEqual( + typeof ClientRequest.prototype._implicitHeader, 'function'); +assert.strictEqual( + typeof ServerResponse.prototype._implicitHeader, 'function'); From cb0baca9828c8da2e7a235135618d27f417ac7c8 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Wed, 3 Aug 2016 16:32:05 -0700 Subject: [PATCH 073/144] doc: use consistent markdown in README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve markdown practices in README: * consistent header indicators * consistent emphasis indicators * wrap bare URLs in `<` and `>` * wrap at 80 chars * specifying language in fenced code PR-URL: https://github.com/nodejs/node/pull/7971 Reviewed-By: Сковорода Никита Андреевич Reviewed-By: Michaël Zasso Reviewed-By: James M Snell --- README.md | 309 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 200 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 6562bcdb5c46d8..e87068c173ffee 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Node.js -======= +# Node.js [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/nodejs/node?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/29/badge)](https://bestpractices.coreinfrastructure.org/projects/29) @@ -28,12 +27,13 @@ If you need help using or installing Node.js, please use the ### Unofficial Resources * IRC (general questions): [#node.js on chat.freenode.net][]. Please see -http://nodeirc.info/ for more information regarding the `#node.js` IRC channel. + for more information regarding the `#node.js` IRC +channel. -*Please note that unofficial resources are neither managed by (nor necessarily +_Please note that unofficial resources are neither managed by (nor necessarily endorsed by) the Node.js TSC/CTC. Specifically, such resources are not currently covered by the [Node.js Moderation Policy][] and the selection and -actions of resource operators/moderators are not subject to TSC/CTC oversight.* +actions of resource operators/moderators are not subject to TSC/CTC oversight._ ## Release Types @@ -86,20 +86,20 @@ documentation of the latest stable version. ### Verifying Binaries -Current, LTS and Nightly download directories all contain a *SHASUM256.txt* +Current, LTS and Nightly download directories all contain a _SHASUM256.txt_ file that lists the SHA checksums for each file available for download. -The *SHASUM256.txt* can be downloaded using curl. +The _SHASUM256.txt_ can be downloaded using curl. -``` +```console $ curl -O https://nodejs.org/dist/vx.y.z/SHASUMS256.txt ``` To check that a downloaded file matches the checksum, run it through `sha256sum` with a command such as: -``` +```console $ grep node-vx.y.z.tar.gz SHASUMS256.txt | sha256sum -c - ``` @@ -115,9 +115,8 @@ the GPG keys of individuals authorized to create releases. They are listed at the bottom of this README under [Release Team](#release-team). Use a command such as this to import the keys: -``` -$ gpg --keyserver pool.sks-keyservers.net \ - --recv-keys DD8F2338BAE7501E3DD5AC78C273792F7D83545D +```console +$ gpg --keyserver pool.sks-keyservers.net --recv-keys DD8F2338BAE7501E3DD5AC78C273792F7D83545D ``` _(See the bottom of this README for a full script to import active @@ -148,96 +147,177 @@ handling your report. ## Current Project Team Members The Node.js project team comprises a group of core collaborators and a sub-group -that forms the _Core Technical Committee_ (CTC) which governs the project. For more -information about the governance of the Node.js project, see +that forms the _Core Technical Committee_ (CTC) which governs the project. For +more information about the governance of the Node.js project, see [GOVERNANCE.md](./GOVERNANCE.md). ### CTC (Core Technical Committee) -* [addaleax](https://github.com/addaleax) - **Anna Henningsen** <anna@addaleax.net> -* [bnoordhuis](https://github.com/bnoordhuis) - **Ben Noordhuis** <info@bnoordhuis.nl> -* [ChALkeR](https://github.com/ChALkeR) - **Сковорода Никита Андреевич** <chalkerx@gmail.com> -* [chrisdickinson](https://github.com/chrisdickinson) - **Chris Dickinson** <christopher.s.dickinson@gmail.com> -* [cjihrig](https://github.com/cjihrig) - **Colin Ihrig** <cjihrig@gmail.com> -* [evanlucas](https://github.com/evanlucas) - **Evan Lucas** <evanlucas@me.com> -* [fishrock123](https://github.com/fishrock123) - **Jeremiah Senkpiel** <fishrock123@rocketmail.com> -* [indutny](https://github.com/indutny) - **Fedor Indutny** <fedor.indutny@gmail.com> -* [jasnell](https://github.com/jasnell) - **James M Snell** <jasnell@gmail.com> -* [mhdawson](https://github.com/mhdawson) - **Michael Dawson** <michael_dawson@ca.ibm.com> -* [misterdjules](https://github.com/misterdjules) - **Julien Gilli** <jgilli@nodejs.org> -* [mscdex](https://github.com/mscdex) - **Brian White** <mscdex@mscdex.net> -* [ofrobots](https://github.com/ofrobots) - **Ali Ijaz Sheikh** <ofrobots@google.com> -* [orangemocha](https://github.com/orangemocha) - **Alexis Campailla** <orangemocha@nodejs.org> -* [rvagg](https://github.com/rvagg) - **Rod Vagg** <rod@vagg.org> -* [shigeki](https://github.com/shigeki) - **Shigeki Ohtsu** <ohtsu@iij.ad.jp> -* [trevnorris](https://github.com/trevnorris) - **Trevor Norris** <trev.norris@gmail.com> -* [Trott](https://github.com/Trott) - **Rich Trott** <rtrott@gmail.com> +* [addaleax](https://github.com/addaleax) - +**Anna Henningsen** <anna@addaleax.net> +* [bnoordhuis](https://github.com/bnoordhuis) - +**Ben Noordhuis** <info@bnoordhuis.nl> +* [ChALkeR](https://github.com/ChALkeR) - +**Сковорода Никита Андреевич** <chalkerx@gmail.com> +* [chrisdickinson](https://github.com/chrisdickinson) - +**Chris Dickinson** <christopher.s.dickinson@gmail.com> +* [cjihrig](https://github.com/cjihrig) - +**Colin Ihrig** <cjihrig@gmail.com> +* [evanlucas](https://github.com/evanlucas) - +**Evan Lucas** <evanlucas@me.com> +* [fishrock123](https://github.com/fishrock123) - +**Jeremiah Senkpiel** <fishrock123@rocketmail.com> +* [indutny](https://github.com/indutny) - +**Fedor Indutny** <fedor.indutny@gmail.com> +* [jasnell](https://github.com/jasnell) - +**James M Snell** <jasnell@gmail.com> +* [mhdawson](https://github.com/mhdawson) - +**Michael Dawson** <michael_dawson@ca.ibm.com> +* [misterdjules](https://github.com/misterdjules) - +**Julien Gilli** <jgilli@nodejs.org> +* [mscdex](https://github.com/mscdex) - +**Brian White** <mscdex@mscdex.net> +* [ofrobots](https://github.com/ofrobots) - +**Ali Ijaz Sheikh** <ofrobots@google.com> +* [orangemocha](https://github.com/orangemocha) - +**Alexis Campailla** <orangemocha@nodejs.org> +* [rvagg](https://github.com/rvagg) - +**Rod Vagg** <rod@vagg.org> +* [shigeki](https://github.com/shigeki) - +**Shigeki Ohtsu** <ohtsu@iij.ad.jp> +* [trevnorris](https://github.com/trevnorris) - +**Trevor Norris** <trev.norris@gmail.com> +* [Trott](https://github.com/Trott) - +**Rich Trott** <rtrott@gmail.com> ### Collaborators -* [andrasq](https://github.com/andrasq) - **Andras** <andras@kinvey.com> -* [AndreasMadsen](https://github.com/AndreasMadsen) - **Andreas Madsen** <amwebdk@gmail.com> -* [bengl](https://github.com/bengl) - **Bryan English** <bryan@bryanenglish.com> -* [benjamingr](https://github.com/benjamingr) - **Benjamin Gruenbaum** <benjamingr@gmail.com> -* [bmeck](https://github.com/bmeck) - **Bradley Farias** <bradley.meck@gmail.com> -* [brendanashworth](https://github.com/brendanashworth) - **Brendan Ashworth** <brendan.ashworth@me.com> -* [bzoz](https://github.com/bzoz) - **Bartosz Sosnowski** <bartosz@janeasystems.com> -* [calvinmetcalf](https://github.com/calvinmetcalf) - **Calvin Metcalf** <calvin.metcalf@gmail.com> -* [claudiorodriguez](https://github.com/claudiorodriguez) - **Claudio Rodriguez** <cjrodr@yahoo.com> -* [domenic](https://github.com/domenic) - **Domenic Denicola** <d@domenic.me> -* [eljefedelrodeodeljefe](https://github.com/eljefedelrodeodeljefe) - **Robert Jefe Lindstaedt** <robert.lindstaedt@gmail.com> -* [estliberitas](https://github.com/estliberitas) - **Alexander Makarenko** <estliberitas@gmail.com> -* [firedfox](https://github.com/firedfox) - **Daniel Wang** <wangyang0123@gmail.com> -* [geek](https://github.com/geek) - **Wyatt Preul** <wpreul@gmail.com> -* [iarna](https://github.com/iarna) - **Rebecca Turner** <me@re-becca.org> -* [isaacs](https://github.com/isaacs) - **Isaac Z. Schlueter** <i@izs.me> -* [iWuzHere](https://github.com/iWuzHere) - **Imran Iqbal** <imran@imraniqbal.org> -* [JacksonTian](https://github.com/JacksonTian) - **Jackson Tian** <shvyo1987@gmail.com> -* [jbergstroem](https://github.com/jbergstroem) - **Johan Bergström** <bugs@bergstroem.nu> -* [jhamhader](https://github.com/jhamhader) - **Yuval Brik** <yuval@brik.org.il> -* [joaocgreis](https://github.com/joaocgreis) - **João Reis** <reis@janeasystems.com> -* [julianduque](https://github.com/julianduque) - **Julian Duque** <julianduquej@gmail.com> -* [JungMinu](https://github.com/JungMinu) - **Minwoo Jung** <jmwsoft@gmail.com> -* [lance](https://github.com/lance) - **Lance Ball** <lball@redhat.com> -* [lxe](https://github.com/lxe) - **Aleksey Smolenchuk** <lxe@lxe.co> -* [matthewloring](https://github.com/matthewloring) - **Matthew Loring** <mattloring@google.com> -* [mcollina](https://github.com/mcollina) - **Matteo Collina** <matteo.collina@gmail.com> -* [micnic](https://github.com/micnic) - **Nicu Micleușanu** <micnic90@gmail.com> -* [mikeal](https://github.com/mikeal) - **Mikeal Rogers** <mikeal.rogers@gmail.com> -* [monsanto](https://github.com/monsanto) - **Christopher Monsanto** <chris@monsan.to> -* [Olegas](https://github.com/Olegas) - **Oleg Elifantiev** <oleg@elifantiev.ru> -* [othiym23](https://github.com/othiym23) - **Forrest L Norvell** <ogd@aoaioxxysz.net> -* [petkaantonov](https://github.com/petkaantonov) - **Petka Antonov** <petka_antonov@hotmail.com> -* [phillipj](https://github.com/phillipj) - **Phillip Johnsen** <johphi@gmail.com> -* [piscisaureus](https://github.com/piscisaureus) - **Bert Belder** <bertbelder@gmail.com> -* [pmq20](https://github.com/pmq20) - **Minqi Pan** <pmq2001@gmail.com> -* [princejwesley](https://github.com/princejwesley) - **Prince John Wesley** <princejohnwesley@gmail.com> -* [qard](https://github.com/qard) - **Stephen Belanger** <admin@stephenbelanger.com> -* [rlidwka](https://github.com/rlidwka) - **Alex Kocharin** <alex@kocharin.ru> -* [rmg](https://github.com/rmg) - **Ryan Graham** <r.m.graham@gmail.com> -* [robertkowalski](https://github.com/robertkowalski) - **Robert Kowalski** <rok@kowalski.gd> -* [romankl](https://github.com/romankl) - **Roman Klauke** <romaaan.git@gmail.com> -* [ronkorving](https://github.com/ronkorving) - **Ron Korving** <ron@ronkorving.nl> -* [RReverser](https://github.com/RReverser) - **Ingvar Stepanyan** <me@rreverser.com> -* [saghul](https://github.com/saghul) - **Saúl Ibarra Corretgé** <saghul@gmail.com> -* [sam-github](https://github.com/sam-github) - **Sam Roberts** <vieuxtech@gmail.com> -* [santigimeno](https://github.com/santigimeno) - **Santiago Gimeno** <santiago.gimeno@gmail.com> -* [seishun](https://github.com/seishun) - **Nikolai Vavilov** <vvnicholas@gmail.com> -* [silverwind](https://github.com/silverwind) - **Roman Reiss** <me@silverwind.io> -* [srl295](https://github.com/srl295) - **Steven R Loomis** <srloomis@us.ibm.com> -* [stefanmb](https://github.com/stefanmb) - **Stefan Budeanu** <stefan@budeanu.com> -* [targos](https://github.com/targos) - **Michaël Zasso** <mic.besace@gmail.com> -* [tellnes](https://github.com/tellnes) - **Christian Tellnes** <christian@tellnes.no> -* [thealphanerd](https://github.com/thealphanerd) - **Myles Borins** <myles.borins@gmail.com> -* [thefourtheye](https://github.com/thefourtheye) - **Sakthipriyan Vairamani** <thechargingvolcano@gmail.com> -* [thekemkid](https://github.com/thekemkid) - **Glen Keane** <glenkeane.94@gmail.com> -* [thlorenz](https://github.com/thlorenz) - **Thorsten Lorenz** <thlorenz@gmx.de> -* [tunniclm](https://github.com/tunniclm) - **Mike Tunnicliffe** <m.j.tunnicliffe@gmail.com> -* [vkurchatkin](https://github.com/vkurchatkin) - **Vladimir Kurchatkin** <vladimir.kurchatkin@gmail.com> -* [whitlockjc](https://github.com/whitlockjc) - **Jeremy Whitlock** <jwhitlock@apache.org> -* [yorkie](https://github.com/yorkie) - **Yorkie Liu** <yorkiefixer@gmail.com> -* [yosuke-furukawa](https://github.com/yosuke-furukawa) - **Yosuke Furukawa** <yosuke.furukawa@gmail.com> -* [zkat](https://github.com/zkat) - **Kat Marchán** <kzm@sykosomatic.org> +* [andrasq](https://github.com/andrasq) - +**Andras** <andras@kinvey.com> +* [AndreasMadsen](https://github.com/AndreasMadsen) - +**Andreas Madsen** <amwebdk@gmail.com> +* [bengl](https://github.com/bengl) - +**Bryan English** <bryan@bryanenglish.com> +* [benjamingr](https://github.com/benjamingr) - +**Benjamin Gruenbaum** <benjamingr@gmail.com> +* [bmeck](https://github.com/bmeck) - +**Bradley Farias** <bradley.meck@gmail.com> +* [brendanashworth](https://github.com/brendanashworth) - +**Brendan Ashworth** <brendan.ashworth@me.com> +* [bzoz](https://github.com/bzoz) - +**Bartosz Sosnowski** <bartosz@janeasystems.com> +* [calvinmetcalf](https://github.com/calvinmetcalf) - +**Calvin Metcalf** <calvin.metcalf@gmail.com> +* [claudiorodriguez](https://github.com/claudiorodriguez) - +**Claudio Rodriguez** <cjrodr@yahoo.com> +* [domenic](https://github.com/domenic) - +**Domenic Denicola** <d@domenic.me> +* [eljefedelrodeodeljefe](https://github.com/eljefedelrodeodeljefe) - +**Robert Jefe Lindstaedt** <robert.lindstaedt@gmail.com> +* [estliberitas](https://github.com/estliberitas) - +**Alexander Makarenko** <estliberitas@gmail.com> +* [firedfox](https://github.com/firedfox) - +**Daniel Wang** <wangyang0123@gmail.com> +* [geek](https://github.com/geek) - +**Wyatt Preul** <wpreul@gmail.com> +* [iarna](https://github.com/iarna) - +**Rebecca Turner** <me@re-becca.org> +* [isaacs](https://github.com/isaacs) - +**Isaac Z. Schlueter** <i@izs.me> +* [iWuzHere](https://github.com/iWuzHere) - +**Imran Iqbal** <imran@imraniqbal.org> +* [JacksonTian](https://github.com/JacksonTian) - +**Jackson Tian** <shvyo1987@gmail.com> +* [jbergstroem](https://github.com/jbergstroem) - +**Johan Bergström** <bugs@bergstroem.nu> +* [jhamhader](https://github.com/jhamhader) - +**Yuval Brik** <yuval@brik.org.il> +* [joaocgreis](https://github.com/joaocgreis) - +**João Reis** <reis@janeasystems.com> +* [julianduque](https://github.com/julianduque) - +**Julian Duque** <julianduquej@gmail.com> +* [JungMinu](https://github.com/JungMinu) - +**Minwoo Jung** <jmwsoft@gmail.com> +* [lance](https://github.com/lance) - +**Lance Ball** <lball@redhat.com> +* [lxe](https://github.com/lxe) - +**Aleksey Smolenchuk** <lxe@lxe.co> +* [matthewloring](https://github.com/matthewloring) - +**Matthew Loring** <mattloring@google.com> +* [mcollina](https://github.com/mcollina) - +**Matteo Collina** <matteo.collina@gmail.com> +* [micnic](https://github.com/micnic) - +**Nicu Micleușanu** <micnic90@gmail.com> +* [mikeal](https://github.com/mikeal) - +**Mikeal Rogers** <mikeal.rogers@gmail.com> +* [monsanto](https://github.com/monsanto) - +**Christopher Monsanto** <chris@monsan.to> +* [Olegas](https://github.com/Olegas) - +**Oleg Elifantiev** <oleg@elifantiev.ru> +* [othiym23](https://github.com/othiym23) - +**Forrest L Norvell** <ogd@aoaioxxysz.net> +* [petkaantonov](https://github.com/petkaantonov) - +**Petka Antonov** <petka_antonov@hotmail.com> +* [phillipj](https://github.com/phillipj) - +**Phillip Johnsen** <johphi@gmail.com> +* [piscisaureus](https://github.com/piscisaureus) - +**Bert Belder** <bertbelder@gmail.com> +* [pmq20](https://github.com/pmq20) - +**Minqi Pan** <pmq2001@gmail.com> +* [princejwesley](https://github.com/princejwesley) - +**Prince John Wesley** <princejohnwesley@gmail.com> +* [qard](https://github.com/qard) - +**Stephen Belanger** <admin@stephenbelanger.com> +* [rlidwka](https://github.com/rlidwka) - +**Alex Kocharin** <alex@kocharin.ru> +* [rmg](https://github.com/rmg) - +**Ryan Graham** <r.m.graham@gmail.com> +* [robertkowalski](https://github.com/robertkowalski) - +**Robert Kowalski** <rok@kowalski.gd> +* [romankl](https://github.com/romankl) - +**Roman Klauke** <romaaan.git@gmail.com> +* [ronkorving](https://github.com/ronkorving) - +**Ron Korving** <ron@ronkorving.nl> +* [RReverser](https://github.com/RReverser) - +**Ingvar Stepanyan** <me@rreverser.com> +* [saghul](https://github.com/saghul) - +**Saúl Ibarra Corretgé** <saghul@gmail.com> +* [sam-github](https://github.com/sam-github) - +**Sam Roberts** <vieuxtech@gmail.com> +* [santigimeno](https://github.com/santigimeno) - +**Santiago Gimeno** <santiago.gimeno@gmail.com> +* [seishun](https://github.com/seishun) - +**Nikolai Vavilov** <vvnicholas@gmail.com> +* [silverwind](https://github.com/silverwind) - +**Roman Reiss** <me@silverwind.io> +* [srl295](https://github.com/srl295) - +**Steven R Loomis** <srloomis@us.ibm.com> +* [stefanmb](https://github.com/stefanmb) - +**Stefan Budeanu** <stefan@budeanu.com> +* [targos](https://github.com/targos) - +**Michaël Zasso** <mic.besace@gmail.com> +* [tellnes](https://github.com/tellnes) - +**Christian Tellnes** <christian@tellnes.no> +* [thealphanerd](https://github.com/thealphanerd) - +**Myles Borins** <myles.borins@gmail.com> +* [thefourtheye](https://github.com/thefourtheye) - +**Sakthipriyan Vairamani** <thechargingvolcano@gmail.com> +* [thekemkid](https://github.com/thekemkid) - +**Glen Keane** <glenkeane.94@gmail.com> +* [thlorenz](https://github.com/thlorenz) - +**Thorsten Lorenz** <thlorenz@gmx.de> +* [tunniclm](https://github.com/tunniclm) - +**Mike Tunnicliffe** <m.j.tunnicliffe@gmail.com> +* [vkurchatkin](https://github.com/vkurchatkin) - +**Vladimir Kurchatkin** <vladimir.kurchatkin@gmail.com> +* [whitlockjc](https://github.com/whitlockjc) - +**Jeremy Whitlock** <jwhitlock@apache.org> +* [yorkie](https://github.com/yorkie) - +**Yorkie Liu** <yorkiefixer@gmail.com> +* [yosuke-furukawa](https://github.com/yosuke-furukawa) - +**Yosuke Furukawa** <yosuke.furukawa@gmail.com> +* [zkat](https://github.com/zkat) - +**Kat Marchán** <kzm@sykosomatic.org> Collaborators & CTC members follow the [COLLABORATOR_GUIDE.md](./COLLABORATOR_GUIDE.md) in maintaining the Node.js project. @@ -246,18 +326,26 @@ maintaining the Node.js project. Releases of Node.js and io.js will be signed with one of the following GPG keys: -* **Chris Dickinson** <christopher.s.dickinson@gmail.com> `9554F04D7259F04124DE6B476D5A82AC7E37093B` -* **Colin Ihrig** <cjihrig@gmail.com> `94AE36675C464D64BAFA68DD7434390BDBE9B9C5` -* **Evan Lucas** <evanlucas@me.com> `B9AE9905FFD7803F25714661B63B535A4C206CA9` -* **James M Snell** <jasnell@keybase.io> `71DCFD284A79C3B38668286BC97EC7A07EDE3FC1` -* **Jeremiah Senkpiel** <fishrock@keybase.io> `FD3A5288F042B6850C66B31F09FE44734EB7990E` -* **Myles Borins** <myles.borins@gmail.com> `C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8` -* **Rod Vagg** <rod@vagg.org> `DD8F2338BAE7501E3DD5AC78C273792F7D83545D` -* **Sam Roberts** <octetcloud@keybase.io> `0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93` +* **Chris Dickinson** <christopher.s.dickinson@gmail.com> +`9554F04D7259F04124DE6B476D5A82AC7E37093B` +* **Colin Ihrig** <cjihrig@gmail.com> +`94AE36675C464D64BAFA68DD7434390BDBE9B9C5` +* **Evan Lucas** <evanlucas@me.com> +`B9AE9905FFD7803F25714661B63B535A4C206CA9` +* **James M Snell** <jasnell@keybase.io> +`71DCFD284A79C3B38668286BC97EC7A07EDE3FC1` +* **Jeremiah Senkpiel** <fishrock@keybase.io> +`FD3A5288F042B6850C66B31F09FE44734EB7990E` +* **Myles Borins** <myles.borins@gmail.com> +`C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8` +* **Rod Vagg** <rod@vagg.org> +`DD8F2338BAE7501E3DD5AC78C273792F7D83545D` +* **Sam Roberts** <octetcloud@keybase.io> +`0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93` The full set of trusted release keys can be imported by running: -``` +```shell gpg --keyserver pool.sks-keyservers.net --recv-keys 9554F04D7259F04124DE6B476D5A82AC7E37093B gpg --keyserver pool.sks-keyservers.net --recv-keys 94AE36675C464D64BAFA68DD7434390BDBE9B9C5 gpg --keyserver pool.sks-keyservers.net --recv-keys 0034A06D9D9B0064CE8ADF6BF1747F4AD2306D93 @@ -268,15 +356,18 @@ gpg --keyserver pool.sks-keyservers.net --recv-keys C4F0DFFF4E8C1A8236409D08E73B gpg --keyserver pool.sks-keyservers.net --recv-keys B9AE9905FFD7803F25714661B63B535A4C206CA9 ``` -See the section above on [Verifying Binaries](#verifying-binaries) for -details on what to do with these keys to verify that a downloaded file is official. +See the section above on [Verifying Binaries](#verifying-binaries) for details +on what to do with these keys to verify that a downloaded file is official. Previous releases of Node.js have been signed with one of the following GPG keys: -* **Isaac Z. Schlueter** <i@izs.me> `93C7E9E91B49E432C2F75674B0A78B0A6C481CF6` -* **Julien Gilli** <jgilli@fastmail.fm> `114F43EE0176B71C7BC219DD50A3051F888C628D` -* **Timothy J Fontaine** <tjfontaine@gmail.com> `7937DFD2AB06298B2293C3187D33FF9D0246406D` +* **Isaac Z. Schlueter** <i@izs.me> +`93C7E9E91B49E432C2F75674B0A78B0A6C481CF6` +* **Julien Gilli** <jgilli@fastmail.fm> +`114F43EE0176B71C7BC219DD50A3051F888C628D` +* **Timothy J Fontaine** <tjfontaine@gmail.com> +`7937DFD2AB06298B2293C3187D33FF9D0246406D` [Website]: https://nodejs.org/en/ [Contributing to the project]: CONTRIBUTING.md From 317ae96c3323ad1162a3090d84154af54df3d441 Mon Sep 17 00:00:00 2001 From: Franziska Hinkelmann Date: Thu, 4 Aug 2016 09:36:50 +0200 Subject: [PATCH 074/144] src: make EnvDelete behave like the delete operator According to TC39 specification, the delete operator returns false or throws in strict mode, if the property is non-configurable. It returns true in all other cases. Process.env can never have non-configurable properties, thus EnvDelete must always return true. This is independent of strict mode. Fixes: https://github.com/nodejs/node/issues/7960 PR-URL: https://github.com/nodejs/node/pull/7975 Reviewed-By: Colin Ihrig Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Anna Henningsen --- src/node.cc | 17 ++++++---------- test/parallel/test-process-env.js | 32 +++++++++++++++++-------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/node.cc b/src/node.cc index 64bbfaac48af71..ac9ce4a96c6891 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2774,23 +2774,18 @@ static void EnvQuery(Local property, static void EnvDeleter(Local property, const PropertyCallbackInfo& info) { - bool rc = true; #ifdef __POSIX__ node::Utf8Value key(info.GetIsolate(), property); - rc = getenv(*key) != nullptr; - if (rc) - unsetenv(*key); + unsetenv(*key); #else String::Value key(property); WCHAR* key_ptr = reinterpret_cast(*key); - if (key_ptr[0] == L'=' || !SetEnvironmentVariableW(key_ptr, nullptr)) { - // Deletion failed. Return true if the key wasn't there in the first place, - // false if it is still there. - rc = GetEnvironmentVariableW(key_ptr, nullptr, 0) == 0 && - GetLastError() != ERROR_SUCCESS; - } + SetEnvironmentVariableW(key_ptr, nullptr); #endif - info.GetReturnValue().Set(rc); + + // process.env never has non-configurable properties, so always + // return true like the tc39 delete operator. + info.GetReturnValue().Set(true); } diff --git a/test/parallel/test-process-env.js b/test/parallel/test-process-env.js index 33a1d9674eaa44..52f6de9278f73d 100644 --- a/test/parallel/test-process-env.js +++ b/test/parallel/test-process-env.js @@ -2,11 +2,8 @@ /* eslint-disable max-len */ require('../common'); -// first things first, set the timezone; see tzset(3) -process.env.TZ = 'Europe/Amsterdam'; - -var assert = require('assert'); -var spawn = require('child_process').spawn; +const assert = require('assert'); +const spawn = require('child_process').spawn; /* For the moment we are not going to support setting the timezone via the * environment variables. The problem is that various V8 platform backends @@ -16,6 +13,8 @@ var spawn = require('child_process').spawn; https://github.com/joyent/node/blob/08782931205bc4f6d28102ebc29fd806e8ccdf1f/deps/v8/src/platform-linux.cc#L339-345 https://github.com/joyent/node/blob/08782931205bc4f6d28102ebc29fd806e8ccdf1f/deps/v8/src/platform-win32.cc#L590-596 +// first things first, set the timezone; see tzset(3) +process.env.TZ = 'Europe/Amsterdam'; // time difference between Greenwich and Amsterdam is +2 hours in the summer date = new Date('Fri, 10 Sep 1982 03:15:00 GMT'); @@ -27,28 +26,28 @@ assert.equal(5, date.getHours()); // changes in environment should be visible to child processes if (process.argv[2] == 'you-are-the-child') { // failed assertion results in process exiting with status code 1 - assert.equal(false, 'NODE_PROCESS_ENV_DELETED' in process.env); - assert.equal(42, process.env.NODE_PROCESS_ENV); - assert.equal('asdf', process.env.hasOwnProperty); + assert.strictEqual(false, 'NODE_PROCESS_ENV_DELETED' in process.env); + assert.strictEqual('42', process.env.NODE_PROCESS_ENV); + assert.strictEqual('asdf', process.env.hasOwnProperty); var hasOwnProperty = Object.prototype.hasOwnProperty; const has = hasOwnProperty.call(process.env, 'hasOwnProperty'); - assert.equal(true, has); + assert.strictEqual(true, has); process.exit(0); } else { - assert.equal(Object.prototype.hasOwnProperty, process.env.hasOwnProperty); + assert.strictEqual(Object.prototype.hasOwnProperty, process.env.hasOwnProperty); const has = process.env.hasOwnProperty('hasOwnProperty'); - assert.equal(false, has); + assert.strictEqual(false, has); process.env.hasOwnProperty = 'asdf'; process.env.NODE_PROCESS_ENV = 42; - assert.equal(42, process.env.NODE_PROCESS_ENV); + assert.strictEqual('42', process.env.NODE_PROCESS_ENV); process.env.NODE_PROCESS_ENV_DELETED = 42; - assert.equal(true, 'NODE_PROCESS_ENV_DELETED' in process.env); + assert.strictEqual(true, 'NODE_PROCESS_ENV_DELETED' in process.env); delete process.env.NODE_PROCESS_ENV_DELETED; - assert.equal(false, 'NODE_PROCESS_ENV_DELETED' in process.env); + assert.strictEqual(false, 'NODE_PROCESS_ENV_DELETED' in process.env); var child = spawn(process.argv[0], [process.argv[1], 'you-are-the-child']); child.stdout.on('data', function(data) { console.log(data.toString()); }); @@ -59,3 +58,8 @@ if (process.argv[2] == 'you-are-the-child') { } }); } + +// delete should return true except for non-configurable properties +// https://github.com/nodejs/node/issues/7960 +delete process.env.NON_EXISTING_VARIABLE; +assert.strictEqual(true, delete process.env.NON_EXISTING_VARIABLE); From 2245e843ccd16a688e93e448edc90ddb760679d1 Mon Sep 17 00:00:00 2001 From: Josh Gavant Date: Wed, 3 Aug 2016 15:57:49 -0700 Subject: [PATCH 075/144] doc: add CTC meeting minutes 2016-07-20 PR-URL: https://github.com/nodejs/node/pull/7970 Reviewed-By: Michael Dawson Reviewed-By: James M Snell --- doc/ctc-meetings/2016-07-20.md | 202 +++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 doc/ctc-meetings/2016-07-20.md diff --git a/doc/ctc-meetings/2016-07-20.md b/doc/ctc-meetings/2016-07-20.md new file mode 100644 index 00000000000000..02f16ae2ac24ca --- /dev/null +++ b/doc/ctc-meetings/2016-07-20.md @@ -0,0 +1,202 @@ +# Node Foundation CTC Meeting 2016-07-20 + +## Links + +* **Audio Recording**: TBP +* **GitHub Issue**: https://github.com/nodejs/node/issues/7809 +* **Minutes Google Doc**: +* _Previous Minutes Google Doc: _ + +## Present + +* Anna Henningsen @addaleax (observer) +* Ben Noordhuis @bnoordhuis (CTC) +* Сковорода Никита Андреевич @ChALkeR (CTC) +* Colin Ihrig @cjihrig (CTC) +* Evan Lucas @evanlucas (CTC) +* Jeremiah Senkpiel @Fishrock123 (CTC) +* Josh Gavant @joshgav (observer/Microsoft) +* Michael Dawson @mhdawson (CTC) +* Julien Gilli @misterdjules (CTC) +* Brian White @mscdex (CTC) +* Ali Ijaz Sheikh @ofrobots (CTC) +* Alexis Campailla @orangemocha (CTC) +* Rod Vagg @rvagg (CTC) +* Seth Thompson @s3ththompson (observer/Google) +* Shigeki Ohtsu @shigeki (CTC) +* Steven R Loomis @srl295 (observer/IBM/ICU) +* Myles Borins @TheAlphaNerd (observer) +* Trevor Norris @trevnorris (CTC) +* Rich Trott @Trott (CTC) + + +## Standup + +* Anna Henningsen @addaleax (observer) + * Issues & PRs + * looking into porting JS-based realpath to C +* Ben Noordhuis @bnoordhuis (CTC) + * The usual (PR review and comment) + * Updating code base to do less manual memory management. PR coming soon. +* Сковорода Никита Андреевич @ChALkeR (CTC) + * Some initial work on docs linting. + * Some comments on issues and PRs. +* Colin Ihrig @cjihrig (CTC) + * Reviewed issues and PRs + * Opened PRs +* Evan Lucas @evanlucas (CTC) + * working on v6.3.1 release + * working on repl bugfix +* Jeremiah Senkpiel @Fishrock123 (CTC) + * Did some timers review for https://github.com/nodejs/node/commit/5aac4c42da104c30d8f701f1042d61c2f06b7e6c + * Clearing out some other old stuff I’ve assigned myself to +* Josh Gavant @joshgav (observer/Microsoft) + * Internal Microsoft work. +* Michael Dawson @mhdawson (CTC) + * Misc issues with PPC machines, added new PPC + machines from newer openstack + * Working with Ian/Sampson on ABI stable abi, status + update at API WG meeting + * Working with Richard/Howard on post-mortem activities, + post-mortem WG meeting this week. + * Misc reviews/lands + * Reading/keeping up/commenting on issues + * Getting ready for Node Summit talk. +* Julien Gilli @misterdjules (CTC) + * Looking forward to getting more involved again + * Investigating timers bug. Looking for someone to mentor on it + * Reviewing and commenting on pull requests +* Brian White @mscdex (CTC) + * Diving deep into reworking API docs + * Reviewing PRs, commenting on issues +* Ali Ijaz Sheikh @ofrobots (CTC) + * shepherding some V8 backports, v8_inspector license issue and roll +* Alexis Campailla @orangemocha (CTC) + * Nothing to report. +* Rod Vagg @rvagg (CTC) + * Usual administrative stuff, some build maintenance +* Seth Thompson @s3ththompson (observer/Google) + * Setting priorities for the next quarter. + * Team is continuing work on v8_inspector. + * Migrating v8_inspector into V8 itself. +* Shigeki Ohtsu @shigeki (CTC) + * Nothing special. Working internal jobs. +* Steven R Loomis @srl295 (observer/IBM/ICU) + * Nodesummit prep… +* Myles Borins @TheAlphaNerd (observer) + * v4.5.0-rc.2 released + * Email sent to npm team +* Trevor Norris @trevnorris (CTC) + * realpath fix +* Rich Trott @Trott (CTC) + * CTC governance doc updates + * onboarded @andrasq, will set up something with @princejwesley next, open to other nominations for after that + * eliminating more flaky tests (IT NEVER ENDS!!!!11!!!) + + +## Agenda + +Extracted from **ctc-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. + +### nodejs/node + +* [meta] realpath issues in v6 [#7726](https://github.com/nodejs/node/issues/7726) +* v4.5.0 proposal [#7688](https://github.com/nodejs/node/pull/7688) +* http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) + +### nodejs/node-eps + +* proposal: WHATWG URL standard implementation [#28](https://github.com/nodejs/node-eps/pull/28) + +## Previous Meeting + +* build: drop support for VS 2013 in v7 [#7484](https://github.com/nodejs/node/pull/7484) + +* Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/pull/7175) + +* http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) + +* v4.5.0 proposal [#7688](https://github.com/nodejs/node/pull/7688) + +* proposal: WHATWG URL standard implementation [#28](https://github.com/nodejs/node-eps/pull/28) + +## Minutes + +### [meta] realpath issues in v6 [#7726](https://github.com/nodejs/node/issues/7726) + +@rvagg: some discussion of reversion to v5 behavior, i.e. JS implementation rather than libuv implementation. + +@trevnorris: looks like everybody’s leaning towards a full revert (or at least a partial revert). I don’t like this plan but will go along. + +@addaleax: Unfortunate to have to do full revert for *nix systems. But having alternate impl for Windows increases maintenance costs. + +As part of the new implementation, the `cache` parameter was removed from the method. It was created to improve perf for the JS impl but is considered less necessary since the native impl performs better anyway. + +Should we reinstate the `cache` parameter as part of the revert? Would this be a semver-major again? Does caching in the JS impl provide a significant perf benefit? + +@addaleax: Benchmarking fs perf will show how much benefit the caching capability in libuv provides. + +@mhdawson: we run two benchmarks nightly: one with caching and one without. + +@orangemocha: It seems okay to have two impl’s, one for Windows and one for *nix, increased maintenance surface isn’t a concern, libuv manages libuv impl. + +@rvagg: As we move v6 to LTS it would be best to have a known-good implementation. So would prefer a full revert, then fix libuv impl independently, then re-integrate. + +@thealphanerd: Could we provide both interfaces? Revert the primary one to original behavior and add a second one with libuv behavior? + +@rvagg: Still doesn’t address breaking change in Windows. + +@fishrock123: also in favor of reverting. This has been going on for a long time, best to revert and then fix. + +@orangemocha: should not compromise correctness for performance. + +@trevnorris: caching could be separated from fs API. For example, it could be part of `module` module. + +@rvagg: This is why I’m in favor of a full reversion. These other discussions may continue for a month and we need to correct problem now. + +@thealphanerd: do we have a list of the original bugs the libuv patch addressed? + +@saghul has a list. + +@rvagg: back to github for now. + +**Next steps**: continue discussion in GH. + +### v4.5.0 proposal [#7688](https://github.com/nodejs/node/pull/7688) + +@thealphanerd is raising visibility for tests and feedback. + +@misterdjules may have some testers. + +### http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) + +@rvagg: Need choices to vote on. + +@ofrobots: Wants to explore more options including `map` so wait for vote. If the goal is to go to a map why don’t we do that now? + +@Fishrock123: Because community has taken dependencies on it being an object. + +@ofrobots: headers end up with “megamorphic IC’s” so wants to research further. + +@Fishrock123: We are fixing this because header names like `__proto__` conflict with default object properties. + +We should really just make an API for headers. + +@rvagg: We’ll come back to this next week. Prepare wording for vote if ready. + +**Next steps**: List available options and conduct vote next week. + + +## Q/A on public fora + +None. + +## Upcoming Meetings + +* CTC: 2016-07-27 +* TSC: 2016-07-28 +* Build: 2016-08-07 +* LTS: 2016-07-25 +* Diagnostics: 2016-08-03 +* Post-Mortem: August +* API: August From cdbeae9adcfe67f54fd21d03a00829c88f5dabf3 Mon Sep 17 00:00:00 2001 From: Josh Gavant Date: Wed, 3 Aug 2016 15:01:46 -0700 Subject: [PATCH 076/144] doc: add CTC meeting minutes 2016-07-13 PR-URL: https://github.com/nodejs/node/pull/7968 Reviewed-By: James M Snell --- doc/ctc-meetings/2016-07-13.md | 236 +++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 doc/ctc-meetings/2016-07-13.md diff --git a/doc/ctc-meetings/2016-07-13.md b/doc/ctc-meetings/2016-07-13.md new file mode 100644 index 00000000000000..467b95deb28754 --- /dev/null +++ b/doc/ctc-meetings/2016-07-13.md @@ -0,0 +1,236 @@ +# Node Foundation CTC Meeting 2016-07-13 + +## Links + +* **Audio Recording**: TBP +* **GitHub Issue**: https://github.com/nodejs/node/issues/7707 +* [Minutes Google Doc](https://docs.google.com/document/d/1fP9_ZNcPoFh2VWCgUFu9-rDiDcMP88vhCC_oX6Aj528) +* _[Previous Minutes Google Doc](https://docs.google.com/document/d/1NWIKwYxDTApvc9Xbq5JTMorRPKIBuBKAA0zcjm8K_II)_ + +## Present + +* Anna Henningsen @addaleax (observer) +* Bradley Meck @bmeck (observer/GoDaddy/TC39) +* Ben Noordhuis @bnoordhuis (CTC) +* Colin Ihrig @cjihrig (CTC) +* Evan Lucas @evanlucas (CTC) +* Jeremiah Senkpiel @Fishrock123 (CTC) +* Fedor Indutny @indutny (CTC) +* Josh Gavant @joshgav (observer/Microsoft) +* Michael Dawson @mhdawson (CTC) +* Brian White @mscdex (CTC) +* Ali Ijaz Sheikh @ofrobots (CTC) +* Alexis Campailla @orangemocha (CTC) +* Rod Vagg @rvagg (CTC) +* Stephen Loomis @srl295 (observer/ICU) +* Myles Borins @TheAlphaNerd (observer) +* Trevor Norris @trevnorris (CTC) +* Rich Trott @Trott (CTC) + + +## Standup + +* Anna Henningsen @addaleax (observer) + * PRs & issues + * Some v4.x backports +* Bradley Meck @bmeck (observer/GoDaddy/TC39) + * Bad news from V8/Chakra. Can’t do property hoisting for Babel like CJS interop. + * Figuring out hooks for creating Modules in older Node versions +* Ben Noordhuis @bnoordhuis (CTC) + * Back-porting patches + * Moving stuff over from malloc() to new[] because of AIX + * ABI compatibility tool + * PRs & issues, of course - how could I forget? +* Colin Ihrig @cjihrig (CTC) + * Reviewed issues and PRs + * Opened a few PRs +* Evan Lucas @evanlucas (CTC) + * Simple doc fix + * Working on cherry-picking into v6.x +* Jeremiah Senkpiel @Fishrock123 (CTC) + * Fixed a TTY test that was silently failing for over a year + * misc PR & issue work +* Fedor Indutny @indutny (CTC) + * Various GYP-related tooling + * Code reviews, and fixing issues +* Josh Gavant @joshgav (observer/Microsoft) + * Diagnostics WG meeting + * debugging docs +* Michael Dawson @mhdawson (CTC) + * Added LinuxOne to v8 tests in CI + * Involvement on some AIX issues + * Working on ABI stable API, API WG meeting this week + * Re-scheduled post-mortem WG meeting for next week, LTS and diagnostic WG meetings + * misc reviews/lands and keeping up on issues +* Brian White @mscdex (CTC) + * Worked on PR to check for accidental git conflict markers when linting in CI + * Backported some commits to v4.x + * Reviewed PRs and commented on issues +* Ali Ijaz Sheikh @ofrobots (CTC) + * Back from vacation, buried in email (sorry for late responses!) +* Alexis Campailla @orangemocha (CTC) + * Investigating ABI incompatibilities. Preparing to drop VS 2013. + * Reviewed miscellaneous Windows issues. + * Resumed work on a PR for case normalization of the module cache on Windows +* Rod Vagg @rvagg (CTC) + * LTS README rework +* Steven Loomis @srl295 (observer/ICU) + * not much here, just trying to keep an eye on issues/PRs +* Myles Borins @TheAlphaNerd (observer) + * Working on v4.5.0 release https://github.com/nodejs/node/pull/7688 + * CITGM Enhancements (XML + Queue) + * Working with V8 team to improve workflow for managing floated commits https://github.com/nodejs/LTS/issues/111 +* Trevor Norris @trevnorris (CTC) + * Working fix for one of the realpath bugs + * Backporting for v4.x + * Working on AsyncWrap implementation details +* Rich Trott @Trott (CTC) + * Trying to handle flaky test outbreak on FreeBSD in CI + * Various ESLint updates/improvements + * Banging my head against test-tick-processor flakiness which is easily the longest-standing flaky test. + + +## Agenda + +Extracted from **ctc-agenda** labelled issues and pull requests from the **nodejs org** prior to the meeting. + +### nodejs/node + +* build: drop support for VS 2013 in v7 [#7484](https://github.com/nodejs/node/pull/7484) +* Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/pull/7175) +* http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) +* v4.5.0 proposal [#7688](https://github.com/nodejs/node/pull/7688) + +### nodejs/node-eps + +* proposal: WHATWG URL standard implementation [#28](https://github.com/nodejs/node-eps/pull/28) + + +## Previous Meeting + +### build: drop support for VS 2013 in v7 [#7484](https://github.com/nodejs/node/issues/7484) (@jasnell) + +To be discussed again. + +### Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/issues/7175) + +@trevnorris was to complete changes, to be discussed again. + +### Replace section 5.1 with unambiguous JavaScript grammar. [#33](https://github.com/nodejs/node-eps/pull/33) + +@jdalton’s proposal was merged. + +### AsyncWrap public API proposal [#18](https://github.com/nodejs/node-eps/pull/18) + +API was accepted, implementation TBD before October. + + +## Minutes + +### build: drop support for VS 2013 in v7 [#7484](https://github.com/nodejs/node/issues/7484) + +@orangemocha: Decision to drop in v7 isn’t controversial. Will need to add tests for modules compiled with 2013 used with Node compiled with 2015. + +@orangemocha: Main question is switching in v6 before LTS. Is it a breaking change? + +Issue with node-sass module only comes up on Windows XP so can be discounted. + +No way to be sure if user modules compiled with 2013 might be incompatible with Node compiled with 2015. Have to run tests. Will CITGM provide sufficient testing? + +@myles: may not be enough native modules in CITGM to provide confidence. + +@Fishrock123: be sure to also test on pre-gyp’ed modules. + +@orangemocha: we may never have complete confidence that this isn’t a breaking change, but node-sass is the only issue ever reported. + +@orangemocha: Should we support modules built with 2013 in v7? +@rvagg: need to include that in tests. + +**Next steps**: Run tests with modules compiled with 2013 to see if there are issues. Keep on agenda for next week and check on progress. + +### Node 6 fs.realpath behavior changes [#7175](https://github.com/nodejs/node/pull/7175) + +* ELOOP fix: https://github.com/nodejs/node/pull/7548 +* Windows PR: https://github.com/nodejs/node/pull/7559 (see also https://github.com/nodejs/node/issues/7192) + +ELOOP issue has been resolved. Windows problem being addressed in another PR. May have to use JS impl for Windows. + +@rvagg: If libuv can’t handle the realpath issue for Windows what should we do? + +@orangemocha: We’re using the JS impl for Windows. + +@trevnorris: we can use the libuv impl and defer to the JS impl if the libuv impl throws unexpectedly. + +@rvagg: should we just revert? How common is the case where this provides a speed-up? + +@trevnorris: keep both libuv and js impl for now. + +**Next steps**: All please review #7548 and #7559. + +### http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) + +@mscdex: Prevent clash of header names with properties inherited from Object (e.g., __proto__). An object with a null prototype is already being used for the same purpose in `querystring.parse` since v6 release. + +@mscdex: Some have suggested cherry-picking some methods from Object such as `toString`: + + * So that object can be inspected. + * To ensure backward compatibility. + +@mscdex: An eventual goal may be to store headers in an ES6 Map instead of on a plain object, but that will change the API considerably. + +@evanlucas: we should follow what we did with query string parameters. + +@rvagg: first need to review as some opposition to that. + +**Next steps**: All review PR. + +### proposal: WHATWG URL standard implementation [node-eps#28](https://github.com/nodejs/node-eps/pull/28) + +@trevnorris: Some discussion about supporting unregistered schemes (e.g. `chrome://`). We should support them, Chrome supports them. + +@trevnorris: `url.parse` can handle incomplete URLs (e.g. no scheme). + +@rvagg: Most important question is should `URL` be a global? There would be a `url` module and a different `URL` global. + +@fishrock123: there would be a transition period and then functionality would be in `URL` + +@rvagg: new impl is quite different from existing `url` module. Would like to see a diff. Migration will be difficult. + +**Next steps**: Waiting for @jasnell to return. Review again next week. + +### v4.5.0 proposal [#7688](https://github.com/nodejs/node/pull/7688) + +@thealphanerd: + +* Would like to include libuv v1.9.1. +* Would like very extensive testing prior to release to exclude breaking changes. + +How can we best test? + +@rvagg: Promote the RC on social media. + +@thealphanerd: npm could help test, Myles will reach out. + +@rvagg: Heroku? (Hunter Loftis) Travis CI? Probably not because it depends on nvm which doesn’t do RC’s yet. + +@thealphanerd: will talk with @ljharb about nvm support for RCs. + +**Next steps**: @thealphanerd will ping all to test RC. + +### ES Modules update + +@bmeck: named imports from CJS modules (e.g. `import {use, route} from "express"` or `import {readFile, readFileSync} from "fs"`) can’t work. + +Updates to come on the topic via: https://github.com/nodejs/node-eps/issues/26 + +## Q/A on public fora + +## Upcoming Meetings + +* CTC: 2016-07-20 +* TSC: 2016-07-14 +* Diagnostics: 2016-08-03 +* Post-Mortem: 2016-07-18 +* API: 2016-07-14 +* LTS: 2016-07-25 +* Build: 2016-07-19 From cb16e97e9f5db5a171747a659ad3b8320a25515f Mon Sep 17 00:00:00 2001 From: Josh Gavant Date: Wed, 3 Aug 2016 14:35:48 -0700 Subject: [PATCH 077/144] tools: add .vscode folder to .gitignore PR-URL: https://github.com/nodejs/node/pull/7967 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Jackson Tian --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c7361af80c79dc..ade43c5baaf432 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ ipch/ *.opensdf *.VC.opendb .vs/ +.vscode/ /config.mk /config.gypi From b5beae25294b66386a9548a970ef964f6039ff5c Mon Sep 17 00:00:00 2001 From: Gibson Fahnestock Date: Tue, 2 Aug 2016 10:58:03 +0100 Subject: [PATCH 078/144] test: remove internal headers from addons PR-URL: https://github.com/nodejs/node/pull/7947 Reviewed-By: Colin Ihrig Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- test/addons/openssl-binding/binding.cc | 5 +---- test/addons/parse-encoding/binding.cc | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/test/addons/openssl-binding/binding.cc b/test/addons/openssl-binding/binding.cc index 59819cd33d2a38..582a94478d26ca 100644 --- a/test/addons/openssl-binding/binding.cc +++ b/test/addons/openssl-binding/binding.cc @@ -1,7 +1,4 @@ -#include "node.h" -#include "../../../src/util.h" -#include "../../../src/util-inl.h" - +#include #include #include diff --git a/test/addons/parse-encoding/binding.cc b/test/addons/parse-encoding/binding.cc index 062e9cb275f082..0a31569e039691 100644 --- a/test/addons/parse-encoding/binding.cc +++ b/test/addons/parse-encoding/binding.cc @@ -1,5 +1,5 @@ -#include "node.h" -#include "v8.h" +#include +#include namespace { From 7c427bdccc05384e7548c2d2e42c451d1d82aac1 Mon Sep 17 00:00:00 2001 From: Bryan English Date: Mon, 6 Jun 2016 16:28:50 -0700 Subject: [PATCH 079/144] doc: clarify "Reviewed-By" iff "LGTM" As per conversation with @Trott, make it clear that Reviewed-By lines should only be added for collaborators who've actually put a LGTM on the PR. PR-URL: https://github.com/nodejs/node/pull/7183 Reviewed-By: Myles Borins Reviewed-By: Evan Lucas Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: JacksonTian - Jackson Tian --- doc/onboarding.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/onboarding.md b/doc/onboarding.md index 99fbc61935c84d..f75a2637413309 100644 --- a/doc/onboarding.md +++ b/doc/onboarding.md @@ -169,6 +169,7 @@ Landing a PR * `Reviewed-By: human ` * Easiest to use `git log` then do a search * (`/Name` + `enter` (+ `n` as much as you need to) in vim) + * Only include collaborators who have commented "LGTM" * `PR-URL: ` * `git push upstream master` * close the original PR with "Landed in ``". From 7fa4be0f87d93dce8cbea10dfaf239404febbc89 Mon Sep 17 00:00:00 2001 From: Phillip Johnsen Date: Thu, 4 Aug 2016 09:47:06 +0200 Subject: [PATCH 080/144] doc: improve server.listen() random port Minor rewording related to making a server listen to a random port, and added how to retrieve which port was randomly chosen by the OS. Also changed documented `server.listen()` signature as it does in fact not require `port` to be provided. PR-URL: https://github.com/nodejs/node/pull/7976 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- doc/api/http.md | 8 +++++--- doc/api/net.md | 17 +++++++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/doc/api/http.md b/doc/api/http.md index 8bd8da55701b16..d263068bd68fc0 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -691,15 +691,17 @@ Start a UNIX socket server listening for connections on the given `path`. This function is asynchronous. `callback` will be added as a listener for the [`'listening'`][] event. See also [`net.Server.listen(path)`][]. -### server.listen(port[, hostname][, backlog][, callback]) +### server.listen([port][, hostname][, backlog][, callback]) Begin accepting connections on the specified `port` and `hostname`. If the `hostname` is omitted, the server will accept connections on any IPv6 address -(`::`) when IPv6 is available, or any IPv4 address (`0.0.0.0`) otherwise. Use a -port value of `0` to have the operating system assign an available port. +(`::`) when IPv6 is available, or any IPv4 address (`0.0.0.0`) otherwise. +Omit the port argument, or use a port value of `0`, to have the operating system +assign a random port, which can be retrieved by using `server.address().port` +after the `'listening'` event has been emitted. To listen to a unix socket, supply a filename instead of port and hostname. diff --git a/doc/api/net.md b/doc/api/net.md index 18090093ea038d..d58d00edbdba2b 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -73,8 +73,7 @@ var server = net.createServer((socket) => { // grab a random port. server.listen(() => { - address = server.address(); - console.log('opened server on %j', address); + console.log('opened server on', server.address()); }); ``` @@ -140,7 +139,7 @@ The last parameter `callback` will be added as a listener for the [`'listening'`][] event. The parameter `backlog` behaves the same as in -[`server.listen(port[, hostname][, backlog][, callback])`][`server.listen(port, host, backlog, callback)`]. +[`server.listen([port][, hostname][, backlog][, callback])`][`server.listen(port, host, backlog, callback)`]. ### server.listen(options[, callback]) Begin accepting connections on the specified `port` and `hostname`. If the `hostname` is omitted, the server will accept connections on any IPv6 address -(`::`) when IPv6 is available, or any IPv4 address (`0.0.0.0`) otherwise. Use a -port value of `0` to have the operating system assign an available port. +(`::`) when IPv6 is available, or any IPv4 address (`0.0.0.0`) otherwise. +Omit the port argument, or use a port value of `0`, to have the operating system +assign a random port, which can be retrieved by using `server.address().port` +after the `'listening'` event has been emitted. Backlog is the maximum length of the queue of pending connections. The actual length will be determined by the OS through sysctl settings such as From b20518a0131b3b2ab09fa1dacf11393dfb386b70 Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Thu, 21 Jul 2016 15:58:56 +0200 Subject: [PATCH 081/144] doc: add `added:` information for events PR-URL: https://github.com/nodejs/node/pull/7822 Reviewed-By: James M Snell Reviewed-By: Brian White --- doc/api/events.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/doc/api/events.md b/doc/api/events.md index 32198fa5194f9c..eab0bef17ed199 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -167,6 +167,9 @@ myEmitter.emit('error', new Error('whoops!')); ``` ## Class: EventEmitter + The `EventEmitter` class is defined and exposed by the `events` module: @@ -178,6 +181,9 @@ All EventEmitters emit the event `'newListener'` when new listeners are added and `'removeListener'` when existing listeners are removed. ### Event: 'newListener' + * `eventName` {String|Symbol} The name of the event being listened for * `listener` {Function} The event handler function @@ -214,6 +220,9 @@ myEmitter.emit('event'); ``` ### Event: 'removeListener' + * `eventName` {String|Symbol} The event name * `listener` {Function} The event handler function @@ -221,6 +230,10 @@ myEmitter.emit('event'); The `'removeListener'` event is emitted *after* the `listener` is removed. ### EventEmitter.listenerCount(emitter, eventName) + > Stability: 0 - Deprecated: Use [`emitter.listenerCount()`][] instead. @@ -236,6 +249,9 @@ console.log(EventEmitter.listenerCount(myEmitter, 'event')); ``` ### EventEmitter.defaultMaxListeners + By default, a maximum of `10` listeners can be registered for any single event. This limit can be changed for individual `EventEmitter` instances @@ -263,10 +279,16 @@ emitter.once('event', () => { ``` ### emitter.addListener(eventName, listener) + Alias for `emitter.on(eventName, listener)`. ### emitter.emit(eventName[, arg1][, arg2][, ...]) + Synchronously calls each of the listeners registered for the event named `eventName`, in the order they were registered, passing the supplied arguments @@ -275,6 +297,9 @@ to each. Returns `true` if the event had listeners, `false` otherwise. ### emitter.eventNames() + Returns an array listing the events for which the emitter has registered listeners. The values in the array will be strings or Symbols. @@ -293,18 +318,27 @@ console.log(myEE.eventNames()); ``` ### emitter.getMaxListeners() + Returns the current max listener value for the `EventEmitter` which is either set by [`emitter.setMaxListeners(n)`][] or defaults to [`EventEmitter.defaultMaxListeners`][]. ### emitter.listenerCount(eventName) + * `eventName` {String|Symbol} The name of the event being listened for Returns the number of listeners listening to the event named `eventName`. ### emitter.listeners(eventName) + Returns a copy of the array of listeners for the event named `eventName`. @@ -317,6 +351,9 @@ console.log(util.inspect(server.listeners('connection'))); ``` ### emitter.on(eventName, listener) + * `eventName` {String|Symbol} The name of the event. * `listener` {Function} The callback function @@ -350,6 +387,9 @@ myEE.emit('foo'); ``` ### emitter.once(eventName, listener) + * `eventName` {String|Symbol} The name of the event. * `listener` {Function} The callback function @@ -380,6 +420,9 @@ myEE.emit('foo'); ``` ### emitter.prependListener(eventName, listener) + * `eventName` {String|Symbol} The name of the event. * `listener` {Function} The callback function @@ -399,6 +442,9 @@ server.prependListener('connection', (stream) => { Returns a reference to the `EventEmitter`, so that calls can be chained. ### emitter.prependOnceListener(eventName, listener) + * `eventName` {String|Symbol} The name of the event. * `listener` {Function} The callback function @@ -416,6 +462,9 @@ server.prependOnceListener('connection', (stream) => { Returns a reference to the `EventEmitter`, so that calls can be chained. ### emitter.removeAllListeners([eventName]) + Removes all listeners, or those of the specified `eventName`. @@ -426,6 +475,9 @@ component or module (e.g. sockets or file streams). Returns a reference to the `EventEmitter`, so that calls can be chained. ### emitter.removeListener(eventName, listener) + Removes the specified `listener` from the listener array for the event named `eventName`. @@ -490,6 +542,9 @@ the `emitter.listeners()` method will need to be recreated. Returns a reference to the `EventEmitter`, so that calls can be chained. ### emitter.setMaxListeners(n) + By default EventEmitters will print a warning if more than `10` listeners are added for a particular event. This is a useful default that helps finding From 4875aa2aa20445ca754dc46db381e02b4f42a486 Mon Sep 17 00:00:00 2001 From: Prince J Wesley Date: Sun, 12 Jun 2016 13:37:33 +0530 Subject: [PATCH 082/144] repl: Add editor mode support ```js > node > .editor // Entering editor mode (^D to finish, ^C to cancel) function test() { console.log('tested!'); } test(); // ^D tested! undefined > ``` PR-URL: https://github.com/nodejs/node/pull/7275 Reviewed-By: James M Snell Reviewed-By: Evan Lucas --- doc/api/repl.md | 15 +++ lib/repl.js | 117 +++++++++++++++++++++++- test/parallel/test-repl-.editor.js | 55 +++++++++++ test/parallel/test-repl-tab-complete.js | 22 +++++ 4 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 test/parallel/test-repl-.editor.js diff --git a/doc/api/repl.md b/doc/api/repl.md index c4cc092ab29f24..d8b86f9ef6a47d 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -38,6 +38,21 @@ The following special commands are supported by all REPL instances: `> .save ./file/to/save.js` * `.load` - Load a file into the current REPL session. `> .load ./file/to/load.js` +* `.editor` - Enter editor mode (`-D` to finish, `-C` to cancel) + +```js +> .editor +// Entering editor mode (^D to finish, ^C to cancel) +function welcome(name) { + return `Hello ${name}!`; +} + +welcome('Node.js User'); + +// ^D +'Hello Node.js User!' +> +``` The following key combinations in the REPL have these special effects: diff --git a/lib/repl.js b/lib/repl.js index d6eedffa3c4dc8..dfe85c6fcfc58e 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -223,6 +223,7 @@ function REPLServer(prompt, self.underscoreAssigned = false; self.last = undefined; self.breakEvalOnSigint = !!breakEvalOnSigint; + self.editorMode = false; self._inTemplateLiteral = false; @@ -394,7 +395,12 @@ function REPLServer(prompt, // Figure out which "complete" function to use. self.completer = (typeof options.completer === 'function') ? options.completer - : complete; + : completer; + + function completer(text, cb) { + complete.call(self, text, self.editorMode + ? self.completeOnEditorMode(cb) : cb); + } Interface.call(this, { input: self.inputStream, @@ -428,9 +434,11 @@ function REPLServer(prompt, }); var sawSIGINT = false; + var sawCtrlD = false; self.on('SIGINT', function() { var empty = self.line.length === 0; self.clearLine(); + self.turnOffEditorMode(); if (!(self.bufferedCommand && self.bufferedCommand.length > 0) && empty) { if (sawSIGINT) { @@ -454,6 +462,11 @@ function REPLServer(prompt, debug('line %j', cmd); sawSIGINT = false; + if (self.editorMode) { + self.bufferedCommand += cmd + '\n'; + return; + } + // leading whitespaces in template literals should not be trimmed. if (self._inTemplateLiteral) { self._inTemplateLiteral = false; @@ -499,7 +512,8 @@ function REPLServer(prompt, // If error was SyntaxError and not JSON.parse error if (e) { - if (e instanceof Recoverable && !self.lineParser.shouldFail) { + if (e instanceof Recoverable && !self.lineParser.shouldFail && + !sawCtrlD) { // Start buffering data like that: // { // ... x: 1 @@ -515,6 +529,7 @@ function REPLServer(prompt, // Clear buffer if no SyntaxErrors self.lineParser.reset(); self.bufferedCommand = ''; + sawCtrlD = false; // If we got any output - print it (if no error) if (!e && @@ -555,9 +570,55 @@ function REPLServer(prompt, }); self.on('SIGCONT', function() { - self.displayPrompt(true); + if (self.editorMode) { + self.outputStream.write(`${self._initialPrompt}.editor\n`); + self.outputStream.write( + '// Entering editor mode (^D to finish, ^C to cancel)\n'); + self.outputStream.write(`${self.bufferedCommand}\n`); + self.prompt(true); + } else { + self.displayPrompt(true); + } }); + // Wrap readline tty to enable editor mode + const ttyWrite = self._ttyWrite.bind(self); + self._ttyWrite = (d, key) => { + if (!self.editorMode || !self.terminal) { + ttyWrite(d, key); + return; + } + + // editor mode + if (key.ctrl && !key.shift) { + switch (key.name) { + case 'd': // End editor mode + self.turnOffEditorMode(); + sawCtrlD = true; + ttyWrite(d, { name: 'return' }); + break; + case 'n': // Override next history item + case 'p': // Override previous history item + break; + default: + ttyWrite(d, key); + } + } else { + switch (key.name) { + case 'up': // Override previous history item + case 'down': // Override next history item + break; + case 'tab': + // prevent double tab behavior + self._previousKey = null; + ttyWrite(d, key); + break; + default: + ttyWrite(d, key); + } + } + }; + self.displayPrompt(); } inherits(REPLServer, Interface); @@ -680,6 +741,12 @@ REPLServer.prototype.setPrompt = function setPrompt(prompt) { REPLServer.super_.prototype.setPrompt.call(this, prompt); }; +REPLServer.prototype.turnOffEditorMode = function() { + this.editorMode = false; + this.setPrompt(this._initialPrompt); +}; + + // A stream to push an array into a REPL // used in REPLServer.complete function ArrayStream() { @@ -987,6 +1054,39 @@ function complete(line, callback) { } } +function longestCommonPrefix(arr = []) { + const cnt = arr.length; + if (cnt === 0) return ''; + if (cnt === 1) return arr[0]; + + const first = arr[0]; + // complexity: O(m * n) + for (let m = 0; m < first.length; m++) { + const c = first[m]; + for (let n = 1; n < cnt; n++) { + const entry = arr[n]; + if (m >= entry.length || c !== entry[m]) { + return first.substring(0, m); + } + } + } + return first; +} + +REPLServer.prototype.completeOnEditorMode = (callback) => (err, results) => { + if (err) return callback(err); + + const [completions, completeOn = ''] = results; + const prefixLength = completeOn.length; + + if (prefixLength === 0) return callback(null, [[], completeOn]); + + const isNotEmpty = (v) => v.length > 0; + const trimCompleteOnPrefix = (v) => v.substring(prefixLength); + const data = completions.filter(isNotEmpty).map(trimCompleteOnPrefix); + + callback(null, [[`${completeOn}${longestCommonPrefix(data)}`], completeOn]); +}; /** * Used to parse and execute the Node REPL commands. @@ -1189,6 +1289,17 @@ function defineDefaultCommands(repl) { this.displayPrompt(); } }); + + repl.defineCommand('editor', { + help: 'Entering editor mode (^D to finish, ^C to cancel)', + action() { + if (!this.terminal) return; + this.editorMode = true; + REPLServer.super_.prototype.setPrompt.call(this, ''); + this.outputStream.write( + '// Entering editor mode (^D to finish, ^C to cancel)\n'); + } + }); } function regexpEscape(s) { diff --git a/test/parallel/test-repl-.editor.js b/test/parallel/test-repl-.editor.js new file mode 100644 index 00000000000000..15765ad517d72a --- /dev/null +++ b/test/parallel/test-repl-.editor.js @@ -0,0 +1,55 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const repl = require('repl'); + +// \u001b[1G - Moves the cursor to 1st column +// \u001b[0J - Clear screen +// \u001b[3G - Moves the cursor to 3rd column +const terminalCode = '\u001b[1G\u001b[0J> \u001b[3G'; + +function run(input, output, event) { + const stream = new common.ArrayStream(); + let found = ''; + + stream.write = (msg) => found += msg.replace('\r', ''); + + const expected = `${terminalCode}.editor\n` + + '// Entering editor mode (^D to finish, ^C to cancel)\n' + + `${input}${output}\n${terminalCode}`; + + const replServer = repl.start({ + prompt: '> ', + terminal: true, + input: stream, + output: stream, + useColors: false + }); + + stream.emit('data', '.editor\n'); + stream.emit('data', input); + replServer.write('', event); + replServer.close(); + assert.strictEqual(found, expected); +} + +const tests = [ + { + input: '', + output: '\n(To exit, press ^C again or type .exit)', + event: {ctrl: true, name: 'c'} + }, + { + input: 'var i = 1;', + output: '', + event: {ctrl: true, name: 'c'} + }, + { + input: 'var i = 1;\ni + 3', + output: '\n4', + event: {ctrl: true, name: 'd'} + } +]; + +tests.forEach(({input, output, event}) => run(input, output, event)); diff --git a/test/parallel/test-repl-tab-complete.js b/test/parallel/test-repl-tab-complete.js index 73a3fd148bf524..4ff4371875c8c2 100644 --- a/test/parallel/test-repl-tab-complete.js +++ b/test/parallel/test-repl-tab-complete.js @@ -348,3 +348,25 @@ testCustomCompleterAsyncMode.complete('a', common.mustCall((error, data) => { 'a' ]); })); + +// tab completion in editor mode +const editorStream = new common.ArrayStream(); +const editor = repl.start({ + stream: editorStream, + terminal: true, + useColors: false +}); + +editorStream.run(['.clear']); +editorStream.run(['.editor']); + +editor.completer('co', common.mustCall((error, data) => { + assert.deepStrictEqual(data, [['con'], 'co']); +})); + +editorStream.run(['.clear']); +editorStream.run(['.editor']); + +editor.completer('var log = console.l', common.mustCall((error, data) => { + assert.deepStrictEqual(data, [['console.log'], 'console.l']); +})); From d37a17ec5fb2193f1766b2a37a5a7d2b914e4ce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BA=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=90=D0=BD=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Thu, 14 Jul 2016 12:46:04 +0300 Subject: [PATCH 083/144] tools: add remark-lint configuration in .remarkrc Specifies the configuration for remark-lint, a markdown linter. This configuration does not cause any warnings on any of the currently present *.md files (ignoring thirdparty). It is useful not only for possible future tooling that would check the markdown files syntax, but also as a configuration for editor plugins, e.g. linter-markdown for atom-linter. Refs: https://github.com/nodejs/node/pull/7637 Refs: https://github.com/nodejs/node/pull/7727 Refs: https://github.com/nodejs/node/pull/7757 PR-URL: https://github.com/nodejs/node/pull/7729 Reviewed-By: Colin Ihrig Reviewed-By: Rich Trott Reviewed-By: James M Snell Reviewed-By: Anna Henningsen Reviewed-By: Robert Jefe Lindstaedt --- .remarkrc | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .remarkrc diff --git a/.remarkrc b/.remarkrc new file mode 100644 index 00000000000000..d00f2c2488286d --- /dev/null +++ b/.remarkrc @@ -0,0 +1,35 @@ +{ + "plugins": { + "remark-lint": { + "code-block-style": false, + "definition-case": false, + "emphasis-marker": false, + "first-heading-level": false, + "heading-increment": false, + "list-item-content-indent": false, + "list-item-bullet-indent": false, + "list-item-indent": false, + "list-item-spacing": false, + "maximum-heading-length": false, + "maximum-line-length": false, + "no-consecutive-blank-lines": false, + "no-duplicate-headings": false, + "no-emphasis-as-heading": false, + "no-file-name-articles": false, + "no-file-name-irregular-characters": false, + "no-heading-punctuation": false, + "no-html": false, + "no-inline-padding": false, + "no-shell-dollars": false, + "no-shortcut-reference-link": false, + "no-literal-urls": false, + "no-missing-blank-lines": false, + "no-multiple-toplevel-headings": false, + "no-undefined-references": false, + "ordered-list-marker-style": false, + "ordered-list-marker-value": false, + "table-pipe-alignment": false, + "unordered-list-marker-style": false + } + } +} From ce776d22f950eee166fea5792c2737c25a92b106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=BA=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=90=D0=BD=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Sat, 6 Aug 2016 00:34:04 +0300 Subject: [PATCH 084/144] doc: fix a markdown error in CTC meeting minutes This fixes a markdown formatting error in 2016-07-13 CTC meeting minutes, __proto__ was rendered incorrectly. This was found by remark-lint. PR-URL: https://github.com/nodejs/node/pull/7729 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Robert Jefe Lindstaedt --- doc/ctc-meetings/2016-07-13.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/ctc-meetings/2016-07-13.md b/doc/ctc-meetings/2016-07-13.md index 467b95deb28754..0c38f3b066a13a 100644 --- a/doc/ctc-meetings/2016-07-13.md +++ b/doc/ctc-meetings/2016-07-13.md @@ -169,7 +169,7 @@ ELOOP issue has been resolved. Windows problem being addressed in another PR. Ma ### http: don't inherit from Object.prototype [#6102](https://github.com/nodejs/node/pull/6102) -@mscdex: Prevent clash of header names with properties inherited from Object (e.g., __proto__). An object with a null prototype is already being used for the same purpose in `querystring.parse` since v6 release. +@mscdex: Prevent clash of header names with properties inherited from Object (e.g., `__proto__`). An object with a null prototype is already being used for the same purpose in `querystring.parse` since v6 release. @mscdex: Some have suggested cherry-picking some methods from Object such as `toString`: From 909254c901a860175d56aae75a43b6e27a9b7e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Fri, 5 Aug 2016 18:01:49 +0200 Subject: [PATCH 085/144] zlib: remove unneeded property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/7987 Reviewed-By: Colin Ihrig Reviewed-By: Anna Henningsen Reviewed-By: Brian White Reviewed-By: Johan Bergström --- src/node_zlib.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/node_zlib.cc b/src/node_zlib.cc index a72e1d1f233c01..977eb58671c0ff 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -54,7 +54,6 @@ class ZCtx : public AsyncWrap { public: ZCtx(Environment* env, Local wrap, node_zlib_mode mode) : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_ZLIB), - chunk_size_(0), dictionary_(nullptr), dictionary_len_(0), err_(0), @@ -179,9 +178,6 @@ class ZCtx : public AsyncWrap { ctx->strm_.next_out = out; ctx->flush_ = flush; - // set this so that later on, I can easily tell how much was written. - ctx->chunk_size_ = out_len; - if (!async) { // sync version ctx->env()->PrintSyncTrace(); @@ -625,7 +621,6 @@ class ZCtx : public AsyncWrap { static const int kDeflateContextSize = 16384; // approximate static const int kInflateContextSize = 10240; // approximate - int chunk_size_; Bytef* dictionary_; size_t dictionary_len_; int err_; From a385277eb5869d5c9366a662f64509d6c6edb50e Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Thu, 4 Aug 2016 23:48:03 +0200 Subject: [PATCH 086/144] test: fix flaky test-vm-sigint-existing-handler Set the `SIGUSR2` handler before spawning the child process to make sure the signal is always handled. Ref: https://github.com/nodejs/node/pull/7854 Fixes: https://github.com/nodejs/node/issues/7981 PR-URL: https://github.com/nodejs/node/pull/7982 Reviewed-By: James M Snell Reviewed-By: Michael Dawson Reviewed-By: Colin Ihrig --- test/parallel/test-vm-sigint-existing-handler.js | 9 ++++++--- test/parallel/test-vm-sigint.js | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/test/parallel/test-vm-sigint-existing-handler.js b/test/parallel/test-vm-sigint-existing-handler.js index 0f86b53dd282be..c0ab1f8d92b821 100644 --- a/test/parallel/test-vm-sigint-existing-handler.js +++ b/test/parallel/test-vm-sigint-existing-handler.js @@ -61,16 +61,19 @@ if (process.argv[2] === 'child') { } process.env.REPL_TEST_PPID = process.pid; -const child = spawn(process.execPath, [ __filename, 'child' ], { - stdio: [null, 'inherit', 'inherit'] -}); +// Set the `SIGUSR2` handler before spawning the child process to make sure +// the signal is always handled. process.on('SIGUSR2', common.mustCall(() => { // First kill() breaks the while(true) loop, second one invokes the real // signal handlers. process.kill(child.pid, 'SIGINT'); }, 3)); +const child = spawn(process.execPath, [__filename, 'child'], { + stdio: [null, 'inherit', 'inherit'] +}); + child.on('close', function(code, signal) { assert.strictEqual(signal, null); assert.strictEqual(code, 0); diff --git a/test/parallel/test-vm-sigint.js b/test/parallel/test-vm-sigint.js index 15d61d3232871a..8846338b78086c 100644 --- a/test/parallel/test-vm-sigint.js +++ b/test/parallel/test-vm-sigint.js @@ -25,11 +25,14 @@ if (process.argv[2] === 'child') { } process.env.REPL_TEST_PPID = process.pid; + +// Set the `SIGUSR2` handler before spawning the child process to make sure +// the signal is always handled. process.on('SIGUSR2', common.mustCall(() => { process.kill(child.pid, 'SIGINT'); })); -const child = spawn(process.execPath, [ __filename, 'child' ], { +const child = spawn(process.execPath, [__filename, 'child'], { stdio: [null, 'pipe', 'inherit'] }); From c843e589145448bd51f313a9d8134667b6d47044 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Fri, 5 Aug 2016 04:36:40 +0200 Subject: [PATCH 087/144] build: export zlib symbols on Windows Base the generated openssl.def on existing zlib.def. We cannot specify more than one DEF file per executable so we need to merge the two DEF files to expose both OpenSSL and Zlib functionality to addons. If OpenSSL is not used, link against zlib.def itself. PR-URL: https://github.com/nodejs/node/pull/7983 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- node.gyp | 7 +++++++ tools/mkssldef.py | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/node.gyp b/node.gyp index a14aa5813243ba..4cb368a8c6f334 100644 --- a/node.gyp +++ b/node.gyp @@ -372,9 +372,14 @@ '-Wl,--no-whole-archive', ], }], + # openssl.def is based on zlib.def, zlib symbols + # are always exported. ['use_openssl_def==1', { 'sources': ['<(SHARED_INTERMEDIATE_DIR)/openssl.def'], }], + ['OS=="win" and use_openssl_def==0', { + 'sources': ['deps/zlib/win32/zlib.def'], + }], ], }], ], @@ -570,6 +575,8 @@ '-X^DSO', '-X^_', '-X^private_', + # Base generated DEF on zlib.def + '-Bdeps/zlib/win32/zlib.def' ], }, 'conditions': [ diff --git a/tools/mkssldef.py b/tools/mkssldef.py index 8cbdbabd976ba9..8354e5712ef099 100755 --- a/tools/mkssldef.py +++ b/tools/mkssldef.py @@ -7,6 +7,7 @@ categories = [] defines = [] excludes = [] +bases = [] if __name__ == '__main__': out = sys.stdout @@ -18,6 +19,7 @@ elif option.startswith('-C'): categories += option[2:].split(',') elif option.startswith('-D'): defines += option[2:].split(',') elif option.startswith('-X'): excludes += option[2:].split(',') + elif option.startswith('-B'): bases += option[2:].split(',') excludes = map(re.compile, excludes) exported = [] @@ -40,5 +42,12 @@ def test(expr): if not satisfy(meta[3], categories): continue exported.append(name) + for filename in bases: + for line in open(filename).readlines(): + line = line.strip() + if line == 'EXPORTS': continue + if line[0] == ';': continue + exported.append(line) + print('EXPORTS', file=out) for name in sorted(exported): print(' ', name, file=out) From dedfcb7858c386a9e42a9539d4434d1f42b2c768 Mon Sep 17 00:00:00 2001 From: kibertoad Date: Wed, 6 Jul 2016 15:12:58 +0300 Subject: [PATCH 088/144] doc: clarify fd closing by `fs.readFile` etc. Ref: https://github.com/nodejs/node/issues/7560 PR-URL: https://github.com/nodejs/node/pull/7561 Reviewed-By: James M Snell Reviewed-By: Anna Henningsen --- doc/api/fs.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index 1984b5642e305b..32ffed51c071e6 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -384,7 +384,8 @@ fs.appendFile('message.txt', 'data to append', 'utf8', callback); Any specified file descriptor has to have been opened for appending. -_Note: Specified file descriptors will not be closed automatically._ +_Note: If a file descriptor is specified as the `file`, it will not be closed +automatically._ ## fs.appendFileSync(file, data[, options]) + +The `process.argv0` property stores a read-only copy of the original value of +`argv[0]` passed when Node.js starts. + +```js +$ bash -c 'exec -a customArgv0 ./node' +> process.argv[0] +'/Volumes/code/external/node/out/Release/node' +> process.argv0 +'customArgv0' +``` + ## process.chdir(directory) + +The number of bytes read so far. + ### readStream.path A Worker object contains all public information and method about a worker. In the master it can be obtained using `cluster.workers`. In a worker it can be obtained using `cluster.worker`. ### Event: 'disconnect' + Similar to the `cluster.on('disconnect')` event, but specific to this worker. @@ -124,12 +130,18 @@ cluster.fork().on('disconnect', () => { ``` ### Event: 'error' + This event is the same as the one provided by [`child_process.fork()`][]. In a worker you can also use `process.on('error')`. ### Event: 'exit' + * `code` {Number} the exit code, if it exited normally. * `signal` {String} the name of the signal (eg. `'SIGHUP'`) that caused @@ -151,6 +163,9 @@ worker.on('exit', (code, signal) => { ``` ### Event: 'listening' + * `address` {Object} @@ -165,6 +180,9 @@ cluster.fork().on('listening', (address) => { It is not emitted in the worker. ### Event: 'message' + * `message` {Object} * `handle` {undefined|Object} @@ -220,6 +238,9 @@ if (cluster.isMaster) { ``` ### Event: 'online' + Similar to the `cluster.on('online')` event, but specific to this worker. @@ -232,6 +253,9 @@ cluster.fork().on('online', () => { It is not emitted in the worker. ### worker.disconnect() + In a worker, this function will close all servers, wait for the `'close'` event on those servers, and then disconnect the IPC channel. @@ -293,6 +317,9 @@ if (cluster.isMaster) { ``` ### worker.exitedAfterDisconnect + * {Boolean} @@ -314,6 +341,9 @@ worker.kill(); ``` ### worker.id + * {Number} @@ -324,17 +354,26 @@ While a worker is alive, this is the key that indexes it in cluster.workers ### worker.isConnected() + This function returns `true` if the worker is connected to its master via its IPC channel, `false` otherwise. A worker is connected to its master after it's been created. It is disconnected after the `'disconnect'` event is emitted. ### worker.isDead() + This function returns `true` if the worker's process has terminated (either because of exiting or being signaled). Otherwise, it returns `false`. ### worker.kill([signal='SIGTERM']) + * `signal` {String} Name of the kill signal to send to the worker process. @@ -351,6 +390,9 @@ Note that in a worker, `process.kill()` exists, but it is not this function, it is [`kill`][]. ### worker.process + * {ChildProcess} @@ -365,6 +407,9 @@ on `process` and `.exitedAfterDisconnect` is not `true`. This protects against accidental disconnection. ### worker.send(message[, sendHandle][, callback]) + * `message` {Object} * `sendHandle` {Handle} @@ -394,6 +439,10 @@ if (cluster.isMaster) { ``` ### worker.suicide + > Stability: 0 - Deprecated: Use [`worker.exitedAfterDisconnect`][] instead. @@ -420,6 +469,9 @@ This API only exists for backwards compatibility and will be removed in the future. ## Event: 'disconnect' + * `worker` {cluster.Worker} @@ -438,6 +490,9 @@ cluster.on('disconnect', (worker) => { ``` ## Event: 'exit' + * `worker` {cluster.Worker} * `code` {Number} the exit code, if it exited normally. @@ -459,6 +514,9 @@ cluster.on('exit', (worker, code, signal) => { See [child_process event: 'exit'][]. ## Event: 'fork' + * `worker` {cluster.Worker} @@ -484,6 +542,9 @@ cluster.on('exit', (worker, code, signal) => { ``` ## Event: 'listening' + * `worker` {cluster.Worker} * `address` {Object} @@ -538,6 +599,9 @@ cluster.on('message', function(worker, message, handle) { ``` ## Event: 'online' + * `worker` {cluster.Worker} @@ -553,6 +617,9 @@ cluster.on('online', (worker) => { ``` ## Event: 'setup' + * `settings` {Object} @@ -565,6 +632,9 @@ The `settings` object is the `cluster.settings` object at the time If accuracy is important, use `cluster.settings`. ## cluster.disconnect([callback]) + * `callback` {Function} called when all workers are disconnected and handles are closed @@ -579,6 +649,9 @@ The method takes an optional callback argument which will be called when finishe This can only be called from the master process. ## cluster.fork([env]) + * `env` {Object} Key/value pairs to add to worker process environment. * return {cluster.Worker} @@ -588,6 +661,9 @@ Spawn a new worker process. This can only be called from the master process. ## cluster.isMaster + * {Boolean} @@ -596,12 +672,18 @@ by the `process.env.NODE_UNIQUE_ID`. If `process.env.NODE_UNIQUE_ID` is undefined, then `isMaster` is `true`. ## cluster.isWorker + * {Boolean} True if the process is not a master (it is the negation of `cluster.isMaster`). ## cluster.schedulingPolicy + The scheduling policy, either `cluster.SCHED_RR` for round-robin or `cluster.SCHED_NONE` to leave it to the operating system. This is a @@ -617,6 +699,9 @@ distribute IOCP handles without incurring a large performance hit. values are `"rr"` and `"none"`. ## cluster.settings + * {Object} * `execArgv` {Array} list of string arguments passed to the Node.js @@ -638,6 +723,9 @@ the settings, including the default values. This object is not supposed to be changed or set manually, by you. ## cluster.setupMaster([settings]) + * `settings` {Object} * `exec` {String} file path to worker file. (Default=`process.argv[1]`) @@ -680,6 +768,9 @@ cluster.fork(); // http worker This can only be called from the master process. ## cluster.worker + * {Object} @@ -698,6 +789,9 @@ if (cluster.isMaster) { ``` ## cluster.workers + * {Object} From 60ff991c09d61d760e38af5899b5fec3e6a38ee9 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sat, 6 Aug 2016 12:11:02 -0700 Subject: [PATCH 112/144] tools: update to ESLint 3.2.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/7999 Reviewed-By: Colin Ihrig Reviewed-By: Roman Reiss Reviewed-By: James M Snell Reviewed-By: Johan Bergström --- Makefile | 2 +- tools/eslint/README.md | 10 +- tools/eslint/bin/eslint.js | 80 - tools/eslint/conf/category-list.json | 35 + tools/eslint/conf/environments.js | 2 +- tools/eslint/conf/eslint-all.js | 10 +- tools/eslint/conf/eslint.json | 2 + tools/eslint/lib/ast-utils.js | 66 +- tools/eslint/lib/cli-engine.js | 97 +- tools/eslint/lib/cli.js | 10 +- .../code-path-analysis/code-path-analyzer.js | 49 +- .../code-path-analysis/code-path-segment.js | 20 +- .../lib/code-path-analysis/code-path-state.js | 239 +- .../lib/code-path-analysis/code-path.js | 34 +- .../lib/code-path-analysis/debug-helpers.js | 34 +- .../lib/code-path-analysis/fork-context.js | 28 +- tools/eslint/lib/config.js | 20 +- tools/eslint/lib/config/autoconfig.js | 34 +- tools/eslint/lib/config/config-file.js | 40 +- tools/eslint/lib/config/config-initializer.js | 36 +- tools/eslint/lib/config/config-ops.js | 22 +- tools/eslint/lib/config/config-rule.js | 30 +- tools/eslint/lib/config/config-validator.js | 16 +- tools/eslint/lib/config/environments.js | 22 +- tools/eslint/lib/config/plugins.js | 10 +- tools/eslint/lib/eslint.js | 129 +- tools/eslint/lib/file-finder.js | 12 +- tools/eslint/lib/formatters/checkstyle.js | 33 +- tools/eslint/lib/formatters/compact.js | 6 +- tools/eslint/lib/formatters/html.js | 20 +- tools/eslint/lib/formatters/jslint-xml.js | 10 +- tools/eslint/lib/formatters/junit.js | 14 +- tools/eslint/lib/formatters/stylish.js | 8 +- tools/eslint/lib/formatters/table.js | 10 +- tools/eslint/lib/formatters/tap.js | 22 +- tools/eslint/lib/formatters/unix.js | 8 +- tools/eslint/lib/formatters/visualstudio.js | 6 +- tools/eslint/lib/ignored-paths.js | 30 +- .../internal-no-invalid-meta.js | 212 + tools/eslint/lib/load-rules.js | 4 +- tools/eslint/lib/options.js | 2 +- tools/eslint/lib/rule-context.js | 6 +- tools/eslint/lib/rules.js | 8 +- tools/eslint/lib/rules/.eslintrc.yml | 2 + tools/eslint/lib/rules/accessor-pairs.js | 24 +- .../eslint/lib/rules/array-bracket-spacing.js | 24 +- .../eslint/lib/rules/array-callback-return.js | 15 +- tools/eslint/lib/rules/arrow-body-style.js | 14 +- tools/eslint/lib/rules/arrow-parens.js | 16 +- tools/eslint/lib/rules/arrow-spacing.js | 26 +- tools/eslint/lib/rules/block-scoped-var.js | 12 +- tools/eslint/lib/rules/block-spacing.js | 12 +- tools/eslint/lib/rules/brace-style.js | 18 +- tools/eslint/lib/rules/callback-return.js | 8 +- tools/eslint/lib/rules/camelcase.js | 8 +- tools/eslint/lib/rules/comma-dangle.js | 22 +- tools/eslint/lib/rules/comma-spacing.js | 20 +- tools/eslint/lib/rules/comma-style.js | 12 +- tools/eslint/lib/rules/complexity.js | 6 +- .../lib/rules/computed-property-spacing.js | 20 +- tools/eslint/lib/rules/consistent-return.js | 14 +- tools/eslint/lib/rules/consistent-this.js | 16 +- tools/eslint/lib/rules/constructor-super.js | 60 +- tools/eslint/lib/rules/curly.js | 30 +- tools/eslint/lib/rules/default-case.js | 16 +- tools/eslint/lib/rules/dot-location.js | 10 +- tools/eslint/lib/rules/dot-notation.js | 10 +- tools/eslint/lib/rules/eol-last.js | 2 +- tools/eslint/lib/rules/eqeqeq.js | 6 +- tools/eslint/lib/rules/func-names.js | 24 +- tools/eslint/lib/rules/func-style.js | 6 +- .../lib/rules/generator-star-spacing.js | 18 +- tools/eslint/lib/rules/global-require.js | 8 +- tools/eslint/lib/rules/guard-for-in.js | 2 +- tools/eslint/lib/rules/handle-callback-err.js | 10 +- tools/eslint/lib/rules/id-blacklist.js | 10 +- tools/eslint/lib/rules/id-length.js | 26 +- tools/eslint/lib/rules/id-match.js | 12 +- tools/eslint/lib/rules/indent.js | 220 +- tools/eslint/lib/rules/init-declarations.js | 16 +- tools/eslint/lib/rules/jsx-quotes.js | 8 +- tools/eslint/lib/rules/key-spacing.js | 213 +- tools/eslint/lib/rules/keyword-spacing.js | 72 +- tools/eslint/lib/rules/linebreak-style.js | 10 +- .../eslint/lib/rules/lines-around-comment.js | 48 +- tools/eslint/lib/rules/max-depth.js | 4 +- tools/eslint/lib/rules/max-len.js | 31 +- tools/eslint/lib/rules/max-lines.js | 26 +- .../eslint/lib/rules/max-nested-callbacks.js | 8 +- tools/eslint/lib/rules/max-params.js | 2 +- .../lib/rules/max-statements-per-line.js | 10 +- tools/eslint/lib/rules/max-statements.js | 8 +- tools/eslint/lib/rules/multiline-ternary.js | 66 + tools/eslint/lib/rules/new-cap.js | 42 +- tools/eslint/lib/rules/new-parens.js | 8 +- tools/eslint/lib/rules/newline-after-var.js | 14 +- .../eslint/lib/rules/newline-before-return.js | 10 +- .../lib/rules/newline-per-chained-call.js | 16 +- tools/eslint/lib/rules/no-alert.js | 8 +- tools/eslint/lib/rules/no-bitwise.js | 8 +- tools/eslint/lib/rules/no-caller.js | 2 +- .../eslint/lib/rules/no-case-declarations.js | 4 +- tools/eslint/lib/rules/no-catch-shadow.js | 6 +- tools/eslint/lib/rules/no-class-assign.js | 2 +- tools/eslint/lib/rules/no-cond-assign.js | 14 +- tools/eslint/lib/rules/no-confusing-arrow.js | 8 +- tools/eslint/lib/rules/no-console.js | 8 +- tools/eslint/lib/rules/no-const-assign.js | 2 +- .../eslint/lib/rules/no-constant-condition.js | 15 +- tools/eslint/lib/rules/no-continue.js | 2 +- tools/eslint/lib/rules/no-control-regex.js | 14 +- tools/eslint/lib/rules/no-div-regex.js | 4 +- tools/eslint/lib/rules/no-dupe-args.js | 8 +- .../eslint/lib/rules/no-dupe-class-members.js | 14 +- tools/eslint/lib/rules/no-dupe-keys.js | 4 +- tools/eslint/lib/rules/no-duplicate-case.js | 6 +- .../eslint/lib/rules/no-duplicate-imports.js | 8 +- tools/eslint/lib/rules/no-else-return.js | 4 +- .../lib/rules/no-empty-character-class.js | 6 +- tools/eslint/lib/rules/no-empty-function.js | 18 +- tools/eslint/lib/rules/no-empty.js | 14 +- tools/eslint/lib/rules/no-eq-null.js | 2 +- tools/eslint/lib/rules/no-eval.js | 48 +- tools/eslint/lib/rules/no-ex-assign.js | 2 +- tools/eslint/lib/rules/no-extend-native.js | 12 +- tools/eslint/lib/rules/no-extra-bind.js | 6 +- .../eslint/lib/rules/no-extra-boolean-cast.js | 8 +- tools/eslint/lib/rules/no-extra-label.js | 10 +- tools/eslint/lib/rules/no-extra-parens.js | 34 +- tools/eslint/lib/rules/no-extra-semi.js | 6 +- tools/eslint/lib/rules/no-fallthrough.js | 20 +- tools/eslint/lib/rules/no-func-assign.js | 2 +- .../eslint/lib/rules/no-implicit-coercion.js | 16 +- tools/eslint/lib/rules/no-implicit-globals.js | 4 +- tools/eslint/lib/rules/no-implied-eval.js | 10 +- tools/eslint/lib/rules/no-inline-comments.js | 14 +- .../eslint/lib/rules/no-inner-declarations.js | 4 +- tools/eslint/lib/rules/no-invalid-regexp.js | 10 +- tools/eslint/lib/rules/no-invalid-this.js | 10 +- .../lib/rules/no-irregular-whitespace.js | 46 +- tools/eslint/lib/rules/no-label-var.js | 6 +- tools/eslint/lib/rules/no-labels.js | 20 +- tools/eslint/lib/rules/no-lone-blocks.js | 8 +- tools/eslint/lib/rules/no-lonely-if.js | 2 +- tools/eslint/lib/rules/no-loop-func.js | 24 +- tools/eslint/lib/rules/no-magic-numbers.js | 8 +- tools/eslint/lib/rules/no-mixed-operators.js | 46 +- tools/eslint/lib/rules/no-mixed-requires.js | 16 +- .../lib/rules/no-mixed-spaces-and-tabs.js | 10 +- tools/eslint/lib/rules/no-multi-spaces.js | 8 +- tools/eslint/lib/rules/no-multi-str.js | 2 +- .../lib/rules/no-multiple-empty-lines.js | 14 +- tools/eslint/lib/rules/no-native-reassign.js | 8 +- tools/eslint/lib/rules/no-negated-in-lhs.js | 2 +- tools/eslint/lib/rules/no-nested-ternary.js | 2 +- tools/eslint/lib/rules/no-new-symbol.js | 6 +- tools/eslint/lib/rules/no-new-wrappers.js | 2 +- tools/eslint/lib/rules/no-obj-calls.js | 2 +- tools/eslint/lib/rules/no-octal-escape.js | 2 +- tools/eslint/lib/rules/no-param-reassign.js | 10 +- tools/eslint/lib/rules/no-path-concat.js | 4 +- tools/eslint/lib/rules/no-plusplus.js | 2 +- tools/eslint/lib/rules/no-process-env.js | 2 +- tools/eslint/lib/rules/no-process-exit.js | 2 +- .../eslint/lib/rules/no-prototype-builtins.js | 8 +- tools/eslint/lib/rules/no-redeclare.js | 12 +- tools/eslint/lib/rules/no-regex-spaces.js | 6 +- .../eslint/lib/rules/no-restricted-globals.js | 7 +- .../eslint/lib/rules/no-restricted-imports.js | 4 +- .../eslint/lib/rules/no-restricted-modules.js | 10 +- .../eslint/lib/rules/no-restricted-syntax.js | 2 +- tools/eslint/lib/rules/no-return-assign.js | 12 +- tools/eslint/lib/rules/no-script-url.js | 2 +- tools/eslint/lib/rules/no-self-assign.js | 10 +- tools/eslint/lib/rules/no-self-compare.js | 2 +- tools/eslint/lib/rules/no-sequences.js | 10 +- .../lib/rules/no-shadow-restricted-names.js | 2 +- tools/eslint/lib/rules/no-shadow.js | 40 +- tools/eslint/lib/rules/no-spaced-func.js | 4 +- tools/eslint/lib/rules/no-sparse-arrays.js | 2 +- tools/eslint/lib/rules/no-sync.js | 2 +- tools/eslint/lib/rules/no-tabs.js | 47 + .../eslint/lib/rules/no-this-before-super.js | 30 +- tools/eslint/lib/rules/no-throw-literal.js | 5 +- tools/eslint/lib/rules/no-trailing-spaces.js | 14 +- tools/eslint/lib/rules/no-undef-init.js | 2 +- tools/eslint/lib/rules/no-undef.js | 10 +- tools/eslint/lib/rules/no-undefined.js | 2 +- .../eslint/lib/rules/no-underscore-dangle.js | 22 +- .../lib/rules/no-unexpected-multiline.js | 12 +- .../lib/rules/no-unmodified-loop-condition.js | 65 +- tools/eslint/lib/rules/no-unneeded-ternary.js | 8 +- tools/eslint/lib/rules/no-unreachable.js | 116 +- tools/eslint/lib/rules/no-unsafe-finally.js | 22 +- .../eslint/lib/rules/no-unused-expressions.js | 10 +- tools/eslint/lib/rules/no-unused-labels.js | 6 +- tools/eslint/lib/rules/no-unused-vars.js | 116 +- .../eslint/lib/rules/no-use-before-define.js | 40 +- tools/eslint/lib/rules/no-useless-call.js | 16 +- .../lib/rules/no-useless-computed-key.js | 10 +- tools/eslint/lib/rules/no-useless-concat.js | 14 +- .../lib/rules/no-useless-constructor.js | 8 +- tools/eslint/lib/rules/no-useless-escape.js | 14 +- tools/eslint/lib/rules/no-useless-rename.js | 6 +- tools/eslint/lib/rules/no-var.js | 135 +- tools/eslint/lib/rules/no-warning-comments.js | 14 +- .../rules/no-whitespace-before-property.js | 12 +- .../eslint/lib/rules/object-curly-newline.js | 38 +- .../eslint/lib/rules/object-curly-spacing.js | 32 +- .../lib/rules/object-property-newline.js | 18 +- tools/eslint/lib/rules/object-shorthand.js | 20 +- .../lib/rules/one-var-declaration-per-line.js | 8 +- tools/eslint/lib/rules/one-var.js | 28 +- tools/eslint/lib/rules/operator-assignment.js | 2 +- tools/eslint/lib/rules/operator-linebreak.js | 26 +- tools/eslint/lib/rules/padded-blocks.js | 20 +- .../eslint/lib/rules/prefer-arrow-callback.js | 34 +- tools/eslint/lib/rules/prefer-const.js | 63 +- tools/eslint/lib/rules/prefer-reflect.js | 22 +- tools/eslint/lib/rules/prefer-rest-params.js | 8 +- tools/eslint/lib/rules/prefer-spread.js | 16 +- tools/eslint/lib/rules/prefer-template.js | 6 +- tools/eslint/lib/rules/quote-props.js | 12 +- tools/eslint/lib/rules/quotes.js | 27 +- tools/eslint/lib/rules/radix.js | 16 +- tools/eslint/lib/rules/require-jsdoc.js | 12 +- tools/eslint/lib/rules/require-yield.js | 4 +- tools/eslint/lib/rules/rest-spread-spacing.js | 8 +- tools/eslint/lib/rules/semi-spacing.js | 22 +- tools/eslint/lib/rules/semi.js | 18 +- tools/eslint/lib/rules/sort-imports.js | 14 +- tools/eslint/lib/rules/sort-vars.js | 6 +- tools/eslint/lib/rules/space-before-blocks.js | 8 +- .../lib/rules/space-before-function-paren.js | 6 +- tools/eslint/lib/rules/space-in-parens.js | 10 +- tools/eslint/lib/rules/space-infix-ops.js | 32 +- tools/eslint/lib/rules/space-unary-ops.js | 30 +- tools/eslint/lib/rules/spaced-comment.js | 172 +- tools/eslint/lib/rules/strict.js | 16 +- .../lib/rules/template-curly-spacing.js | 18 +- tools/eslint/lib/rules/unicode-bom.js | 2 +- tools/eslint/lib/rules/valid-jsdoc.js | 24 +- tools/eslint/lib/rules/valid-typeof.js | 6 +- tools/eslint/lib/rules/vars-on-top.js | 16 +- tools/eslint/lib/rules/wrap-iife.js | 8 +- tools/eslint/lib/rules/wrap-regex.js | 4 +- tools/eslint/lib/rules/yield-star-spacing.js | 22 +- tools/eslint/lib/rules/yoda.js | 30 +- .../lib/testers/event-generator-tester.js | 8 +- tools/eslint/lib/testers/rule-tester.js | 62 +- tools/eslint/lib/timing.js | 24 +- tools/eslint/lib/token-store.js | 14 +- .../lib/util/comment-event-generator.js | 6 +- tools/eslint/lib/util/glob-util.js | 26 +- tools/eslint/lib/util/hash.js | 2 +- tools/eslint/lib/util/module-resolver.js | 8 +- tools/eslint/lib/util/npm-util.js | 12 +- tools/eslint/lib/util/path-util.js | 8 +- tools/eslint/lib/util/source-code-fixer.js | 18 +- tools/eslint/lib/util/source-code-util.js | 16 +- tools/eslint/lib/util/source-code.js | 16 +- tools/eslint/lib/util/traverser.js | 6 +- tools/eslint/lib/util/xml-escape.js | 34 + .../node_modules/acorn-jsx/package.json | 23 +- tools/eslint/node_modules/acorn/AUTHORS | 6 +- tools/eslint/node_modules/acorn/bin/acorn | 94 +- .../node_modules/acorn/bin/build-acorn.js | 82 - .../acorn/bin/generate-identifier-regex.js | 12 +- .../node_modules/acorn/dist/acorn.es.js | 3112 +++++++++ tools/eslint/node_modules/acorn/dist/acorn.js | 6012 ++++++++--------- .../node_modules/acorn/dist/acorn_loose.es.js | 1261 ++++ .../node_modules/acorn/dist/acorn_loose.js | 2305 ++++--- .../eslint/node_modules/acorn/dist/walk.es.js | 342 + tools/eslint/node_modules/acorn/dist/walk.js | 693 +- tools/eslint/node_modules/acorn/package.json | 86 +- .../node_modules/acorn/rollup/config.bin.js | 15 + .../node_modules/acorn/rollup/config.loose.js | 20 + .../node_modules/acorn/rollup/config.main.js | 11 + .../node_modules/acorn/rollup/config.walk.js | 11 + .../node_modules/acorn/src/bin/acorn.js | 4 +- .../node_modules/acorn/src/expression.js | 14 +- .../node_modules/acorn/src/identifier.js | 8 +- tools/eslint/node_modules/acorn/src/index.js | 2 +- .../acorn/src/loose/acorn_loose.js | 0 .../acorn/src/loose/expression.js | 2 +- .../node_modules/acorn/src/loose/index.js | 2 +- .../node_modules/acorn/src/loose/state.js | 2 +- .../node_modules/acorn/src/loose/statement.js | 2 +- .../node_modules/acorn/src/loose/tokenize.js | 2 +- tools/eslint/node_modules/acorn/src/lval.js | 4 +- .../node_modules/acorn/src/statement.js | 2 +- .../node_modules/acorn/src/tokencontext.js | 2 +- .../node_modules/acorn/src/tokentype.js | 93 +- .../node_modules/ansi-escapes/package.json | 25 +- .../node_modules/ansi-regex/package.json | 31 +- .../node_modules/ansi-styles/package.json | 27 +- .../eslint/node_modules/argparse/package.json | 23 +- .../node_modules/array-union/package.json | 25 +- .../node_modules/array-uniq/package.json | 25 +- tools/eslint/node_modules/arrify/package.json | 27 +- .../node_modules/balanced-match/README.md | 4 +- .../node_modules/balanced-match/index.js | 2 +- .../node_modules/balanced-match/package.json | 53 +- .../eslint/node_modules/bluebird/package.json | 25 +- .../node_modules/brace-expansion/index.js | 10 + .../node_modules/brace-expansion/package.json | 55 +- .../node_modules/caller-path/package.json | 25 +- .../node_modules/callsites/package.json | 25 +- tools/eslint/node_modules/chalk/package.json | 31 +- .../node_modules/circular-json/LICENSE.txt | 19 + .../node_modules/circular-json/README.md | 135 + .../circular-json/build/circular-json.js | 2 + .../circular-json/build/circular-json.max.js | 189 + .../circular-json/build/circular-json.node.js | 185 + .../node_modules/circular-json/package.json | 97 + .../circular-json/template/license.after | 2 + .../circular-json/template/license.before | 1 + .../node_modules/cli-cursor/package.json | 25 +- .../node_modules/cli-width/package.json | 29 +- .../node_modules/code-point-at/package.json | 25 +- .../node_modules/concat-map/package.json | 51 +- .../node_modules/concat-stream/package.json | 31 +- .../node_modules/core-util-is/package.json | 25 +- tools/eslint/node_modules/d/package.json | 25 +- tools/eslint/node_modules/debug/package.json | 37 +- .../eslint/node_modules/deep-is/package.json | 55 +- tools/eslint/node_modules/del/package.json | 25 +- .../node_modules/esutils/package.json | 25 +- .../eslint/node_modules/doctrine/package.json | 27 +- .../eslint/node_modules/es5-ext/package.json | 25 +- .../node_modules/es6-iterator/package.json | 25 +- .../eslint/node_modules/es6-map/package.json | 32 +- .../eslint/node_modules/es6-set/package.json | 25 +- .../node_modules/es6-symbol/package.json | 25 +- .../node_modules/es6-weak-map/package.json | 27 +- .../escape-string-regexp/package.json | 29 +- tools/eslint/node_modules/escope/package.json | 31 +- tools/eslint/node_modules/espree/package.json | 58 +- .../eslint/node_modules/esprima/package.json | 27 +- .../node_modules/estraverse/package.json | 33 +- .../node_modules/esrecurse/package.json | 31 +- .../node_modules/estraverse/package.json | 33 +- .../eslint/node_modules/esutils/package.json | 29 +- .../node_modules/event-emitter/package.json | 25 +- .../node_modules/exit-hook/package.json | 25 +- .../fast-levenshtein/levenshtein.js | 2 +- .../fast-levenshtein/package.json | 47 +- .../eslint/node_modules/figures/package.json | 25 +- .../node_modules/file-entry-cache/README.md | 39 +- .../node_modules/file-entry-cache/cache.js | 10 +- .../file-entry-cache/changelog.md | 10 + .../file-entry-cache/package.json | 70 +- .../eslint/node_modules/flat-cache/README.md | 3 + tools/eslint/node_modules/flat-cache/cache.js | 11 +- .../node_modules/flat-cache/changelog.md | 41 + .../node_modules/flat-cache/package.json | 66 +- tools/eslint/node_modules/flat-cache/utils.js | 29 + .../node_modules/fs.realpath/package.json | 25 +- .../generate-function/package.json | 25 +- .../generate-object-property/package.json | 25 +- tools/eslint/node_modules/glob/package.json | 25 +- .../eslint/node_modules/globals/package.json | 37 +- tools/eslint/node_modules/globby/package.json | 33 +- .../eslint/node_modules/graceful-fs/README.md | 2 +- .../node_modules/graceful-fs/package.json | 46 +- .../node_modules/graceful-fs/polyfills.js | 55 +- .../eslint/node_modules/has-ansi/package.json | 29 +- tools/eslint/node_modules/ignore/package.json | 23 +- .../node_modules/imurmurhash/package.json | 25 +- .../eslint/node_modules/inflight/package.json | 37 +- .../eslint/node_modules/inherits/package.json | 23 +- .../eslint/node_modules/inquirer/package.json | 27 +- .../is-fullwidth-code-point/package.json | 25 +- .../is-my-json-valid/package.json | 35 +- .../node_modules/is-path-cwd/package.json | 25 +- .../node_modules/is-path-in-cwd/package.json | 27 +- .../node_modules/is-path-inside/package.json | 25 +- .../node_modules/is-property/package.json | 25 +- .../node_modules/is-resolvable/package.json | 25 +- .../eslint/node_modules/isarray/package.json | 31 +- .../eslint/node_modules/js-yaml/package.json | 33 +- .../json-stable-stringify/package.json | 29 +- .../eslint/node_modules/jsonify/package.json | 21 +- .../node_modules/jsonpointer/package.json | 35 +- tools/eslint/node_modules/levn/package.json | 29 +- tools/eslint/node_modules/lodash/README.md | 6 +- .../node_modules/lodash/_addMapEntry.js | 2 +- .../node_modules/lodash/_addSetEntry.js | 1 + tools/eslint/node_modules/lodash/_apply.js | 3 +- .../eslint/node_modules/lodash/_baseClamp.js | 2 +- .../eslint/node_modules/lodash/_baseClone.js | 2 +- .../node_modules/lodash/_baseConforms.js | 23 +- .../node_modules/lodash/_baseConformsTo.js | 28 + .../eslint/node_modules/lodash/_baseDelay.js | 6 +- .../eslint/node_modules/lodash/_baseGetTag.js | 22 + tools/eslint/node_modules/lodash/_baseGt.js | 2 +- .../node_modules/lodash/_baseInRange.js | 2 +- .../node_modules/lodash/_baseIndexOf.js | 5 +- .../node_modules/lodash/_baseIsArrayBuffer.js | 26 + .../eslint/node_modules/lodash/_baseIsDate.js | 27 + .../eslint/node_modules/lodash/_baseIsMap.js | 18 + .../eslint/node_modules/lodash/_baseIsNaN.js | 12 + .../node_modules/lodash/_baseIsRegExp.js | 27 + .../eslint/node_modules/lodash/_baseIsSet.js | 18 + .../node_modules/lodash/_baseIsTypedArray.js | 69 + tools/eslint/node_modules/lodash/_baseKeys.js | 6 +- tools/eslint/node_modules/lodash/_baseLt.js | 2 +- .../node_modules/lodash/_baseMergeDeep.js | 5 +- tools/eslint/node_modules/lodash/_baseNth.js | 2 +- tools/eslint/node_modules/lodash/_basePick.js | 11 +- .../eslint/node_modules/lodash/_basePickBy.js | 6 +- .../node_modules/lodash/_basePropertyOf.js | 14 + .../eslint/node_modules/lodash/_baseRange.js | 2 +- tools/eslint/node_modules/lodash/_baseRest.js | 35 + .../eslint/node_modules/lodash/_baseUnary.js | 2 +- .../node_modules/lodash/_checkGlobal.js | 12 - .../eslint/node_modules/lodash/_copyObject.js | 4 +- .../node_modules/lodash/_createAggregator.js | 2 +- .../node_modules/lodash/_createAssigner.js | 6 +- .../{_createBaseWrapper.js => _createBind.js} | 13 +- .../{_createCtorWrapper.js => _createCtor.js} | 4 +- ..._createCurryWrapper.js => _createCurry.js} | 19 +- .../eslint/node_modules/lodash/_createFind.js | 15 +- .../eslint/node_modules/lodash/_createFlow.js | 8 +- ...reateHybridWrapper.js => _createHybrid.js} | 21 +- .../lodash/_createMathOperation.js | 5 +- .../eslint/node_modules/lodash/_createOver.js | 11 +- ...atePartialWrapper.js => _createPartial.js} | 13 +- .../node_modules/lodash/_createRange.js | 9 +- ...ateRecurryWrapper.js => _createRecurry.js} | 14 +- .../eslint/node_modules/lodash/_createSet.js | 2 +- .../{_createWrapper.js => _createWrap.js} | 27 +- .../node_modules/lodash/_deburrLetter.js | 6 +- .../node_modules/lodash/_defineProperty.js | 11 + .../node_modules/lodash/_equalArrays.js | 4 +- .../eslint/node_modules/lodash/_equalByTag.js | 19 +- .../node_modules/lodash/_equalObjects.js | 4 +- .../node_modules/lodash/_escapeHtmlChar.js | 6 +- .../eslint/node_modules/lodash/_freeGlobal.js | 4 + .../node_modules/lodash/_getPrototype.js | 6 +- .../eslint/node_modules/lodash/_getSymbols.js | 18 +- .../node_modules/lodash/_getSymbolsIn.js | 9 +- tools/eslint/node_modules/lodash/_getTag.js | 5 +- .../node_modules/lodash/_getWrapDetails.js | 17 + .../eslint/node_modules/lodash/_indexOfNaN.js | 23 - .../node_modules/lodash/_insertWrapDetails.js | 21 + .../node_modules/lodash/_isFlattenable.js | 9 +- .../lodash/_isFlattenableIteratee.js | 16 - .../eslint/node_modules/lodash/_mergeData.js | 2 +- .../node_modules/lodash/_mergeDefaults.js | 5 +- tools/eslint/node_modules/lodash/_nodeUtil.js | 22 + tools/eslint/node_modules/lodash/_overArg.js | 15 + tools/eslint/node_modules/lodash/_root.js | 12 +- .../node_modules/lodash/_setWrapToString.js | 27 + tools/eslint/node_modules/lodash/_stackSet.js | 10 +- .../node_modules/lodash/_stringToPath.js | 10 +- .../node_modules/lodash/_unescapeHtmlChar.js | 6 +- .../node_modules/lodash/_updateWrapDetails.js | 46 + tools/eslint/node_modules/lodash/add.js | 2 +- tools/eslint/node_modules/lodash/ary.js | 6 +- tools/eslint/node_modules/lodash/assign.js | 12 +- tools/eslint/node_modules/lodash/assignIn.js | 12 +- tools/eslint/node_modules/lodash/at.js | 4 +- tools/eslint/node_modules/lodash/attempt.js | 6 +- tools/eslint/node_modules/lodash/before.js | 2 +- tools/eslint/node_modules/lodash/bind.js | 16 +- tools/eslint/node_modules/lodash/bindAll.js | 10 +- tools/eslint/node_modules/lodash/bindKey.js | 12 +- .../eslint/node_modules/lodash/collection.js | 1 - tools/eslint/node_modules/lodash/cond.js | 6 +- tools/eslint/node_modules/lodash/conforms.js | 13 +- .../eslint/node_modules/lodash/conformsTo.js | 32 + tools/eslint/node_modules/lodash/core.js | 417 +- tools/eslint/node_modules/lodash/core.min.js | 46 +- tools/eslint/node_modules/lodash/countBy.js | 2 +- tools/eslint/node_modules/lodash/curry.js | 6 +- .../eslint/node_modules/lodash/curryRight.js | 6 +- tools/eslint/node_modules/lodash/debounce.js | 21 +- tools/eslint/node_modules/lodash/defaultTo.js | 25 + tools/eslint/node_modules/lodash/defaults.js | 8 +- .../node_modules/lodash/defaultsDeep.js | 11 +- tools/eslint/node_modules/lodash/defer.js | 4 +- tools/eslint/node_modules/lodash/delay.js | 4 +- .../eslint/node_modules/lodash/difference.js | 12 +- .../node_modules/lodash/differenceBy.js | 13 +- .../node_modules/lodash/differenceWith.js | 8 +- tools/eslint/node_modules/lodash/divide.js | 2 +- .../node_modules/lodash/dropRightWhile.js | 3 +- tools/eslint/node_modules/lodash/dropWhile.js | 2 +- tools/eslint/node_modules/lodash/endsWith.js | 3 +- tools/eslint/node_modules/lodash/eq.js | 4 +- tools/eslint/node_modules/lodash/every.js | 2 +- tools/eslint/node_modules/lodash/filter.js | 4 +- tools/eslint/node_modules/lodash/find.js | 2 +- tools/eslint/node_modules/lodash/findIndex.js | 2 +- tools/eslint/node_modules/lodash/findKey.js | 3 +- tools/eslint/node_modules/lodash/findLast.js | 2 +- .../node_modules/lodash/findLastIndex.js | 2 +- .../eslint/node_modules/lodash/findLastKey.js | 3 +- tools/eslint/node_modules/lodash/flatMap.js | 2 +- .../eslint/node_modules/lodash/flatMapDeep.js | 2 +- .../node_modules/lodash/flatMapDepth.js | 2 +- tools/eslint/node_modules/lodash/flip.js | 6 +- tools/eslint/node_modules/lodash/flow.js | 2 +- tools/eslint/node_modules/lodash/flowRight.js | 2 +- tools/eslint/node_modules/lodash/fp/F.js | 1 + tools/eslint/node_modules/lodash/fp/T.js | 1 + .../node_modules/lodash/fp/_baseConvert.js | 125 +- .../eslint/node_modules/lodash/fp/_mapping.js | 107 +- .../node_modules/lodash/fp/assignAll.js | 5 + .../node_modules/lodash/fp/assignAllWith.js | 5 + .../node_modules/lodash/fp/assignInAll.js | 5 + .../node_modules/lodash/fp/assignInAllWith.js | 5 + .../eslint/node_modules/lodash/fp/conforms.js | 6 +- .../node_modules/lodash/fp/conformsTo.js | 5 + .../node_modules/lodash/fp/defaultTo.js | 5 + .../node_modules/lodash/fp/defaultsAll.js | 5 + .../node_modules/lodash/fp/defaultsDeepAll.js | 5 + .../eslint/node_modules/lodash/fp/dropLast.js | 1 + .../node_modules/lodash/fp/dropLastWhile.js | 1 + .../node_modules/lodash/fp/extendAll.js | 1 + .../node_modules/lodash/fp/extendAllWith.js | 1 + .../eslint/node_modules/lodash/fp/indexBy.js | 1 + .../eslint/node_modules/lodash/fp/matches.js | 6 +- .../eslint/node_modules/lodash/fp/mergeAll.js | 5 + .../node_modules/lodash/fp/mergeAllWith.js | 5 + .../eslint/node_modules/lodash/fp/property.js | 6 +- .../node_modules/lodash/fp/propertyOf.js | 2 +- .../lodash/fp/symmetricDifference.js | 1 + .../lodash/fp/symmetricDifferenceBy.js | 1 + .../lodash/fp/symmetricDifferenceWith.js | 1 + .../eslint/node_modules/lodash/fp/takeLast.js | 1 + .../node_modules/lodash/fp/takeLastWhile.js | 1 + tools/eslint/node_modules/lodash/fp/where.js | 1 + .../eslint/node_modules/lodash/fp/whereEq.js | 2 +- tools/eslint/node_modules/lodash/fp/zipAll.js | 5 + tools/eslint/node_modules/lodash/fromPairs.js | 4 +- tools/eslint/node_modules/lodash/get.js | 2 +- tools/eslint/node_modules/lodash/groupBy.js | 2 +- tools/eslint/node_modules/lodash/identity.js | 4 +- tools/eslint/node_modules/lodash/inRange.js | 5 +- tools/eslint/node_modules/lodash/includes.js | 4 +- .../node_modules/lodash/intersection.js | 6 +- .../node_modules/lodash/intersectionBy.js | 11 +- .../node_modules/lodash/intersectionWith.js | 6 +- tools/eslint/node_modules/lodash/invertBy.js | 3 +- tools/eslint/node_modules/lodash/invoke.js | 4 +- tools/eslint/node_modules/lodash/invokeMap.js | 10 +- .../eslint/node_modules/lodash/isArguments.js | 2 +- tools/eslint/node_modules/lodash/isArray.js | 4 +- .../node_modules/lodash/isArrayBuffer.js | 24 +- tools/eslint/node_modules/lodash/isBoolean.js | 3 +- tools/eslint/node_modules/lodash/isBuffer.js | 11 +- tools/eslint/node_modules/lodash/isDate.js | 25 +- tools/eslint/node_modules/lodash/isEqual.js | 4 +- .../eslint/node_modules/lodash/isFunction.js | 3 +- tools/eslint/node_modules/lodash/isMap.js | 16 +- tools/eslint/node_modules/lodash/isMatch.js | 12 +- tools/eslint/node_modules/lodash/isNative.js | 16 +- tools/eslint/node_modules/lodash/isNumber.js | 3 +- tools/eslint/node_modules/lodash/isRegExp.js | 25 +- tools/eslint/node_modules/lodash/isSet.js | 16 +- tools/eslint/node_modules/lodash/isString.js | 3 +- tools/eslint/node_modules/lodash/isSymbol.js | 3 +- .../node_modules/lodash/isTypedArray.js | 67 +- tools/eslint/node_modules/lodash/isWeakMap.js | 3 +- tools/eslint/node_modules/lodash/isWeakSet.js | 3 +- tools/eslint/node_modules/lodash/keyBy.js | 2 +- tools/eslint/node_modules/lodash/lang.js | 1 + .../eslint/node_modules/lodash/lastIndexOf.js | 5 +- tools/eslint/node_modules/lodash/lodash.js | 1411 ++-- .../eslint/node_modules/lodash/lodash.min.js | 245 +- tools/eslint/node_modules/lodash/map.js | 3 +- tools/eslint/node_modules/lodash/mapKeys.js | 3 +- tools/eslint/node_modules/lodash/mapValues.js | 3 +- tools/eslint/node_modules/lodash/matches.js | 16 +- .../node_modules/lodash/matchesProperty.js | 10 +- tools/eslint/node_modules/lodash/maxBy.js | 5 +- tools/eslint/node_modules/lodash/meanBy.js | 5 +- tools/eslint/node_modules/lodash/merge.js | 12 +- tools/eslint/node_modules/lodash/mergeWith.js | 13 +- tools/eslint/node_modules/lodash/method.js | 4 +- tools/eslint/node_modules/lodash/methodOf.js | 4 +- tools/eslint/node_modules/lodash/minBy.js | 5 +- tools/eslint/node_modules/lodash/multiply.js | 2 +- tools/eslint/node_modules/lodash/negate.js | 9 +- tools/eslint/node_modules/lodash/noop.js | 2 +- tools/eslint/node_modules/lodash/nthArg.js | 4 +- tools/eslint/node_modules/lodash/object.js | 1 + tools/eslint/node_modules/lodash/omit.js | 4 +- tools/eslint/node_modules/lodash/omitBy.js | 11 +- tools/eslint/node_modules/lodash/once.js | 2 +- tools/eslint/node_modules/lodash/over.js | 4 +- tools/eslint/node_modules/lodash/overArgs.js | 18 +- tools/eslint/node_modules/lodash/overEvery.js | 4 +- tools/eslint/node_modules/lodash/overSome.js | 4 +- tools/eslint/node_modules/lodash/package.json | 55 +- tools/eslint/node_modules/lodash/partial.js | 16 +- .../node_modules/lodash/partialRight.js | 16 +- tools/eslint/node_modules/lodash/partition.js | 3 +- tools/eslint/node_modules/lodash/pick.js | 4 +- tools/eslint/node_modules/lodash/pickBy.js | 8 +- tools/eslint/node_modules/lodash/pull.js | 6 +- tools/eslint/node_modules/lodash/pullAllBy.js | 4 +- tools/eslint/node_modules/lodash/pullAt.js | 6 +- tools/eslint/node_modules/lodash/random.js | 6 +- tools/eslint/node_modules/lodash/rearg.js | 10 +- tools/eslint/node_modules/lodash/reject.js | 11 +- tools/eslint/node_modules/lodash/remove.js | 2 +- tools/eslint/node_modules/lodash/rest.js | 30 +- tools/eslint/node_modules/lodash/some.js | 3 +- tools/eslint/node_modules/lodash/sortBy.js | 18 +- .../node_modules/lodash/sortedIndexBy.js | 4 +- .../node_modules/lodash/sortedLastIndexBy.js | 4 +- .../node_modules/lodash/sortedUniqBy.js | 2 +- tools/eslint/node_modules/lodash/spread.js | 4 +- .../eslint/node_modules/lodash/startsWith.js | 3 +- tools/eslint/node_modules/lodash/stubArray.js | 2 +- tools/eslint/node_modules/lodash/stubFalse.js | 2 +- .../eslint/node_modules/lodash/stubObject.js | 2 +- .../eslint/node_modules/lodash/stubString.js | 2 +- tools/eslint/node_modules/lodash/stubTrue.js | 2 +- tools/eslint/node_modules/lodash/subtract.js | 2 +- tools/eslint/node_modules/lodash/sumBy.js | 5 +- .../node_modules/lodash/takeRightWhile.js | 2 +- tools/eslint/node_modules/lodash/takeWhile.js | 2 +- tools/eslint/node_modules/lodash/throttle.js | 7 +- tools/eslint/node_modules/lodash/toArray.js | 2 +- tools/eslint/node_modules/lodash/union.js | 6 +- tools/eslint/node_modules/lodash/unionBy.js | 13 +- tools/eslint/node_modules/lodash/unionWith.js | 9 +- tools/eslint/node_modules/lodash/uniqBy.js | 4 +- tools/eslint/node_modules/lodash/unzip.js | 6 +- tools/eslint/node_modules/lodash/util.js | 1 + tools/eslint/node_modules/lodash/without.js | 8 +- tools/eslint/node_modules/lodash/wrap.js | 8 +- tools/eslint/node_modules/lodash/wrapperAt.js | 4 +- .../node_modules/lodash/wrapperLodash.js | 20 +- tools/eslint/node_modules/lodash/xor.js | 6 +- tools/eslint/node_modules/lodash/xorBy.js | 10 +- tools/eslint/node_modules/lodash/xorWith.js | 6 +- tools/eslint/node_modules/lodash/zip.js | 8 +- tools/eslint/node_modules/lodash/zipWith.js | 4 +- .../node_modules/minimatch/package.json | 25 +- .../eslint/node_modules/minimist/package.json | 29 +- tools/eslint/node_modules/mkdirp/package.json | 25 +- tools/eslint/node_modules/ms/package.json | 23 +- .../node_modules/mute-stream/package.json | 27 +- .../node_modules/number-is-nan/package.json | 25 +- .../node_modules/object-assign/package.json | 29 +- tools/eslint/node_modules/once/package.json | 25 +- .../eslint/node_modules/onetime/package.json | 25 +- .../node_modules/optionator/package.json | 27 +- .../node_modules/os-homedir/package.json | 25 +- .../path-is-absolute/package.json | 27 +- .../node_modules/path-is-inside/package.json | 27 +- tools/eslint/node_modules/pify/package.json | 25 +- .../node_modules/pinkie-promise/package.json | 25 +- tools/eslint/node_modules/pinkie/package.json | 25 +- .../node_modules/pluralize/package.json | 25 +- .../node_modules/prelude-ls/package.json | 29 +- .../process-nextick-args/package.json | 23 +- .../eslint/node_modules/progress/package.json | 43 +- .../node_modules/read-json-sync/LICENSE | 20 - .../node_modules/read-json-sync/README.md | 44 - .../node_modules/read-json-sync/index.js | 11 - .../node_modules/read-json-sync/package.json | 95 - .../node_modules/readable-stream/package.json | 35 +- .../node_modules/readline2/package.json | 27 +- .../require-uncached/package.json | 25 +- .../node_modules/resolve-from/package.json | 27 +- .../node_modules/restore-cursor/package.json | 25 +- tools/eslint/node_modules/rimraf/package.json | 43 +- tools/eslint/node_modules/rimraf/rimraf.js | 4 +- .../node_modules/run-async/package.json | 27 +- .../eslint/node_modules/rx-lite/package.json | 23 +- .../eslint/node_modules/shelljs/package.json | 41 +- .../node_modules/slice-ansi/package.json | 27 +- .../node_modules/sprintf-js/package.json | 25 +- .../node_modules/string-width/package.json | 27 +- .../node_modules/string_decoder/package.json | 27 +- .../node_modules/strip-ansi/package.json | 29 +- .../node_modules/strip-bom/package.json | 25 +- .../strip-json-comments/package.json | 25 +- .../node_modules/supports-color/package.json | 29 +- tools/eslint/node_modules/table/package.json | 25 +- .../node_modules/text-table/package.json | 29 +- .../eslint/node_modules/through/package.json | 25 +- tools/eslint/node_modules/tryit/package.json | 29 +- tools/eslint/node_modules/tv4/package.json | 27 +- .../node_modules/type-check/package.json | 27 +- .../node_modules/typedarray/package.json | 29 +- .../node_modules/user-home/package.json | 25 +- .../node_modules/util-deprecate/package.json | 27 +- .../eslint/node_modules/wordwrap/package.json | 29 +- tools/eslint/node_modules/wrappy/package.json | 29 +- tools/eslint/node_modules/write/package.json | 23 +- .../eslint/node_modules/xregexp/package.json | 27 +- tools/eslint/node_modules/xtend/package.json | 35 +- tools/eslint/package.json | 62 +- vcbuild.bat | 2 +- 701 files changed, 18378 insertions(+), 10561 deletions(-) delete mode 100755 tools/eslint/bin/eslint.js create mode 100644 tools/eslint/conf/category-list.json create mode 100644 tools/eslint/lib/internal-rules/internal-no-invalid-meta.js create mode 100644 tools/eslint/lib/rules/.eslintrc.yml create mode 100644 tools/eslint/lib/rules/multiline-ternary.js create mode 100644 tools/eslint/lib/rules/no-tabs.js create mode 100644 tools/eslint/lib/util/xml-escape.js delete mode 100644 tools/eslint/node_modules/acorn/bin/build-acorn.js create mode 100644 tools/eslint/node_modules/acorn/dist/acorn.es.js create mode 100644 tools/eslint/node_modules/acorn/dist/acorn_loose.es.js create mode 100644 tools/eslint/node_modules/acorn/dist/walk.es.js create mode 100644 tools/eslint/node_modules/acorn/rollup/config.bin.js create mode 100644 tools/eslint/node_modules/acorn/rollup/config.loose.js create mode 100644 tools/eslint/node_modules/acorn/rollup/config.main.js create mode 100644 tools/eslint/node_modules/acorn/rollup/config.walk.js delete mode 100644 tools/eslint/node_modules/acorn/src/loose/acorn_loose.js create mode 100644 tools/eslint/node_modules/circular-json/LICENSE.txt create mode 100644 tools/eslint/node_modules/circular-json/README.md create mode 100644 tools/eslint/node_modules/circular-json/build/circular-json.js create mode 100644 tools/eslint/node_modules/circular-json/build/circular-json.max.js create mode 100644 tools/eslint/node_modules/circular-json/build/circular-json.node.js create mode 100644 tools/eslint/node_modules/circular-json/package.json create mode 100644 tools/eslint/node_modules/circular-json/template/license.after create mode 100644 tools/eslint/node_modules/circular-json/template/license.before create mode 100644 tools/eslint/node_modules/flat-cache/utils.js create mode 100644 tools/eslint/node_modules/lodash/_baseConformsTo.js create mode 100644 tools/eslint/node_modules/lodash/_baseGetTag.js create mode 100644 tools/eslint/node_modules/lodash/_baseIsArrayBuffer.js create mode 100644 tools/eslint/node_modules/lodash/_baseIsDate.js create mode 100644 tools/eslint/node_modules/lodash/_baseIsMap.js create mode 100644 tools/eslint/node_modules/lodash/_baseIsNaN.js create mode 100644 tools/eslint/node_modules/lodash/_baseIsRegExp.js create mode 100644 tools/eslint/node_modules/lodash/_baseIsSet.js create mode 100644 tools/eslint/node_modules/lodash/_baseIsTypedArray.js create mode 100644 tools/eslint/node_modules/lodash/_basePropertyOf.js create mode 100644 tools/eslint/node_modules/lodash/_baseRest.js delete mode 100644 tools/eslint/node_modules/lodash/_checkGlobal.js rename tools/eslint/node_modules/lodash/{_createBaseWrapper.js => _createBind.js} (62%) rename tools/eslint/node_modules/lodash/{_createCtorWrapper.js => _createCtor.js} (95%) rename tools/eslint/node_modules/lodash/{_createCurryWrapper.js => _createCurry.js} (66%) rename tools/eslint/node_modules/lodash/{_createHybridWrapper.js => _createHybrid.js} (80%) rename tools/eslint/node_modules/lodash/{_createPartialWrapper.js => _createPartial.js} (75%) rename tools/eslint/node_modules/lodash/{_createRecurryWrapper.js => _createRecurry.js} (79%) rename tools/eslint/node_modules/lodash/{_createWrapper.js => _createWrap.js} (79%) create mode 100644 tools/eslint/node_modules/lodash/_defineProperty.js create mode 100644 tools/eslint/node_modules/lodash/_freeGlobal.js create mode 100644 tools/eslint/node_modules/lodash/_getWrapDetails.js delete mode 100644 tools/eslint/node_modules/lodash/_indexOfNaN.js create mode 100644 tools/eslint/node_modules/lodash/_insertWrapDetails.js delete mode 100644 tools/eslint/node_modules/lodash/_isFlattenableIteratee.js create mode 100644 tools/eslint/node_modules/lodash/_nodeUtil.js create mode 100644 tools/eslint/node_modules/lodash/_overArg.js create mode 100644 tools/eslint/node_modules/lodash/_setWrapToString.js create mode 100644 tools/eslint/node_modules/lodash/_updateWrapDetails.js create mode 100644 tools/eslint/node_modules/lodash/conformsTo.js create mode 100644 tools/eslint/node_modules/lodash/defaultTo.js create mode 100644 tools/eslint/node_modules/lodash/fp/F.js create mode 100644 tools/eslint/node_modules/lodash/fp/T.js create mode 100644 tools/eslint/node_modules/lodash/fp/assignAll.js create mode 100644 tools/eslint/node_modules/lodash/fp/assignAllWith.js create mode 100644 tools/eslint/node_modules/lodash/fp/assignInAll.js create mode 100644 tools/eslint/node_modules/lodash/fp/assignInAllWith.js create mode 100644 tools/eslint/node_modules/lodash/fp/conformsTo.js create mode 100644 tools/eslint/node_modules/lodash/fp/defaultTo.js create mode 100644 tools/eslint/node_modules/lodash/fp/defaultsAll.js create mode 100644 tools/eslint/node_modules/lodash/fp/defaultsDeepAll.js create mode 100644 tools/eslint/node_modules/lodash/fp/dropLast.js create mode 100644 tools/eslint/node_modules/lodash/fp/dropLastWhile.js create mode 100644 tools/eslint/node_modules/lodash/fp/extendAll.js create mode 100644 tools/eslint/node_modules/lodash/fp/extendAllWith.js create mode 100644 tools/eslint/node_modules/lodash/fp/indexBy.js create mode 100644 tools/eslint/node_modules/lodash/fp/mergeAll.js create mode 100644 tools/eslint/node_modules/lodash/fp/mergeAllWith.js create mode 100644 tools/eslint/node_modules/lodash/fp/symmetricDifference.js create mode 100644 tools/eslint/node_modules/lodash/fp/symmetricDifferenceBy.js create mode 100644 tools/eslint/node_modules/lodash/fp/symmetricDifferenceWith.js create mode 100644 tools/eslint/node_modules/lodash/fp/takeLast.js create mode 100644 tools/eslint/node_modules/lodash/fp/takeLastWhile.js create mode 100644 tools/eslint/node_modules/lodash/fp/where.js create mode 100644 tools/eslint/node_modules/lodash/fp/zipAll.js delete mode 100755 tools/eslint/node_modules/read-json-sync/LICENSE delete mode 100755 tools/eslint/node_modules/read-json-sync/README.md delete mode 100755 tools/eslint/node_modules/read-json-sync/index.js delete mode 100644 tools/eslint/node_modules/read-json-sync/package.json diff --git a/Makefile b/Makefile index 7e68c20972394c..a28dc3176115a6 100644 --- a/Makefile +++ b/Makefile @@ -705,7 +705,7 @@ cpplint: @$(PYTHON) tools/cpplint.py $(CPPLINT_FILES) @$(PYTHON) tools/check-imports.py -ifneq ("","$(wildcard tools/eslint/bin/eslint.js)") +ifneq ("","$(wildcard tools/eslint/lib/eslint.js)") lint: jslint cpplint CONFLICT_RE=^>>>>>>> [0-9A-Fa-f]+|^<<<<<<< [A-Za-z]+ lint-ci: jslint-ci cpplint diff --git a/tools/eslint/README.md b/tools/eslint/README.md index 5493563c4e3479..8ba9eaf0b5f1bd 100644 --- a/tools/eslint/README.md +++ b/tools/eslint/README.md @@ -126,9 +126,6 @@ These folks keep the project moving and are resources for help. * Henry Zhu ([@hzoo](https://github.com/hzoo)) * Marat Dulin ([@mdevils](https://github.com/mdevils)) * Alexej Yaroshevich ([@zxqfox](https://github.com/zxqfox)) - -### Issues Team - * Kevin Partington ([@platinumazure](https://github.com/platinumazure)) * Vitor Balocco ([@vitorbal](https://github.com/vitorbal)) @@ -169,6 +166,8 @@ ESLint follows [semantic versioning](http://semver.org). However, due to the nat * An existing formatter is removed. * Part of the public API is removed or changed in an incompatible way. +According to our policy, any minor update may report more errors than the previous release (ex: from a bug fix). As such, we recommend using the tilde (`~`) in `package.json` e.g. `"eslint": "~3.1.0"` to guarantee the results of your builds. + ## Frequently Asked Questions ### How is ESLint different from JSHint? @@ -187,7 +186,10 @@ Yes. Since we are solving the same problems, ESLint and JSCS teams have decided ### So, should I stop using JSCS and start using ESLint? -Not yet. We are still working to smooth the transition. You can see our progress [here](https://github.com/eslint/eslint/milestones/JSCS%20Compatibility). We’ll announce when all of the changes necessary to support JSCS users in ESLint are complete and will start encouraging JSCS users to switch to ESLint at that time. Meanwhile, we recommend you to upgrade to JSCS 3.0 and provide feedback to the team. +Maybe, depending on how much you need it. [JSCS has reached end of life](http://eslint.org/blog/2016/07/jscs-end-of-life), but if it is working for you then there is no reason to move yet. We are still working to smooth the transition. You can see our progress [here](https://github.com/eslint/eslint/milestones/JSCS%20Compatibility). We’ll announce when all of the changes necessary to support JSCS users in ESLint are complete and will start encouraging JSCS users to switch to ESLint at that time. + +If you are having issues with JSCS, you can try to move to ESLint. We are focusing our time and energy on JSCS compatibility issues. + ### Is ESLint just linting or does it also check style? diff --git a/tools/eslint/bin/eslint.js b/tools/eslint/bin/eslint.js deleted file mode 100755 index e03ab6f426e0ef..00000000000000 --- a/tools/eslint/bin/eslint.js +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env node - -/** - * @fileoverview Main CLI that is run via the eslint command. - * @author Nicholas C. Zakas - */ - -"use strict"; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -var exitCode = 0, - useStdIn = (process.argv.indexOf("--stdin") > -1), - init = (process.argv.indexOf("--init") > -1), - debug = (process.argv.indexOf("--debug") > -1); - -// must do this initialization *before* other requires in order to work -if (debug) { - require("debug").enable("eslint:*,-eslint:code-path"); -} - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -// now we can safely include the other modules that use debug -var concat = require("concat-stream"), - cli = require("../lib/cli"), - path = require("path"), - fs = require("fs"); - -//------------------------------------------------------------------------------ -// Execution -//------------------------------------------------------------------------------ - -process.on("uncaughtException", function(err){ - // lazy load - var lodash = require("lodash"); - - if (typeof err.messageTemplate === "string" && err.messageTemplate.length > 0) { - var template = lodash.template(fs.readFileSync(path.resolve(__dirname, "../messages/" + err.messageTemplate + ".txt"), "utf-8")); - - console.log("\nOops! Something went wrong! :("); - console.log("\n" + template(err.messageData || {})); - } else { - console.log(err.message); - console.log(err.stack); - } - - process.exit(1); -}); - -if (useStdIn) { - process.stdin.pipe(concat({ encoding: "string" }, function(text) { - try { - exitCode = cli.execute(process.argv, text); - } catch (ex) { - console.error(ex.message); - console.error(ex.stack); - exitCode = 1; - } - })); -} else if (init) { - var configInit = require("../lib/config/config-initializer"); - configInit.initializeConfig(function(err) { - if (err) { - exitCode = 1; - console.error(err.message); - console.error(err.stack); - } else { - exitCode = 0; - } - }); -} else { - exitCode = cli.execute(process.argv); -} - -process.exitCode = exitCode; diff --git a/tools/eslint/conf/category-list.json b/tools/eslint/conf/category-list.json new file mode 100644 index 00000000000000..d7e84b6c15fe93 --- /dev/null +++ b/tools/eslint/conf/category-list.json @@ -0,0 +1,35 @@ +{ + "categories": [ + { "name": "Possible Errors", "description": "These rules relate to possible syntax or logic errors in JavaScript code:" }, + { "name": "Best Practices", "description": "These rules relate to better ways of doing things to help you avoid problems:" }, + { "name": "Strict Mode", "description": "These rules relate to strict mode directives:" }, + { "name": "Variables", "description": "These rules relate to variable declarations:" }, + { "name": "Node.js and CommonJS", "description": "These rules relate to code running in Node.js, or in browsers with CommonJS:" }, + { "name": "Stylistic Issues", "description": "These rules relate to style guidelines, and are therefore quite subjective:" }, + { "name": "ECMAScript 6", "description": "These rules relate to ES6, also known as ES2015:" } + ], + "removed": { + "name": "Removed", + "description": "These rules from older versions of ESLint have been replaced by newer rules:", + "rules": [ + { "removed": "generator-star", "replacedBy": ["generator-star-spacing"] }, + { "removed": "global-strict", "replacedBy": ["strict"] }, + { "removed": "no-arrow-condition", "replacedBy": ["no-confusing-arrow", "no-constant-condition"] }, + { "removed": "no-comma-dangle", "replacedBy": ["comma-dangle"] }, + { "removed": "no-empty-class", "replacedBy": ["no-empty-character-class"] }, + { "removed": "no-empty-label", "replacedBy": ["no-labels"] }, + { "removed": "no-extra-strict", "replacedBy": ["strict"] }, + { "removed": "no-reserved-keys", "replacedBy": ["quote-props"] }, + { "removed": "no-space-before-semi", "replacedBy": ["semi-spacing"] }, + { "removed": "no-wrap-func", "replacedBy": ["no-extra-parens"] }, + { "removed": "space-after-function-name", "replacedBy": ["space-before-function-paren"] }, + { "removed": "space-after-keywords", "replacedBy": ["keyword-spacing"] }, + { "removed": "space-before-function-parentheses", "replacedBy": ["space-before-function-paren"] }, + { "removed": "space-before-keywords", "replacedBy": ["keyword-spacing"] }, + { "removed": "space-in-brackets", "replacedBy": ["object-curly-spacing", "array-bracket-spacing"] }, + { "removed": "space-return-throw-case", "replacedBy": ["keyword-spacing"] }, + { "removed": "space-unary-word-ops", "replacedBy": ["space-unary-ops"] }, + { "removed": "spaced-line-comment", "replacedBy": ["spaced-comment"] } + ] + } +} \ No newline at end of file diff --git a/tools/eslint/conf/environments.js b/tools/eslint/conf/environments.js index ee76503827cb24..d938a6cfaa941d 100644 --- a/tools/eslint/conf/environments.js +++ b/tools/eslint/conf/environments.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var globals = require("globals"); +let globals = require("globals"); //------------------------------------------------------------------------------ // Public Interface diff --git a/tools/eslint/conf/eslint-all.js b/tools/eslint/conf/eslint-all.js index 8740e8c07d46e8..53d5cdb82d8c28 100644 --- a/tools/eslint/conf/eslint-all.js +++ b/tools/eslint/conf/eslint-all.js @@ -9,16 +9,18 @@ // Requirements //------------------------------------------------------------------------------ -var fs = require("fs"), +let fs = require("fs"), path = require("path"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var ruleFiles = fs.readdirSync(path.resolve(__dirname, "../lib/rules")); -var enabledRules = ruleFiles.reduce(function(result, filename) { - result[path.basename(filename, ".js")] = "error"; +let ruleFiles = fs.readdirSync(path.resolve(__dirname, "../lib/rules")); +let enabledRules = ruleFiles.reduce(function(result, filename) { + if (path.extname(filename) === ".js") { + result[path.basename(filename, ".js")] = "error"; + } return result; }, {}); diff --git a/tools/eslint/conf/eslint.json b/tools/eslint/conf/eslint.json index 94317bcd89aa61..53b2e7559066ab 100644 --- a/tools/eslint/conf/eslint.json +++ b/tools/eslint/conf/eslint.json @@ -99,6 +99,7 @@ "no-spaced-func": "off", "no-sparse-arrays": "error", "no-sync": "off", + "no-tabs": "off", "no-ternary": "off", "no-trailing-spaces": "off", "no-this-before-super": "error", @@ -174,6 +175,7 @@ "max-params": "off", "max-statements": "off", "max-statements-per-line": "off", + "multiline-ternary": "off", "new-cap": "off", "new-parens": "off", "newline-after-var": "off", diff --git a/tools/eslint/lib/ast-utils.js b/tools/eslint/lib/ast-utils.js index c8d6dcb4915e21..881cc26c5f08a4 100644 --- a/tools/eslint/lib/ast-utils.js +++ b/tools/eslint/lib/ast-utils.js @@ -9,18 +9,19 @@ // Requirements //------------------------------------------------------------------------------ -var esutils = require("esutils"); +let esutils = require("esutils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/; -var arrayOrTypedArrayPattern = /Array$/; -var arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/; -var bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/; -var breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/; -var thisTagPattern = /^[\s\*]*@this/m; +let anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/; +let anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/; +let arrayOrTypedArrayPattern = /Array$/; +let arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/; +let bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/; +let breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/; +let thisTagPattern = /^[\s\*]*@this/m; /** * Checks reference if is non initializer and writable. @@ -31,7 +32,7 @@ var thisTagPattern = /^[\s\*]*@this/m; * @private */ function isModifyingReference(reference, index, references) { - var identifier = reference.identifier, + let identifier = reference.identifier, modifyingDifferentIdentifier; /* @@ -159,7 +160,7 @@ function isMethodWhichHasThisArg(node) { * @returns {boolean} Whether or not the node has a `@this` tag in its comments. */ function hasJSDocThisTag(node, sourceCode) { - var jsdocComment = sourceCode.getJSDocComment(node); + let jsdocComment = sourceCode.getJSDocComment(node); if (jsdocComment && thisTagPattern.test(jsdocComment.value)) { return true; @@ -182,7 +183,7 @@ function hasJSDocThisTag(node, sourceCode) { * @private */ function isParenthesised(sourceCode, node) { - var previousToken = sourceCode.getTokenBefore(node), + let previousToken = sourceCode.getTokenBefore(node), nextToken = sourceCode.getTokenAfter(node); return Boolean(previousToken && nextToken) && @@ -284,7 +285,7 @@ module.exports = { * @returns {boolean} `true` if the node is an ESLint directive comment */ isDirectiveComment: function(node) { - var comment = node.value.trim(); + let comment = node.value.trim(); return ( node.type === "Line" && comment.indexOf("eslint-") === 0 || @@ -317,10 +318,10 @@ module.exports = { * @returns {escope.Variable|null} A found variable or `null`. */ getVariableByName: function(initScope, name) { - var scope = initScope; + let scope = initScope; while (scope) { - var variable = scope.set.get(name); + let variable = scope.set.get(name); if (variable) { return variable; @@ -359,7 +360,7 @@ module.exports = { } while (node) { - var parent = node.parent; + let parent = node.parent; switch (parent.type) { @@ -378,14 +379,15 @@ module.exports = { // // setup... // return function foo() { ... }; // })(); - case "ReturnStatement": - var func = getUpperFunction(parent); + case "ReturnStatement": { + const func = getUpperFunction(parent); if (func === null || !isCallee(func)) { return true; } node = func.parent; break; + } // e.g. // var obj = { foo() { ... } }; @@ -551,5 +553,37 @@ module.exports = { // no default } return 18; + }, + + /** + * Checks whether a given node is a loop node or not. + * The following types are loop nodes: + * + * - DoWhileStatement + * - ForInStatement + * - ForOfStatement + * - ForStatement + * - WhileStatement + * + * @param {ASTNode|null} node - A node to check. + * @returns {boolean} `true` if the node is a loop node. + */ + isLoop: function(node) { + return Boolean(node && anyLoopPattern.test(node.type)); + }, + + /** + * Checks whether a given node is a function node or not. + * The following types are function nodes: + * + * - ArrowFunctionExpression + * - FunctionDeclaration + * - FunctionExpression + * + * @param {ASTNode|null} node - A node to check. + * @returns {boolean} `true` if the node is a function node. + */ + isFunction: function(node) { + return Boolean(node && anyFunctionPattern.test(node.type)); } }; diff --git a/tools/eslint/lib/cli-engine.js b/tools/eslint/lib/cli-engine.js index 410fd7f3674156..cf28aa1d592c16 100644 --- a/tools/eslint/lib/cli-engine.js +++ b/tools/eslint/lib/cli-engine.js @@ -15,7 +15,7 @@ // Requirements //------------------------------------------------------------------------------ -var fs = require("fs"), +let fs = require("fs"), path = require("path"), lodash = require("lodash"), @@ -44,16 +44,25 @@ var fs = require("fs"), /** * The options to configure a CLI engine with. * @typedef {Object} CLIEngineOptions + * @property {boolean} allowInlineConfig Enable or disable inline configuration comments. + * @property {boolean|Object} baseConfig Base config object. True enables recommend rules and environments. + * @property {boolean} cache Enable result caching. + * @property {string} cacheLocation The cache file to use instead of .eslintcache. * @property {string} configFile The configuration file to use. - * @property {boolean|object} baseConfig Base config object. True enables recommend rules and environments. - * @property {boolean} ignore False disables use of .eslintignore. - * @property {string[]} rulePaths An array of directories to load custom rules from. - * @property {boolean} useEslintrc False disables looking for .eslintrc + * @property {string} cwd The value to use for the current working directory. * @property {string[]} envs An array of environments to load. - * @property {string[]} globals An array of global variables to declare. * @property {string[]} extensions An array of file extensions to check. - * @property {Object} rules An object of rules to use. + * @property {boolean} fix Execute in autofix mode. + * @property {string[]} globals An array of global variables to declare. + * @property {boolean} ignore False disables use of .eslintignore. * @property {string} ignorePath The ignore file to use instead of .eslintignore. + * @property {string} ignorePattern A glob pattern of files to ignore. + * @property {boolean} useEslintrc False disables looking for .eslintrc + * @property {string} parser The name of the parser to use. + * @property {Object} parserOptions An object of parserOption settings to use. + * @property {string[]} plugins An array of plugins to load. + * @property {Object} rules An object of rules to use. + * @property {string[]} rulePaths An array of directories to load custom rules from. */ /** @@ -129,7 +138,7 @@ function calculateStatsPerRun(results) { */ function multipassFix(text, config, options) { - var messages = [], + let messages = [], fixedResult, fixed = false, passNumber = 0, @@ -203,7 +212,7 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) { // clear all existing settings for a new file eslint.reset(); - var filePath, + let filePath, config, messages, stats, @@ -227,7 +236,7 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) { loadedPlugins = Plugins.getAll(); - for (var plugin in loadedPlugins) { + for (let plugin in loadedPlugins) { if (loadedPlugins[plugin].processors && Object.keys(loadedPlugins[plugin].processors).indexOf(fileExtension) >= 0) { processor = loadedPlugins[plugin].processors[fileExtension]; break; @@ -236,8 +245,8 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) { if (processor) { debug("Using processor"); - var parsedBlocks = processor.preprocess(text, filename); - var unprocessedMessages = []; + let parsedBlocks = processor.preprocess(text, filename); + let unprocessedMessages = []; parsedBlocks.forEach(function(block) { unprocessedMessages.push(eslint.verify(block, config, { @@ -268,7 +277,7 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) { stats = calculateStatsPerFile(messages); - var result = { + let result = { filePath: filename, messages: messages, errorCount: stats.errorCount, @@ -293,7 +302,7 @@ function processText(text, configHelper, filename, fix, allowInlineConfig) { */ function processFile(filename, configHelper, options) { - var text = fs.readFileSync(path.resolve(filename), "utf8"), + let text = fs.readFileSync(path.resolve(filename), "utf8"), result = processText(text, configHelper, filename, options.fix, options.allowInlineConfig); return result; @@ -308,10 +317,10 @@ function processFile(filename, configHelper, options) { * @private */ function createIgnoreResult(filePath, baseDir) { - var message; - var isHidden = /^\./.test(path.basename(filePath)); - var isInNodeModules = baseDir && /^node_modules/.test(path.relative(baseDir, filePath)); - var isInBowerComponents = baseDir && /^bower_components/.test(path.relative(baseDir, filePath)); + let message; + let isHidden = /^\./.test(path.basename(filePath)); + let isInNodeModules = baseDir && /^node_modules/.test(path.relative(baseDir, filePath)); + let isInBowerComponents = baseDir && /^bower_components/.test(path.relative(baseDir, filePath)); if (isHidden) { message = "File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern \'!\'\") to override."; @@ -340,7 +349,7 @@ function createIgnoreResult(filePath, baseDir) { /** * Checks if the given message is an error message. - * @param {object} message The message to check. + * @param {Object} message The message to check. * @returns {boolean} Whether or not the message is an error message. * @private */ @@ -368,8 +377,8 @@ function getCacheFile(cacheFile, cwd) { */ cacheFile = path.normalize(cacheFile); - var resolvedCacheFile = path.resolve(cwd, cacheFile); - var looksLikeADirectory = cacheFile[cacheFile.length - 1 ] === path.sep; + let resolvedCacheFile = path.resolve(cwd, cacheFile); + let looksLikeADirectory = cacheFile[cacheFile.length - 1 ] === path.sep; /** * return the name for the cache file in case the provided parameter is a directory @@ -379,7 +388,7 @@ function getCacheFile(cacheFile, cwd) { return path.join(resolvedCacheFile, ".cache_" + hash(cwd)); } - var fileStats; + let fileStats; try { fileStats = fs.lstatSync(resolvedCacheFile); @@ -446,7 +455,7 @@ function CLIEngine(options) { */ this.options = options; - var cacheFile = getCacheFile(this.options.cacheLocation || this.options.cacheFile, this.options.cwd); + let cacheFile = getCacheFile(this.options.cacheLocation || this.options.cacheFile, this.options.cwd); /** * Cache used to avoid operating on files that haven't changed since the @@ -458,7 +467,7 @@ function CLIEngine(options) { // load in additional rules if (this.options.rulePaths) { - var cwd = this.options.cwd; + let cwd = this.options.cwd; this.options.rulePaths.forEach(function(rulesdir) { debug("Loading rules from " + rulesdir); @@ -480,7 +489,7 @@ function CLIEngine(options) { */ CLIEngine.getFormatter = function(format) { - var formatterPath; + let formatterPath; // default is stylish format = format || "stylish"; @@ -493,7 +502,7 @@ CLIEngine.getFormatter = function(format) { // if there's a slash, then it's a file if (format.indexOf("/") > -1) { - var cwd = this.options ? this.options.cwd : process.cwd(); + let cwd = this.options ? this.options.cwd : process.cwd(); formatterPath = path.resolve(cwd, format); } else { @@ -518,10 +527,10 @@ CLIEngine.getFormatter = function(format) { * @returns {LintResult[]} The filtered results. */ CLIEngine.getErrorResults = function(results) { - var filtered = []; + let filtered = []; results.forEach(function(result) { - var filteredMessages = result.messages.filter(isErrorMessage); + let filteredMessages = result.messages.filter(isErrorMessage); if (filteredMessages.length > 0) { filtered.push({ @@ -579,7 +588,7 @@ CLIEngine.prototype = { * @returns {Object} The results for all files that were linted. */ executeOnFiles: function(patterns) { - var results = [], + let results = [], options = this.options, fileCache = this._fileCache, configHelper = new Config(options), @@ -594,7 +603,7 @@ CLIEngine.prototype = { * @returns {string} the hash of the config */ function hashOfConfigFor(filename) { - var config = configHelper.getConfig(filename); + let config = configHelper.getConfig(filename); if (!prevConfig) { prevConfig = {}; @@ -609,7 +618,7 @@ CLIEngine.prototype = { */ prevConfig.config = config; - var eslintVersion = pkg.version; + let eslintVersion = pkg.version; prevConfig.hash = hash(eslintVersion + "_" + stringify(config)); } @@ -625,7 +634,8 @@ CLIEngine.prototype = { * @returns {void} */ function executeOnFile(filename, warnIgnored) { - var hashOfConfig; + let hashOfConfig, + descriptor; if (warnIgnored) { results.push(createIgnoreResult(filename, options.cwd)); @@ -639,12 +649,12 @@ CLIEngine.prototype = { * with the metadata and the flag that determines if * the file has changed */ - var descriptor = fileCache.getFileDescriptor(filename); - var meta = descriptor.meta || {}; + descriptor = fileCache.getFileDescriptor(filename); + let meta = descriptor.meta || {}; hashOfConfig = hashOfConfigFor(filename); - var changed = descriptor.changed || meta.hashOfConfig !== hashOfConfig; + let changed = descriptor.changed || meta.hashOfConfig !== hashOfConfig; if (!changed) { debug("Skipping file since hasn't changed: " + filename); @@ -666,7 +676,7 @@ CLIEngine.prototype = { debug("Processing " + filename); - var res = processFile(filename, configHelper, options); + let res = processFile(filename, configHelper, options); if (options.cache) { @@ -732,7 +742,7 @@ CLIEngine.prototype = { */ executeOnText: function(text, filename, warnIgnored) { - var results = [], + let results = [], stats, options = this.options, configHelper = new Config(options), @@ -742,8 +752,11 @@ CLIEngine.prototype = { if (filename && !path.isAbsolute(filename)) { filename = path.resolve(options.cwd, filename); } - if (filename && warnIgnored && ignoredPaths.contains(filename)) { - results.push(createIgnoreResult(filename, options.cwd)); + + if (filename && ignoredPaths.contains(filename)) { + if (warnIgnored) { + results.push(createIgnoreResult(filename, options.cwd)); + } } else { results.push(processText(text, configHelper, filename, options.fix, options.allowInlineConfig)); } @@ -765,7 +778,7 @@ CLIEngine.prototype = { * @returns {Object} A configuration object for the file. */ getConfigForFile: function(filePath) { - var configHelper = new Config(this.options); + let configHelper = new Config(this.options); return configHelper.getConfig(filePath); }, @@ -776,8 +789,8 @@ CLIEngine.prototype = { * @returns {boolean} Whether or not the given path is ignored. */ isPathIgnored: function(filePath) { - var ignoredPaths; - var resolvedPath = path.resolve(this.options.cwd, filePath); + let ignoredPaths; + let resolvedPath = path.resolve(this.options.cwd, filePath); ignoredPaths = new IgnoredPaths(this.options); return ignoredPaths.contains(resolvedPath); diff --git a/tools/eslint/lib/cli.js b/tools/eslint/lib/cli.js index 887c3c7671f612..b8bbda4cae8c19 100644 --- a/tools/eslint/lib/cli.js +++ b/tools/eslint/lib/cli.js @@ -15,7 +15,7 @@ // Requirements //------------------------------------------------------------------------------ -var fs = require("fs"), +let fs = require("fs"), path = require("path"), debug = require("debug"), @@ -70,7 +70,7 @@ function translateOptions(cliOptions) { * @private */ function printResults(engine, results, format, outputFile) { - var formatter, + let formatter, output, filePath; @@ -116,7 +116,7 @@ function printResults(engine, results, format, outputFile) { * Encapsulates all CLI behavior for eslint. Makes it easier to test as well as * for other Node.js programs to effectively run the CLI. */ -var cli = { +let cli = { /** * Executes the CLI based on an array of arguments that is passed in. @@ -126,7 +126,7 @@ var cli = { */ execute: function(args, text) { - var currentOptions, + let currentOptions, files, report, engine, @@ -172,7 +172,7 @@ var cli = { return 1; } - var fileConfig = engine.getConfigForFile(files[0]); + let fileConfig = engine.getConfigForFile(files[0]); log.info(JSON.stringify(fileConfig, null, " ")); return 0; diff --git a/tools/eslint/lib/code-path-analysis/code-path-analyzer.js b/tools/eslint/lib/code-path-analysis/code-path-analyzer.js index 4e55cccee64869..00db3064dc4e87 100644 --- a/tools/eslint/lib/code-path-analysis/code-path-analyzer.js +++ b/tools/eslint/lib/code-path-analysis/code-path-analyzer.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var assert = require("assert"), +let assert = require("assert"), CodePath = require("./code-path"), CodePathSegment = require("./code-path-segment"), IdGenerator = require("./id-generator"), @@ -38,7 +38,7 @@ function isCaseNode(node) { * @returns {boolean} `true` if the node is a test of a choice statement. */ function isForkingByTrueOrFalse(node) { - var parent = node.parent; + let parent = node.parent; switch (parent.type) { case "ConditionalExpression": @@ -83,7 +83,7 @@ function getBooleanValueIfSimpleConstant(node) { * @returns {boolean} `true` if the node is a reference. */ function isIdentifierReference(node) { - var parent = node.parent; + let parent = node.parent; switch (parent.type) { case "LabeledStatement": @@ -135,12 +135,12 @@ function isIdentifierReference(node) { * @returns {void} */ function forwardCurrentToHead(analyzer, node) { - var codePath = analyzer.codePath; - var state = CodePath.getState(codePath); - var currentSegments = state.currentSegments; - var headSegments = state.headSegments; - var end = Math.max(currentSegments.length, headSegments.length); - var i, currentSegment, headSegment; + let codePath = analyzer.codePath; + let state = CodePath.getState(codePath); + let currentSegments = state.currentSegments; + let headSegments = state.headSegments; + let end = Math.max(currentSegments.length, headSegments.length); + let i, currentSegment, headSegment; // Fires leaving events. for (i = 0; i < end; ++i) { @@ -191,11 +191,11 @@ function forwardCurrentToHead(analyzer, node) { * @returns {void} */ function leaveFromCurrentSegment(analyzer, node) { - var state = CodePath.getState(analyzer.codePath); - var currentSegments = state.currentSegments; + let state = CodePath.getState(analyzer.codePath); + let currentSegments = state.currentSegments; - for (var i = 0; i < currentSegments.length; ++i) { - var currentSegment = currentSegments[i]; + for (let i = 0; i < currentSegments.length; ++i) { + let currentSegment = currentSegments[i]; debug.dump("onCodePathSegmentEnd " + currentSegment.id); if (currentSegment.reachable) { @@ -221,9 +221,9 @@ function leaveFromCurrentSegment(analyzer, node) { * @returns {void} */ function preprocess(analyzer, node) { - var codePath = analyzer.codePath; - var state = CodePath.getState(codePath); - var parent = node.parent; + let codePath = analyzer.codePath; + let state = CodePath.getState(codePath); + let parent = node.parent; switch (parent.type) { case "LogicalExpression": @@ -328,9 +328,9 @@ function preprocess(analyzer, node) { * @returns {void} */ function processCodePathToEnter(analyzer, node) { - var codePath = analyzer.codePath; - var state = codePath && CodePath.getState(codePath); - var parent = node.parent; + let codePath = analyzer.codePath; + let state = codePath && CodePath.getState(codePath); + let parent = node.parent; switch (node.type) { case "Program": @@ -419,9 +419,9 @@ function processCodePathToEnter(analyzer, node) { * @returns {void} */ function processCodePathToExit(analyzer, node) { - var codePath = analyzer.codePath; - var state = CodePath.getState(codePath); - var dontForward = false; + let codePath = analyzer.codePath; + let state = CodePath.getState(codePath); + let dontForward = false; switch (node.type) { case "IfStatement": @@ -536,8 +536,8 @@ function postprocess(analyzer, node) { case "Program": case "FunctionDeclaration": case "FunctionExpression": - case "ArrowFunctionExpression": - var codePath = analyzer.codePath; + case "ArrowFunctionExpression": { + let codePath = analyzer.codePath; // Mark the current path as the final node. CodePath.getState(codePath).makeFinal(); @@ -555,6 +555,7 @@ function postprocess(analyzer, node) { debug.dumpState(node, CodePath.getState(codePath), true); } break; + } default: break; diff --git a/tools/eslint/lib/code-path-analysis/code-path-segment.js b/tools/eslint/lib/code-path-analysis/code-path-segment.js index d5361ccd07413b..544a9da2784743 100644 --- a/tools/eslint/lib/code-path-analysis/code-path-segment.js +++ b/tools/eslint/lib/code-path-analysis/code-path-segment.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var debug = require("./debug-helpers"); +let debug = require("./debug-helpers"); //------------------------------------------------------------------------------ // Helpers @@ -22,11 +22,11 @@ var debug = require("./debug-helpers"); * @returns {CodePathSegment[]} The replaced array. */ function flattenUnusedSegments(segments) { - var done = Object.create(null); - var retv = []; + let done = Object.create(null); + let retv = []; - for (var i = 0; i < segments.length; ++i) { - var segment = segments[i]; + for (let i = 0; i < segments.length; ++i) { + let segment = segments[i]; // Ignores duplicated. if (done[segment.id]) { @@ -35,8 +35,8 @@ function flattenUnusedSegments(segments) { // Use previous segments if unused. if (!segment.internal.used) { - for (var j = 0; j < segment.allPrevSegments.length; ++j) { - var prevSegment = segment.allPrevSegments[j]; + for (let j = 0; j < segment.allPrevSegments.length; ++j) { + let prevSegment = segment.allPrevSegments[j]; if (!done[prevSegment.id]) { done[prevSegment.id] = true; @@ -175,7 +175,7 @@ CodePathSegment.newNext = function(id, allPrevSegments) { * @returns {CodePathSegment} The created segment. */ CodePathSegment.newUnreachable = function(id, allPrevSegments) { - var segment = new CodePathSegment(id, flattenUnusedSegments(allPrevSegments), false); + let segment = new CodePathSegment(id, flattenUnusedSegments(allPrevSegments), false); // In `if (a) return a; foo();` case, the unreachable segment preceded by // the return statement is not used but must not be remove. @@ -211,11 +211,11 @@ CodePathSegment.markUsed = function(segment) { } segment.internal.used = true; - var i; + let i; if (segment.reachable) { for (i = 0; i < segment.allPrevSegments.length; ++i) { - var prevSegment = segment.allPrevSegments[i]; + let prevSegment = segment.allPrevSegments[i]; prevSegment.allNextSegments.push(segment); prevSegment.nextSegments.push(segment); diff --git a/tools/eslint/lib/code-path-analysis/code-path-state.js b/tools/eslint/lib/code-path-analysis/code-path-state.js index 0492d832c2c40f..7c3d4a35e62f03 100644 --- a/tools/eslint/lib/code-path-analysis/code-path-state.js +++ b/tools/eslint/lib/code-path-analysis/code-path-state.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var CodePathSegment = require("./code-path-segment"), +let CodePathSegment = require("./code-path-segment"), ForkContext = require("./fork-context"); //------------------------------------------------------------------------------ @@ -30,8 +30,8 @@ var CodePathSegment = require("./code-path-segment"), * @returns {void} */ function addToReturnedOrThrown(dest, others, all, segments) { - for (var i = 0; i < segments.length; ++i) { - var segment = segments[i]; + for (let i = 0; i < segments.length; ++i) { + let segment = segments[i]; dest.push(segment); if (others.indexOf(segment) === -1) { @@ -52,7 +52,7 @@ function getContinueContext(state, label) { return state.loopContext; } - var context = state.loopContext; + let context = state.loopContext; while (context) { if (context.label === label) { @@ -73,7 +73,7 @@ function getContinueContext(state, label) { * @returns {LoopContext|SwitchContext} A context for a `break` statement. */ function getBreakContext(state, label) { - var context = state.breakContext; + let context = state.breakContext; while (context) { if (label ? context.label === label : context.breakable) { @@ -93,7 +93,7 @@ function getBreakContext(state, label) { * @returns {TryContext|CodePathState} A context for a `return` statement. */ function getReturnContext(state) { - var context = state.tryContext; + let context = state.tryContext; while (context) { if (context.hasFinalizer && context.position !== "finally") { @@ -112,7 +112,7 @@ function getReturnContext(state) { * @returns {TryContext|CodePathState} A context for a `throw` statement. */ function getThrowContext(state) { - var context = state.tryContext; + let context = state.tryContext; while (context) { if (context.position === "try" || @@ -149,9 +149,9 @@ function remove(xs, x) { * @returns {void} */ function removeConnection(prevSegments, nextSegments) { - for (var i = 0; i < prevSegments.length; ++i) { - var prevSegment = prevSegments[i]; - var nextSegment = nextSegments[i]; + for (let i = 0; i < prevSegments.length; ++i) { + let prevSegment = prevSegments[i]; + let nextSegment = nextSegments[i]; remove(prevSegment.nextSegments, nextSegment); remove(prevSegment.allNextSegments, nextSegment); @@ -169,11 +169,11 @@ function removeConnection(prevSegments, nextSegments) { * @returns {void} */ function makeLooped(state, fromSegments, toSegments) { - var end = Math.min(fromSegments.length, toSegments.length); + let end = Math.min(fromSegments.length, toSegments.length); - for (var i = 0; i < end; ++i) { - var fromSegment = fromSegments[i]; - var toSegment = toSegments[i]; + for (let i = 0; i < end; ++i) { + let fromSegment = fromSegments[i]; + let toSegment = toSegments[i]; if (toSegment.reachable) { fromSegment.nextSegments.push(toSegment); @@ -225,7 +225,7 @@ function finalizeTestSegmentsOfFor(context, choiceContext, head) { * @constructor * @param {IdGenerator} idGenerator - An id generator to generate id for code * path segments. - * @param {function} onLooped - A callback function to notify looping. + * @param {Function} onLooped - A callback function to notify looping. */ function CodePathState(idGenerator, onLooped) { this.idGenerator = idGenerator; @@ -241,9 +241,9 @@ function CodePathState(idGenerator, onLooped) { this.initialSegment = this.forkContext.head[0]; // returnedSegments and thrownSegments push elements into finalSegments also. - var final = this.finalSegments = []; - var returned = this.returnedForkContext = []; - var thrown = this.thrownForkContext = []; + let final = this.finalSegments = []; + let returned = this.returnedForkContext = []; + let thrown = this.thrownForkContext = []; returned.add = addToReturnedOrThrown.bind(null, returned, thrown, final); thrown.add = addToReturnedOrThrown.bind(null, thrown, returned, final); @@ -266,7 +266,7 @@ CodePathState.prototype = { * @type {ForkContext} */ get parentForkContext() { - var current = this.forkContext; + let current = this.forkContext; return current && current.upper; }, @@ -292,7 +292,7 @@ CodePathState.prototype = { * @returns {ForkContext} The last context. */ popForkContext: function() { - var lastContext = this.forkContext; + let lastContext = this.forkContext; this.forkContext = lastContext.upper; this.forkContext.replaceHead(lastContext.makeNext(0, -1)); @@ -370,12 +370,12 @@ CodePathState.prototype = { * @returns {ChoiceContext} The popped context. */ popChoiceContext: function() { - var context = this.choiceContext; + let context = this.choiceContext; this.choiceContext = context.upper; - var forkContext = this.forkContext; - var headSegments = forkContext.head; + let forkContext = this.forkContext; + let headSegments = forkContext.head; switch (context.kind) { case "&&": @@ -396,7 +396,7 @@ CodePathState.prototype = { * test chunk. */ if (context.isForkingAsResult) { - var parentContext = this.choiceContext; + let parentContext = this.choiceContext; parentContext.trueForkContext.addAll(context.trueForkContext); parentContext.falseForkContext.addAll(context.falseForkContext); @@ -443,7 +443,7 @@ CodePathState.prototype = { } // Merges all paths. - var prevForkContext = context.trueForkContext; + let prevForkContext = context.trueForkContext; prevForkContext.addAll(context.falseForkContext); forkContext.replaceHead(prevForkContext.makeNext(0, -1)); @@ -458,8 +458,8 @@ CodePathState.prototype = { * @returns {void} */ makeLogicalRight: function() { - var context = this.choiceContext; - var forkContext = this.forkContext; + let context = this.choiceContext; + let forkContext = this.forkContext; if (context.processed) { @@ -467,7 +467,7 @@ CodePathState.prototype = { * This got segments already from the child choice context. * Creates the next path from own true/false fork context. */ - var prevForkContext = + let prevForkContext = context.kind === "&&" ? context.trueForkContext : /* kind === "||" */ context.falseForkContext; @@ -502,8 +502,8 @@ CodePathState.prototype = { * @returns {void} */ makeIfConsequent: function() { - var context = this.choiceContext; - var forkContext = this.forkContext; + let context = this.choiceContext; + let forkContext = this.forkContext; /* * If any result were not transferred from child contexts, @@ -529,8 +529,8 @@ CodePathState.prototype = { * @returns {void} */ makeIfAlternate: function() { - var context = this.choiceContext; - var forkContext = this.forkContext; + let context = this.choiceContext; + let forkContext = this.forkContext; /* * The head segments are the path of the `if` block. @@ -583,12 +583,12 @@ CodePathState.prototype = { * @returns {void} */ popSwitchContext: function() { - var context = this.switchContext; + let context = this.switchContext; this.switchContext = context.upper; - var forkContext = this.forkContext; - var brokenForkContext = this.popBreakContext().brokenForkContext; + let forkContext = this.forkContext; + let brokenForkContext = this.popBreakContext().brokenForkContext; if (context.countForks === 0) { @@ -605,10 +605,10 @@ CodePathState.prototype = { return; } - var lastSegments = forkContext.head; + let lastSegments = forkContext.head; this.forkBypassPath(); - var lastCaseSegments = forkContext.head; + let lastCaseSegments = forkContext.head; /* * `brokenForkContext` is used to make the next segment. @@ -640,7 +640,7 @@ CodePathState.prototype = { } // Pops the segment context stack until the entry segment. - for (var i = 0; i < context.countForks; ++i) { + for (let i = 0; i < context.countForks; ++i) { this.forkContext = this.forkContext.upper; } @@ -659,7 +659,7 @@ CodePathState.prototype = { * @returns {void} */ makeSwitchCaseBody: function(isEmpty, isDefault) { - var context = this.switchContext; + let context = this.switchContext; if (!context.hasCase) { return; @@ -670,8 +670,8 @@ CodePathState.prototype = { * The parent fork context has two segments. * Those are from the current case and the body of the previous case. */ - var parentForkContext = this.forkContext; - var forkContext = this.pushForkContext(); + let parentForkContext = this.forkContext; + let forkContext = this.pushForkContext(); forkContext.add(parentForkContext.makeNext(0, -1)); @@ -731,7 +731,7 @@ CodePathState.prototype = { * @returns {void} */ popTryContext: function() { - var context = this.tryContext; + let context = this.tryContext; this.tryContext = context.upper; @@ -747,19 +747,19 @@ CodePathState.prototype = { * block. */ - var returned = context.returnedForkContext; - var thrown = context.thrownForkContext; + let returned = context.returnedForkContext; + let thrown = context.thrownForkContext; if (returned.empty && thrown.empty) { return; } // Separate head to normal paths and leaving paths. - var headSegments = this.forkContext.head; + let headSegments = this.forkContext.head; this.forkContext = this.forkContext.upper; - var normalSegments = headSegments.slice(0, headSegments.length / 2 | 0); - var leavingSegments = headSegments.slice(headSegments.length / 2 | 0); + let normalSegments = headSegments.slice(0, headSegments.length / 2 | 0); + let leavingSegments = headSegments.slice(headSegments.length / 2 | 0); // Forwards the leaving path to upper contexts. if (!returned.empty) { @@ -785,9 +785,9 @@ CodePathState.prototype = { * @returns {void} */ makeCatchBlock: function() { - var context = this.tryContext; - var forkContext = this.forkContext; - var thrown = context.thrownForkContext; + let context = this.tryContext; + let forkContext = this.forkContext; + let thrown = context.thrownForkContext; // Update state. context.position = "catch"; @@ -796,7 +796,7 @@ CodePathState.prototype = { // Merge thrown paths. thrown.add(forkContext.head); - var thrownSegments = thrown.makeNext(0, -1); + let thrownSegments = thrown.makeNext(0, -1); // Fork to a bypass and the merged thrown path. this.pushForkContext(); @@ -814,11 +814,11 @@ CodePathState.prototype = { * @returns {void} */ makeFinallyBlock: function() { - var context = this.tryContext; - var forkContext = this.forkContext; - var returned = context.returnedForkContext; - var thrown = context.thrownForkContext; - var headOfLeavingSegments = forkContext.head; + let context = this.tryContext; + let forkContext = this.forkContext; + let returned = context.returnedForkContext; + let thrown = context.thrownForkContext; + let headOfLeavingSegments = forkContext.head; // Update state. if (context.position === "catch") { @@ -843,11 +843,11 @@ CodePathState.prototype = { * Create a parallel segment from merging returned and thrown. * This segment will leave at the end of this finally block. */ - var segments = forkContext.makeNext(-1, -1); - var j; + let segments = forkContext.makeNext(-1, -1); + let j; - for (var i = 0; i < forkContext.count; ++i) { - var prevSegsOfLeavingSegment = [headOfLeavingSegments[i]]; + for (let i = 0; i < forkContext.count; ++i) { + let prevSegsOfLeavingSegment = [headOfLeavingSegments[i]]; for (j = 0; j < returned.segmentsList.length; ++j) { prevSegsOfLeavingSegment.push(returned.segmentsList[j][i]); @@ -872,13 +872,13 @@ CodePathState.prototype = { * @returns {void} */ makeFirstThrowablePathInTryBlock: function() { - var forkContext = this.forkContext; + let forkContext = this.forkContext; if (!forkContext.reachable) { return; } - var context = getThrowContext(this); + let context = getThrowContext(this); if (context === this || context.position !== "try" || @@ -905,8 +905,8 @@ CodePathState.prototype = { * @returns {void} */ pushLoopContext: function(type, label) { - var forkContext = this.forkContext; - var breakContext = this.pushBreakContext(true, label); + let forkContext = this.forkContext; + let breakContext = this.pushBreakContext(true, label); switch (type) { case "WhileStatement": @@ -977,13 +977,13 @@ CodePathState.prototype = { * @returns {void} */ popLoopContext: function() { - var context = this.loopContext; + let context = this.loopContext; this.loopContext = context.upper; - var forkContext = this.forkContext; - var brokenForkContext = this.popBreakContext().brokenForkContext; - var choiceContext; + let forkContext = this.forkContext; + let brokenForkContext = this.popBreakContext().brokenForkContext; + let choiceContext; // Creates a looped path. switch (context.type) { @@ -996,7 +996,7 @@ CodePathState.prototype = { context.continueDestSegments); break; - case "DoWhileStatement": + case "DoWhileStatement": { choiceContext = this.popChoiceContext(); if (!choiceContext.processed) { @@ -1008,15 +1008,16 @@ CodePathState.prototype = { } // `true` paths go to looping. - var segmentsList = choiceContext.trueForkContext.segmentsList; + const segmentsList = choiceContext.trueForkContext.segmentsList; - for (var i = 0; i < segmentsList.length; ++i) { + for (let i = 0; i < segmentsList.length; ++i) { makeLooped( this, segmentsList[i], context.entrySegments); } break; + } case "ForInStatement": case "ForOfStatement": @@ -1047,9 +1048,9 @@ CodePathState.prototype = { * @returns {void} */ makeWhileTest: function(test) { - var context = this.loopContext; - var forkContext = this.forkContext; - var testSegments = forkContext.makeNext(0, -1); + let context = this.loopContext; + let forkContext = this.forkContext; + let testSegments = forkContext.makeNext(0, -1); // Update state. context.test = test; @@ -1063,9 +1064,9 @@ CodePathState.prototype = { * @returns {void} */ makeWhileBody: function() { - var context = this.loopContext; - var choiceContext = this.choiceContext; - var forkContext = this.forkContext; + let context = this.loopContext; + let choiceContext = this.choiceContext; + let forkContext = this.forkContext; if (!choiceContext.processed) { choiceContext.trueForkContext.add(forkContext.head); @@ -1085,9 +1086,9 @@ CodePathState.prototype = { * @returns {void} */ makeDoWhileBody: function() { - var context = this.loopContext; - var forkContext = this.forkContext; - var bodySegments = forkContext.makeNext(-1, -1); + let context = this.loopContext; + let forkContext = this.forkContext; + let bodySegments = forkContext.makeNext(-1, -1); // Update state. context.entrySegments = bodySegments; @@ -1101,15 +1102,15 @@ CodePathState.prototype = { * @returns {void} */ makeDoWhileTest: function(test) { - var context = this.loopContext; - var forkContext = this.forkContext; + let context = this.loopContext; + let forkContext = this.forkContext; context.test = test; // Creates paths of `continue` statements. if (!context.continueForkContext.empty) { context.continueForkContext.add(forkContext.head); - var testSegments = context.continueForkContext.makeNext(0, -1); + let testSegments = context.continueForkContext.makeNext(0, -1); forkContext.replaceHead(testSegments); } @@ -1122,10 +1123,10 @@ CodePathState.prototype = { * @returns {void} */ makeForTest: function(test) { - var context = this.loopContext; - var forkContext = this.forkContext; - var endOfInitSegments = forkContext.head; - var testSegments = forkContext.makeNext(-1, -1); + let context = this.loopContext; + let forkContext = this.forkContext; + let endOfInitSegments = forkContext.head; + let testSegments = forkContext.makeNext(-1, -1); // Update state. context.test = test; @@ -1140,9 +1141,9 @@ CodePathState.prototype = { * @returns {void} */ makeForUpdate: function() { - var context = this.loopContext; - var choiceContext = this.choiceContext; - var forkContext = this.forkContext; + let context = this.loopContext; + let choiceContext = this.choiceContext; + let forkContext = this.forkContext; // Make the next paths of the test. if (context.testSegments) { @@ -1155,7 +1156,7 @@ CodePathState.prototype = { } // Update state. - var updateSegments = forkContext.makeDisconnected(-1, -1); + let updateSegments = forkContext.makeDisconnected(-1, -1); context.continueDestSegments = context.updateSegments = updateSegments; forkContext.replaceHead(updateSegments); @@ -1167,9 +1168,9 @@ CodePathState.prototype = { * @returns {void} */ makeForBody: function() { - var context = this.loopContext; - var choiceContext = this.choiceContext; - var forkContext = this.forkContext; + let context = this.loopContext; + let choiceContext = this.choiceContext; + let forkContext = this.forkContext; // Update state. if (context.updateSegments) { @@ -1191,7 +1192,7 @@ CodePathState.prototype = { context.endOfInitSegments = forkContext.head; } - var bodySegments = context.endOfTestSegments; + let bodySegments = context.endOfTestSegments; if (!bodySegments) { @@ -1199,7 +1200,7 @@ CodePathState.prototype = { * If there is not the `test` part, the `body` path comes from the * `init` part and the `update` part. */ - var prevForkContext = ForkContext.newEmpty(forkContext); + let prevForkContext = ForkContext.newEmpty(forkContext); prevForkContext.add(context.endOfInitSegments); if (context.endOfUpdateSegments) { @@ -1219,9 +1220,9 @@ CodePathState.prototype = { * @returns {void} */ makeForInOfLeft: function() { - var context = this.loopContext; - var forkContext = this.forkContext; - var leftSegments = forkContext.makeDisconnected(-1, -1); + let context = this.loopContext; + let forkContext = this.forkContext; + let leftSegments = forkContext.makeDisconnected(-1, -1); // Update state. context.prevSegments = forkContext.head; @@ -1236,12 +1237,12 @@ CodePathState.prototype = { * @returns {void} */ makeForInOfRight: function() { - var context = this.loopContext; - var forkContext = this.forkContext; - var temp = ForkContext.newEmpty(forkContext); + let context = this.loopContext; + let forkContext = this.forkContext; + let temp = ForkContext.newEmpty(forkContext); temp.add(context.prevSegments); - var rightSegments = temp.makeNext(-1, -1); + let rightSegments = temp.makeNext(-1, -1); // Update state. context.endOfLeftSegments = forkContext.head; @@ -1255,12 +1256,12 @@ CodePathState.prototype = { * @returns {void} */ makeForInOfBody: function() { - var context = this.loopContext; - var forkContext = this.forkContext; - var temp = ForkContext.newEmpty(forkContext); + let context = this.loopContext; + let forkContext = this.forkContext; + let temp = ForkContext.newEmpty(forkContext); temp.add(context.endOfLeftSegments); - var bodySegments = temp.makeNext(-1, -1); + let bodySegments = temp.makeNext(-1, -1); // Make a path: `right` -> `left`. makeLooped(this, forkContext.head, context.leftSegments); @@ -1280,7 +1281,7 @@ CodePathState.prototype = { * @param {boolean} breakable - The flag to indicate it can break by * an unlabeled BreakStatement. * @param {string|null} label - The label of this context. - * @returns {object} The new context. + * @returns {Object} The new context. */ pushBreakContext: function(breakable, label) { this.breakContext = { @@ -1295,17 +1296,17 @@ CodePathState.prototype = { /** * Removes the top item of the break context stack. * - * @returns {object} The removed context. + * @returns {Object} The removed context. */ popBreakContext: function() { - var context = this.breakContext; - var forkContext = this.forkContext; + let context = this.breakContext; + let forkContext = this.forkContext; this.breakContext = context.upper; // Process this context here for other than switches and loops. if (!context.breakable) { - var brokenForkContext = context.brokenForkContext; + let brokenForkContext = context.brokenForkContext; if (!brokenForkContext.empty) { brokenForkContext.add(forkContext.head); @@ -1326,13 +1327,13 @@ CodePathState.prototype = { * @returns {void} */ makeBreak: function(label) { - var forkContext = this.forkContext; + let forkContext = this.forkContext; if (!forkContext.reachable) { return; } - var context = getBreakContext(this, label); + let context = getBreakContext(this, label); /* istanbul ignore else: foolproof (syntax error) */ if (context) { @@ -1352,13 +1353,13 @@ CodePathState.prototype = { * @returns {void} */ makeContinue: function(label) { - var forkContext = this.forkContext; + let forkContext = this.forkContext; if (!forkContext.reachable) { return; } - var context = getContinueContext(this, label); + let context = getContinueContext(this, label); /* istanbul ignore else: foolproof (syntax error) */ if (context) { @@ -1387,7 +1388,7 @@ CodePathState.prototype = { * @returns {void} */ makeReturn: function() { - var forkContext = this.forkContext; + let forkContext = this.forkContext; if (forkContext.reachable) { getReturnContext(this).returnedForkContext.add(forkContext.head); @@ -1404,7 +1405,7 @@ CodePathState.prototype = { * @returns {void} */ makeThrow: function() { - var forkContext = this.forkContext; + let forkContext = this.forkContext; if (forkContext.reachable) { getThrowContext(this).thrownForkContext.add(forkContext.head); @@ -1417,7 +1418,7 @@ CodePathState.prototype = { * @returns {void} */ makeFinal: function() { - var segments = this.currentSegments; + let segments = this.currentSegments; if (segments.length > 0 && segments[0].reachable) { this.returnedForkContext.add(segments); diff --git a/tools/eslint/lib/code-path-analysis/code-path.js b/tools/eslint/lib/code-path-analysis/code-path.js index 035e34e712e002..3fdc99afc3f658 100644 --- a/tools/eslint/lib/code-path-analysis/code-path.js +++ b/tools/eslint/lib/code-path-analysis/code-path.js @@ -9,8 +9,8 @@ // Requirements //------------------------------------------------------------------------------ -var CodePathState = require("./code-path-state"); -var IdGenerator = require("./id-generator"); +let CodePathState = require("./code-path-state"); +let IdGenerator = require("./id-generator"); //------------------------------------------------------------------------------ // Public Interface @@ -22,7 +22,7 @@ var IdGenerator = require("./id-generator"); * @constructor * @param {string} id - An identifier. * @param {CodePath|null} upper - The code path of the upper function scope. - * @param {function} onLooped - A callback function to notify looping. + * @param {Function} onLooped - A callback function to notify looping. */ function CodePath(id, upper, onLooped) { @@ -117,10 +117,10 @@ CodePath.prototype = { * - `controller.skip()` - Skip the following segments in this branch. * - `controller.break()` - Skip all following segments. * - * @param {object} [options] - Omittable. + * @param {Object} [options] - Omittable. * @param {CodePathSegment} [options.first] - The first segment to traverse. * @param {CodePathSegment} [options.last] - The last segment to traverse. - * @param {function} callback - A callback function. + * @param {Function} callback - A callback function. * @returns {void} */ traverseSegments: function(options, callback) { @@ -130,18 +130,18 @@ CodePath.prototype = { } options = options || {}; - var startSegment = options.first || this.internal.initialSegment; - var lastSegment = options.last; - - var item = null; - var index = 0; - var end = 0; - var segment = null; - var visited = Object.create(null); - var stack = [[startSegment, 0]]; - var skippedSegment = null; - var broken = false; - var controller = { + let startSegment = options.first || this.internal.initialSegment; + let lastSegment = options.last; + + let item = null; + let index = 0; + let end = 0; + let segment = null; + let visited = Object.create(null); + let stack = [[startSegment, 0]]; + let skippedSegment = null; + let broken = false; + let controller = { skip: function() { if (stack.length <= 1) { broken = true; diff --git a/tools/eslint/lib/code-path-analysis/debug-helpers.js b/tools/eslint/lib/code-path-analysis/debug-helpers.js index e68c94bc496a0d..ea31a1a9d73816 100644 --- a/tools/eslint/lib/code-path-analysis/debug-helpers.js +++ b/tools/eslint/lib/code-path-analysis/debug-helpers.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var debug = require("debug")("eslint:code-path"); +let debug = require("debug")("eslint:code-path"); //------------------------------------------------------------------------------ // Helpers @@ -54,8 +54,8 @@ module.exports = { * @returns {void} */ dumpState: !debug.enabled ? debug : /* istanbul ignore next */ function(node, state, leaving) { - for (var i = 0; i < state.currentSegments.length; ++i) { - var segInternal = state.currentSegments[i].internal; + for (let i = 0; i < state.currentSegments.length; ++i) { + let segInternal = state.currentSegments[i].internal; if (leaving) { segInternal.exitNodes.push(node); @@ -80,7 +80,7 @@ module.exports = { * @see http://www.webgraphviz.com */ dumpDot: !debug.enabled ? debug : /* istanbul ignore next */ function(codePath) { - var text = + let text = "\n" + "digraph {\n" + "node[shape=box,style=\"rounded,filled\",fillcolor=white];\n" + @@ -93,11 +93,11 @@ module.exports = { text += "thrown[label=\"✘\",shape=circle,width=0.3,height=0.3,fixedsize];\n"; } - var traceMap = Object.create(null); - var arrows = this.makeDotArrows(codePath, traceMap); + let traceMap = Object.create(null); + let arrows = this.makeDotArrows(codePath, traceMap); - for (var id in traceMap) { // eslint-disable-line guard-for-in - var segment = traceMap[id]; + for (let id in traceMap) { // eslint-disable-line guard-for-in + let segment = traceMap[id]; text += id + "["; @@ -140,26 +140,26 @@ module.exports = { * The DOT code can be visialized with Graphvis. * * @param {CodePath} codePath - A code path to make DOT. - * @param {object} traceMap - Optional. A map to check whether or not segments had been done. + * @param {Object} traceMap - Optional. A map to check whether or not segments had been done. * @returns {string} A DOT code of the code path. */ makeDotArrows: function(codePath, traceMap) { - var stack = [[codePath.initialSegment, 0]]; - var done = traceMap || Object.create(null); - var lastId = codePath.initialSegment.id; - var text = "initial->" + codePath.initialSegment.id; + let stack = [[codePath.initialSegment, 0]]; + let done = traceMap || Object.create(null); + let lastId = codePath.initialSegment.id; + let text = "initial->" + codePath.initialSegment.id; while (stack.length > 0) { - var item = stack.pop(); - var segment = item[0]; - var index = item[1]; + let item = stack.pop(); + let segment = item[0]; + let index = item[1]; if (done[segment.id] && index === 0) { continue; } done[segment.id] = segment; - var nextSegment = segment.allNextSegments[index]; + let nextSegment = segment.allNextSegments[index]; if (!nextSegment) { continue; diff --git a/tools/eslint/lib/code-path-analysis/fork-context.js b/tools/eslint/lib/code-path-analysis/fork-context.js index 00e0f97c40300f..93e59e7a028fde 100644 --- a/tools/eslint/lib/code-path-analysis/fork-context.js +++ b/tools/eslint/lib/code-path-analysis/fork-context.js @@ -13,7 +13,7 @@ // Requirements //------------------------------------------------------------------------------ -var assert = require("assert"), +let assert = require("assert"), CodePathSegment = require("./code-path-segment"); //------------------------------------------------------------------------------ @@ -40,11 +40,11 @@ function isReachable(segment) { * @param {ForkContext} context - An instance. * @param {number} begin - The first index of the previous segments. * @param {number} end - The last index of the previous segments. - * @param {function} create - A factory function of new segments. + * @param {Function} create - A factory function of new segments. * @returns {CodePathSegment[]} New segments. */ function makeSegments(context, begin, end, create) { - var list = context.segmentsList; + let list = context.segmentsList; if (begin < 0) { begin = list.length + begin; @@ -53,12 +53,12 @@ function makeSegments(context, begin, end, create) { end = list.length + end; } - var segments = []; + let segments = []; - for (var i = 0; i < context.count; ++i) { - var allPrevSegments = []; + for (let i = 0; i < context.count; ++i) { + let allPrevSegments = []; - for (var j = begin; j <= end; ++j) { + for (let j = begin; j <= end; ++j) { allPrevSegments.push(list[j][i]); } @@ -80,9 +80,9 @@ function makeSegments(context, begin, end, create) { */ function mergeExtraSegments(context, segments) { while (segments.length > context.count) { - var merged = []; + let merged = []; - for (var i = 0, length = segments.length / 2 | 0; i < length; ++i) { + for (let i = 0, length = segments.length / 2 | 0; i < length; ++i) { merged.push(CodePathSegment.newNext( context.idGenerator.next(), [segments[i], segments[i + length]] @@ -120,7 +120,7 @@ ForkContext.prototype = { * @type {CodePathSegment[]} */ get head() { - var list = this.segmentsList; + let list = this.segmentsList; return list.length === 0 ? [] : list[list.length - 1]; }, @@ -138,7 +138,7 @@ ForkContext.prototype = { * @type {boolean} */ get reachable() { - var segments = this.head; + let segments = this.head; return segments.length > 0 && segments.some(isReachable); }, @@ -214,9 +214,9 @@ ForkContext.prototype = { addAll: function(context) { assert(context.count === this.count); - var source = context.segmentsList; + let source = context.segmentsList; - for (var i = 0; i < source.length; ++i) { + for (let i = 0; i < source.length; ++i) { this.segmentsList.push(source[i]); } }, @@ -238,7 +238,7 @@ ForkContext.prototype = { * @returns {ForkContext} New fork context. */ ForkContext.newRoot = function(idGenerator) { - var context = new ForkContext(idGenerator, null, 1); + let context = new ForkContext(idGenerator, null, 1); context.add([CodePathSegment.newRoot(idGenerator.next())]); diff --git a/tools/eslint/lib/config.js b/tools/eslint/lib/config.js index a485774d7757bb..8c8533a22830ba 100644 --- a/tools/eslint/lib/config.js +++ b/tools/eslint/lib/config.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var path = require("path"), +let path = require("path"), ConfigOps = require("./config/config-ops"), ConfigFile = require("./config/config-file"), Plugins = require("./config/plugins"), @@ -23,7 +23,7 @@ var path = require("path"), // Constants //------------------------------------------------------------------------------ -var PERSONAL_CONFIG_DIR = userHome || null; +let PERSONAL_CONFIG_DIR = userHome || null; //------------------------------------------------------------------------------ // Helpers @@ -48,7 +48,7 @@ function isObject(item) { * @private */ function loadConfig(configToLoad) { - var config = {}, + let config = {}, filePath = ""; if (configToLoad) { @@ -75,7 +75,7 @@ function loadConfig(configToLoad) { * @private */ function getPersonalConfig() { - var config, + let config, filename; if (PERSONAL_CONFIG_DIR) { @@ -106,7 +106,7 @@ function hasRules(options) { * @returns {Object} The local config object, or an empty object if there is no local config. */ function getLocalConfig(thisConfig, directory) { - var found, + let found, i, localConfig, localConfigFile, @@ -162,10 +162,10 @@ function getLocalConfig(thisConfig, directory) { if (personalConfig) { config = ConfigOps.merge(config, personalConfig); - } else if (!hasRules(thisConfig.options)) { + } else if (!hasRules(thisConfig.options) && !thisConfig.options.baseConfig) { // No config file, no manual configuration, and no rules, so error. - var noConfigError = new Error("No ESLint configuration found."); + let noConfigError = new Error("No ESLint configuration found."); noConfigError.messageTemplate = "no-config-found"; noConfigError.messageData = { @@ -191,7 +191,7 @@ function getLocalConfig(thisConfig, directory) { * @param {Object} options Options to be passed in */ function Config(options) { - var useConfig; + let useConfig; options = options || {}; @@ -217,7 +217,7 @@ function Config(options) { * If user declares "foo", convert to "foo:false". */ this.globals = (options.globals || []).reduce(function(globals, def) { - var parts = def.split(":"); + let parts = def.split(":"); globals[parts[0]] = (parts.length > 1 && parts[1] === "true"); @@ -244,7 +244,7 @@ function Config(options) { * @returns {Object} config object */ Config.prototype.getConfig = function(filePath) { - var config, + let config, userConfig, directory = filePath ? path.dirname(filePath) : this.options.cwd; diff --git a/tools/eslint/lib/config/autoconfig.js b/tools/eslint/lib/config/autoconfig.js index be3d0970741935..2cd753e95dd9f8 100644 --- a/tools/eslint/lib/config/autoconfig.js +++ b/tools/eslint/lib/config/autoconfig.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"), +let lodash = require("lodash"), debug = require("debug"), eslint = require("../eslint"), configRule = require("./config-rule"), @@ -20,7 +20,7 @@ var lodash = require("lodash"), // Data //------------------------------------------------------------------------------ -var MAX_CONFIG_COMBINATIONS = 17, // 16 combinations + 1 for severity only +let MAX_CONFIG_COMBINATIONS = 17, // 16 combinations + 1 for severity only RECOMMENDED_CONFIG_NAME = "eslint:recommended"; //------------------------------------------------------------------------------ @@ -89,7 +89,7 @@ Registry.prototype = { * @returns {void} */ populateFromCoreRules: function() { - var rulesConfig = configRule.createCoreRuleConfigs(); + let rulesConfig = configRule.createCoreRuleConfigs(); this.rules = makeRegistryItems(rulesConfig); }, @@ -109,7 +109,7 @@ Registry.prototype = { * @returns {Object[]} "rules" configurations to use for linting */ buildRuleSets: function() { - var idx = 0, + let idx = 0, ruleIds = Object.keys(this.rules), ruleSets = []; @@ -122,7 +122,7 @@ Registry.prototype = { * @param {string} rule The ruleId to add. * @returns {void} */ - var addRuleToRuleSet = function(rule) { + let addRuleToRuleSet = function(rule) { /* * This check ensures that there is a rule configuration and that @@ -130,7 +130,7 @@ Registry.prototype = { * If it has too many configs, we will only use the most basic of * the possible configurations. */ - var hasFewCombos = (this.rules[rule].length <= MAX_CONFIG_COMBINATIONS); + let hasFewCombos = (this.rules[rule].length <= MAX_CONFIG_COMBINATIONS); if (this.rules[rule][idx] && (hasFewCombos || this.rules[rule][idx].specificity <= 2)) { @@ -170,12 +170,12 @@ Registry.prototype = { * @returns {void} */ stripFailingConfigs: function() { - var ruleIds = Object.keys(this.rules), + let ruleIds = Object.keys(this.rules), newRegistry = new Registry(); newRegistry.rules = lodash.assign({}, this.rules); ruleIds.forEach(function(ruleId) { - var errorFreeItems = newRegistry.rules[ruleId].filter(function(registryItem) { + let errorFreeItems = newRegistry.rules[ruleId].filter(function(registryItem) { return (registryItem.errorCount === 0); }); @@ -195,7 +195,7 @@ Registry.prototype = { * @returns {void} */ stripExtraConfigs: function() { - var ruleIds = Object.keys(this.rules), + let ruleIds = Object.keys(this.rules), newRegistry = new Registry(); newRegistry.rules = lodash.assign({}, this.rules); @@ -216,11 +216,11 @@ Registry.prototype = { * @returns {Registry} A registry of failing rules. */ getFailingRulesRegistry: function() { - var ruleIds = Object.keys(this.rules), + let ruleIds = Object.keys(this.rules), failingRegistry = new Registry(); ruleIds.forEach(function(ruleId) { - var failingConfigs = this.rules[ruleId].filter(function(registryItem) { + let failingConfigs = this.rules[ruleId].filter(function(registryItem) { return (registryItem.errorCount > 0); }); @@ -239,7 +239,7 @@ Registry.prototype = { * @returns {Object} An eslint config with rules section populated */ createConfig: function() { - var ruleIds = Object.keys(this.rules), + let ruleIds = Object.keys(this.rules), config = {rules: {}}; ruleIds.forEach(function(ruleId) { @@ -258,7 +258,7 @@ Registry.prototype = { * @returns {Registry} A registry of rules */ filterBySpecificity: function(specificity) { - var ruleIds = Object.keys(this.rules), + let ruleIds = Object.keys(this.rules), newRegistry = new Registry(); newRegistry.rules = lodash.assign({}, this.rules); @@ -280,7 +280,7 @@ Registry.prototype = { * @returns {Registry} New registry with errorCount populated */ lintSourceCode: function(sourceCodes, config, cb) { - var totalFilesLinting, + let totalFilesLinting, lintConfig, ruleSets, ruleSetIdx, @@ -307,7 +307,7 @@ Registry.prototype = { ruleSets.forEach(function(ruleSet) { lintConfig = lodash.assign({}, config, {rules: ruleSet}); - var lintResults = eslint.verify(sourceCodes[filename], lintConfig); + let lintResults = eslint.verify(sourceCodes[filename], lintConfig); lintResults.forEach(function(result) { @@ -344,11 +344,11 @@ Registry.prototype = { * @returns {Object} config object using `"extends": "eslint:recommended"` */ function extendFromRecommended(config) { - var newConfig = lodash.assign({}, config); + let newConfig = lodash.assign({}, config); ConfigOps.normalizeToStrings(newConfig); - var recRules = Object.keys(recConfig.rules).filter(function(ruleId) { + let recRules = Object.keys(recConfig.rules).filter(function(ruleId) { return ConfigOps.isErrorSeverity(recConfig.rules[ruleId]); }); diff --git a/tools/eslint/lib/config/config-file.js b/tools/eslint/lib/config/config-file.js index e2996e3eb90e64..9120c12f3c49cd 100644 --- a/tools/eslint/lib/config/config-file.js +++ b/tools/eslint/lib/config/config-file.js @@ -11,7 +11,7 @@ // Requirements //------------------------------------------------------------------------------ -var debug = require("debug"), +let debug = require("debug"), fs = require("fs"), path = require("path"), ConfigOps = require("./config-ops"), @@ -48,7 +48,7 @@ function sortByKey(a, b) { // Private //------------------------------------------------------------------------------ -var CONFIG_FILES = [ +let CONFIG_FILES = [ ".eslintrc.js", ".eslintrc.yaml", ".eslintrc.yml", @@ -57,7 +57,7 @@ var CONFIG_FILES = [ "package.json" ]; -var resolver = new ModuleResolver(); +let resolver = new ModuleResolver(); debug = debug("eslint:config-file"); @@ -94,7 +94,7 @@ function loadYAMLConfigFile(filePath) { debug("Loading YAML config file: " + filePath); // lazy load YAML to improve performance when not used - var yaml = require("js-yaml"); + let yaml = require("js-yaml"); try { @@ -137,7 +137,7 @@ function loadLegacyConfigFile(filePath) { debug("Loading config file: " + filePath); // lazy load YAML to improve performance when not used - var yaml = require("js-yaml"); + let yaml = require("js-yaml"); try { return yaml.safeLoad(stripComments(readFile(filePath))) || /* istanbul ignore next */ {}; @@ -192,7 +192,7 @@ function loadPackageJSONConfigFile(filePath) { * @private */ function loadConfigFile(file) { - var config, + let config, filePath = file.filePath; switch (path.extname(filePath)) { @@ -236,7 +236,7 @@ function loadConfigFile(file) { function writeJSONConfigFile(config, filePath) { debug("Writing JSON config file: " + filePath); - var content = stringify(config, {cmp: sortByKey, space: 4}); + let content = stringify(config, {cmp: sortByKey, space: 4}); fs.writeFileSync(filePath, content, "utf8"); } @@ -252,9 +252,9 @@ function writeYAMLConfigFile(config, filePath) { debug("Writing YAML config file: " + filePath); // lazy load YAML to improve performance when not used - var yaml = require("js-yaml"); + let yaml = require("js-yaml"); - var content = yaml.safeDump(config, {sortKeys: true}); + let content = yaml.safeDump(config, {sortKeys: true}); fs.writeFileSync(filePath, content, "utf8"); } @@ -269,7 +269,7 @@ function writeYAMLConfigFile(config, filePath) { function writeJSConfigFile(config, filePath) { debug("Writing JS config file: " + filePath); - var content = "module.exports = " + stringify(config, {cmp: sortByKey, space: 4}) + ";"; + let content = "module.exports = " + stringify(config, {cmp: sortByKey, space: 4}) + ";"; fs.writeFileSync(filePath, content, "utf8"); } @@ -313,7 +313,7 @@ function write(config, filePath) { function getBaseDir(configFilePath) { // calculates the path of the project including ESLint as dependency - var projectPath = path.resolve(__dirname, "../../../"); + let projectPath = path.resolve(__dirname, "../../../"); if (configFilePath && pathIsInside(configFilePath, projectPath)) { @@ -336,7 +336,7 @@ function getBaseDir(configFilePath) { * @private */ function getLookupPath(configFilePath) { - var basedir = getBaseDir(configFilePath); + let basedir = getBaseDir(configFilePath); return path.join(basedir, "node_modules"); } @@ -352,7 +352,7 @@ function getLookupPath(configFilePath) { * @private */ function applyExtends(config, filePath, relativeTo) { - var configExtends = config.extends; + let configExtends = config.extends; // normalize into an array for easier handling if (!Array.isArray(config.extends)) { @@ -431,7 +431,7 @@ function normalizePackageName(name, prefix) { * it's a scoped package * package name is "eslint-config", or just a username */ - var scopedPackageShortcutRegex = new RegExp("^(@[^\/]+)(?:\/(?:" + prefix + ")?)?$"), + let scopedPackageShortcutRegex = new RegExp("^(@[^\/]+)(?:\/(?:" + prefix + ")?)?$"), scopedPackageNameRegex = new RegExp("^" + prefix + "(-|$)"); if (scopedPackageShortcutRegex.test(name)) { @@ -463,11 +463,11 @@ function resolve(filePath, relativeTo) { if (isFilePath(filePath)) { return { filePath: path.resolve(relativeTo || "", filePath) }; } else { - var normalizedPackageName; + let normalizedPackageName; if (filePath.indexOf("plugin:") === 0) { - var packagePath = filePath.substr(7, filePath.lastIndexOf("/") - 7); - var configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1); + let packagePath = filePath.substr(7, filePath.lastIndexOf("/") - 7); + let configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1); normalizedPackageName = normalizePackageName(packagePath, "eslint-plugin"); debug("Attempting to resolve " + normalizedPackageName); @@ -493,7 +493,7 @@ function resolve(filePath, relativeTo) { * @private */ function load(filePath, applyEnvironments, relativeTo) { - var resolvedPath = resolve(filePath, relativeTo), + let resolvedPath = resolve(filePath, relativeTo), dirname = path.dirname(resolvedPath.filePath), lookupPath = getLookupPath(dirname), config = loadConfigFile(resolvedPath); @@ -565,9 +565,9 @@ module.exports = { */ getFilenameForDirectory: function(directory) { - var filename; + let filename; - for (var i = 0, len = CONFIG_FILES.length; i < len; i++) { + for (let i = 0, len = CONFIG_FILES.length; i < len; i++) { filename = path.join(directory, CONFIG_FILES[i]); if (fs.existsSync(filename)) { return filename; diff --git a/tools/eslint/lib/config/config-initializer.js b/tools/eslint/lib/config/config-initializer.js index 91d2454a8a44f3..ca52a06c657b31 100644 --- a/tools/eslint/lib/config/config-initializer.js +++ b/tools/eslint/lib/config/config-initializer.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var util = require("util"), +let util = require("util"), debug = require("debug"), lodash = require("lodash"), inquirer = require("inquirer"), @@ -38,7 +38,7 @@ debug = debug("eslint:config-initializer"); function writeFile(config, format) { // default is .js - var extname = ".js"; + let extname = ".js"; if (format === "YAML") { extname = ".yml"; @@ -60,7 +60,7 @@ function writeFile(config, format) { * @returns {void} */ function installModules(config) { - var modules = [], + let modules = [], installStatus, modulesToInstall; @@ -86,7 +86,7 @@ function installModules(config) { // Install packages which aren't already installed modulesToInstall = Object.keys(installStatus).filter(function(module) { - var notInstalled = installStatus[module] === false; + let notInstalled = installStatus[module] === false; if (module === "eslint" && notInstalled) { log.info("Local ESLint installation not found."); @@ -113,10 +113,10 @@ function installModules(config) { * @returns {Object} config object with configured rules */ function configureRules(answers, config) { - var BAR_TOTAL = 20, + let BAR_TOTAL = 20, BAR_SOURCE_CODE_TOTAL = 4; - var newConfig = lodash.assign({}, config), + let newConfig = lodash.assign({}, config), bar, patterns, sourceCodes, @@ -163,7 +163,7 @@ function configureRules(answers, config) { debug("\nRegistry: " + util.inspect(registry.rules, {depth: null})); // Create a list of recommended rules, because we don't want to disable them - var recRules = Object.keys(recConfig.rules).filter(function(ruleId) { + let recRules = Object.keys(recConfig.rules).filter(function(ruleId) { return ConfigOps.isErrorSeverity(recConfig.rules[ruleId]); }); @@ -202,12 +202,12 @@ function configureRules(answers, config) { bar.update(BAR_TOTAL); // Log out some stats to let the user know what happened - var finalRuleIds = Object.keys(newConfig.rules), + let finalRuleIds = Object.keys(newConfig.rules), totalRules = finalRuleIds.length; - var enabledRules = finalRuleIds.filter(function(ruleId) { + let enabledRules = finalRuleIds.filter(function(ruleId) { return (newConfig.rules[ruleId] !== 0); }).length; - var resultMessage = [ + let resultMessage = [ "\nEnabled " + enabledRules + " out of " + totalRules, "rules based on " + fileQty, "file" + ((fileQty === 1) ? "." : "s.") @@ -225,7 +225,7 @@ function configureRules(answers, config) { * @returns {Object} config object */ function processAnswers(answers) { - var config = {rules: {}, env: {}}; + let config = {rules: {}, env: {}}; if (answers.es6) { config.env.es6 = true; @@ -275,10 +275,10 @@ function processAnswers(answers) { * @returns {Object} config object */ function getConfigForStyleGuide(guide) { - var guides = { + let guides = { google: {extends: "google"}, airbnb: {extends: "airbnb", plugins: ["react"]}, - standard: {extends: "standard", plugins: ["standard"]} + standard: {extends: "standard", plugins: ["standard", "promise"]} }; if (!guides[guide]) { @@ -293,11 +293,11 @@ function getConfigForStyleGuide(guide) { /* istanbul ignore next: no need to test inquirer*/ /** * Ask use a few questions on command prompt - * @param {function} callback callback function when file has been written + * @param {Function} callback callback function when file has been written * @returns {void} */ function promptUser(callback) { - var config; + let config; inquirer.prompt([ { @@ -419,7 +419,7 @@ function promptUser(callback) { // early exit if you are using automatic style generation if (earlyAnswers.source === "auto") { try { - var combinedAnswers = lodash.assign({}, earlyAnswers, secondAnswers); + let combinedAnswers = lodash.assign({}, earlyAnswers, secondAnswers); config = processAnswers(combinedAnswers); installModules(config); @@ -469,7 +469,7 @@ function promptUser(callback) { } ], function(answers) { try { - var totalAnswers = lodash.assign({}, earlyAnswers, secondAnswers, answers); + let totalAnswers = lodash.assign({}, earlyAnswers, secondAnswers, answers); config = processAnswers(totalAnswers); installModules(config); @@ -488,7 +488,7 @@ function promptUser(callback) { // Public Interface //------------------------------------------------------------------------------ -var init = { +let init = { getConfigForStyleGuide: getConfigForStyleGuide, processAnswers: processAnswers, initializeConfig: /* istanbul ignore next */ function(callback) { diff --git a/tools/eslint/lib/config/config-ops.js b/tools/eslint/lib/config/config-ops.js index d62169502b7497..2e0c29a752d3f6 100644 --- a/tools/eslint/lib/config/config-ops.js +++ b/tools/eslint/lib/config/config-ops.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"), +let lodash = require("lodash"), debug = require("debug"), Environments = require("./environments"); @@ -19,7 +19,7 @@ var lodash = require("lodash"), debug = debug("eslint:config-ops"); -var RULE_SEVERITY_STRINGS = ["off", "warn", "error"], +let RULE_SEVERITY_STRINGS = ["off", "warn", "error"], RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce(function(map, value, index) { map[value] = index; return map; @@ -53,7 +53,7 @@ module.exports = { */ createEnvironmentConfig: function(env) { - var envConfig = this.createEmptyConfig(); + let envConfig = this.createEmptyConfig(); if (env) { @@ -62,7 +62,7 @@ module.exports = { Object.keys(env).filter(function(name) { return env[name]; }).forEach(function(name) { - var environment = Environments.get(name); + let environment = Environments.get(name); if (environment) { debug("Creating config for environment " + name); @@ -134,8 +134,8 @@ module.exports = { * (https://github.com/KyleAMathews/deepmerge) * and modified to meet our needs. */ - var array = Array.isArray(src) || Array.isArray(target); - var dst = array && [] || {}; + let array = Array.isArray(src) || Array.isArray(target); + let dst = array && [] || {}; combine = !!combine; isRule = !!isRule; @@ -202,7 +202,7 @@ module.exports = { if (config.rules) { Object.keys(config.rules).forEach(function(ruleId) { - var ruleConfig = config.rules[ruleId]; + let ruleConfig = config.rules[ruleId]; if (typeof ruleConfig === "string") { config.rules[ruleId] = RULE_SEVERITY[ruleConfig.toLowerCase()] || 0; @@ -224,7 +224,7 @@ module.exports = { if (config.rules) { Object.keys(config.rules).forEach(function(ruleId) { - var ruleConfig = config.rules[ruleId]; + let ruleConfig = config.rules[ruleId]; if (typeof ruleConfig === "number") { config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0]; @@ -242,7 +242,7 @@ module.exports = { */ isErrorSeverity: function(ruleConfig) { - var severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; + let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; if (typeof severity === "string") { severity = RULE_SEVERITY[severity.toLowerCase()] || 0; @@ -257,7 +257,7 @@ module.exports = { * @returns {boolean} `true` if the configuration has valid severity. */ isValidSeverity: function(ruleConfig) { - var severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; + let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; if (typeof severity === "string") { severity = severity.toLowerCase(); @@ -267,7 +267,7 @@ module.exports = { /** * Checks whether every rule of a given config has valid severity or not. - * @param {object} config - The configuration for rules. + * @param {Object} config - The configuration for rules. * @returns {boolean} `true` if the configuration has valid severity. */ isEverySeverityValid: function(config) { diff --git a/tools/eslint/lib/config/config-rule.js b/tools/eslint/lib/config/config-rule.js index c0a394efee10fd..f4c2803ff7e24d 100644 --- a/tools/eslint/lib/config/config-rule.js +++ b/tools/eslint/lib/config/config-rule.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var rules = require("../rules"), +let rules = require("../rules"), loadRules = require("../load-rules"); @@ -41,7 +41,7 @@ function explodeArray(xs) { * @returns {array} A mixture of the elements of the first and second arrays. */ function combineArrays(arr1, arr2) { - var res = []; + let res = []; if (arr1.length === 0) { return explodeArray(arr2); @@ -78,8 +78,8 @@ function combineArrays(arr1, arr2) { * @returns {Array[]} Array of arrays of objects grouped by property */ function groupByProperty(objects) { - var groupedObj = objects.reduce(function(accumulator, obj) { - var prop = Object.keys(obj)[0]; + let groupedObj = objects.reduce(function(accumulator, obj) { + let prop = Object.keys(obj)[0]; accumulator[prop] = accumulator[prop] ? accumulator[prop].concat(obj) : [obj]; return accumulator; @@ -144,7 +144,7 @@ function groupByProperty(objects) { * @returns {Object[]} Combined objects for each combination of input properties and values */ function combinePropertyObjects(objArr1, objArr2) { - var res = []; + let res = []; if (objArr1.length === 0) { return objArr2; @@ -154,9 +154,9 @@ function combinePropertyObjects(objArr1, objArr2) { } objArr1.forEach(function(obj1) { objArr2.forEach(function(obj2) { - var combinedObj = {}; - var obj1Props = Object.keys(obj1); - var obj2Props = Object.keys(obj2); + let combinedObj = {}; + let obj1Props = Object.keys(obj1); + let obj2Props = Object.keys(obj2); obj1Props.forEach(function(prop1) { combinedObj[prop1] = obj1[prop1]; @@ -229,12 +229,12 @@ RuleConfigSet.prototype = { * @returns {void} */ addObject: function(obj) { - var objectConfigSet = { + let objectConfigSet = { objectConfigs: [], add: function(property, values) { - var optionObj; + let optionObj; - for (var idx = 0; idx < values.length; idx++) { + for (let idx = 0; idx < values.length; idx++) { optionObj = {}; optionObj[property] = values[idx]; this.objectConfigs.push(optionObj); @@ -274,7 +274,7 @@ RuleConfigSet.prototype = { * @returns {array[]} Valid rule configurations */ function generateConfigsFromSchema(schema) { - var configSet = new RuleConfigSet(); + let configSet = new RuleConfigSet(); if (Array.isArray(schema)) { schema.forEach(function(opt) { @@ -301,11 +301,11 @@ function generateConfigsFromSchema(schema) { * @returns {rulesConfig} Hash of rule names and arrays of possible configurations */ function createCoreRuleConfigs() { - var ruleList = loadRules(); + let ruleList = loadRules(); return Object.keys(ruleList).reduce(function(accumulator, id) { - var rule = rules.get(id); - var schema = (typeof rule === "function") ? rule.schema : rule.meta.schema; + let rule = rules.get(id); + let schema = (typeof rule === "function") ? rule.schema : rule.meta.schema; accumulator[id] = generateConfigsFromSchema(schema); return accumulator; diff --git a/tools/eslint/lib/config/config-validator.js b/tools/eslint/lib/config/config-validator.js index ebc70516c195d5..6695260a23a8fa 100644 --- a/tools/eslint/lib/config/config-validator.js +++ b/tools/eslint/lib/config/config-validator.js @@ -9,12 +9,12 @@ // Requirements //------------------------------------------------------------------------------ -var rules = require("../rules"), +let rules = require("../rules"), Environments = require("./environments"), schemaValidator = require("is-my-json-valid"), util = require("util"); -var validators = { +let validators = { rules: Object.create(null) }; @@ -25,10 +25,10 @@ var validators = { /** * Gets a complete options schema for a rule. * @param {string} id The rule's unique name. - * @returns {object} JSON Schema for the rule's options. + * @returns {Object} JSON Schema for the rule's options. */ function getRuleOptionsSchema(id) { - var rule = rules.get(id), + let rule = rules.get(id), schema = rule && rule.schema || rule && rule.meta && rule.meta.schema; // Given a tuple of schemas, insert warning level at the beginning @@ -61,7 +61,7 @@ function getRuleOptionsSchema(id) { * @returns {void} */ function validateRuleOptions(id, options, source) { - var validateRule = validators.rules[id], + let validateRule = validators.rules[id], message, severity, localOptions, @@ -119,7 +119,7 @@ function validateRuleOptions(id, options, source) { /** * Validates an environment object - * @param {object} environment The environment config object to validate. + * @param {Object} environment The environment config object to validate. * @param {string} source The location to report with any errors. * @returns {void} */ @@ -137,7 +137,7 @@ function validateEnvironment(environment, source) { if (typeof environment === "object") { Object.keys(environment).forEach(function(env) { if (!Environments.get(env)) { - var message = [ + let message = [ source, ":\n", "\tEnvironment key \"", env, "\" is unknown\n" ]; @@ -152,7 +152,7 @@ function validateEnvironment(environment, source) { /** * Validates an entire config object. - * @param {object} config The config object to validate. + * @param {Object} config The config object to validate. * @param {string} source The location to report with any errors. * @returns {void} */ diff --git a/tools/eslint/lib/config/environments.js b/tools/eslint/lib/config/environments.js index 8daef864e3179c..9a5defbfc27e05 100644 --- a/tools/eslint/lib/config/environments.js +++ b/tools/eslint/lib/config/environments.js @@ -8,13 +8,13 @@ // Requirements //------------------------------------------------------------------------------ -var envs = require("../../conf/environments"); +let envs = require("../../conf/environments"); //------------------------------------------------------------------------------ // Private //------------------------------------------------------------------------------ -var environments = Object.create(null); +let environments = new Map(); /** * Loads the default environments. @@ -23,7 +23,7 @@ var environments = Object.create(null); */ function load() { Object.keys(envs).forEach(function(envName) { - environments[envName] = envs[envName]; + environments.set(envName, envs[envName]); }); } @@ -36,15 +36,15 @@ load(); module.exports = { - load: load, + load, /** * Gets the environment with the given name. * @param {string} name The name of the environment to retrieve. * @returns {Object?} The environment object or null if not found. */ - get: function(name) { - return environments[name] || null; + get(name) { + return environments.get(name) || null; }, /** @@ -53,8 +53,8 @@ module.exports = { * @param {Object} env The environment settings. * @returns {void} */ - define: function(name, env) { - environments[name] = env; + define(name, env) { + environments.set(name, env); }, /** @@ -63,7 +63,7 @@ module.exports = { * @param {string} pluginName The name of the plugin. * @returns {void} */ - importPlugin: function(plugin, pluginName) { + importPlugin(plugin, pluginName) { if (plugin.environments) { Object.keys(plugin.environments).forEach(function(envName) { this.define(pluginName + "/" + envName, plugin.environments[envName]); @@ -75,8 +75,8 @@ module.exports = { * Resets all environments. Only use for tests! * @returns {void} */ - testReset: function() { - environments = Object.create(null); + testReset() { + environments = new Map(); load(); } }; diff --git a/tools/eslint/lib/config/plugins.js b/tools/eslint/lib/config/plugins.js index e157eb123c9df5..7065045c1216c8 100644 --- a/tools/eslint/lib/config/plugins.js +++ b/tools/eslint/lib/config/plugins.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var debug = require("debug"), +let debug = require("debug"), Environments = require("./environments"), rules = require("../rules"); @@ -18,9 +18,9 @@ var debug = require("debug"), debug = debug("eslint:plugins"); -var plugins = Object.create(null); +let plugins = Object.create(null); -var PLUGIN_NAME_PREFIX = "eslint-plugin-", +let PLUGIN_NAME_PREFIX = "eslint-plugin-", NAMESPACE_REGEX = /^@.*\//i; /** @@ -67,7 +67,7 @@ module.exports = { * @returns {void} */ define: function(pluginName, plugin) { - var pluginNameWithoutNamespace = removeNamespace(pluginName), + let pluginNameWithoutNamespace = removeNamespace(pluginName), pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace); plugins[pluginNameWithoutPrefix] = plugin; @@ -104,7 +104,7 @@ module.exports = { * @throws {Error} If the plugin cannot be loaded. */ load: function(pluginName) { - var pluginNamespace = getNamespace(pluginName), + let pluginNamespace = getNamespace(pluginName), pluginNameWithoutNamespace = removeNamespace(pluginName), pluginNameWithoutPrefix = removePrefix(pluginNameWithoutNamespace), plugin = null; diff --git a/tools/eslint/lib/eslint.js b/tools/eslint/lib/eslint.js index 69ad96e820bf5d..01b43eb4ee192e 100644 --- a/tools/eslint/lib/eslint.js +++ b/tools/eslint/lib/eslint.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var assert = require("assert"), +let assert = require("assert"), EventEmitter = require("events").EventEmitter, escope = require("escope"), levn = require("levn"), @@ -41,19 +41,16 @@ var assert = require("assert"), * @returns {Object} Result map object of names and boolean values */ function parseBooleanConfig(string, comment) { - var items = {}; + let items = {}; - // Collapse whitespace around : to make parsing easier - string = string.replace(/\s*:\s*/g, ":"); - - // Collapse whitespace around , - string = string.replace(/\s*,\s*/g, ","); + // Collapse whitespace around `:` and `,` to make parsing easier + string = string.replace(/\s*([:,])\s*/g, "$1"); string.split(/\s|,+/).forEach(function(name) { if (!name) { return; } - var pos = name.indexOf(":"), + let pos = name.indexOf(":"), value; if (pos !== -1) { @@ -78,7 +75,7 @@ function parseBooleanConfig(string, comment) { * @returns {Object} Result map object */ function parseJsonConfig(string, location, messages) { - var items = {}; + let items = {}; // Parses a JSON-like comment by the same way as parsing CLI option. try { @@ -125,7 +122,7 @@ function parseJsonConfig(string, location, messages) { * @returns {Object} Result map of values and true values */ function parseListConfig(string) { - var items = {}; + let items = {}; // Collapse whitespace around , string = string.replace(/\s*,\s*/g, ","); @@ -150,7 +147,7 @@ function parseListConfig(string) { * @returns {void} */ function addDeclaredGlobals(program, globalScope, config) { - var declaredGlobals = {}, + let declaredGlobals = {}, exportedGlobals = {}, explicitGlobals = {}, builtin = Environments.get("builtin"); @@ -159,7 +156,7 @@ function addDeclaredGlobals(program, globalScope, config) { Object.keys(config.env).forEach(function(name) { if (config.env[name]) { - var env = Environments.get(name), + let env = Environments.get(name), environmentGlobals = env && env.globals; if (environmentGlobals) { @@ -173,7 +170,7 @@ function addDeclaredGlobals(program, globalScope, config) { lodash.assign(explicitGlobals, config.astGlobals); Object.keys(declaredGlobals).forEach(function(name) { - var variable = globalScope.set.get(name); + let variable = globalScope.set.get(name); if (!variable) { variable = new escope.Variable(name, globalScope); @@ -185,7 +182,7 @@ function addDeclaredGlobals(program, globalScope, config) { }); Object.keys(explicitGlobals).forEach(function(name) { - var variable = globalScope.set.get(name); + let variable = globalScope.set.get(name); if (!variable) { variable = new escope.Variable(name, globalScope); @@ -199,7 +196,7 @@ function addDeclaredGlobals(program, globalScope, config) { // mark all exported variables as such Object.keys(exportedGlobals).forEach(function(name) { - var variable = globalScope.set.get(name); + let variable = globalScope.set.get(name); if (variable) { variable.eslintUsed = true; @@ -212,8 +209,8 @@ function addDeclaredGlobals(program, globalScope, config) { * references and remove the ones that were added by configuration. */ globalScope.through = globalScope.through.filter(function(reference) { - var name = reference.identifier.name; - var variable = globalScope.set.get(name); + let name = reference.identifier.name; + let variable = globalScope.set.get(name); if (variable) { @@ -267,7 +264,7 @@ function disableReporting(reportingConfig, start, rulesToDisable) { * @returns {void} */ function enableReporting(reportingConfig, start, rulesToEnable) { - var i; + let i; if (rulesToEnable.length) { rulesToEnable.forEach(function(rule) { @@ -281,7 +278,7 @@ function enableReporting(reportingConfig, start, rulesToEnable) { } else { // find all previous disabled locations if they was started as list of rules - var prevStart; + let prevStart; for (i = reportingConfig.length - 1; i >= 0; i--) { if (prevStart && prevStart !== reportingConfig[i].start) { @@ -305,22 +302,22 @@ function enableReporting(reportingConfig, start, rulesToEnable) { * @param {Object} config The existing configuration data. * @param {Object[]} reportingConfig The existing reporting configuration data. * @param {Object[]} messages The messages queue. - * @returns {object} Modified config object + * @returns {Object} Modified config object */ function modifyConfigsFromComments(filename, ast, config, reportingConfig, messages) { - var commentConfig = { + let commentConfig = { exported: {}, astGlobals: {}, rules: {}, env: {} }; - var commentRules = {}; + let commentRules = {}; ast.comments.forEach(function(comment) { - var value = comment.value.trim(); - var match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/.exec(value); + let value = comment.value.trim(); + let match = /^(eslint(-\w+){0,3}|exported|globals?)(\s|$)/.exec(value); if (match) { value = value.substring(match.index + match[1].length); @@ -348,16 +345,17 @@ function modifyConfigsFromComments(filename, ast, config, reportingConfig, messa enableReporting(reportingConfig, comment.loc.start, Object.keys(parseListConfig(value))); break; - case "eslint": - var items = parseJsonConfig(value, comment.loc, messages); + case "eslint": { + const items = parseJsonConfig(value, comment.loc, messages); Object.keys(items).forEach(function(name) { - var ruleValue = items[name]; + let ruleValue = items[name]; validator.validateRuleOptions(name, ruleValue, filename + " line " + comment.loc.start.line); commentRules[name] = ruleValue; }); break; + } // no default } @@ -375,7 +373,7 @@ function modifyConfigsFromComments(filename, ast, config, reportingConfig, messa // apply environment configs Object.keys(commentConfig.env).forEach(function(name) { - var env = Environments.get(name); + let env = Environments.get(name); if (env) { commentConfig = ConfigOps.merge(commentConfig, env); @@ -395,9 +393,9 @@ function modifyConfigsFromComments(filename, ast, config, reportingConfig, messa */ function isDisabledByReportingConfig(reportingConfig, ruleId, location) { - for (var i = 0, c = reportingConfig.length; i < c; i++) { + for (let i = 0, c = reportingConfig.length; i < c; i++) { - var ignore = reportingConfig[i]; + let ignore = reportingConfig[i]; if ((!ignore.rule || ignore.rule === ruleId) && (location.line > ignore.start.line || (location.line === ignore.start.line && location.column >= ignore.start.column)) && @@ -419,13 +417,13 @@ function prepareConfig(config) { config.globals = config.globals || config.global || {}; delete config.global; - var copiedRules = {}, + let copiedRules = {}, parserOptions = {}, preparedConfig; if (typeof config.rules === "object") { Object.keys(config.rules).forEach(function(k) { - var rule = config.rules[k]; + let rule = config.rules[k]; if (rule === null) { throw new Error("Invalid config for rule '" + k + "'\."); @@ -441,7 +439,7 @@ function prepareConfig(config) { // merge in environment parserOptions if (typeof config.env === "object") { Object.keys(config.env).forEach(function(envName) { - var env = Environments.get(envName); + let env = Environments.get(envName); if (config.env[envName] && env && env.parserOptions) { parserOptions = ConfigOps.merge(parserOptions, env.parserOptions); @@ -484,8 +482,8 @@ function createStubRule(message) { /** * Creates a fake rule object - * @param {object} context context object for each rule - * @returns {object} collection of node to listen on + * @param {Object} context context object for each rule + * @returns {Object} collection of node to listen on */ function createRuleModule(context) { return { @@ -509,7 +507,7 @@ function createStubRule(message) { */ function getRuleReplacementMessage(ruleId) { if (ruleId in replacements.rules) { - var newRules = replacements.rules[ruleId]; + let newRules = replacements.rules[ruleId]; return "Rule \'" + ruleId + "\' was removed and replaced by: " + newRules.join(", "); } @@ -517,15 +515,15 @@ function getRuleReplacementMessage(ruleId) { return null; } -var eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//g; +let eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//g; /** * Checks whether or not there is a comment which has "eslint-env *" in a given text. * @param {string} text - A source code text to check. - * @returns {object|null} A result of parseListConfig() with "eslint-env *" comment. + * @returns {Object|null} A result of parseListConfig() with "eslint-env *" comment. */ function findEslintEnv(text) { - var match, retv; + let match, retv; eslintEnvPattern.lastIndex = 0; @@ -565,7 +563,7 @@ function stripUnicodeBOM(text) { */ module.exports = (function() { - var api = Object.create(new EventEmitter()), + let api = Object.create(new EventEmitter()), messages = [], currentConfig = null, currentScopes = null, @@ -587,7 +585,7 @@ module.exports = (function() { */ function parse(text, config) { - var parser, + let parser, parserOptions = { loc: true, range: true, @@ -629,8 +627,8 @@ module.exports = (function() { } catch (ex) { // If the message includes a leading line number, strip it: - var message = ex.message.replace(/^line \d+:/i, "").trim(); - var source = (ex.lineNumber) ? SourceCode.splitLines(text)[ex.lineNumber - 1] : null; + let message = ex.message.replace(/^line \d+:/i, "").trim(); + let source = (ex.lineNumber) ? SourceCode.splitLines(text)[ex.lineNumber - 1] : null; messages.push({ ruleId: null, @@ -721,7 +719,7 @@ module.exports = (function() { */ api.verify = function(textOrSourceCode, config, filenameOrOptions, saveState) { - var ast, + let ast, shebang, ecmaFeatures, ecmaVersion, @@ -742,7 +740,7 @@ module.exports = (function() { } // search and apply "eslint-env *". - var envInFile = findEslintEnv(text || textOrSourceCode.text); + let envInFile = findEslintEnv(text || textOrSourceCode.text); if (envInFile) { if (!config || !config.env) { @@ -797,7 +795,7 @@ module.exports = (function() { Object.keys(config.rules).filter(function(key) { return getRuleSeverity(config.rules[key]) > 0; }).forEach(function(key) { - var ruleCreator, + let ruleCreator, severity, options, rule; @@ -805,7 +803,7 @@ module.exports = (function() { ruleCreator = rules.get(key); if (!ruleCreator) { - var replacementMsg = getRuleReplacementMessage(key); + let replacementMsg = getRuleReplacementMessage(key); if (replacementMsg) { ruleCreator = createStubRule(replacementMsg); @@ -819,7 +817,7 @@ module.exports = (function() { options = getRuleOptions(config.rules[key]); try { - var ruleContext = new RuleContext( + let ruleContext = new RuleContext( key, api, severity, options, config.settings, config.parserOptions, config.parser, ruleCreator.meta); @@ -865,7 +863,7 @@ module.exports = (function() { scopeMap = []; currentScopes.forEach(function(scope, index) { - var range = scope.block.range[0]; + let range = scope.block.range[0]; /* * Sometimes two scopes are returned for a given node. This is @@ -888,7 +886,7 @@ module.exports = (function() { } } - var eventGenerator = new NodeEventGenerator(api); + let eventGenerator = new NodeEventGenerator(api); eventGenerator = new CodePathAnalyzer(eventGenerator); eventGenerator = new CommentEventGenerator(eventGenerator, sourceCode); @@ -912,7 +910,7 @@ module.exports = (function() { // sort by line and column messages.sort(function(a, b) { - var lineDiff = a.line - b.line; + let lineDiff = a.line - b.line; if (lineDiff === 0) { return a.column - b.column; @@ -954,7 +952,10 @@ module.exports = (function() { location = node.loc.start; } - // else, assume location was provided, so node may be omitted + // Store end location. + let endLocation = location.end; + + location = location.start || location; if (isDisabledByReportingConfig(reportingConfig, ruleId, location)) { return; @@ -971,7 +972,7 @@ module.exports = (function() { }); } - var problem = { + let problem = { ruleId: ruleId, severity: severity, message: message, @@ -981,6 +982,12 @@ module.exports = (function() { source: sourceCode.lines[location.line - 1] || "" }; + // Define endLine and endColumn if exists. + if (endLocation) { + problem.endLine = endLocation.line; + problem.endColumn = endLocation.column + 1; // switch to 1-base instead of 0-base + } + // ensure there's range and text properties, otherwise it's not a valid fix if (fix && Array.isArray(fix.range) && (typeof fix.text === "string")) { @@ -1004,7 +1011,7 @@ module.exports = (function() { }; // methods that exist on SourceCode object - var externalMethods = { + let externalMethods = { getSource: "getText", getSourceLines: "getLines", getAllComments: "getAllComments", @@ -1026,7 +1033,7 @@ module.exports = (function() { // copy over methods Object.keys(externalMethods).forEach(function(methodName) { - var exMethodName = externalMethods[methodName]; + let exMethodName = externalMethods[methodName]; // All functions expected to have less arguments than 5. api[methodName] = function(a, b, c, d, e) { @@ -1050,14 +1057,14 @@ module.exports = (function() { * @returns {Object} An object representing the current node's scope. */ api.getScope = function() { - var parents = traverser.parents(), + let parents = traverser.parents(), scope = currentScopes[0]; // Don't do this for Program nodes - they have no parents if (parents.length) { // if current node introduces a scope, add it to the list - var current = traverser.current(); + let current = traverser.current(); if (currentConfig.parserOptions.ecmaVersion >= 6) { if (["BlockStatement", "SwitchStatement", "CatchClause", "FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"].indexOf(current.type) >= 0) { @@ -1070,7 +1077,7 @@ module.exports = (function() { } // Ascend the current node's parents - for (var i = parents.length - 1; i >= 0; --i) { + for (let i = parents.length - 1; i >= 0; --i) { // Get the innermost scope scope = scopeManager.acquire(parents[i], true); @@ -1096,7 +1103,7 @@ module.exports = (function() { * false if not. */ api.markVariableAsUsed = function(name) { - var scope = this.getScope(), + let scope = this.getScope(), hasGlobalReturn = currentConfig.parserOptions.ecmaFeatures && currentConfig.parserOptions.ecmaFeatures.globalReturn, specialScope = hasGlobalReturn || currentConfig.parserOptions.sourceType === "module", variables, @@ -1140,13 +1147,13 @@ module.exports = (function() { * @param {Function} ruleModule Function from context to object mapping AST node types to event handlers * @returns {void} */ - var defineRule = api.defineRule = function(ruleId, ruleModule) { + let defineRule = api.defineRule = function(ruleId, ruleModule) { rules.define(ruleId, ruleModule); }; /** * Defines many new linting rules. - * @param {object} rulesToDefine map from unique rule identifier to rule + * @param {Object} rulesToDefine map from unique rule identifier to rule * @returns {void} */ api.defineRules = function(rulesToDefine) { diff --git a/tools/eslint/lib/file-finder.js b/tools/eslint/lib/file-finder.js index 45594057000b21..f003504c25e08e 100644 --- a/tools/eslint/lib/file-finder.js +++ b/tools/eslint/lib/file-finder.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var fs = require("fs"), +let fs = require("fs"), path = require("path"); //------------------------------------------------------------------------------ @@ -55,11 +55,11 @@ function FileFinder(files, cwd) { * @returns {Object} Hashmap of filenames */ function normalizeDirectoryEntries(entries, directory, supportedConfigs) { - var fileHash = {}; + let fileHash = {}; entries.forEach(function(entry) { if (supportedConfigs.indexOf(entry) >= 0) { - var resolvedEntry = path.resolve(directory, entry); + let resolvedEntry = path.resolve(directory, entry); if (fs.statSync(resolvedEntry).isFile()) { fileHash[entry] = resolvedEntry; @@ -79,7 +79,7 @@ function normalizeDirectoryEntries(entries, directory, supportedConfigs) { * @returns {string[]} The file paths found. */ FileFinder.prototype.findAllInDirectoryAndParents = function(directory) { - var cache = this.cache, + let cache = this.cache, child, dirs, fileNames, @@ -106,10 +106,10 @@ FileFinder.prototype.findAllInDirectoryAndParents = function(directory) { dirs[searched++] = directory; cache[directory] = []; - var filesMap = normalizeDirectoryEntries(getDirectoryEntries(directory), directory, fileNames); + let filesMap = normalizeDirectoryEntries(getDirectoryEntries(directory), directory, fileNames); if (Object.keys(filesMap).length) { - for (var k = 0; k < fileNames.length; k++) { + for (let k = 0; k < fileNames.length; k++) { if (filesMap[fileNames[k]]) { filePath = filesMap[fileNames[k]]; diff --git a/tools/eslint/lib/formatters/checkstyle.js b/tools/eslint/lib/formatters/checkstyle.js index 0bb9627adf2bd5..11ee60490a0ba6 100644 --- a/tools/eslint/lib/formatters/checkstyle.js +++ b/tools/eslint/lib/formatters/checkstyle.js @@ -4,13 +4,15 @@ */ "use strict"; +let xmlEscape = require("../util/xml-escape"); + //------------------------------------------------------------------------------ // Helper Functions //------------------------------------------------------------------------------ /** * Returns the severity of warning or error - * @param {object} message message object to examine + * @param {Object} message message object to examine * @returns {string} severity level * @private */ @@ -22,44 +24,19 @@ function getMessageType(message) { } } -/** - * Returns the escaped value for a character - * @param {string} s string to examine - * @returns {string} severity level - * @private - */ -function xmlEscape(s) { - return ("" + s).replace(/[<>&"']/g, function(c) { - switch (c) { - case "<": - return "<"; - case ">": - return ">"; - case "&": - return "&"; - case "\"": - return """; - case "'": - return "'"; - default: - throw new Error("unreachable"); - } - }); -} - //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ module.exports = function(results) { - var output = ""; + let output = ""; output += ""; output += ""; results.forEach(function(result) { - var messages = result.messages; + let messages = result.messages; output += ""; diff --git a/tools/eslint/lib/formatters/compact.js b/tools/eslint/lib/formatters/compact.js index 0c31b073e3fefd..72233f6f363026 100644 --- a/tools/eslint/lib/formatters/compact.js +++ b/tools/eslint/lib/formatters/compact.js @@ -10,7 +10,7 @@ /** * Returns the severity of warning or error - * @param {object} message message object to examine + * @param {Object} message message object to examine * @returns {string} severity level * @private */ @@ -29,12 +29,12 @@ function getMessageType(message) { module.exports = function(results) { - var output = "", + let output = "", total = 0; results.forEach(function(result) { - var messages = result.messages; + let messages = result.messages; total += messages.length; diff --git a/tools/eslint/lib/formatters/html.js b/tools/eslint/lib/formatters/html.js index da3f7596fd04b6..87d2910b48a7f5 100644 --- a/tools/eslint/lib/formatters/html.js +++ b/tools/eslint/lib/formatters/html.js @@ -4,17 +4,17 @@ */ "use strict"; -var lodash = require("lodash"); -var fs = require("fs"); -var path = require("path"); +let lodash = require("lodash"); +let fs = require("fs"); +let path = require("path"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var pageTemplate = lodash.template(fs.readFileSync(path.join(__dirname, "html-template-page.html"), "utf-8")); -var messageTemplate = lodash.template(fs.readFileSync(path.join(__dirname, "html-template-message.html"), "utf-8")); -var resultTemplate = lodash.template(fs.readFileSync(path.join(__dirname, "html-template-result.html"), "utf-8")); +let pageTemplate = lodash.template(fs.readFileSync(path.join(__dirname, "html-template-page.html"), "utf-8")); +let messageTemplate = lodash.template(fs.readFileSync(path.join(__dirname, "html-template-message.html"), "utf-8")); +let resultTemplate = lodash.template(fs.readFileSync(path.join(__dirname, "html-template-result.html"), "utf-8")); /** * Given a word and a count, append an s if count is not one. @@ -33,8 +33,8 @@ function pluralize(word, count) { * @returns {string} The formatted string, pluralized where necessary */ function renderSummary(totalErrors, totalWarnings) { - var totalProblems = totalErrors + totalWarnings; - var renderedText = totalProblems + " " + pluralize("problem", totalProblems); + let totalProblems = totalErrors + totalWarnings; + let renderedText = totalProblems + " " + pluralize("problem", totalProblems); if (totalProblems !== 0) { renderedText += " (" + totalErrors + " " + pluralize("error", totalErrors) + ", " + totalWarnings + " " + pluralize("warning", totalWarnings) + ")"; @@ -71,7 +71,7 @@ function renderMessages(messages, parentIndex) { * @returns {string} HTML (table row) describing a message. */ return lodash.map(messages, function(message) { - var lineNumber, + let lineNumber, columnNumber; lineNumber = message.line || 0; @@ -110,7 +110,7 @@ function renderResults(results) { //------------------------------------------------------------------------------ module.exports = function(results) { - var totalErrors, + let totalErrors, totalWarnings; totalErrors = 0; diff --git a/tools/eslint/lib/formatters/jslint-xml.js b/tools/eslint/lib/formatters/jslint-xml.js index 483172ca5d8f23..11fe812d063156 100644 --- a/tools/eslint/lib/formatters/jslint-xml.js +++ b/tools/eslint/lib/formatters/jslint-xml.js @@ -4,7 +4,7 @@ */ "use strict"; -var lodash = require("lodash"); +let xmlEscape = require("../util/xml-escape"); //------------------------------------------------------------------------------ // Public Interface @@ -12,21 +12,21 @@ var lodash = require("lodash"); module.exports = function(results) { - var output = ""; + let output = ""; output += ""; output += ""; results.forEach(function(result) { - var messages = result.messages; + let messages = result.messages; output += ""; messages.forEach(function(message) { output += ""; }); diff --git a/tools/eslint/lib/formatters/junit.js b/tools/eslint/lib/formatters/junit.js index c53fd8141baf5a..6b7bed30a15600 100644 --- a/tools/eslint/lib/formatters/junit.js +++ b/tools/eslint/lib/formatters/junit.js @@ -4,7 +4,7 @@ */ "use strict"; -var lodash = require("lodash"); +let xmlEscape = require("../util/xml-escape"); //------------------------------------------------------------------------------ // Helper Functions @@ -12,7 +12,7 @@ var lodash = require("lodash"); /** * Returns the severity of warning or error - * @param {object} message message object to examine + * @param {Object} message message object to examine * @returns {string} severity level * @private */ @@ -30,28 +30,28 @@ function getMessageType(message) { module.exports = function(results) { - var output = ""; + let output = ""; output += "\n"; output += "\n"; results.forEach(function(result) { - var messages = result.messages; + let messages = result.messages; if (messages.length) { output += "\n"; } messages.forEach(function(message) { - var type = message.fatal ? "error" : "failure"; + let type = message.fatal ? "error" : "failure"; output += ""; - output += "<" + type + " message=\"" + lodash.escape(message.message || "") + "\">"; + output += "<" + type + " message=\"" + xmlEscape(message.message || "") + "\">"; output += ""; output += ""; diff --git a/tools/eslint/lib/formatters/stylish.js b/tools/eslint/lib/formatters/stylish.js index d8645755bf9dc4..ebcea1ccdbd3f8 100644 --- a/tools/eslint/lib/formatters/stylish.js +++ b/tools/eslint/lib/formatters/stylish.js @@ -4,7 +4,7 @@ */ "use strict"; -var chalk = require("chalk"), +let chalk = require("chalk"), table = require("text-table"); //------------------------------------------------------------------------------ @@ -27,14 +27,14 @@ function pluralize(word, count) { module.exports = function(results) { - var output = "\n", + let output = "\n", total = 0, errors = 0, warnings = 0, summaryColor = "yellow"; results.forEach(function(result) { - var messages = result.messages; + let messages = result.messages; if (messages.length === 0) { return; @@ -45,7 +45,7 @@ module.exports = function(results) { output += table( messages.map(function(message) { - var messageType; + let messageType; if (message.fatal || message.severity === 2) { messageType = chalk.red("error"); diff --git a/tools/eslint/lib/formatters/table.js b/tools/eslint/lib/formatters/table.js index e2876444556b24..d760c18ec5ff81 100644 --- a/tools/eslint/lib/formatters/table.js +++ b/tools/eslint/lib/formatters/table.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var chalk, +let chalk, table, pluralize; @@ -26,7 +26,7 @@ pluralize = require("pluralize"); * @returns {string} A text table. */ function drawTable(messages) { - var rows; + let rows; rows = []; @@ -43,7 +43,7 @@ function drawTable(messages) { ]); messages.forEach(function(message) { - var messageType; + let messageType; if (message.fatal || message.severity === 2) { messageType = chalk.red("error"); @@ -96,7 +96,7 @@ function drawTable(messages) { * @returns {string} A column of text tables. */ function drawReport(results) { - var files; + let files; files = results.map(function(result) { if (!result.messages.length) { @@ -118,7 +118,7 @@ function drawReport(results) { //------------------------------------------------------------------------------ module.exports = function(report) { - var result, + let result, errorCount, warningCount; diff --git a/tools/eslint/lib/formatters/tap.js b/tools/eslint/lib/formatters/tap.js index d898e30393ec5e..c5c70171f1ff23 100644 --- a/tools/eslint/lib/formatters/tap.js +++ b/tools/eslint/lib/formatters/tap.js @@ -4,7 +4,7 @@ */ "use strict"; -var yaml = require("js-yaml"); +let yaml = require("js-yaml"); //------------------------------------------------------------------------------ // Helper Functions @@ -12,8 +12,8 @@ var yaml = require("js-yaml"); /** * Returns a canonical error level string based upon the error message passed in. - * @param {object} message Individual error message provided by eslint - * @returns {String} Error level string + * @param {Object} message Individual error message provided by eslint + * @returns {string} Error level string */ function getMessageType(message) { if (message.fatal || message.severity === 2) { @@ -25,12 +25,12 @@ function getMessageType(message) { /** * Takes in a JavaScript object and outputs a TAP diagnostics string - * @param {object} diagnostic JavaScript object to be embedded as YAML into output. + * @param {Object} diagnostic JavaScript object to be embedded as YAML into output. * @returns {string} diagnostics string with YAML embedded - TAP version 13 compliant */ function outputDiagnostics(diagnostic) { - var prefix = " "; - var output = prefix + "---\n"; + let prefix = " "; + let output = prefix + "---\n"; output += prefix + yaml.safeDump(diagnostic).split("\n").join("\n" + prefix); output += "...\n"; @@ -42,18 +42,18 @@ function outputDiagnostics(diagnostic) { //------------------------------------------------------------------------------ module.exports = function(results) { - var output = "TAP version 13\n1.." + results.length + "\n"; + let output = "TAP version 13\n1.." + results.length + "\n"; results.forEach(function(result, id) { - var messages = result.messages; - var testResult = "ok"; - var diagnostics = {}; + let messages = result.messages; + let testResult = "ok"; + let diagnostics = {}; if (messages.length > 0) { testResult = "not ok"; messages.forEach(function(message) { - var diagnostic = { + let diagnostic = { message: message.message, severity: getMessageType(message), data: { diff --git a/tools/eslint/lib/formatters/unix.js b/tools/eslint/lib/formatters/unix.js index ce429fee25b9ce..ee4e14929b50e2 100644 --- a/tools/eslint/lib/formatters/unix.js +++ b/tools/eslint/lib/formatters/unix.js @@ -10,8 +10,8 @@ /** * Returns a canonical error level string based upon the error message passed in. - * @param {object} message Individual error message provided by eslint - * @returns {String} Error level string + * @param {Object} message Individual error message provided by eslint + * @returns {string} Error level string */ function getMessageType(message) { if (message.fatal || message.severity === 2) { @@ -28,12 +28,12 @@ function getMessageType(message) { module.exports = function(results) { - var output = "", + let output = "", total = 0; results.forEach(function(result) { - var messages = result.messages; + let messages = result.messages; total += messages.length; diff --git a/tools/eslint/lib/formatters/visualstudio.js b/tools/eslint/lib/formatters/visualstudio.js index 5d53dde289ed04..836577271ea14f 100644 --- a/tools/eslint/lib/formatters/visualstudio.js +++ b/tools/eslint/lib/formatters/visualstudio.js @@ -11,7 +11,7 @@ /** * Returns the severity of warning or error - * @param {object} message message object to examine + * @param {Object} message message object to examine * @returns {string} severity level * @private */ @@ -30,12 +30,12 @@ function getMessageType(message) { module.exports = function(results) { - var output = "", + let output = "", total = 0; results.forEach(function(result) { - var messages = result.messages; + let messages = result.messages; total += messages.length; diff --git a/tools/eslint/lib/ignored-paths.js b/tools/eslint/lib/ignored-paths.js index 9a7739ebee963f..729bddd20a3d5f 100644 --- a/tools/eslint/lib/ignored-paths.js +++ b/tools/eslint/lib/ignored-paths.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"), +let lodash = require("lodash"), fs = require("fs"), path = require("path"), debug = require("debug"), @@ -23,12 +23,12 @@ debug = debug("eslint:ignored-paths"); // Constants //------------------------------------------------------------------------------ -var ESLINT_IGNORE_FILENAME = ".eslintignore"; -var DEFAULT_IGNORE_DIRS = [ +let ESLINT_IGNORE_FILENAME = ".eslintignore"; +let DEFAULT_IGNORE_DIRS = [ "node_modules/", "bower_components/" ]; -var DEFAULT_OPTIONS = { +let DEFAULT_OPTIONS = { dotfiles: false, cwd: process.cwd() }; @@ -47,15 +47,15 @@ var DEFAULT_OPTIONS = { function findIgnoreFile(cwd) { cwd = cwd || DEFAULT_OPTIONS.cwd; - var ignoreFilePath = path.resolve(cwd, ESLINT_IGNORE_FILENAME); + let ignoreFilePath = path.resolve(cwd, ESLINT_IGNORE_FILENAME); return fs.existsSync(ignoreFilePath) ? ignoreFilePath : ""; } /** * Merge options with defaults - * @param {object} options Options to merge with DEFAULT_OPTIONS constant - * @returns {object} Merged options + * @param {Object} options Options to merge with DEFAULT_OPTIONS constant + * @returns {Object} Merged options */ function mergeDefaultOptions(options) { options = (options || {}); @@ -78,7 +78,7 @@ function IgnoredPaths(options) { /** * add pattern to node-ignore instance - * @param {object} ig, instance of node-ignore + * @param {Object} ig, instance of node-ignore * @param {string} pattern, pattern do add to ig * @returns {array} raw ignore rules */ @@ -88,7 +88,7 @@ function IgnoredPaths(options) { /** * add ignore file to node-ignore instance - * @param {object} ig, instance of node-ignore + * @param {Object} ig, instance of node-ignore * @param {string} filepath, file to add to ig * @returns {array} raw ignore rules */ @@ -124,7 +124,7 @@ function IgnoredPaths(options) { addPattern(this.ig.default, this.defaultPatterns); if (options.ignore !== false) { - var ignorePath; + let ignorePath; if (options.ignorePath) { debug("Using specific ignore file"); @@ -174,9 +174,9 @@ function IgnoredPaths(options) { */ IgnoredPaths.prototype.contains = function(filepath, category) { - var result = false; - var absolutePath = path.resolve(this.options.cwd, filepath); - var relativePath = pathUtil.getRelativePath(absolutePath, this.options.cwd); + let result = false; + let absolutePath = path.resolve(this.options.cwd, filepath); + let relativePath = pathUtil.getRelativePath(absolutePath, this.options.cwd); if ((typeof category === "undefined") || (category === "default")) { result = result || (this.ig.default.filter([relativePath]).length === 0); @@ -195,13 +195,13 @@ IgnoredPaths.prototype.contains = function(filepath, category) { * @returns {string[]} list of glob ignore patterns */ IgnoredPaths.prototype.getIgnoredFoldersGlobPatterns = function() { - var dirs = DEFAULT_IGNORE_DIRS; + let dirs = DEFAULT_IGNORE_DIRS; if (this.options.ignore) { /* eslint-disable no-underscore-dangle */ - var patterns = this.ig.custom._rules.filter(function(rule) { + let patterns = this.ig.custom._rules.filter(function(rule) { return rule.negative; }).map(function(rule) { return rule.origin; diff --git a/tools/eslint/lib/internal-rules/internal-no-invalid-meta.js b/tools/eslint/lib/internal-rules/internal-no-invalid-meta.js new file mode 100644 index 00000000000000..820218dc47e71d --- /dev/null +++ b/tools/eslint/lib/internal-rules/internal-no-invalid-meta.js @@ -0,0 +1,212 @@ +/** + * @fileoverview Internal rule to prevent missing or invalid meta property in core rules. + * @author Vitor Balocco + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the property of the Object node passed in that has the name specified. + * + * @param {string} property Name of the property to return. + * @param {ASTNode} node The ObjectExpression node. + * @returns {ASTNode} The Property node or null if not found. + */ +function getPropertyFromObject(property, node) { + let properties = node.properties; + + for (let i = 0; i < properties.length; i++) { + if (properties[i].key.name === property) { + return properties[i]; + } + } + + return null; +} + +/** + * Extracts the `meta` property from the ObjectExpression that all rules export. + * + * @param {ASTNode} exportsNode ObjectExpression node that the rule exports. + * @returns {ASTNode} The `meta` Property node or null if not found. + */ +function getMetaPropertyFromExportsNode(exportsNode) { + return getPropertyFromObject("meta", exportsNode); +} + +/** + * Whether this `meta` ObjectExpression has a `docs` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `docs` property exists. + */ +function hasMetaDocs(metaPropertyNode) { + return Boolean(getPropertyFromObject("docs", metaPropertyNode.value)); +} + +/** + * Whether this `meta` ObjectExpression has a `docs.description` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `docs.description` property exists. + */ +function hasMetaDocsDescription(metaPropertyNode) { + let metaDocs = getPropertyFromObject("docs", metaPropertyNode.value); + + return metaDocs && getPropertyFromObject("description", metaDocs.value); +} + +/** + * Whether this `meta` ObjectExpression has a `docs.category` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `docs.category` property exists. + */ +function hasMetaDocsCategory(metaPropertyNode) { + let metaDocs = getPropertyFromObject("docs", metaPropertyNode.value); + + return metaDocs && getPropertyFromObject("category", metaDocs.value); +} + +/** + * Whether this `meta` ObjectExpression has a `docs.recommended` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `docs.recommended` property exists. + */ +function hasMetaDocsRecommended(metaPropertyNode) { + let metaDocs = getPropertyFromObject("docs", metaPropertyNode.value); + + return metaDocs && getPropertyFromObject("recommended", metaDocs.value); +} + +/** + * Whether this `meta` ObjectExpression has a `schema` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `schema` property exists. + */ +function hasMetaSchema(metaPropertyNode) { + return getPropertyFromObject("schema", metaPropertyNode.value); +} + +/** + * Whether this `meta` ObjectExpression has a `fixable` property defined or not. + * + * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. + * @returns {boolean} `true` if a `fixable` property exists. + */ +function hasMetaFixable(metaPropertyNode) { + return getPropertyFromObject("fixable", metaPropertyNode.value); +} + +/** + * Checks the validity of the meta definition of this rule and reports any errors found. + * + * @param {RuleContext} context The ESLint rule context. + * @param {ASTNode} exportsNode ObjectExpression node that the rule exports. + * @param {boolean} ruleIsFixable whether the rule is fixable or not. + * @returns {void} + */ +function checkMetaValidity(context, exportsNode, ruleIsFixable) { + let metaProperty = getMetaPropertyFromExportsNode(exportsNode); + + if (!metaProperty) { + context.report(exportsNode, "Rule is missing a meta property."); + return; + } + + if (!hasMetaDocs(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.docs property."); + return; + } + + if (!hasMetaDocsDescription(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.docs.description property."); + return; + } + + if (!hasMetaDocsCategory(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.docs.category property."); + return; + } + + if (!hasMetaDocsRecommended(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.docs.recommended property."); + return; + } + + if (!hasMetaSchema(metaProperty)) { + context.report(metaProperty, "Rule is missing a meta.schema property."); + return; + } + + if (ruleIsFixable && !hasMetaFixable(metaProperty)) { + context.report(metaProperty, "Rule is fixable, but is missing a meta.fixable property."); + return; + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce correct use of `meta` property in core rules", + category: "Internal", + recommended: false + }, + + schema: [] + }, + + create: function(context) { + let metaExportsValue; + let ruleIsFixable = false; + + return { + AssignmentExpression: function(node) { + if (node.left && + node.right && + node.left.type === "MemberExpression" && + node.left.object.name === "module" && + node.left.property.name === "exports") { + + metaExportsValue = node.right; + } + }, + + CallExpression: function(node) { + + // If the rule has a call for `context.report` and a property `fix` + // is being passed in, then we consider that the rule is fixable. + // + // Note that we only look for context.report() calls in the new + // style (with single MessageDescriptor argument), because only + // calls in the new style can specify a fix. + if (node.callee.type === "MemberExpression" && + node.callee.object.type === "Identifier" && + node.callee.object.name === "context" && + node.callee.property.type === "Identifier" && + node.callee.property.name === "report" && + node.arguments.length === 1 && + node.arguments[0].type === "ObjectExpression") { + + if (getPropertyFromObject("fix", node.arguments[0])) { + ruleIsFixable = true; + } + } + }, + + "Program:exit": function() { + checkMetaValidity(context, metaExportsValue, ruleIsFixable); + } + }; + } +}; diff --git a/tools/eslint/lib/load-rules.js b/tools/eslint/lib/load-rules.js index 6691dbba4b350a..ed7732db3fe230 100644 --- a/tools/eslint/lib/load-rules.js +++ b/tools/eslint/lib/load-rules.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var fs = require("fs"), +let fs = require("fs"), path = require("path"); //------------------------------------------------------------------------------ @@ -29,7 +29,7 @@ module.exports = function(rulesDir, cwd) { rulesDir = path.resolve(cwd, rulesDir); } - var rules = Object.create(null); + let rules = Object.create(null); fs.readdirSync(rulesDir).forEach(function(file) { if (path.extname(file) !== ".js") { diff --git a/tools/eslint/lib/options.js b/tools/eslint/lib/options.js index eb58a623330b1b..b1ab7eb9675391 100644 --- a/tools/eslint/lib/options.js +++ b/tools/eslint/lib/options.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var optionator = require("optionator"); +let optionator = require("optionator"); //------------------------------------------------------------------------------ // Initialization and Public Interface diff --git a/tools/eslint/lib/rule-context.js b/tools/eslint/lib/rule-context.js index 49b4dfc77d5f5d..e0428744b9256e 100644 --- a/tools/eslint/lib/rule-context.js +++ b/tools/eslint/lib/rule-context.js @@ -8,13 +8,13 @@ // Requirements //------------------------------------------------------------------------------ -var RuleFixer = require("./util/rule-fixer"); +let RuleFixer = require("./util/rule-fixer"); //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ -var PASSTHROUGHS = [ +let PASSTHROUGHS = [ "getAncestors", "getDeclaredVariables", "getFilename", @@ -111,7 +111,7 @@ RuleContext.prototype = { * @returns {void} */ report: function(nodeOrDescriptor, location, message, opts) { - var descriptor, + let descriptor, fix = null; // check to see if it's a new style call diff --git a/tools/eslint/lib/rules.js b/tools/eslint/lib/rules.js index 24a8fd8a497bb9..3552d494a00ab3 100644 --- a/tools/eslint/lib/rules.js +++ b/tools/eslint/lib/rules.js @@ -9,13 +9,13 @@ // Requirements //------------------------------------------------------------------------------ -var loadRules = require("./load-rules"); +let loadRules = require("./load-rules"); //------------------------------------------------------------------------------ // Privates //------------------------------------------------------------------------------ -var rules = Object.create(null); +let rules = Object.create(null); //------------------------------------------------------------------------------ // Public Interface @@ -38,7 +38,7 @@ function define(ruleId, ruleModule) { * @returns {void} */ function load(rulesDir, cwd) { - var newRules = loadRules(rulesDir, cwd); + let newRules = loadRules(rulesDir, cwd); Object.keys(newRules).forEach(function(ruleId) { define(ruleId, newRules[ruleId]); @@ -53,7 +53,7 @@ function load(rulesDir, cwd) { */ function importPlugin(pluginRules, pluginName) { Object.keys(pluginRules).forEach(function(ruleId) { - var qualifiedRuleId = pluginName + "/" + ruleId, + let qualifiedRuleId = pluginName + "/" + ruleId, rule = pluginRules[ruleId]; define(qualifiedRuleId, rule); diff --git a/tools/eslint/lib/rules/.eslintrc.yml b/tools/eslint/lib/rules/.eslintrc.yml new file mode 100644 index 00000000000000..fded5b84978444 --- /dev/null +++ b/tools/eslint/lib/rules/.eslintrc.yml @@ -0,0 +1,2 @@ +rules: + internal-no-invalid-meta: "error" diff --git a/tools/eslint/lib/rules/accessor-pairs.js b/tools/eslint/lib/rules/accessor-pairs.js index 3ed9f0dc0ccd8d..b80b44dc9fb941 100644 --- a/tools/eslint/lib/rules/accessor-pairs.js +++ b/tools/eslint/lib/rules/accessor-pairs.js @@ -28,7 +28,7 @@ function isIdentifier(node, name) { * @returns {boolean} `true` if the node is an argument of the specified method call. */ function isArgumentOfMethodCall(node, index, object, property) { - var parent = node.parent; + let parent = node.parent; return ( parent.type === "CallExpression" && @@ -91,9 +91,9 @@ module.exports = { }] }, create: function(context) { - var config = context.options[0] || {}; - var checkGetWithoutSet = config.getWithoutSet === true; - var checkSetWithoutGet = config.setWithoutGet !== false; + let config = context.options[0] || {}; + let checkGetWithoutSet = config.getWithoutSet === true; + let checkSetWithoutGet = config.setWithoutGet !== false; /** * Checks a object expression to see if it has setter and getter both present or none. @@ -102,14 +102,14 @@ module.exports = { * @private */ function checkLonelySetGet(node) { - var isSetPresent = false; - var isGetPresent = false; - var isDescriptor = isPropertyDescriptor(node); + let isSetPresent = false; + let isGetPresent = false; + let isDescriptor = isPropertyDescriptor(node); - for (var i = 0, end = node.properties.length; i < end; i++) { - var property = node.properties[i]; + for (let i = 0, end = node.properties.length; i < end; i++) { + let property = node.properties[i]; - var propToCheck = ""; + let propToCheck = ""; if (property.kind === "init") { if (isDescriptor && !property.computed) { @@ -139,9 +139,9 @@ module.exports = { } if (checkSetWithoutGet && isSetPresent && !isGetPresent) { - context.report(node, "Getter is not present"); + context.report(node, "Getter is not present."); } else if (checkGetWithoutSet && isGetPresent && !isSetPresent) { - context.report(node, "Setter is not present"); + context.report(node, "Setter is not present."); } } diff --git a/tools/eslint/lib/rules/array-bracket-spacing.js b/tools/eslint/lib/rules/array-bracket-spacing.js index 09598031b4942e..6e26e0cbd50b98 100644 --- a/tools/eslint/lib/rules/array-bracket-spacing.js +++ b/tools/eslint/lib/rules/array-bracket-spacing.js @@ -4,7 +4,7 @@ */ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -40,7 +40,7 @@ module.exports = { ] }, create: function(context) { - var spaced = context.options[0] === "always", + let spaced = context.options[0] === "always", sourceCode = context.getSourceCode(); /** @@ -54,7 +54,7 @@ module.exports = { return context.options[1] ? context.options[1][option] === !spaced : false; } - var options = { + let options = { spaced: spaced, singleElementException: isOptionSet("singleValue"), objectsInArraysException: isOptionSet("objectsInArrays"), @@ -75,9 +75,9 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "There should be no space after '" + token.value + "'", + message: "There should be no space after '" + token.value + "'.", fix: function(fixer) { - var nextToken = sourceCode.getTokenAfter(token); + let nextToken = sourceCode.getTokenAfter(token); return fixer.removeRange([token.range[1], nextToken.range[0]]); } @@ -94,9 +94,9 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "There should be no space before '" + token.value + "'", + message: "There should be no space before '" + token.value + "'.", fix: function(fixer) { - var previousToken = sourceCode.getTokenBefore(token); + let previousToken = sourceCode.getTokenBefore(token); return fixer.removeRange([previousToken.range[1], token.range[0]]); } @@ -113,7 +113,7 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "A space is required after '" + token.value + "'", + message: "A space is required after '" + token.value + "'.", fix: function(fixer) { return fixer.insertTextAfter(token, " "); } @@ -130,7 +130,7 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "A space is required before '" + token.value + "'", + message: "A space is required before '" + token.value + "'.", fix: function(fixer) { return fixer.insertTextBefore(token, " "); } @@ -165,20 +165,20 @@ module.exports = { return; } - var first = sourceCode.getFirstToken(node), + let first = sourceCode.getFirstToken(node), second = sourceCode.getFirstToken(node, 1), penultimate = sourceCode.getLastToken(node, 1), last = sourceCode.getLastToken(node), firstElement = node.elements[0], lastElement = node.elements[node.elements.length - 1]; - var openingBracketMustBeSpaced = + let openingBracketMustBeSpaced = options.objectsInArraysException && isObjectType(firstElement) || options.arraysInArraysException && isArrayType(firstElement) || options.singleElementException && node.elements.length === 1 ? !options.spaced : options.spaced; - var closingBracketMustBeSpaced = + let closingBracketMustBeSpaced = options.objectsInArraysException && isObjectType(lastElement) || options.arraysInArraysException && isArrayType(lastElement) || options.singleElementException && node.elements.length === 1 diff --git a/tools/eslint/lib/rules/array-callback-return.js b/tools/eslint/lib/rules/array-callback-return.js index 714c189c6b5495..d72fd57b2e8c1a 100644 --- a/tools/eslint/lib/rules/array-callback-return.js +++ b/tools/eslint/lib/rules/array-callback-return.js @@ -9,14 +9,14 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/; -var TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/; +let TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/; +let TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/; /** * Checks a given code path segment is reachable. @@ -104,7 +104,7 @@ function isTargetMethod(node) { */ function isCallbackOfArrayMethod(node) { while (node) { - var parent = node.parent; + let parent = node.parent; switch (parent.type) { @@ -123,14 +123,15 @@ function isCallbackOfArrayMethod(node) { // // setup... // return function callback() { ... }; // })()); - case "ReturnStatement": - var func = astUtils.getUpperFunction(parent); + case "ReturnStatement": { + const func = astUtils.getUpperFunction(parent); if (func === null || !astUtils.isCallee(func)) { return false; } node = func.parent; break; + } // e.g. // Array.from([], function() {}); @@ -176,7 +177,7 @@ module.exports = { }, create: function(context) { - var funcInfo = { + let funcInfo = { upper: null, codePath: null, hasReturn: false, diff --git a/tools/eslint/lib/rules/arrow-body-style.js b/tools/eslint/lib/rules/arrow-body-style.js index 13486fa74bc69d..16f082edae5c3e 100644 --- a/tools/eslint/lib/rules/arrow-body-style.js +++ b/tools/eslint/lib/rules/arrow-body-style.js @@ -50,11 +50,11 @@ module.exports = { }, create: function(context) { - var options = context.options; - var always = options[0] === "always"; - var asNeeded = !options[0] || options[0] === "as-needed"; - var never = options[0] === "never"; - var requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral; + let options = context.options; + let always = options[0] === "always"; + let asNeeded = !options[0] || options[0] === "as-needed"; + let never = options[0] === "never"; + let requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral; /** * Determines whether a arrow function body needs braces @@ -62,7 +62,7 @@ module.exports = { * @returns {void} */ function validate(node) { - var arrowBody = node.body; + let arrowBody = node.body; if (arrowBody.type === "BlockStatement") { if (never) { @@ -72,7 +72,7 @@ module.exports = { message: "Unexpected block statement surrounding arrow body." }); } else { - var blockBody = arrowBody.body; + let blockBody = arrowBody.body; if (blockBody.length !== 1) { return; diff --git a/tools/eslint/lib/rules/arrow-parens.js b/tools/eslint/lib/rules/arrow-parens.js index 86b972e80093b5..fd70ee3465a2a0 100644 --- a/tools/eslint/lib/rules/arrow-parens.js +++ b/tools/eslint/lib/rules/arrow-parens.js @@ -26,11 +26,11 @@ module.exports = { }, create: function(context) { - var message = "Expected parentheses around arrow function argument."; - var asNeededMessage = "Unexpected parentheses around single function argument"; - var asNeeded = context.options[0] === "as-needed"; + let message = "Expected parentheses around arrow function argument."; + let asNeededMessage = "Unexpected parentheses around single function argument."; + let asNeeded = context.options[0] === "as-needed"; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Determines whether a arrow function argument end with `)` @@ -38,7 +38,7 @@ module.exports = { * @returns {void} */ function parens(node) { - var token = sourceCode.getFirstToken(node); + let token = sourceCode.getFirstToken(node); // as-needed: x => x if (asNeeded && node.params.length === 1 && node.params[0].type === "Identifier") { @@ -47,8 +47,8 @@ module.exports = { node: node, message: asNeededMessage, fix: function(fixer) { - var paramToken = context.getTokenAfter(token); - var closingParenToken = context.getTokenAfter(paramToken); + let paramToken = context.getTokenAfter(token); + let closingParenToken = context.getTokenAfter(paramToken); return fixer.replaceTextRange([ token.range[0], @@ -61,7 +61,7 @@ module.exports = { } if (token.type === "Identifier") { - var after = sourceCode.getTokenAfter(token); + let after = sourceCode.getTokenAfter(token); // (x) => x if (after.value !== ")") { diff --git a/tools/eslint/lib/rules/arrow-spacing.js b/tools/eslint/lib/rules/arrow-spacing.js index 3af5ae1f84463d..354c860c7b0a7c 100644 --- a/tools/eslint/lib/rules/arrow-spacing.js +++ b/tools/eslint/lib/rules/arrow-spacing.js @@ -37,13 +37,13 @@ module.exports = { create: function(context) { // merge rules with default - var rule = { before: true, after: true }, + let rule = { before: true, after: true }, option = context.options[0] || {}; rule.before = option.before !== false; rule.after = option.after !== false; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Get tokens of arrow(`=>`) and before/after arrow. @@ -51,14 +51,14 @@ module.exports = { * @returns {Object} Tokens of arrow and before/after arrow. */ function getTokens(node) { - var t = sourceCode.getFirstToken(node); - var before; + let t = sourceCode.getFirstToken(node); + let before; while (t.type !== "Punctuator" || t.value !== "=>") { before = t; t = sourceCode.getTokenAfter(t); } - var after = sourceCode.getTokenAfter(t); + let after = sourceCode.getTokenAfter(t); return { before: before, arrow: t, after: after }; } @@ -69,8 +69,8 @@ module.exports = { * @returns {Object} count of space before/after arrow. */ function countSpaces(tokens) { - var before = tokens.arrow.range[0] - tokens.before.range[1]; - var after = tokens.after.range[0] - tokens.arrow.range[1]; + let before = tokens.arrow.range[0] - tokens.before.range[1]; + let after = tokens.after.range[0] - tokens.arrow.range[1]; return { before: before, after: after }; } @@ -83,8 +83,8 @@ module.exports = { * @returns {void} */ function spaces(node) { - var tokens = getTokens(node); - var countSpace = countSpaces(tokens); + let tokens = getTokens(node); + let countSpace = countSpaces(tokens); if (rule.before) { @@ -92,7 +92,7 @@ module.exports = { if (countSpace.before === 0) { context.report({ node: tokens.before, - message: "Missing space before =>", + message: "Missing space before =>.", fix: function(fixer) { return fixer.insertTextBefore(tokens.arrow, " "); } @@ -104,7 +104,7 @@ module.exports = { if (countSpace.before > 0) { context.report({ node: tokens.before, - message: "Unexpected space before =>", + message: "Unexpected space before =>.", fix: function(fixer) { return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]); } @@ -118,7 +118,7 @@ module.exports = { if (countSpace.after === 0) { context.report({ node: tokens.after, - message: "Missing space after =>", + message: "Missing space after =>.", fix: function(fixer) { return fixer.insertTextAfter(tokens.arrow, " "); } @@ -130,7 +130,7 @@ module.exports = { if (countSpace.after > 0) { context.report({ node: tokens.after, - message: "Unexpected space after =>", + message: "Unexpected space after =>.", fix: function(fixer) { return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]); } diff --git a/tools/eslint/lib/rules/block-scoped-var.js b/tools/eslint/lib/rules/block-scoped-var.js index 3da07adcba1a1f..f8198ea10ac14a 100644 --- a/tools/eslint/lib/rules/block-scoped-var.js +++ b/tools/eslint/lib/rules/block-scoped-var.js @@ -20,7 +20,7 @@ module.exports = { }, create: function(context) { - var stack = []; + let stack = []; /** * Makes a block scope. @@ -45,7 +45,7 @@ module.exports = { * @returns {void} */ function report(reference) { - var identifier = reference.identifier; + let identifier = reference.identifier; context.report( identifier, @@ -64,7 +64,7 @@ module.exports = { } // Defines a predicate to check whether or not a given reference is outside of valid scope. - var scopeRange = stack[stack.length - 1]; + let scopeRange = stack[stack.length - 1]; /** * Check if a reference is out of scope @@ -73,15 +73,15 @@ module.exports = { * @private */ function isOutsideOfScope(reference) { - var idRange = reference.identifier.range; + let idRange = reference.identifier.range; return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1]; } // Gets declared variables, and checks its references. - var variables = context.getDeclaredVariables(node); + let variables = context.getDeclaredVariables(node); - for (var i = 0; i < variables.length; ++i) { + for (let i = 0; i < variables.length; ++i) { // Reports. variables[i] diff --git a/tools/eslint/lib/rules/block-spacing.js b/tools/eslint/lib/rules/block-spacing.js index 54ae83d117d497..eb24cea319d51c 100644 --- a/tools/eslint/lib/rules/block-spacing.js +++ b/tools/eslint/lib/rules/block-spacing.js @@ -5,7 +5,7 @@ "use strict"; -var util = require("../ast-utils"); +let util = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -27,7 +27,7 @@ module.exports = { }, create: function(context) { - var always = (context.options[0] !== "never"), + let always = (context.options[0] !== "never"), message = always ? "Requires a space" : "Unexpected space(s)", sourceCode = context.getSourceCode(); @@ -72,10 +72,10 @@ module.exports = { function checkSpacingInsideBraces(node) { // Gets braces and the first/last token of content. - var openBrace = getOpenBrace(node); - var closeBrace = sourceCode.getLastToken(node); - var firstToken = sourceCode.getTokenOrCommentAfter(openBrace); - var lastToken = sourceCode.getTokenOrCommentBefore(closeBrace); + let openBrace = getOpenBrace(node); + let closeBrace = sourceCode.getLastToken(node); + let firstToken = sourceCode.getTokenOrCommentAfter(openBrace); + let lastToken = sourceCode.getTokenOrCommentBefore(closeBrace); // Skip if the node is invalid or empty. if (openBrace.type !== "Punctuator" || diff --git a/tools/eslint/lib/rules/brace-style.js b/tools/eslint/lib/rules/brace-style.js index 785a71e4e7b0aa..325130a4a2f86f 100644 --- a/tools/eslint/lib/rules/brace-style.js +++ b/tools/eslint/lib/rules/brace-style.js @@ -34,11 +34,11 @@ module.exports = { }, create: function(context) { - var style = context.options[0] || "1tbs", + let style = context.options[0] || "1tbs", params = context.options[1] || {}, sourceCode = context.getSourceCode(); - var OPEN_MESSAGE = "Opening curly brace does not appear on the same line as controlling statement.", + let OPEN_MESSAGE = "Opening curly brace does not appear on the same line as controlling statement.", OPEN_MESSAGE_ALLMAN = "Opening curly brace appears on the same line as controlling statement.", BODY_MESSAGE = "Statement inside of curly braces should be on next line.", CLOSE_MESSAGE = "Closing curly brace does not appear on the same line as the subsequent block.", @@ -61,7 +61,7 @@ module.exports = { /** * Check if the token is an punctuator with a value of curly brace - * @param {object} token - Token to check + * @param {Object} token - Token to check * @returns {boolean} true if its a curly punctuator * @private */ @@ -78,11 +78,11 @@ module.exports = { * @private */ function checkBlock() { - var blockProperties = arguments; + let blockProperties = arguments; return function(node) { Array.prototype.forEach.call(blockProperties, function(blockProp) { - var block = node[blockProp], + let block = node[blockProp], previousToken, curlyToken, curlyTokenEnd, @@ -129,7 +129,7 @@ module.exports = { * @private */ function checkIfStatement(node) { - var tokens; + let tokens; checkBlock("consequent", "alternate")(node); @@ -157,7 +157,7 @@ module.exports = { * @private */ function checkTryStatement(node) { - var tokens; + let tokens; checkBlock("block", "finalizer")(node); @@ -180,7 +180,7 @@ module.exports = { * @private */ function checkCatchClause(node) { - var previousToken = sourceCode.getTokenBefore(node), + let previousToken = sourceCode.getTokenBefore(node), firstToken = sourceCode.getFirstToken(node); checkBlock("body")(node); @@ -205,7 +205,7 @@ module.exports = { * @private */ function checkSwitchStatement(node) { - var tokens; + let tokens; if (node.cases && node.cases.length) { tokens = sourceCode.getTokensBefore(node.cases[0], 2); diff --git a/tools/eslint/lib/rules/callback-return.js b/tools/eslint/lib/rules/callback-return.js index 1d70d0c637308f..0b9d4a48941182 100644 --- a/tools/eslint/lib/rules/callback-return.js +++ b/tools/eslint/lib/rules/callback-return.js @@ -24,7 +24,7 @@ module.exports = { create: function(context) { - var callbacks = context.options[0] || ["callback", "cb", "next"], + let callbacks = context.options[0] || ["callback", "cb", "next"], sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- @@ -50,7 +50,7 @@ module.exports = { /** * Check to see if a node contains only identifers * @param {ASTNode} node The node to check - * @returns {Boolean} Whether or not the node contains only identifers + * @returns {boolean} Whether or not the node contains only identifers */ function containsOnlyIdentifiers(node) { if (node.type === "Identifier") { @@ -71,7 +71,7 @@ module.exports = { /** * Check to see if a CallExpression is in our callback list. * @param {ASTNode} node The node to check against our callback names list. - * @returns {Boolean} Whether or not this function matches our callback name. + * @returns {boolean} Whether or not this function matches our callback name. */ function isCallback(node) { return containsOnlyIdentifiers(node.callee) && callbacks.indexOf(sourceCode.getText(node.callee)) > -1; @@ -118,7 +118,7 @@ module.exports = { } // find the closest block, return or loop - var closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {}, + let closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {}, lastItem, parentType; // if our parent is a return we know we're ok diff --git a/tools/eslint/lib/rules/camelcase.js b/tools/eslint/lib/rules/camelcase.js index 28f9e8296b1926..b336e595dc964b 100644 --- a/tools/eslint/lib/rules/camelcase.js +++ b/tools/eslint/lib/rules/camelcase.js @@ -37,11 +37,11 @@ module.exports = { //-------------------------------------------------------------------------- // contains reported nodes to avoid reporting twice on destructuring with shorthand notation - var reported = []; + let reported = []; /** * Checks if a string contains an underscore and isn't all upper-case - * @param {String} name The string to check. + * @param {string} name The string to check. * @returns {boolean} if the string is underscored * @private */ @@ -64,7 +64,7 @@ module.exports = { } } - var options = context.options[0] || {}, + let options = context.options[0] || {}, properties = options.properties || ""; if (properties !== "always" && properties !== "never") { @@ -79,7 +79,7 @@ module.exports = { * Leading and trailing underscores are commonly used to flag * private/protected identifiers, strip them */ - var name = node.name.replace(/^_+|_+$/g, ""), + let name = node.name.replace(/^_+|_+$/g, ""), effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; // MemberExpressions get special rules diff --git a/tools/eslint/lib/rules/comma-dangle.js b/tools/eslint/lib/rules/comma-dangle.js index d2478cacfb0748..69a72e8fcad5d1 100644 --- a/tools/eslint/lib/rules/comma-dangle.js +++ b/tools/eslint/lib/rules/comma-dangle.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"); +let lodash = require("lodash"); /** * Checks whether or not a trailing comma is allowed in a given node. @@ -45,9 +45,9 @@ module.exports = { }, create: function(context) { - var mode = context.options[0]; - var UNEXPECTED_MESSAGE = "Unexpected trailing comma."; - var MISSING_MESSAGE = "Missing trailing comma."; + let mode = context.options[0]; + let UNEXPECTED_MESSAGE = "Unexpected trailing comma."; + let MISSING_MESSAGE = "Missing trailing comma."; /** * Checks whether or not a given node is multiline. @@ -58,13 +58,13 @@ module.exports = { * @returns {boolean} `true` if the node is multiline. */ function isMultiline(node) { - var lastItem = lodash.last(node.properties || node.elements || node.specifiers); + let lastItem = lodash.last(node.properties || node.elements || node.specifiers); if (!lastItem) { return false; } - var sourceCode = context.getSourceCode(), + let sourceCode = context.getSourceCode(), penultimateToken = sourceCode.getLastToken(lastItem), lastToken = sourceCode.getTokenAfter(penultimateToken); @@ -91,13 +91,13 @@ module.exports = { * @returns {void} */ function forbidTrailingComma(node) { - var lastItem = lodash.last(node.properties || node.elements || node.specifiers); + let lastItem = lodash.last(node.properties || node.elements || node.specifiers); if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { return; } - var sourceCode = context.getSourceCode(), + let sourceCode = context.getSourceCode(), trailingToken; // last item can be surrounded by parentheses for object and array literals @@ -132,7 +132,7 @@ module.exports = { * @returns {void} */ function forceTrailingComma(node) { - var lastItem = lodash.last(node.properties || node.elements || node.specifiers); + let lastItem = lodash.last(node.properties || node.elements || node.specifiers); if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { return; @@ -142,7 +142,7 @@ module.exports = { return; } - var sourceCode = context.getSourceCode(), + let sourceCode = context.getSourceCode(), penultimateToken = lastItem, trailingToken = sourceCode.getTokenAfter(lastItem); @@ -199,7 +199,7 @@ module.exports = { } // Chooses a checking function. - var checkForTrailingComma; + let checkForTrailingComma; if (mode === "always") { checkForTrailingComma = forceTrailingComma; diff --git a/tools/eslint/lib/rules/comma-spacing.js b/tools/eslint/lib/rules/comma-spacing.js index 22fb8b235f5c9d..ea516e03335277 100644 --- a/tools/eslint/lib/rules/comma-spacing.js +++ b/tools/eslint/lib/rules/comma-spacing.js @@ -4,7 +4,7 @@ */ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -38,10 +38,10 @@ module.exports = { create: function(context) { - var sourceCode = context.getSourceCode(); - var tokensAndComments = sourceCode.tokensAndComments; + let sourceCode = context.getSourceCode(); + let tokensAndComments = sourceCode.tokensAndComments; - var options = { + let options = { before: context.options[0] ? !!context.options[0].before : false, after: context.options[0] ? !!context.options[0].after : true }; @@ -51,7 +51,7 @@ module.exports = { //-------------------------------------------------------------------------- // list of comma tokens to ignore for the check of leading whitespace - var commaTokensToIgnore = []; + let commaTokensToIgnore = []; /** * Determines if a given token is a comma operator. @@ -82,8 +82,8 @@ module.exports = { return fixer.insertTextAfter(node, " "); } } else { - var start, end; - var newText = ""; + let start, end; + let newText = ""; if (dir === "before") { start = otherNode.range[1]; @@ -136,10 +136,10 @@ module.exports = { * @returns {void} */ function addNullElementsToIgnoreList(node) { - var previousToken = sourceCode.getFirstToken(node); + let previousToken = sourceCode.getFirstToken(node); node.elements.forEach(function(element) { - var token; + let token; if (element === null) { token = sourceCode.getTokenAfter(previousToken); @@ -162,7 +162,7 @@ module.exports = { return { "Program:exit": function() { - var previousToken, + let previousToken, nextToken; tokensAndComments.forEach(function(token, i) { diff --git a/tools/eslint/lib/rules/comma-style.js b/tools/eslint/lib/rules/comma-style.js index 173df90c33e813..69b657f62d46be 100644 --- a/tools/eslint/lib/rules/comma-style.js +++ b/tools/eslint/lib/rules/comma-style.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -39,7 +39,7 @@ module.exports = { }, create: function(context) { - var style = context.options[0] || "last", + let style = context.options[0] || "last", exceptions = {}, sourceCode = context.getSourceCode(); @@ -108,7 +108,7 @@ module.exports = { * @returns {void} */ function validateComma(node, property) { - var items = node[property], + let items = node[property], arrayLiteral = (node.type === "ArrayExpression"), previousItemToken; @@ -118,7 +118,7 @@ module.exports = { previousItemToken = sourceCode.getFirstToken(node); items.forEach(function(item) { - var commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken, + let commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken, currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken), reportItem = item || currentItemToken, tokenBeforeComma = sourceCode.getTokenBefore(commaToken); @@ -158,7 +158,7 @@ module.exports = { */ if (arrayLiteral) { - var lastToken = sourceCode.getLastToken(node), + let lastToken = sourceCode.getLastToken(node), nextToLastToken = sourceCode.getTokenBefore(lastToken); if (isComma(nextToLastToken)) { @@ -177,7 +177,7 @@ module.exports = { // Public //-------------------------------------------------------------------------- - var nodes = {}; + let nodes = {}; if (!exceptions.VariableDeclaration) { nodes.VariableDeclaration = function(node) { diff --git a/tools/eslint/lib/rules/complexity.js b/tools/eslint/lib/rules/complexity.js index 029b739808d6d7..394df98c44aac1 100644 --- a/tools/eslint/lib/rules/complexity.js +++ b/tools/eslint/lib/rules/complexity.js @@ -45,7 +45,7 @@ module.exports = { }, create: function(context) { - var option = context.options[0], + let option = context.options[0], THRESHOLD = 20; if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") { @@ -63,7 +63,7 @@ module.exports = { //-------------------------------------------------------------------------- // Using a stack to store complexity (handling nested functions) - var fns = []; + let fns = []; /** * When parsing a new function, store it in our function stack @@ -81,7 +81,7 @@ module.exports = { * @private */ function endFunction(node) { - var complexity = fns.pop(), + let complexity = fns.pop(), name = "anonymous"; if (node.id) { diff --git a/tools/eslint/lib/rules/computed-property-spacing.js b/tools/eslint/lib/rules/computed-property-spacing.js index 89f0cc87b1e932..1122c5c83c3946 100644 --- a/tools/eslint/lib/rules/computed-property-spacing.js +++ b/tools/eslint/lib/rules/computed-property-spacing.js @@ -4,7 +4,7 @@ */ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -28,8 +28,8 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); - var propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never" + let sourceCode = context.getSourceCode(); + let propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never" //-------------------------------------------------------------------------- // Helpers @@ -46,7 +46,7 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "There should be no space after '" + token.value + "'", + message: "There should be no space after '" + token.value + "'.", fix: function(fixer) { return fixer.removeRange([token.range[1], tokenAfter.range[0]]); } @@ -64,7 +64,7 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "There should be no space before '" + token.value + "'", + message: "There should be no space before '" + token.value + "'.", fix: function(fixer) { return fixer.removeRange([tokenBefore.range[1], token.range[0]]); } @@ -81,7 +81,7 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "A space is required after '" + token.value + "'", + message: "A space is required after '" + token.value + "'.", fix: function(fixer) { return fixer.insertTextAfter(token, " "); } @@ -98,7 +98,7 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "A space is required before '" + token.value + "'", + message: "A space is required before '" + token.value + "'.", fix: function(fixer) { return fixer.insertTextBefore(token, " "); } @@ -108,7 +108,7 @@ module.exports = { /** * Returns a function that checks the spacing of a node on the property name * that was passed in. - * @param {String} propertyName The property on the node to check for spacing + * @param {string} propertyName The property on the node to check for spacing * @returns {Function} A function that will check spacing on a node */ function checkSpacing(propertyName) { @@ -117,9 +117,9 @@ module.exports = { return; } - var property = node[propertyName]; + let property = node[propertyName]; - var before = sourceCode.getTokenBefore(property), + let before = sourceCode.getTokenBefore(property), first = sourceCode.getFirstToken(property), last = sourceCode.getLastToken(property), after = sourceCode.getTokenAfter(property); diff --git a/tools/eslint/lib/rules/consistent-return.js b/tools/eslint/lib/rules/consistent-return.js index 10f1d41cf4b65b..ffadd31bfd73db 100644 --- a/tools/eslint/lib/rules/consistent-return.js +++ b/tools/eslint/lib/rules/consistent-return.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers @@ -57,9 +57,9 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; - var treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true; - var funcInfo = null; + let options = context.options[0] || {}; + let treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true; + let funcInfo = null; /** * Checks whether of not the implicit returning is consistent if the last @@ -69,7 +69,7 @@ module.exports = { * @returns {void} */ function checkLastSegment(node) { - var loc, type; + let loc, type; /* * Skip if it expected no return value or unreachable. @@ -135,8 +135,8 @@ module.exports = { // Reports a given return statement if it's inconsistent. ReturnStatement: function(node) { - var argument = node.argument; - var hasReturnValue = Boolean(argument); + let argument = node.argument; + let hasReturnValue = Boolean(argument); if (treatUndefinedAsUnspecified && hasReturnValue) { hasReturnValue = !isIdentifier(argument, "undefined") && argument.operator !== "void"; diff --git a/tools/eslint/lib/rules/consistent-this.js b/tools/eslint/lib/rules/consistent-this.js index 042e1a0aaeddd5..339c43995e8467 100644 --- a/tools/eslint/lib/rules/consistent-this.js +++ b/tools/eslint/lib/rules/consistent-this.js @@ -27,7 +27,7 @@ module.exports = { }, create: function(context) { - var aliases = []; + let aliases = []; if (context.options.length === 0) { aliases.push("that"); @@ -57,7 +57,7 @@ module.exports = { * @returns {void} */ function checkAssignment(node, name, value) { - var isThis = value.type === "ThisExpression"; + let isThis = value.type === "ThisExpression"; if (aliases.indexOf(name) !== -1) { if (!isThis || node.operator && node.operator !== "=") { @@ -73,12 +73,12 @@ module.exports = { * Ensures that a variable declaration of the alias in a program or function * is assigned to the correct value. * @param {string} alias alias the check the assignment of. - * @param {object} scope scope of the current code we are checking. + * @param {Object} scope scope of the current code we are checking. * @private * @returns {void} */ function checkWasAssigned(alias, scope) { - var variable = scope.set.get(alias); + let variable = scope.set.get(alias); if (!variable) { return; @@ -94,7 +94,7 @@ module.exports = { // The alias has been declared and not assigned: check it was // assigned later in the same scope. if (!variable.references.some(function(reference) { - var write = reference.writeExpr; + let write = reference.writeExpr; return ( reference.from === scope && @@ -115,7 +115,7 @@ module.exports = { * @returns {void} */ function ensureWasAssigned() { - var scope = context.getScope(); + let scope = context.getScope(); aliases.forEach(function(alias) { checkWasAssigned(alias, scope); @@ -128,8 +128,8 @@ module.exports = { "FunctionDeclaration:exit": ensureWasAssigned, VariableDeclarator: function(node) { - var id = node.id; - var isDestructuring = + let id = node.id; + let isDestructuring = id.type === "ArrayPattern" || id.type === "ObjectPattern"; if (node.init !== null && !isDestructuring) { diff --git a/tools/eslint/lib/rules/constructor-super.js b/tools/eslint/lib/rules/constructor-super.js index 4b2aacf5755281..7b7e8cfd3e9b80 100644 --- a/tools/eslint/lib/rules/constructor-super.js +++ b/tools/eslint/lib/rules/constructor-super.js @@ -75,10 +75,11 @@ function isPossibleConstructor(node) { isPossibleConstructor(node.consequent) ); - case "SequenceExpression": - var lastExpression = node.expressions[node.expressions.length - 1]; + case "SequenceExpression": { + const lastExpression = node.expressions[node.expressions.length - 1]; return isPossibleConstructor(lastExpression); + } default: return false; @@ -111,7 +112,7 @@ module.exports = { * - scope: The scope of own class. * - codePath: The code path object of the constructor. */ - var funcInfo = null; + let funcInfo = null; /* * {Map} @@ -120,7 +121,7 @@ module.exports = { * - calledInEveryPaths: A flag of be called `super()` in all code paths. * - validNodes: */ - var segInfoMap = Object.create(null); + let segInfoMap = Object.create(null); /** * Gets the flag which shows `super()` is called in some paths. @@ -163,8 +164,8 @@ module.exports = { if (isConstructorFunction(node)) { // Class > ClassBody > MethodDefinition > FunctionExpression - var classNode = node.parent.parent.parent; - var superClass = classNode.superClass; + let classNode = node.parent.parent.parent; + let superClass = classNode.superClass; funcInfo = { upper: funcInfo, @@ -192,7 +193,7 @@ module.exports = { * @returns {void} */ onCodePathEnd: function(codePath, node) { - var hasExtends = funcInfo.hasExtends; + let hasExtends = funcInfo.hasExtends; // Pop. funcInfo = funcInfo.upper; @@ -202,9 +203,9 @@ module.exports = { } // Reports if `super()` lacked. - var segments = codePath.returnedSegments; - var calledInEveryPaths = segments.every(isCalledInEveryPath); - var calledInSomePaths = segments.some(isCalledInSomePath); + let segments = codePath.returnedSegments; + let calledInEveryPaths = segments.every(isCalledInEveryPath); + let calledInSomePaths = segments.some(isCalledInSomePath); if (!calledInEveryPaths) { context.report({ @@ -227,14 +228,14 @@ module.exports = { } // Initialize info. - var info = segInfoMap[segment.id] = { + let info = segInfoMap[segment.id] = { calledInSomePaths: false, calledInEveryPaths: false, validNodes: [] }; // When there are previous segments, aggregates these. - var prevSegments = segment.prevSegments; + let prevSegments = segment.prevSegments; if (prevSegments.length > 0) { info.calledInSomePaths = prevSegments.some(isCalledInSomePath); @@ -257,13 +258,13 @@ module.exports = { } // Update information inside of the loop. - var isRealLoop = toSegment.prevSegments.length >= 2; + let isRealLoop = toSegment.prevSegments.length >= 2; funcInfo.codePath.traverseSegments( {first: toSegment, last: fromSegment}, function(segment) { - var info = segInfoMap[segment.id]; - var prevSegments = segment.prevSegments; + let info = segInfoMap[segment.id]; + let prevSegments = segment.prevSegments; // Updates flags. info.calledInSomePaths = prevSegments.some(isCalledInSomePath); @@ -271,12 +272,12 @@ module.exports = { // If flags become true anew, reports the valid nodes. if (info.calledInSomePaths || isRealLoop) { - var nodes = info.validNodes; + let nodes = info.validNodes; info.validNodes = []; - for (var i = 0; i < nodes.length; ++i) { - var node = nodes[i]; + for (let i = 0; i < nodes.length; ++i) { + let node = nodes[i]; context.report({ message: "Unexpected duplicate 'super()'.", @@ -305,23 +306,22 @@ module.exports = { // Reports if needed. if (funcInfo.hasExtends) { - var segments = funcInfo.codePath.currentSegments; - var reachable = false; - var duplicate = false; + let segments = funcInfo.codePath.currentSegments; + let duplicate = false; + let info = null; - for (var i = 0; i < segments.length; ++i) { - var segment = segments[i]; + for (let i = 0; i < segments.length; ++i) { + let segment = segments[i]; if (segment.reachable) { - var info = segInfoMap[segment.id]; + info = segInfoMap[segment.id]; - reachable = true; duplicate = duplicate || info.calledInSomePaths; info.calledInSomePaths = info.calledInEveryPaths = true; } } - if (reachable) { + if (info) { if (duplicate) { context.report({ message: "Unexpected duplicate 'super()'.", @@ -360,13 +360,13 @@ module.exports = { } // Returning argument is a substitute of 'super()'. - var segments = funcInfo.codePath.currentSegments; + let segments = funcInfo.codePath.currentSegments; - for (var i = 0; i < segments.length; ++i) { - var segment = segments[i]; + for (let i = 0; i < segments.length; ++i) { + let segment = segments[i]; if (segment.reachable) { - var info = segInfoMap[segment.id]; + let info = segInfoMap[segment.id]; info.calledInSomePaths = info.calledInEveryPaths = true; } diff --git a/tools/eslint/lib/rules/curly.js b/tools/eslint/lib/rules/curly.js index 257366fabe844c..912f321565e80f 100644 --- a/tools/eslint/lib/rules/curly.js +++ b/tools/eslint/lib/rules/curly.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -53,12 +53,12 @@ module.exports = { create: function(context) { - var multiOnly = (context.options[0] === "multi"); - var multiLine = (context.options[0] === "multi-line"); - var multiOrNest = (context.options[0] === "multi-or-nest"); - var consistent = (context.options[1] === "consistent"); + let multiOnly = (context.options[0] === "multi"); + let multiLine = (context.options[0] === "multi-line"); + let multiOrNest = (context.options[0] === "multi-or-nest"); + let consistent = (context.options[1] === "consistent"); - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers @@ -71,7 +71,7 @@ module.exports = { * @private */ function isCollapsedOneLiner(node) { - var before = sourceCode.getTokenBefore(node), + let before = sourceCode.getTokenBefore(node), last = sourceCode.getLastToken(node); return before.loc.start.line === last.loc.end.line; @@ -84,7 +84,7 @@ module.exports = { * @private */ function isOneLiner(node) { - var first = sourceCode.getFirstToken(node), + let first = sourceCode.getFirstToken(node), last = sourceCode.getLastToken(node); return first.loc.start.line === last.loc.end.line; @@ -96,7 +96,7 @@ module.exports = { * @returns {Token} The `else` keyword token. */ function getElseKeyword(node) { - var token = sourceCode.getTokenAfter(node.consequent); + let token = sourceCode.getTokenAfter(node.consequent); while (token.type !== "Keyword" || token.value !== "else") { token = sourceCode.getTokenAfter(token); @@ -180,7 +180,7 @@ module.exports = { * @param {ASTNode} body The body node to check for blocks. * @param {string} name The name to report if there's a problem. * @param {string} suffix Additional string to add to the end of a report. - * @returns {object} a prepared check object, with "actual", "expected", "check" properties. + * @returns {Object} a prepared check object, with "actual", "expected", "check" properties. * "actual" will be `true` or `false` whether the body is already a block statement. * "expected" will be `true` or `false` if the body should be a block statement or not, or * `null` if it doesn't matter, depending on the rule options. It can be modified to change @@ -189,8 +189,8 @@ module.exports = { * properties. */ function prepareCheck(node, body, name, suffix) { - var hasBlock = (body.type === "BlockStatement"); - var expected = null; + let hasBlock = (body.type === "BlockStatement"); + let expected = null; if (node.type === "IfStatement" && node.consequent === body && requiresBraceOfConsequent(node)) { expected = true; @@ -230,11 +230,11 @@ module.exports = { /** * Prepares to check the bodies of a "if", "else if" and "else" chain. * @param {ASTNode} node The first IfStatement node of the chain. - * @returns {object[]} prepared checks for each body of the chain. See `prepareCheck` for more + * @returns {Object[]} prepared checks for each body of the chain. See `prepareCheck` for more * information. */ function prepareIfChecks(node) { - var preparedChecks = []; + let preparedChecks = []; do { preparedChecks.push(prepareCheck(node, node.consequent, "if", "condition")); @@ -252,7 +252,7 @@ module.exports = { * all have braces. * If all nodes shouldn't have braces, make sure they don't. */ - var expected = preparedChecks.some(function(preparedCheck) { + let expected = preparedChecks.some(function(preparedCheck) { if (preparedCheck.expected !== null) { return preparedCheck.expected; } diff --git a/tools/eslint/lib/rules/default-case.js b/tools/eslint/lib/rules/default-case.js index ae70a59284fb4a..9bcb1c065b8c49 100644 --- a/tools/eslint/lib/rules/default-case.js +++ b/tools/eslint/lib/rules/default-case.js @@ -4,7 +4,7 @@ */ "use strict"; -var DEFAULT_COMMENT_PATTERN = /^no default$/; +let DEFAULT_COMMENT_PATTERN = /^no default$/; //------------------------------------------------------------------------------ // Rule Definition @@ -30,12 +30,12 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; - var commentPattern = options.commentPattern ? + let options = context.options[0] || {}; + let commentPattern = options.commentPattern ? new RegExp(options.commentPattern) : DEFAULT_COMMENT_PATTERN; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers @@ -67,16 +67,16 @@ module.exports = { return; } - var hasDefault = node.cases.some(function(v) { + let hasDefault = node.cases.some(function(v) { return v.test === null; }); if (!hasDefault) { - var comment; - var comments; + let comment; + let comments; - var lastCase = last(node.cases); + let lastCase = last(node.cases); comments = sourceCode.getComments(lastCase).trailing; diff --git a/tools/eslint/lib/rules/dot-location.js b/tools/eslint/lib/rules/dot-location.js index 2b29e0f49bf285..5a5ad353bfd4ff 100644 --- a/tools/eslint/lib/rules/dot-location.js +++ b/tools/eslint/lib/rules/dot-location.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -28,12 +28,12 @@ module.exports = { create: function(context) { - var config = context.options[0]; + let config = context.options[0]; // default to onObject if no preference is passed - var onObject = config === "object" || !config; + let onObject = config === "object" || !config; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Reports if the dot between object and property is on the correct loccation. @@ -43,7 +43,7 @@ module.exports = { * @returns {void} */ function checkDotLocation(obj, prop, node) { - var dot = sourceCode.getTokenBefore(prop); + let dot = sourceCode.getTokenBefore(prop); if (dot.type === "Punctuator" && dot.value === ".") { if (onObject) { diff --git a/tools/eslint/lib/rules/dot-notation.js b/tools/eslint/lib/rules/dot-notation.js index 07e0b0a8db82a7..e359b118ccbf46 100644 --- a/tools/eslint/lib/rules/dot-notation.js +++ b/tools/eslint/lib/rules/dot-notation.js @@ -8,8 +8,8 @@ // Rule Definition //------------------------------------------------------------------------------ -var validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/; -var keywords = require("../util/keywords"); +let validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/; +let keywords = require("../util/keywords"); module.exports = { meta: { @@ -36,10 +36,10 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; - var allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords; + let options = context.options[0] || {}; + let allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords; - var allowPattern; + let allowPattern; if (options.allowPattern) { allowPattern = new RegExp(options.allowPattern); diff --git a/tools/eslint/lib/rules/eol-last.js b/tools/eslint/lib/rules/eol-last.js index 60b070f1abe8a6..faa4521cf1265d 100644 --- a/tools/eslint/lib/rules/eol-last.js +++ b/tools/eslint/lib/rules/eol-last.js @@ -35,7 +35,7 @@ module.exports = { Program: function checkBadEOF(node) { - var sourceCode = context.getSourceCode(), + let sourceCode = context.getSourceCode(), src = sourceCode.getText(), location = {column: 1}, linebreakStyle = context.options[0] || "unix", diff --git a/tools/eslint/lib/rules/eqeqeq.js b/tools/eslint/lib/rules/eqeqeq.js index 441f5b751cf20d..124c9dd61a3e53 100644 --- a/tools/eslint/lib/rules/eqeqeq.js +++ b/tools/eslint/lib/rules/eqeqeq.js @@ -25,7 +25,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Checks if an expression is a typeof expression @@ -71,12 +71,12 @@ module.exports = { /** * Gets the location (line and column) of the binary expression's operator * @param {ASTNode} node The binary expression node to check - * @param {String} operator The operator to find + * @param {string} operator The operator to find * @returns {Object} { line, column } location of operator * @private */ function getOperatorLocation(node) { - var opToken = sourceCode.getTokenAfter(node.left); + let opToken = sourceCode.getTokenAfter(node.left); return {line: opToken.loc.start.line, column: opToken.loc.start.column}; } diff --git a/tools/eslint/lib/rules/func-names.js b/tools/eslint/lib/rules/func-names.js index 44b989b2c47116..12d8d34d5da3e3 100644 --- a/tools/eslint/lib/rules/func-names.js +++ b/tools/eslint/lib/rules/func-names.js @@ -5,6 +5,15 @@ "use strict"; +/** + * Checks whether or not a given variable is a function name. + * @param {escope.Variable} variable - A variable to check. + * @returns {boolean} `true` if the variable is a function name. + */ +function isFunctionName(variable) { + return variable && variable.defs[0].type === "FunctionName"; +} + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -25,7 +34,7 @@ module.exports = { }, create: function(context) { - var never = context.options[0] === "never"; + let never = context.options[0] === "never"; /** * Determines whether the current FunctionExpression node is a get, set, or @@ -33,7 +42,7 @@ module.exports = { * @returns {boolean} True if the node is a get, set, or shorthand method. */ function isObjectOrClassMethod() { - var parent = context.getAncestors().pop(); + let parent = context.getAncestors().pop(); return (parent.type === "MethodDefinition" || ( parent.type === "Property" && ( @@ -45,9 +54,16 @@ module.exports = { } return { - FunctionExpression: function(node) { + "FunctionExpression:exit": function(node) { + + // Skip recursive functions. + let nameVar = context.getDeclaredVariables(node)[0]; + + if (isFunctionName(nameVar) && nameVar.references.length > 0) { + return; + } - var name = node.id && node.id.name; + let name = node.id && node.id.name; if (never) { if (name) { diff --git a/tools/eslint/lib/rules/func-style.js b/tools/eslint/lib/rules/func-style.js index 9dad6c0755656d..e1cdc1d1bd199b 100644 --- a/tools/eslint/lib/rules/func-style.js +++ b/tools/eslint/lib/rules/func-style.js @@ -34,12 +34,12 @@ module.exports = { create: function(context) { - var style = context.options[0], + let style = context.options[0], allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions === true, enforceDeclarations = (style === "declaration"), stack = []; - var nodesToCheck = { + let nodesToCheck = { Program: function() { stack = []; }, @@ -79,7 +79,7 @@ module.exports = { }; nodesToCheck["ArrowFunctionExpression:exit"] = function(node) { - var hasThisExpr = stack.pop(); + let hasThisExpr = stack.pop(); if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") { context.report(node.parent, "Expected a function declaration."); diff --git a/tools/eslint/lib/rules/generator-star-spacing.js b/tools/eslint/lib/rules/generator-star-spacing.js index 0cab2be50eb9dc..e55fe9b512136c 100644 --- a/tools/eslint/lib/rules/generator-star-spacing.js +++ b/tools/eslint/lib/rules/generator-star-spacing.js @@ -40,7 +40,7 @@ module.exports = { create: function(context) { - var mode = (function(option) { + let mode = (function(option) { if (!option || typeof option === "string") { return { before: { before: true, after: false }, @@ -52,7 +52,7 @@ module.exports = { return option; }(context.options[0])); - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Gets `*` token from a given node. @@ -63,7 +63,7 @@ module.exports = { * @returns {Token} `*` token. */ function getStarToken(node) { - var token = sourceCode.getFirstToken(node); + let token = sourceCode.getFirstToken(node); while (token.value !== "*") { token = sourceCode.getTokenAfter(token); @@ -83,11 +83,11 @@ module.exports = { */ function checkSpacing(side, leftToken, rightToken) { if (!!(rightToken.range[0] - leftToken.range[1]) !== mode[side]) { - var after = leftToken.value === "*"; - var spaceRequired = mode[side]; - var node = after ? leftToken : rightToken; - var type = spaceRequired ? "Missing" : "Unexpected"; - var message = type + " space " + side + " *."; + let after = leftToken.value === "*"; + let spaceRequired = mode[side]; + let node = after ? leftToken : rightToken; + let type = spaceRequired ? "Missing" : "Unexpected"; + let message = type + " space " + side + " *."; context.report({ node: node, @@ -111,7 +111,7 @@ module.exports = { * @returns {void} */ function checkFunction(node) { - var prevToken, starToken, nextToken; + let prevToken, starToken, nextToken; if (!node.generator) { return; diff --git a/tools/eslint/lib/rules/global-require.js b/tools/eslint/lib/rules/global-require.js index d1298719a9a80d..0a104bc3493a0c 100644 --- a/tools/eslint/lib/rules/global-require.js +++ b/tools/eslint/lib/rules/global-require.js @@ -5,7 +5,7 @@ "use strict"; -var ACCEPTABLE_PARENTS = [ +let ACCEPTABLE_PARENTS = [ "AssignmentExpression", "VariableDeclarator", "MemberExpression", @@ -23,7 +23,7 @@ var ACCEPTABLE_PARENTS = [ * @returns {Reference|null} Returns the found reference or null if none were found. */ function findReference(scope, node) { - var references = scope.references.filter(function(reference) { + let references = scope.references.filter(function(reference) { return reference.identifier.range[0] === node.range[0] && reference.identifier.range[1] === node.range[1]; }); @@ -43,7 +43,7 @@ function findReference(scope, node) { * @returns {boolean} Whether or not the name is shadowed. */ function isShadowed(scope, node) { - var reference = findReference(scope, node); + let reference = findReference(scope, node); return reference && reference.resolved && reference.resolved.defs.length > 0; } @@ -62,7 +62,7 @@ module.exports = { create: function(context) { return { CallExpression: function(node) { - var currentScope = context.getScope(), + let currentScope = context.getScope(), isGoodRequire; if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) { diff --git a/tools/eslint/lib/rules/guard-for-in.js b/tools/eslint/lib/rules/guard-for-in.js index b43dda39e46968..7e4dfbc43e3087 100644 --- a/tools/eslint/lib/rules/guard-for-in.js +++ b/tools/eslint/lib/rules/guard-for-in.js @@ -30,7 +30,7 @@ module.exports = { * If the for-in statement has {}, then the real body is the body * of the BlockStatement. Otherwise, just use body as provided. */ - var body = node.body.type === "BlockStatement" ? node.body.body[0] : node.body; + let body = node.body.type === "BlockStatement" ? node.body.body[0] : node.body; if (body && body.type !== "IfStatement") { context.report(node, "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype."); diff --git a/tools/eslint/lib/rules/handle-callback-err.js b/tools/eslint/lib/rules/handle-callback-err.js index 09bf0da9771428..836d3a6de761e3 100644 --- a/tools/eslint/lib/rules/handle-callback-err.js +++ b/tools/eslint/lib/rules/handle-callback-err.js @@ -26,7 +26,7 @@ module.exports = { create: function(context) { - var errorArgument = context.options[0] || "err"; + let errorArgument = context.options[0] || "err"; /** * Checks if the given argument should be interpreted as a regexp pattern. @@ -34,7 +34,7 @@ module.exports = { * @returns {boolean} Whether or not the string should be interpreted as a pattern. */ function isPattern(stringToCheck) { - var firstChar = stringToCheck[0]; + let firstChar = stringToCheck[0]; return firstChar === "^"; } @@ -46,7 +46,7 @@ module.exports = { */ function matchesConfiguredErrorName(name) { if (isPattern(errorArgument)) { - var regexp = new RegExp(errorArgument); + let regexp = new RegExp(errorArgument); return regexp.test(name); } @@ -55,7 +55,7 @@ module.exports = { /** * Get the parameters of a given function scope. - * @param {object} scope The function scope. + * @param {Object} scope The function scope. * @returns {array} All parameters of the given scope. */ function getParameters(scope) { @@ -70,7 +70,7 @@ module.exports = { * @returns {void} */ function checkForError(node) { - var scope = context.getScope(), + let scope = context.getScope(), parameters = getParameters(scope), firstParameter = parameters[0]; diff --git a/tools/eslint/lib/rules/id-blacklist.js b/tools/eslint/lib/rules/id-blacklist.js index 142d8d21f4bc63..d2be0d12c3064d 100644 --- a/tools/eslint/lib/rules/id-blacklist.js +++ b/tools/eslint/lib/rules/id-blacklist.js @@ -34,12 +34,12 @@ module.exports = { // Helpers //-------------------------------------------------------------------------- - var blacklist = context.options; + let blacklist = context.options; /** * Checks if a string matches the provided pattern - * @param {String} name The string to check. + * @param {string} name The string to check. * @returns {boolean} if the string is a match * @private */ @@ -51,7 +51,7 @@ module.exports = { * Verifies if we should report an error or not based on the effective * parent node and the identifier name. * @param {ASTNode} effectiveParent The effective parent node of the node to be reported - * @param {String} name The identifier name of the identifier node + * @param {string} name The identifier name of the identifier node * @returns {boolean} whether an error should be reported or not */ function shouldReport(effectiveParent, name) { @@ -67,7 +67,7 @@ module.exports = { * @private */ function report(node) { - context.report(node, "Identifier '{{name}}' is blacklisted", { + context.report(node, "Identifier '{{name}}' is blacklisted.", { name: node.name }); } @@ -75,7 +75,7 @@ module.exports = { return { Identifier: function(node) { - var name = node.name, + let name = node.name, effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; // MemberExpressions get special rules diff --git a/tools/eslint/lib/rules/id-length.js b/tools/eslint/lib/rules/id-length.js index 43437513acb480..d337cdaccef7e3 100644 --- a/tools/eslint/lib/rules/id-length.js +++ b/tools/eslint/lib/rules/id-length.js @@ -45,18 +45,18 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; - var minLength = typeof options.min !== "undefined" ? options.min : 2; - var maxLength = typeof options.max !== "undefined" ? options.max : Infinity; - var properties = options.properties !== "never"; - var exceptions = (options.exceptions ? options.exceptions : []) + let options = context.options[0] || {}; + let minLength = typeof options.min !== "undefined" ? options.min : 2; + let maxLength = typeof options.max !== "undefined" ? options.max : Infinity; + let properties = options.properties !== "never"; + let exceptions = (options.exceptions ? options.exceptions : []) .reduce(function(obj, item) { obj[item] = true; return obj; }, {}); - var SUPPORTED_EXPRESSIONS = { + let SUPPORTED_EXPRESSIONS = { MemberExpression: properties && function(parent) { return !parent.computed && ( @@ -87,24 +87,24 @@ module.exports = { return { Identifier: function(node) { - var name = node.name; - var parent = node.parent; + let name = node.name; + let parent = node.parent; - var isShort = name.length < minLength; - var isLong = name.length > maxLength; + let isShort = name.length < minLength; + let isLong = name.length > maxLength; if (!(isShort || isLong) || exceptions[name]) { return; // Nothing to report } - var isValidExpression = SUPPORTED_EXPRESSIONS[parent.type]; + let isValidExpression = SUPPORTED_EXPRESSIONS[parent.type]; if (isValidExpression && (isValidExpression === true || isValidExpression(parent, node))) { context.report( node, isShort ? - "Identifier name '{{name}}' is too short. (< {{min}})" : - "Identifier name '{{name}}' is too long. (> {{max}})", + "Identifier name '{{name}}' is too short (< {{min}})." : + "Identifier name '{{name}}' is too long (> {{max}}).", { name: name, min: minLength, max: maxLength } ); } diff --git a/tools/eslint/lib/rules/id-match.js b/tools/eslint/lib/rules/id-match.js index 4c9f4351088c57..4128cbf3d1aaae 100644 --- a/tools/eslint/lib/rules/id-match.js +++ b/tools/eslint/lib/rules/id-match.js @@ -38,16 +38,16 @@ module.exports = { // Helpers //-------------------------------------------------------------------------- - var pattern = context.options[0] || "^.+$", + let pattern = context.options[0] || "^.+$", regexp = new RegExp(pattern); - var options = context.options[1] || {}, + let options = context.options[1] || {}, properties = !!options.properties, onlyDeclarations = !!options.onlyDeclarations; /** * Checks if a string matches the provided pattern - * @param {String} name The string to check. + * @param {string} name The string to check. * @returns {boolean} if the string is a match * @private */ @@ -59,7 +59,7 @@ module.exports = { * Verifies if we should report an error or not based on the effective * parent node and the identifier name. * @param {ASTNode} effectiveParent The effective parent node of the node to be reported - * @param {String} name The identifier name of the identifier node + * @param {string} name The identifier name of the identifier node * @returns {boolean} whether an error should be reported or not */ function shouldReport(effectiveParent, name) { @@ -84,7 +84,7 @@ module.exports = { return { Identifier: function(node) { - var name = node.name, + let name = node.name, parent = node.parent, effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent; @@ -122,7 +122,7 @@ module.exports = { } } else { - var isDeclaration = effectiveParent.type === "FunctionDeclaration" || effectiveParent.type === "VariableDeclarator"; + let isDeclaration = effectiveParent.type === "FunctionDeclaration" || effectiveParent.type === "VariableDeclarator"; if (onlyDeclarations && !isDeclaration) { return; diff --git a/tools/eslint/lib/rules/indent.js b/tools/eslint/lib/rules/indent.js index 3c0c9827d84859..b24f942d1aedac 100644 --- a/tools/eslint/lib/rules/indent.js +++ b/tools/eslint/lib/rules/indent.js @@ -11,8 +11,8 @@ //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ -var util = require("util"); -var lodash = require("lodash"); +let util = require("util"); +let lodash = require("lodash"); module.exports = { meta: { @@ -71,6 +71,10 @@ module.exports = { outerIIFEBody: { type: "integer", minimum: 0 + }, + MemberExpression: { + type: "integer", + minimum: 0 } }, additionalProperties: false @@ -80,12 +84,12 @@ module.exports = { create: function(context) { - var MESSAGE = "Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}."; - var DEFAULT_VARIABLE_INDENT = 1; + let MESSAGE = "Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}."; + let DEFAULT_VARIABLE_INDENT = 1; - var indentType = "space"; - var indentSize = 4; - var options = { + let indentType = "space"; + let indentSize = 4; + let options = { SwitchCase: 0, VariableDeclarator: { var: DEFAULT_VARIABLE_INDENT, @@ -95,7 +99,7 @@ module.exports = { outerIIFEBody: null }; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); if (context.options.length) { if (context.options[0] === "tab") { @@ -107,10 +111,10 @@ module.exports = { } if (context.options[1]) { - var opts = context.options[1]; + let opts = context.options[1]; options.SwitchCase = opts.SwitchCase || 0; - var variableDeclaratorRules = opts.VariableDeclarator; + let variableDeclaratorRules = opts.VariableDeclarator; if (typeof variableDeclaratorRules === "number") { options.VariableDeclarator = { @@ -125,15 +129,19 @@ module.exports = { if (typeof opts.outerIIFEBody === "number") { options.outerIIFEBody = opts.outerIIFEBody; } + + if (typeof opts.MemberExpression === "number") { + options.MemberExpression = opts.MemberExpression; + } } } - var indentPattern = { + let indentPattern = { normal: indentType === "space" ? /^ +/ : /^\t+/, excludeCommas: indentType === "space" ? /^[ ,]+/ : /^[\t,]+/ }; - var caseIndentStore = {}; + let caseIndentStore = {}; /** * Reports a given indent violation and properly pluralizes the message @@ -145,13 +153,13 @@ module.exports = { * @returns {void} */ function report(node, needed, gotten, loc, isLastNodeCheck) { - var msgContext = { + let msgContext = { needed: needed, type: indentType, characters: needed === 1 ? "character" : "characters", gotten: gotten }; - var indentChar = indentType === "space" ? " " : "\t"; + let indentChar = indentType === "space" ? " " : "\t"; /** * Responsible for fixing the indentation issue fix @@ -159,10 +167,10 @@ module.exports = { * @private */ function getFixerFunction() { - var rangeToFix = []; + let rangeToFix = []; if (needed > gotten) { - var spaces = "" + new Array(needed - gotten + 1).join(indentChar); // replace with repeat in future + let spaces = "" + new Array(needed - gotten + 1).join(indentChar); // replace with repeat in future if (isLastNodeCheck === true) { rangeToFix = [ @@ -224,10 +232,10 @@ module.exports = { * @returns {int} Indent */ function getNodeIndent(node, byLastLine, excludeCommas) { - var token = byLastLine ? sourceCode.getLastToken(node) : sourceCode.getFirstToken(node); - var src = sourceCode.getText(token, token.loc.start.column); - var regExp = excludeCommas ? indentPattern.excludeCommas : indentPattern.normal; - var indent = regExp.exec(src); + let token = byLastLine ? sourceCode.getLastToken(node) : sourceCode.getFirstToken(node); + let src = sourceCode.getText(token, token.loc.start.column); + let regExp = excludeCommas ? indentPattern.excludeCommas : indentPattern.normal; + let indent = regExp.exec(src); return indent ? indent[0].length : 0; } @@ -239,7 +247,7 @@ module.exports = { * @returns {boolean} true if its the first in the its start line */ function isNodeFirstInLine(node, byEndLocation) { - var firstToken = byEndLocation === true ? sourceCode.getLastToken(node, 1) : sourceCode.getTokenBefore(node), + let firstToken = byEndLocation === true ? sourceCode.getLastToken(node, 1) : sourceCode.getTokenBefore(node), startLine = byEndLocation === true ? node.loc.end.line : node.loc.start.line, endLine = firstToken ? firstToken.loc.end.line : -1; @@ -254,7 +262,7 @@ module.exports = { * @returns {void} */ function checkNodeIndent(node, indent, excludeCommas) { - var nodeIndent = getNodeIndent(node, false, excludeCommas); + let nodeIndent = getNodeIndent(node, false, excludeCommas); if ( node.type !== "ArrayExpression" && node.type !== "ObjectExpression" && @@ -274,7 +282,7 @@ module.exports = { function checkNodesIndent(nodes, indent, excludeCommas) { nodes.forEach(function(node) { if (node.type === "IfStatement" && node.alternate) { - var elseToken = sourceCode.getTokenBefore(node.alternate); + let elseToken = sourceCode.getTokenBefore(node.alternate); checkNodeIndent(elseToken, indent, excludeCommas); } @@ -289,8 +297,8 @@ module.exports = { * @returns {void} */ function checkLastNodeLineIndent(node, lastLineIndent) { - var lastToken = sourceCode.getLastToken(node); - var endIndent = getNodeIndent(lastToken, true); + let lastToken = sourceCode.getLastToken(node); + let endIndent = getNodeIndent(lastToken, true); if (endIndent !== lastLineIndent && isNodeFirstInLine(node, true)) { report( @@ -310,7 +318,7 @@ module.exports = { * @returns {void} */ function checkFirstNodeLineIndent(node, firstLineIndent) { - var startIndent = getNodeIndent(node, false); + let startIndent = getNodeIndent(node, false); if (startIndent !== firstLineIndent && isNodeFirstInLine(node)) { report( @@ -323,19 +331,40 @@ module.exports = { } /** - * Returns the VariableDeclarator based on the current node + * Returns a parent node of given node based on a specified type * if not present then return null * @param {ASTNode} node node to examine + * @param {string} type type that is being looked for * @returns {ASTNode|void} if found then node otherwise null */ - function getVariableDeclaratorNode(node) { - var parent = node.parent; + function getParentNodeByType(node, type) { + let parent = node.parent; - while (parent.type !== "VariableDeclarator" && parent.type !== "Program") { + while (parent.type !== type && parent.type !== "Program") { parent = parent.parent; } - return parent.type === "VariableDeclarator" ? parent : null; + return parent.type === type ? parent : null; + } + + /** + * Returns the VariableDeclarator based on the current node + * if not present then return null + * @param {ASTNode} node node to examine + * @returns {ASTNode|void} if found then node otherwise null + */ + function getVariableDeclaratorNode(node) { + return getParentNodeByType(node, "VariableDeclarator"); + } + + /** + * Returns the ExpressionStatement based on the current node + * if not present then return null + * @param {ASTNode} node node to examine + * @returns {ASTNode|void} if found then node otherwise null + */ + function getAssignmentExpressionNode(node) { + return getParentNodeByType(node, "AssignmentExpression"); } /** @@ -358,7 +387,7 @@ module.exports = { * @returns {boolean} True if arguments are multi-line */ function isArgBeforeCalleeNodeMultiline(node) { - var parent = node.parent; + let parent = node.parent; if (parent.arguments.length >= 2 && parent.arguments[1] === node) { return parent.arguments[0].loc.end.line > parent.arguments[0].loc.start.line; @@ -367,19 +396,46 @@ module.exports = { return false; } - /** + /** * Check to see if the node is a file level IIFE * @param {ASTNode} node The function node to check. * @returns {boolean} True if the node is the outer IIFE */ function isOuterIIFE(node) { - var parent = node.parent; + let parent = node.parent; + let stmt = parent.parent; - return ( - parent.type === "CallExpression" && - parent.callee === node && - parent.parent.type === "ExpressionStatement" && - parent.parent.parent && parent.parent.parent.type === "Program" + /* + * Verify that the node is an IIEF + */ + if ( + parent.type !== "CallExpression" || + parent.callee !== node) { + + return false; + } + + /* + * Navigate legal ancestors to determine whether this IIEF is outer + */ + while ( + stmt.type === "UnaryExpression" && ( + stmt.operator === "!" || + stmt.operator === "~" || + stmt.operator === "+" || + stmt.operator === "-") || + stmt.type === "AssignmentExpression" || + stmt.type === "LogicalExpression" || + stmt.type === "SequenceExpression" || + stmt.type === "VariableDeclarator") { + + stmt = stmt.parent; + } + + return (( + stmt.type === "ExpressionStatement" || + stmt.type === "VariableDeclaration") && + stmt.parent && stmt.parent.type === "Program" ); } @@ -403,8 +459,8 @@ module.exports = { * * Looks for 'Models' */ - var calleeNode = node.parent; // FunctionExpression - var indent; + let calleeNode = node.parent; // FunctionExpression + let indent; if (calleeNode.parent && (calleeNode.parent.type === "Property" || @@ -419,7 +475,7 @@ module.exports = { } if (calleeNode.parent.type === "CallExpression") { - var calleeParent = calleeNode.parent; + let calleeParent = calleeNode.parent; if (calleeNode.type !== "FunctionExpression" && calleeNode.type !== "ArrowFunctionExpression") { if (calleeParent && calleeParent.loc.start.line < node.loc.start.line) { @@ -436,7 +492,7 @@ module.exports = { // function body indent should be indent + indent size, unless this // is the outer IIFE and that option is enabled. - var functionOffset = indentSize; + let functionOffset = indentSize; if (options.outerIIFEBody !== null && isOuterIIFE(calleeNode)) { functionOffset = options.outerIIFEBody * indentSize; @@ -444,7 +500,7 @@ module.exports = { indent += functionOffset; // check if the node is inside a variable - var parentVarNode = getVariableDeclaratorNode(node); + let parentVarNode = getVariableDeclaratorNode(node); if (parentVarNode && isNodeInVarOnTop(node, parentVarNode)) { indent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; @@ -464,7 +520,7 @@ module.exports = { * @returns {boolean} Whether or not the block starts and ends on the same line. */ function isSingleLineNode(node) { - var lastToken = sourceCode.getLastToken(node), + let lastToken = sourceCode.getLastToken(node), startLine = node.loc.start.line, endLine = lastToken.loc.end.line; @@ -497,7 +553,7 @@ module.exports = { return; } - var elements = (node.type === "ArrayExpression") ? node.elements : node.properties; + let elements = (node.type === "ArrayExpression") ? node.elements : node.properties; // filter out empty elements example would be [ , 2] so remove first element as espree considers it as null elements = elements.filter(function(elem) { @@ -509,14 +565,14 @@ module.exports = { return; } - var nodeIndent; - var elementsIndent; - var parentVarNode = getVariableDeclaratorNode(node); + let nodeIndent; + let elementsIndent; + let parentVarNode = getVariableDeclaratorNode(node); // TODO - come up with a better strategy in future if (isNodeFirstInLine(node)) { - var parent = node.parent; - var effectiveParent = parent; + let parent = node.parent; + let effectiveParent = parent; if (parent.type === "MemberExpression") { if (isNodeFirstInLine(parent)) { @@ -605,14 +661,14 @@ module.exports = { return; } - var indent; - var nodesToCheck = []; + let indent; + let nodesToCheck = []; /* * For this statements we should check indent from statement beginning, * not from the beginning of the block. */ - var statementsWithProperties = [ + let statementsWithProperties = [ "IfStatement", "WhileStatement", "ForStatement", "ForInStatement", "ForOfStatement", "DoWhileStatement", "ClassDeclaration" ]; @@ -647,7 +703,7 @@ module.exports = { */ function filterOutSameLineVars(node) { return node.declarations.reduce(function(finalCollection, elem) { - var lastElem = finalCollection[finalCollection.length - 1]; + let lastElem = finalCollection[finalCollection.length - 1]; if ((elem.loc.start.line !== node.loc.start.line && !lastElem) || (lastElem && lastElem.loc.start.line !== elem.loc.start.line)) { @@ -664,11 +720,11 @@ module.exports = { * @returns {void} */ function checkIndentInVariableDeclarations(node) { - var elements = filterOutSameLineVars(node); - var nodeIndent = getNodeIndent(node); - var lastElement = elements[elements.length - 1]; + let elements = filterOutSameLineVars(node); + let nodeIndent = getNodeIndent(node); + let lastElement = elements[elements.length - 1]; - var elementsIndent = nodeIndent + indentSize * options.VariableDeclarator[node.kind]; + let elementsIndent = nodeIndent + indentSize * options.VariableDeclarator[node.kind]; // Comma can be placed before declaration checkNodesIndent(elements, elementsIndent, true); @@ -678,7 +734,7 @@ module.exports = { return; } - var tokenBeforeLastElement = sourceCode.getTokenBefore(lastElement); + let tokenBeforeLastElement = sourceCode.getTokenBefore(lastElement); if (tokenBeforeLastElement.value === ",") { @@ -708,8 +764,8 @@ module.exports = { * @returns {int} indent size */ function expectedCaseIndent(node, switchIndent) { - var switchNode = (node.type === "SwitchStatement") ? node : node.parent; - var caseIndent; + let switchNode = (node.type === "SwitchStatement") ? node : node.parent; + let caseIndent; if (caseIndentStore[switchNode.loc.start.line]) { return caseIndentStore[switchNode.loc.start.line]; @@ -772,11 +828,45 @@ module.exports = { checkIndentInArrayOrObjectBlock(node); }, + MemberExpression: function(node) { + if (typeof options.MemberExpression === "undefined") { + return; + } + + if (isSingleLineNode(node)) { + return; + } + + // The typical layout of variable declarations and assignments + // alter the expectation of correct indentation. Skip them. + // TODO: Add appropriate configuration options for variable + // declarations and assignments. + if (getVariableDeclaratorNode(node)) { + return; + } + + if (getAssignmentExpressionNode(node)) { + return; + } + + let propertyIndent = getNodeIndent(node) + indentSize * options.MemberExpression; + + let checkNodes = [node.property]; + + let dot = context.getTokenBefore(node.property); + + if (dot.type === "Punctuator" && dot.value === ".") { + checkNodes.push(dot); + } + + checkNodesIndent(checkNodes, propertyIndent); + }, + SwitchStatement: function(node) { // Switch is not a 'BlockStatement' - var switchIndent = getNodeIndent(node); - var caseIndent = expectedCaseIndent(node, switchIndent); + let switchIndent = getNodeIndent(node); + let caseIndent = expectedCaseIndent(node, switchIndent); checkNodesIndent(node.cases, caseIndent); @@ -790,7 +880,7 @@ module.exports = { if (isSingleLineNode(node)) { return; } - var caseIndent = expectedCaseIndent(node); + let caseIndent = expectedCaseIndent(node); checkNodesIndent(node.consequent, caseIndent + indentSize); } diff --git a/tools/eslint/lib/rules/init-declarations.js b/tools/eslint/lib/rules/init-declarations.js index 66b0a0aea43c1a..e51596f7af5bfd 100644 --- a/tools/eslint/lib/rules/init-declarations.js +++ b/tools/eslint/lib/rules/init-declarations.js @@ -26,8 +26,8 @@ function isForLoop(block) { * @returns {boolean} `true` when the node has its initializer. */ function isInitialized(node) { - var declaration = node.parent; - var block = declaration.parent; + let declaration = node.parent; + let block = declaration.parent; if (isForLoop(block)) { if (block.type === "ForStatement") { @@ -87,11 +87,11 @@ module.exports = { create: function(context) { - var MODE_ALWAYS = "always", + let MODE_ALWAYS = "always", MODE_NEVER = "never"; - var mode = context.options[0] || MODE_ALWAYS; - var params = context.options[1] || {}; + let mode = context.options[0] || MODE_ALWAYS; + let params = context.options[1] || {}; //-------------------------------------------------------------------------- // Public API @@ -100,11 +100,11 @@ module.exports = { return { "VariableDeclaration:exit": function(node) { - var kind = node.kind, + let kind = node.kind, declarations = node.declarations; - for (var i = 0; i < declarations.length; ++i) { - var declaration = declarations[i], + for (let i = 0; i < declarations.length; ++i) { + let declaration = declarations[i], id = declaration.id, initialized = isInitialized(declaration), isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent); diff --git a/tools/eslint/lib/rules/jsx-quotes.js b/tools/eslint/lib/rules/jsx-quotes.js index 6b3a2efef7143c..c3d87623cdfec2 100644 --- a/tools/eslint/lib/rules/jsx-quotes.js +++ b/tools/eslint/lib/rules/jsx-quotes.js @@ -9,13 +9,13 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ -var QUOTE_SETTINGS = { +let QUOTE_SETTINGS = { "prefer-double": { quote: "\"", description: "singlequote", @@ -54,7 +54,7 @@ module.exports = { }, create: function(context) { - var quoteOption = context.options[0] || "prefer-double", + let quoteOption = context.options[0] || "prefer-double", setting = QUOTE_SETTINGS[quoteOption]; /** @@ -69,7 +69,7 @@ module.exports = { return { JSXAttribute: function(node) { - var attributeValue = node.value; + let attributeValue = node.value; if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) { context.report({ diff --git a/tools/eslint/lib/rules/key-spacing.js b/tools/eslint/lib/rules/key-spacing.js index 1cf677865d2281..25aba47ba00a42 100644 --- a/tools/eslint/lib/rules/key-spacing.js +++ b/tools/eslint/lib/rules/key-spacing.js @@ -34,7 +34,7 @@ function last(arr) { * @returns {boolean} True if the candidate property is part of the group. */ function continuesPropertyGroup(lastMember, candidate) { - var groupEndLine = lastMember.loc.start.line, + let groupEndLine = lastMember.loc.start.line, candidateStartLine = candidate.loc.start.line, comments, i; @@ -71,19 +71,15 @@ function isSingleLine(node) { return (node.loc.end.line === node.loc.start.line); } -/** Sets option values from the configured options with defaults +/** + * Initializes a single option property from the configuration with defaults for undefined values * @param {Object} toOptions Object to be initialized * @param {Object} fromOptions Object to be initialized from * @returns {Object} The object with correctly initialized options and values */ -function initOptions(toOptions, fromOptions) { +function initOptionProperty(toOptions, fromOptions) { toOptions.mode = fromOptions.mode || "strict"; - // Set align if exists - multiLine case - if (typeof fromOptions.align !== "undefined") { - toOptions.align = fromOptions.align; - } - // Set value of beforeColon if (typeof fromOptions.beforeColon !== "undefined") { toOptions.beforeColon = +fromOptions.beforeColon; @@ -98,6 +94,55 @@ function initOptions(toOptions, fromOptions) { toOptions.afterColon = 1; } + // Set align if exists + if (typeof fromOptions.align !== "undefined") { + if (typeof fromOptions.align === "object") { + toOptions.align = fromOptions.align; + } else { // "string" + toOptions.align = { + on: fromOptions.align, + mode: toOptions.mode, + beforeColon: toOptions.beforeColon, + afterColon: toOptions.afterColon + }; + } + } + + return toOptions; +} + +/** + * Initializes all the option values (singleLine, multiLine and align) from the configuration with defaults for undefined values + * @param {Object} toOptions Object to be initialized + * @param {Object} fromOptions Object to be initialized from + * @returns {Object} The object with correctly initialized options and values + */ +function initOptions(toOptions, fromOptions) { + if (typeof fromOptions.align === "object") { + + // Initialize the alignment configuration + toOptions.align = initOptionProperty({}, fromOptions.align); + toOptions.align.on = fromOptions.align.on || "colon"; + toOptions.align.mode = fromOptions.align.mode || "strict"; + + toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); + toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); + + } else { // string or undefined + toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); + toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); + + // If alignment options are defined in multiLine, pull them out into the general align configuration + if (toOptions.multiLine.align) { + toOptions.align = { + on: toOptions.multiLine.align.on, + mode: toOptions.multiLine.mode, + beforeColon: toOptions.multiLine.align.beforeColon, + afterColon: toOptions.multiLine.align.afterColon + }; + } + } + return toOptions; } @@ -105,7 +150,7 @@ function initOptions(toOptions, fromOptions) { // Rule Definition //------------------------------------------------------------------------------ -var messages = { +let messages = { key: "{{error}} space after {{computed}}key '{{key}}'.", value: "{{error}} space before value for {{computed}}key '{{key}}'." }; @@ -126,7 +171,29 @@ module.exports = { type: "object", properties: { align: { - enum: ["colon", "value"] + anyOf: [ + { + enum: ["colon", "value"] + }, + { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + on: { + enum: ["colon", "value"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + ] }, mode: { enum: ["strict", "minimum"] @@ -162,7 +229,29 @@ module.exports = { type: "object", properties: { align: { - enum: ["colon", "value"] + anyOf: [ + { + enum: ["colon", "value"] + }, + { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + on: { + enum: ["colon", "value"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + ] }, mode: { enum: ["strict", "minimum"] @@ -178,6 +267,57 @@ module.exports = { } }, additionalProperties: false + }, + { + type: "object", + properties: { + singleLine: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + multiLine: { + type: "object", + properties: { + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + align: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + on: { + enum: ["colon", "value"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false } ] }] @@ -193,17 +333,18 @@ module.exports = { * align: "colon" // Optional, or "value" * } */ + let options = context.options[0] || {}, + ruleOptions = initOptions({}, options), + multiLineOptions = ruleOptions.multiLine, + singleLineOptions = ruleOptions.singleLine, + alignmentOptions = ruleOptions.align || null; - var options = context.options[0] || {}, - multiLineOptions = initOptions({}, (options.multiLine || options)), - singleLineOptions = initOptions({}, (options.singleLine || options)); - - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Determines if the given property is key-value property. * @param {ASTNode} property Property node to check. - * @returns {Boolean} Whether the property is a key-value property. + * @returns {boolean} Whether the property is a key-value property. */ function isKeyValueProperty(property) { return !( @@ -220,7 +361,7 @@ module.exports = { * @returns {ASTNode} The last token before a colon punctuator. */ function getLastTokenBeforeColon(node) { - var prevNode; + let prevNode; while (node && (node.type !== "Punctuator" || node.value !== ":")) { prevNode = node; @@ -251,7 +392,7 @@ module.exports = { * @returns {string} The property's key. */ function getKey(property) { - var key = property.key; + let key = property.key; if (property.computed) { return sourceCode.getText().slice(key.range[0], key.range[1]); @@ -271,7 +412,7 @@ module.exports = { * @returns {void} */ function report(property, side, whitespace, expected, mode) { - var diff = whitespace.length - expected, + let diff = whitespace.length - expected, nextColon = getNextColon(property.key), tokenBeforeColon = sourceCode.getTokenBefore(nextColon), tokenAfterColon = sourceCode.getTokenAfter(nextColon), @@ -335,7 +476,7 @@ module.exports = { * @returns {int} Width of the key. */ function getKeyWidth(property) { - var startToken, endToken; + let startToken, endToken; startToken = sourceCode.getFirstToken(property); endToken = getLastTokenBeforeColon(property.key); @@ -349,7 +490,7 @@ module.exports = { * @returns {Object} Whitespace before and after the property's colon. */ function getPropertyWhitespace(property) { - var whitespace = /(\s*):(\s*)/.exec(sourceCode.getText().slice( + let whitespace = /(\s*):(\s*)/.exec(sourceCode.getText().slice( property.key.range[1], property.value.range[0] )); @@ -373,7 +514,7 @@ module.exports = { } return node.properties.reduce(function(groups, property) { - var currentGroup = last(groups), + let currentGroup = last(groups), prev = last(currentGroup); if (!prev || continuesPropertyGroup(prev, property)) { @@ -394,14 +535,22 @@ module.exports = { * @returns {void} */ function verifyGroupAlignment(properties) { - var length = properties.length, + let length = properties.length, widths = properties.map(getKeyWidth), // Width of keys, including quotes targetWidth = Math.max.apply(null, widths), + align = alignmentOptions.on, // "value" or "colon" i, property, whitespace, width, - align = multiLineOptions.align, - beforeColon = multiLineOptions.beforeColon, - afterColon = multiLineOptions.afterColon, - mode = multiLineOptions.mode; + beforeColon, afterColon, mode; + + if (alignmentOptions && length > 1) { // When aligning values within a group, use the alignment configuration. + beforeColon = alignmentOptions.beforeColon; + afterColon = alignmentOptions.afterColon; + mode = alignmentOptions.mode; + } else { + beforeColon = multiLineOptions.beforeColon; + afterColon = multiLineOptions.afterColon; + mode = alignmentOptions.mode; + } // Conditionally include one space before or after colon targetWidth += (align === "colon" ? beforeColon : afterColon); @@ -441,7 +590,7 @@ module.exports = { * @returns {void} */ function verifySpacing(node, lineOptions) { - var actual = getPropertyWhitespace(node); + let actual = getPropertyWhitespace(node); if (actual) { // Object literal getters/setters lack colons report(node, "key", actual.beforeColon, lineOptions.beforeColon, lineOptions.mode); @@ -455,9 +604,9 @@ module.exports = { * @returns {void} */ function verifyListSpacing(properties) { - var length = properties.length; + let length = properties.length; - for (var i = 0; i < length; i++) { + for (let i = 0; i < length; i++) { verifySpacing(properties[i], singleLineOptions); } } @@ -466,7 +615,7 @@ module.exports = { // Public API //-------------------------------------------------------------------------- - if (multiLineOptions.align) { // Verify vertical alignment + if (alignmentOptions) { // Verify vertical alignment return { ObjectExpression: function(node) { diff --git a/tools/eslint/lib/rules/keyword-spacing.js b/tools/eslint/lib/rules/keyword-spacing.js index f771029a581d44..3c8d171ce868a6 100644 --- a/tools/eslint/lib/rules/keyword-spacing.js +++ b/tools/eslint/lib/rules/keyword-spacing.js @@ -9,26 +9,26 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"), +let astUtils = require("../ast-utils"), keywords = require("../util/keywords"); //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ -var PREV_TOKEN = /^[\)\]\}>]$/; -var NEXT_TOKEN = /^(?:[\(\[\{<~!]|\+\+?|--?)$/; -var PREV_TOKEN_M = /^[\)\]\}>*]$/; -var NEXT_TOKEN_M = /^[\{*]$/; -var TEMPLATE_OPEN_PAREN = /\$\{$/; -var TEMPLATE_CLOSE_PAREN = /^\}/; -var CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template)$/; -var KEYS = keywords.concat(["as", "await", "from", "get", "let", "of", "set", "yield"]); +let PREV_TOKEN = /^[\)\]\}>]$/; +let NEXT_TOKEN = /^(?:[\(\[\{<~!]|\+\+?|--?)$/; +let PREV_TOKEN_M = /^[\)\]\}>*]$/; +let NEXT_TOKEN_M = /^[\{*]$/; +let TEMPLATE_OPEN_PAREN = /\$\{$/; +let TEMPLATE_CLOSE_PAREN = /^\}/; +let CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template)$/; +let KEYS = keywords.concat(["as", "await", "from", "get", "let", "of", "set", "yield"]); // check duplications. (function() { KEYS.sort(); - for (var i = 1; i < KEYS.length; ++i) { + for (let i = 1; i < KEYS.length; ++i) { if (KEYS[i] === KEYS[i - 1]) { throw new Error("Duplication was found in the keyword list: " + KEYS[i]); } @@ -101,7 +101,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Reports a given token if there are not space(s) before the token. @@ -114,7 +114,7 @@ module.exports = { function expectSpaceBefore(token, pattern) { pattern = pattern || PREV_TOKEN; - var prevToken = sourceCode.getTokenBefore(token); + let prevToken = sourceCode.getTokenBefore(token); if (prevToken && (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && @@ -144,7 +144,7 @@ module.exports = { function unexpectSpaceBefore(token, pattern) { pattern = pattern || PREV_TOKEN; - var prevToken = sourceCode.getTokenBefore(token); + let prevToken = sourceCode.getTokenBefore(token); if (prevToken && (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && @@ -174,7 +174,7 @@ module.exports = { function expectSpaceAfter(token, pattern) { pattern = pattern || NEXT_TOKEN; - var nextToken = sourceCode.getTokenAfter(token); + let nextToken = sourceCode.getTokenAfter(token); if (nextToken && (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && @@ -204,7 +204,7 @@ module.exports = { function unexpectSpaceAfter(token, pattern) { pattern = pattern || NEXT_TOKEN; - var nextToken = sourceCode.getTokenAfter(token); + let nextToken = sourceCode.getTokenAfter(token); if (nextToken && (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && @@ -226,28 +226,28 @@ module.exports = { /** * Parses the option object and determines check methods for each keyword. * - * @param {object|undefined} options - The option object to parse. - * @returns {object} - Normalized option object. + * @param {Object|undefined} options - The option object to parse. + * @returns {Object} - Normalized option object. * Keys are keywords (there are for every keyword). * Values are instances of `{"before": function, "after": function}`. */ function parseOptions(options) { - var before = !options || options.before !== false; - var after = !options || options.after !== false; - var defaultValue = { + let before = !options || options.before !== false; + let after = !options || options.after !== false; + let defaultValue = { before: before ? expectSpaceBefore : unexpectSpaceBefore, after: after ? expectSpaceAfter : unexpectSpaceAfter }; - var overrides = (options && options.overrides) || {}; - var retv = Object.create(null); + let overrides = (options && options.overrides) || {}; + let retv = Object.create(null); - for (var i = 0; i < KEYS.length; ++i) { - var key = KEYS[i]; - var override = overrides[key]; + for (let i = 0; i < KEYS.length; ++i) { + let key = KEYS[i]; + let override = overrides[key]; if (override) { - var thisBefore = ("before" in override) ? override.before : before; - var thisAfter = ("after" in override) ? override.after : after; + let thisBefore = ("before" in override) ? override.before : before; + let thisAfter = ("after" in override) ? override.after : after; retv[key] = { before: thisBefore ? expectSpaceBefore : unexpectSpaceBefore, @@ -261,7 +261,7 @@ module.exports = { return retv; } - var checkMethodMap = parseOptions(context.options[0]); + let checkMethodMap = parseOptions(context.options[0]); /** * Reports a given token if usage of spacing followed by the token is @@ -308,7 +308,7 @@ module.exports = { * @returns {void} */ function checkSpacingAroundFirstToken(node) { - var firstToken = node && sourceCode.getFirstToken(node); + let firstToken = node && sourceCode.getFirstToken(node); if (firstToken && firstToken.type === "Keyword") { checkSpacingAround(firstToken); @@ -326,7 +326,7 @@ module.exports = { * @returns {void} */ function checkSpacingBeforeFirstToken(node) { - var firstToken = node && sourceCode.getFirstToken(node); + let firstToken = node && sourceCode.getFirstToken(node); if (firstToken && firstToken.type === "Keyword") { checkSpacingBefore(firstToken); @@ -342,7 +342,7 @@ module.exports = { */ function checkSpacingAroundTokenBefore(node) { if (node) { - var token = sourceCode.getTokenBefore(node); + let token = sourceCode.getTokenBefore(node); while (token.type !== "Keyword") { token = sourceCode.getTokenBefore(token); @@ -424,7 +424,7 @@ module.exports = { checkSpacingAroundFirstToken(node); // `of` is not a keyword token. - var token = sourceCode.getTokenBefore(node.right); + let token = sourceCode.getTokenBefore(node.right); while (token.value !== "of") { token = sourceCode.getTokenBefore(token); @@ -445,13 +445,13 @@ module.exports = { * @returns {void} */ function checkSpacingForModuleDeclaration(node) { - var firstToken = sourceCode.getFirstToken(node); + let firstToken = sourceCode.getFirstToken(node); checkSpacingBefore(firstToken, PREV_TOKEN_M); checkSpacingAfter(firstToken, NEXT_TOKEN_M); if (node.source) { - var fromToken = sourceCode.getTokenBefore(node.source); + let fromToken = sourceCode.getTokenBefore(node.source); checkSpacingBefore(fromToken, PREV_TOKEN_M); checkSpacingAfter(fromToken, NEXT_TOKEN_M); @@ -466,7 +466,7 @@ module.exports = { * @returns {void} */ function checkSpacingForImportNamespaceSpecifier(node) { - var asToken = sourceCode.getFirstToken(node, 1); + let asToken = sourceCode.getFirstToken(node, 1); checkSpacingBefore(asToken, PREV_TOKEN_M); } @@ -483,7 +483,7 @@ module.exports = { checkSpacingAroundFirstToken(node); } if (node.kind === "get" || node.kind === "set") { - var token = sourceCode.getFirstToken( + let token = sourceCode.getFirstToken( node, node.static ? 1 : 0 ); diff --git a/tools/eslint/lib/rules/linebreak-style.js b/tools/eslint/lib/rules/linebreak-style.js index 5e6b819f3fe616..a8a5e4ed88483e 100644 --- a/tools/eslint/lib/rules/linebreak-style.js +++ b/tools/eslint/lib/rules/linebreak-style.js @@ -28,10 +28,10 @@ module.exports = { create: function(context) { - var EXPECTED_LF_MSG = "Expected linebreaks to be 'LF' but found 'CRLF'.", + let EXPECTED_LF_MSG = "Expected linebreaks to be 'LF' but found 'CRLF'.", EXPECTED_CRLF_MSG = "Expected linebreaks to be 'CRLF' but found 'LF'."; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers @@ -41,7 +41,7 @@ module.exports = { * Builds a fix function that replaces text at the specified range in the source text. * @param {int[]} range The range to replace * @param {string} text The text to insert. - * @returns {function} Fixer function + * @returns {Function} Fixer function * @private */ function createFix(range, text) { @@ -56,7 +56,7 @@ module.exports = { return { Program: function checkForlinebreakStyle(node) { - var linebreakStyle = context.options[0] || "unix", + let linebreakStyle = context.options[0] || "unix", expectedLF = linebreakStyle === "unix", expectedLFChars = expectedLF ? "\n" : "\r\n", source = sourceCode.getText(), @@ -65,7 +65,7 @@ module.exports = { index, range; - var i = 0; + let i = 0; while ((match = pattern.exec(source)) !== null) { i++; diff --git a/tools/eslint/lib/rules/lines-around-comment.js b/tools/eslint/lib/rules/lines-around-comment.js index a227fe4184f995..70775b42132fca 100644 --- a/tools/eslint/lib/rules/lines-around-comment.js +++ b/tools/eslint/lib/rules/lines-around-comment.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"), +let lodash = require("lodash"), astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ @@ -21,7 +21,7 @@ var lodash = require("lodash"), * @returns {Array} An array of line numbers. */ function getEmptyLineNums(lines) { - var emptyLines = lines.map(function(line, i) { + let emptyLines = lines.map(function(line, i) { return { code: line.trim(), num: i + 1 @@ -41,11 +41,11 @@ function getEmptyLineNums(lines) { * @returns {Array} An array of line numbers. */ function getCommentLineNums(comments) { - var lines = []; + let lines = []; comments.forEach(function(token) { - var start = token.loc.start.line; - var end = token.loc.end.line; + let start = token.loc.start.line; + let end = token.loc.end.line; lines.push(start, end); }); @@ -108,7 +108,7 @@ module.exports = { create: function(context) { - var options = context.options[0] ? lodash.assign({}, context.options[0]) : {}; + let options = context.options[0] ? lodash.assign({}, context.options[0]) : {}; options.beforeLineComment = options.beforeLineComment || false; options.afterLineComment = options.afterLineComment || false; @@ -117,9 +117,9 @@ module.exports = { options.allowBlockStart = options.allowBlockStart || false; options.allowBlockEnd = options.allowBlockEnd || false; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); - var lines = sourceCode.lines, + let lines = sourceCode.lines, numLines = lines.length + 1, comments = sourceCode.getAllComments(), commentLines = getCommentLineNums(comments), @@ -141,7 +141,7 @@ module.exports = { * @returns {boolean} True if the comment is not alone. */ function codeAroundComment(node) { - var token; + let token; token = node; do { @@ -184,8 +184,8 @@ module.exports = { * @returns {boolean} True if the comment is at parent start. */ function isCommentAtParentStart(node, nodeType) { - var ancestors = context.getAncestors(); - var parent; + let ancestors = context.getAncestors(); + let parent; if (ancestors.length) { parent = ancestors.pop(); @@ -202,8 +202,8 @@ module.exports = { * @returns {boolean} True if the comment is at parent end. */ function isCommentAtParentEnd(node, nodeType) { - var ancestors = context.getAncestors(); - var parent; + let ancestors = context.getAncestors(); + let parent; if (ancestors.length) { parent = ancestors.pop(); @@ -271,27 +271,27 @@ module.exports = { * Checks if a comment node has lines around it (ignores inline comments) * @param {ASTNode} node The Comment node. * @param {Object} opts Options to determine the newline. - * @param {Boolean} opts.after Should have a newline after this line. - * @param {Boolean} opts.before Should have a newline before this line. + * @param {boolean} opts.after Should have a newline after this line. + * @param {boolean} opts.before Should have a newline before this line. * @returns {void} */ function checkForEmptyLine(node, opts) { - var after = opts.after, + let after = opts.after, before = opts.before; - var prevLineNum = node.loc.start.line - 1, + let prevLineNum = node.loc.start.line - 1, nextLineNum = node.loc.end.line + 1, commentIsNotAlone = codeAroundComment(node); - var blockStartAllowed = options.allowBlockStart && isCommentAtBlockStart(node), + let blockStartAllowed = options.allowBlockStart && isCommentAtBlockStart(node), blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(node), objectStartAllowed = options.allowObjectStart && isCommentAtObjectStart(node), objectEndAllowed = options.allowObjectEnd && isCommentAtObjectEnd(node), arrayStartAllowed = options.allowArrayStart && isCommentAtArrayStart(node), arrayEndAllowed = options.allowArrayEnd && isCommentAtArrayEnd(node); - var exceptionStartAllowed = blockStartAllowed || objectStartAllowed || arrayStartAllowed; - var exceptionEndAllowed = blockEndAllowed || objectEndAllowed || arrayEndAllowed; + let exceptionStartAllowed = blockStartAllowed || objectStartAllowed || arrayStartAllowed; + let exceptionEndAllowed = blockEndAllowed || objectEndAllowed || arrayEndAllowed; // ignore top of the file and bottom of the file if (prevLineNum < 1) { @@ -306,14 +306,14 @@ module.exports = { return; } - var previousTokenOrComment = sourceCode.getTokenOrCommentBefore(node); - var nextTokenOrComment = sourceCode.getTokenOrCommentAfter(node); + let previousTokenOrComment = sourceCode.getTokenOrCommentBefore(node); + let nextTokenOrComment = sourceCode.getTokenOrCommentAfter(node); // check for newline before if (!exceptionStartAllowed && before && !lodash.includes(commentAndEmptyLines, prevLineNum) && !(isCommentNodeType(previousTokenOrComment) && astUtils.isTokenOnSameLine(previousTokenOrComment, node))) { - var lineStart = node.range[0] - node.loc.start.column; - var range = [lineStart, lineStart]; + let lineStart = node.range[0] - node.loc.start.column; + let range = [lineStart, lineStart]; context.report({ node: node, diff --git a/tools/eslint/lib/rules/max-depth.js b/tools/eslint/lib/rules/max-depth.js index 317f06c68f397a..dbc1f6d48c5de3 100644 --- a/tools/eslint/lib/rules/max-depth.js +++ b/tools/eslint/lib/rules/max-depth.js @@ -49,7 +49,7 @@ module.exports = { // Helpers //-------------------------------------------------------------------------- - var functionStack = [], + let functionStack = [], option = context.options[0], maxDepth = 4; @@ -88,7 +88,7 @@ module.exports = { * @private */ function pushBlock(node) { - var len = ++functionStack[functionStack.length - 1]; + let len = ++functionStack[functionStack.length - 1]; if (len > maxDepth) { context.report(node, "Blocks are nested too deeply ({{depth}}).", diff --git a/tools/eslint/lib/rules/max-len.js b/tools/eslint/lib/rules/max-len.js index b5813bbfaa77c8..1bb63990d80cdc 100644 --- a/tools/eslint/lib/rules/max-len.js +++ b/tools/eslint/lib/rules/max-len.js @@ -9,7 +9,7 @@ // Constants //------------------------------------------------------------------------------ -var OPTIONS_SCHEMA = { +let OPTIONS_SCHEMA = { type: "object", properties: { code: { @@ -40,7 +40,7 @@ var OPTIONS_SCHEMA = { additionalProperties: false }; -var OPTIONS_OR_INTEGER_SCHEMA = { +let OPTIONS_OR_INTEGER_SCHEMA = { anyOf: [ OPTIONS_SCHEMA, { @@ -79,9 +79,9 @@ module.exports = { * too many false positives * - We don't care about matching the entire URL, any small segment is fine */ - var URL_REGEXP = /[^:/?#]:\/\/[^?#]/; + let URL_REGEXP = /[^:/?#]:\/\/[^?#]/; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Computes the length of a line that may contain tabs. The width of each @@ -92,10 +92,10 @@ module.exports = { * @private */ function computeLineLength(line, tabWidth) { - var extraCharacterCount = 0; + let extraCharacterCount = 0; line.replace(/\t/g, function(match, offset) { - var totalOffset = offset + extraCharacterCount, + let totalOffset = offset + extraCharacterCount, previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0, spaceCount = tabWidth - previousTabStopOffset; @@ -105,8 +105,8 @@ module.exports = { } // The options object must be the last option specified… - var lastOption = context.options[context.options.length - 1]; - var options = typeof lastOption === "object" ? Object.create(lastOption) : {}; + let lastOption = context.options[context.options.length - 1]; + let options = typeof lastOption === "object" ? Object.create(lastOption) : {}; // …but max code length… if (typeof context.options[0] === "number") { @@ -118,7 +118,7 @@ module.exports = { options.tabWidth = context.options[1]; } - var maxLength = options.code || 80, + let maxLength = options.code || 80, tabWidth = options.tabWidth || 4, ignorePattern = options.ignorePattern || null, ignoreComments = options.ignoreComments || false, @@ -156,7 +156,7 @@ module.exports = { * @returns {boolean} If the comment covers the entire line */ function isFullLineComment(line, lineNumber, comment) { - var start = comment.loc.start, + let start = comment.loc.start, end = comment.loc.end, isFirstTokenOnLine = !line.slice(0, comment.loc.start.column).trim(); @@ -188,7 +188,7 @@ module.exports = { function checkProgramForMaxLength(node) { // split (honors line-ending) - var lines = sourceCode.lines, + let lines = sourceCode.lines, // list of comments to ignore comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? sourceCode.getAllComments() : [], @@ -199,23 +199,24 @@ module.exports = { lines.forEach(function(line, i) { // i is zero-indexed, line numbers are one-indexed - var lineNumber = i + 1; + let lineNumber = i + 1; /* * if we're checking comment length; we need to know whether this * line is a comment */ - var lineIsComment = false; + let lineIsComment = false; /* * We can short-circuit the comment checks if we're already out of * comments to check. */ if (commentsIndex < comments.length) { + let comment = null; // iterate over comments until we find one past the current line do { - var comment = comments[++commentsIndex]; + comment = comments[++commentsIndex]; } while (comment && comment.loc.start.line <= lineNumber); // and step back by one @@ -234,7 +235,7 @@ module.exports = { return; } - var lineLength = computeLineLength(line, tabWidth); + let lineLength = computeLineLength(line, tabWidth); if (lineIsComment && ignoreComments) { return; diff --git a/tools/eslint/lib/rules/max-lines.js b/tools/eslint/lib/rules/max-lines.js index 751310e81da42a..1e311eaffbc25a 100644 --- a/tools/eslint/lib/rules/max-lines.js +++ b/tools/eslint/lib/rules/max-lines.js @@ -8,8 +8,8 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"); -var astUtils = require("../ast-utils"); +let lodash = require("lodash"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -52,7 +52,7 @@ module.exports = { }, create: function(context) { - var option = context.options[0], + let option = context.options[0], max = 300; if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") { @@ -63,10 +63,10 @@ module.exports = { max = option; } - var skipComments = option && option.skipComments; - var skipBlankLines = option && option.skipBlankLines; + let skipComments = option && option.skipComments; + let skipBlankLines = option && option.skipBlankLines; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Returns whether or not a token is a comment node type @@ -83,10 +83,10 @@ module.exports = { * @returns {int[]} The line numbers */ function getLinesWithoutCode(comment) { - var start = comment.loc.start.line; - var end = comment.loc.end.line; + let start = comment.loc.start.line; + let end = comment.loc.end.line; - var token; + let token; token = comment; do { @@ -114,7 +114,7 @@ module.exports = { return { "Program:exit": function() { - var lines = sourceCode.lines.map(function(text, i) { + let lines = sourceCode.lines.map(function(text, i) { return { lineNumber: i + 1, text: text }; }); @@ -125,9 +125,9 @@ module.exports = { } if (skipComments) { - var comments = sourceCode.getAllComments(); + let comments = sourceCode.getAllComments(); - var commentLines = lodash.flatten(comments.map(function(comment) { + let commentLines = lodash.flatten(comments.map(function(comment) { return getLinesWithoutCode(comment); })); @@ -139,7 +139,7 @@ module.exports = { if (lines.length > max) { context.report({ loc: { line: 1, column: 0 }, - message: "File must be at most " + max + " lines long" + message: "File must be at most " + max + " lines long." }); } } diff --git a/tools/eslint/lib/rules/max-nested-callbacks.js b/tools/eslint/lib/rules/max-nested-callbacks.js index 06554127c63242..a1145c1f1a6834 100644 --- a/tools/eslint/lib/rules/max-nested-callbacks.js +++ b/tools/eslint/lib/rules/max-nested-callbacks.js @@ -48,7 +48,7 @@ module.exports = { //-------------------------------------------------------------------------- // Constants //-------------------------------------------------------------------------- - var option = context.options[0], + let option = context.options[0], THRESHOLD = 10; if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") { @@ -65,7 +65,7 @@ module.exports = { // Helpers //-------------------------------------------------------------------------- - var callbackStack = []; + let callbackStack = []; /** * Checks a given function node for too many callbacks. @@ -74,14 +74,14 @@ module.exports = { * @private */ function checkFunction(node) { - var parent = node.parent; + let parent = node.parent; if (parent.type === "CallExpression") { callbackStack.push(node); } if (callbackStack.length > THRESHOLD) { - var opts = {num: callbackStack.length, max: THRESHOLD}; + let opts = {num: callbackStack.length, max: THRESHOLD}; context.report(node, "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", opts); } diff --git a/tools/eslint/lib/rules/max-params.js b/tools/eslint/lib/rules/max-params.js index 5d9d64fac10af9..9fb922392b60a9 100644 --- a/tools/eslint/lib/rules/max-params.js +++ b/tools/eslint/lib/rules/max-params.js @@ -45,7 +45,7 @@ module.exports = { create: function(context) { - var option = context.options[0], + let option = context.options[0], numParams = 3; if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") { diff --git a/tools/eslint/lib/rules/max-statements-per-line.js b/tools/eslint/lib/rules/max-statements-per-line.js index 55f09746c30836..165c6dd137556f 100644 --- a/tools/eslint/lib/rules/max-statements-per-line.js +++ b/tools/eslint/lib/rules/max-statements-per-line.js @@ -32,7 +32,7 @@ module.exports = { create: function(context) { - var sourceCode = context.getSourceCode(), + let sourceCode = context.getSourceCode(), options = context.options[0] || {}, lastStatementLine = 0, numberOfStatementsOnThisLine = 0, @@ -43,7 +43,7 @@ module.exports = { // Helpers //-------------------------------------------------------------------------- - var SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/; + let SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/; /** * Gets the actual last token of a given node. @@ -52,7 +52,7 @@ module.exports = { * @returns {Token} The actual last token. */ function getActualLastToken(node) { - var lastToken = sourceCode.getLastToken(node); + let lastToken = sourceCode.getLastToken(node); if (lastToken.value === ";") { lastToken = sourceCode.getTokenBefore(lastToken); @@ -68,7 +68,7 @@ module.exports = { * @returns {void} */ function enterStatement(node) { - var line = node.loc.start.line; + let line = node.loc.start.line; // Skip to allow non-block statements if this is direct child of control statements. // `if (a) foo();` is counted as 1. @@ -100,7 +100,7 @@ module.exports = { * @returns {void} */ function leaveStatement(node) { - var line = getActualLastToken(node).loc.end.line; + let line = getActualLastToken(node).loc.end.line; // Update state. if (line !== lastStatementLine) { diff --git a/tools/eslint/lib/rules/max-statements.js b/tools/eslint/lib/rules/max-statements.js index 72904c64bad0c4..6708be3a12e191 100644 --- a/tools/eslint/lib/rules/max-statements.js +++ b/tools/eslint/lib/rules/max-statements.js @@ -58,7 +58,7 @@ module.exports = { // Helpers //-------------------------------------------------------------------------- - var functionStack = [], + let functionStack = [], option = context.options[0], maxStatements = 10, ignoreTopLevelFunctions = context.options[1] && context.options[1].ignoreTopLevelFunctions || false, @@ -107,7 +107,7 @@ module.exports = { * @private */ function endFunction(node) { - var count = functionStack.pop(); + let count = functionStack.pop(); if (ignoreTopLevelFunctions && functionStack.length === 0) { topLevelFunctions.push({ node: node, count: count}); @@ -147,8 +147,8 @@ module.exports = { } topLevelFunctions.forEach(function(element) { - var count = element.count; - var node = element.node; + let count = element.count; + let node = element.node; reportIfTooManyStatements(node, count, maxStatements); }); diff --git a/tools/eslint/lib/rules/multiline-ternary.js b/tools/eslint/lib/rules/multiline-ternary.js new file mode 100644 index 00000000000000..469eb134ded6e8 --- /dev/null +++ b/tools/eslint/lib/rules/multiline-ternary.js @@ -0,0 +1,66 @@ +/** + * @fileoverview Enforce newlines between operands of ternary expressions + * @author Kai Cataldo + */ + +"use strict"; + +let astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "enforce newlines between operands of ternary expressions", + category: "Stylistic Issues", + recommended: false + }, + schema: [] + }, + + create: function(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Tests whether node is preceded by supplied tokens + * @param {ASTNode} node - node to check + * @param {ASTNode} parentNode - parent of node to report + * @returns {void} + * @private + */ + function reportError(node, parentNode) { + context.report({ + node: node, + message: "Expected newline between {{typeOfError}} of ternary expression.", + data: { + typeOfError: node === parentNode.test ? "test and consequent" : "consequent and alternate" + } + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ConditionalExpression: function(node) { + let areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(node.test, node.consequent); + let areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(node.consequent, node.alternate); + + if (areTestAndConsequentOnSameLine) { + reportError(node.test, node); + } + + if (areConsequentAndAlternateOnSameLine) { + reportError(node.consequent, node); + } + } + }; + } +}; diff --git a/tools/eslint/lib/rules/new-cap.js b/tools/eslint/lib/rules/new-cap.js index 2dabb30a65511b..5e1baa540cc4e5 100644 --- a/tools/eslint/lib/rules/new-cap.js +++ b/tools/eslint/lib/rules/new-cap.js @@ -9,13 +9,13 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"); +let lodash = require("lodash"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var CAPS_ALLOWED = [ +let CAPS_ALLOWED = [ "Array", "Boolean", "Date", @@ -61,7 +61,7 @@ function invert(map, key) { * @returns {Object} Object with cap is new exceptions. */ function calculateCapIsNewExceptions(config) { - var capIsNewExceptions = checkArray(config, "capIsNewExceptions", CAPS_ALLOWED); + let capIsNewExceptions = checkArray(config, "capIsNewExceptions", CAPS_ALLOWED); if (capIsNewExceptions !== CAPS_ALLOWED) { capIsNewExceptions = capIsNewExceptions.concat(CAPS_ALLOWED); @@ -115,19 +115,19 @@ module.exports = { create: function(context) { - var config = context.options[0] ? lodash.assign({}, context.options[0]) : {}; + let config = context.options[0] ? lodash.assign({}, context.options[0]) : {}; config.newIsCap = config.newIsCap !== false; config.capIsNew = config.capIsNew !== false; - var skipProperties = config.properties === false; + let skipProperties = config.properties === false; - var newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {}); + let newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {}); - var capIsNewExceptions = calculateCapIsNewExceptions(config); + let capIsNewExceptions = calculateCapIsNewExceptions(config); - var listeners = {}; + let listeners = {}; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers @@ -140,7 +140,7 @@ module.exports = { */ function extractNameFromExpression(node) { - var name = "", + let name = "", property; if (node.callee.type === "MemberExpression") { @@ -164,10 +164,10 @@ module.exports = { * @returns {string} capitalization state: "non-alpha", "lower", or "upper" */ function getCap(str) { - var firstChar = str.charAt(0); + let firstChar = str.charAt(0); - var firstCharLower = firstChar.toLowerCase(); - var firstCharUpper = firstChar.toUpperCase(); + let firstCharLower = firstChar.toLowerCase(); + let firstCharUpper = firstChar.toUpperCase(); if (firstCharLower === firstCharUpper) { @@ -185,7 +185,7 @@ module.exports = { * @param {Object} allowedMap Object mapping calleeName to a Boolean * @param {ASTNode} node CallExpression node * @param {string} calleeName Capitalized callee name from a CallExpression - * @returns {Boolean} Returns true if the callee may be capitalized + * @returns {boolean} Returns true if the callee may be capitalized */ function isCapAllowed(allowedMap, node, calleeName) { if (allowedMap[calleeName] || allowedMap[sourceCode.getText(node.callee)]) { @@ -209,7 +209,7 @@ module.exports = { * @returns {void} */ function report(node, message) { - var callee = node.callee; + let callee = node.callee; if (callee.type === "MemberExpression") { callee = callee.property; @@ -225,11 +225,11 @@ module.exports = { if (config.newIsCap) { listeners.NewExpression = function(node) { - var constructorName = extractNameFromExpression(node); + let constructorName = extractNameFromExpression(node); if (constructorName) { - var capitalization = getCap(constructorName); - var isAllowed = capitalization !== "lower" || isCapAllowed(newIsCapExceptions, node, constructorName); + let capitalization = getCap(constructorName); + let isAllowed = capitalization !== "lower" || isCapAllowed(newIsCapExceptions, node, constructorName); if (!isAllowed) { report(node, "A constructor name should not start with a lowercase letter."); @@ -241,11 +241,11 @@ module.exports = { if (config.capIsNew) { listeners.CallExpression = function(node) { - var calleeName = extractNameFromExpression(node); + let calleeName = extractNameFromExpression(node); if (calleeName) { - var capitalization = getCap(calleeName); - var isAllowed = capitalization !== "upper" || isCapAllowed(capIsNewExceptions, node, calleeName); + let capitalization = getCap(calleeName); + let isAllowed = capitalization !== "upper" || isCapAllowed(capIsNewExceptions, node, calleeName); if (!isAllowed) { report(node, "A function with a name starting with an uppercase letter should only be used as a constructor."); diff --git a/tools/eslint/lib/rules/new-parens.js b/tools/eslint/lib/rules/new-parens.js index ec6106647af25d..7ebd144b7ee766 100644 --- a/tools/eslint/lib/rules/new-parens.js +++ b/tools/eslint/lib/rules/new-parens.js @@ -21,18 +21,18 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { NewExpression: function(node) { - var tokens = sourceCode.getTokens(node); - var prenticesTokens = tokens.filter(function(token) { + let tokens = sourceCode.getTokens(node); + let prenticesTokens = tokens.filter(function(token) { return token.value === "(" || token.value === ")"; }); if (prenticesTokens.length < 2) { - context.report(node, "Missing '()' invoking a constructor"); + context.report(node, "Missing '()' invoking a constructor."); } } }; diff --git a/tools/eslint/lib/rules/newline-after-var.js b/tools/eslint/lib/rules/newline-after-var.js index 8801407c0bf0c2..cb06c6f26145ee 100644 --- a/tools/eslint/lib/rules/newline-after-var.js +++ b/tools/eslint/lib/rules/newline-after-var.js @@ -26,16 +26,16 @@ module.exports = { create: function(context) { - var ALWAYS_MESSAGE = "Expected blank line after variable declarations.", + let ALWAYS_MESSAGE = "Expected blank line after variable declarations.", NEVER_MESSAGE = "Unexpected blank line after variable declarations."; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); // Default `mode` to "always". - var mode = context.options[0] === "never" ? "never" : "always"; + let mode = context.options[0] === "never" ? "never" : "always"; // Cache starting and ending line numbers of comments for faster lookup - var commentEndLine = sourceCode.getAllComments().reduce(function(result, token) { + let commentEndLine = sourceCode.getAllComments().reduce(function(result, token) { result[token.loc.start.line] = token.loc.end.line; return result; }, {}); @@ -83,7 +83,7 @@ module.exports = { * @returns {boolean} True if `node` is last of their parent block. */ function isLastNode(node) { - var token = sourceCode.getTokenAfter(node); + let token = sourceCode.getTokenAfter(node); return !token || (token.type === "Punctuator" && token.value === "}"); } @@ -95,7 +95,7 @@ module.exports = { * @returns {boolean} True if `token` does not start immediately after a comment */ function hasBlankLineAfterComment(token, commentStartLine) { - var commentEnd = commentEndLine[commentStartLine]; + let commentEnd = commentEndLine[commentStartLine]; // If there's another comment, repeat check for blank line if (commentEndLine[commentEnd + 1]) { @@ -114,7 +114,7 @@ module.exports = { * @returns {void} */ function checkForBlankLine(node) { - var lastToken = sourceCode.getLastToken(node), + let lastToken = sourceCode.getLastToken(node), nextToken = sourceCode.getTokenAfter(node), nextLineNum = lastToken.loc.end.line + 1, noNextLineToken, diff --git a/tools/eslint/lib/rules/newline-before-return.js b/tools/eslint/lib/rules/newline-before-return.js index 5c8a139358c8b3..966ddb9193b505 100644 --- a/tools/eslint/lib/rules/newline-before-return.js +++ b/tools/eslint/lib/rules/newline-before-return.js @@ -20,7 +20,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers @@ -34,7 +34,7 @@ module.exports = { * @private */ function isPrecededByTokens(node, testTokens) { - var tokenBefore = sourceCode.getTokenBefore(node); + let tokenBefore = sourceCode.getTokenBefore(node); return testTokens.some(function(token) { return tokenBefore.value === token; @@ -48,7 +48,7 @@ module.exports = { * @private */ function isFirstNode(node) { - var parentType = node.parent.type; + let parentType = node.parent.type; if (node.parent.body) { return Array.isArray(node.parent.body) @@ -75,7 +75,7 @@ module.exports = { * @private */ function calcCommentLines(node, lineNumTokenBefore) { - var comments = sourceCode.getComments(node).leading, + let comments = sourceCode.getComments(node).leading, numLinesComments = 0; if (!comments.length) { @@ -109,7 +109,7 @@ module.exports = { * @private */ function hasNewlineBefore(node) { - var tokenBefore = sourceCode.getTokenBefore(node), + let tokenBefore = sourceCode.getTokenBefore(node), lineNumNode = node.loc.start.line, lineNumTokenBefore, commentLines; diff --git a/tools/eslint/lib/rules/newline-per-chained-call.js b/tools/eslint/lib/rules/newline-per-chained-call.js index c412d53e994841..068e7b97ae9579 100644 --- a/tools/eslint/lib/rules/newline-per-chained-call.js +++ b/tools/eslint/lib/rules/newline-per-chained-call.js @@ -33,10 +33,10 @@ module.exports = { create: function(context) { - var options = context.options[0] || {}, + let options = context.options[0] || {}, ignoreChainWithDepth = options.ignoreChainWithDepth || 2; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Gets the property text of a given MemberExpression node. @@ -46,9 +46,9 @@ module.exports = { * @returns {string} The property text of the node. */ function getPropertyText(node) { - var prefix = node.computed ? "[" : "."; - var lines = sourceCode.getText(node.property).split(/\r\n|\r|\n/g); - var suffix = node.computed && lines.length === 1 ? "]" : ""; + let prefix = node.computed ? "[" : "."; + let lines = sourceCode.getText(node.property).split(/\r\n|\r|\n/g); + let suffix = node.computed && lines.length === 1 ? "]" : ""; return prefix + lines[0] + suffix; } @@ -59,9 +59,9 @@ module.exports = { return; } - var callee = node.callee; - var parent = callee.object; - var depth = 1; + let callee = node.callee; + let parent = callee.object; + let depth = 1; while (parent && parent.callee) { depth += 1; diff --git a/tools/eslint/lib/rules/no-alert.js b/tools/eslint/lib/rules/no-alert.js index e491dfefc5504e..1ff04a3b687c0f 100644 --- a/tools/eslint/lib/rules/no-alert.js +++ b/tools/eslint/lib/rules/no-alert.js @@ -51,7 +51,7 @@ function getPropertyName(memberExpressionNode) { * @returns {Reference|null} Returns the found reference or null if none were found. */ function findReference(scope, node) { - var references = scope.references.filter(function(reference) { + let references = scope.references.filter(function(reference) { return reference.identifier.range[0] === node.range[0] && reference.identifier.range[1] === node.range[1]; }); @@ -70,7 +70,7 @@ function findReference(scope, node) { * @returns {boolean} Whether or not the name is shadowed. */ function isShadowed(scope, globalScope, node) { - var reference = findReference(scope, node); + let reference = findReference(scope, node); return reference && reference.resolved && reference.resolved.defs.length > 0; } @@ -108,7 +108,7 @@ module.exports = { }, create: function(context) { - var globalScope; + let globalScope; return { @@ -117,7 +117,7 @@ module.exports = { }, CallExpression: function(node) { - var callee = node.callee, + let callee = node.callee, identifierName, currentScope = context.getScope(); diff --git a/tools/eslint/lib/rules/no-bitwise.js b/tools/eslint/lib/rules/no-bitwise.js index 0294998ecc1022..bfb6c180da4a12 100644 --- a/tools/eslint/lib/rules/no-bitwise.js +++ b/tools/eslint/lib/rules/no-bitwise.js @@ -8,7 +8,7 @@ // // Set of bitwise operators. // -var BITWISE_OPERATORS = [ +let BITWISE_OPERATORS = [ "^", "|", "&", "<<", ">>", ">>>", "^=", "|=", "&=", "<<=", ">>=", ">>>=", "~" @@ -47,9 +47,9 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; - var allowed = options.allow || []; - var int32Hint = options.int32Hint === true; + let options = context.options[0] || {}; + let allowed = options.allow || []; + let int32Hint = options.int32Hint === true; /** * Reports an unexpected use of a bitwise operator. diff --git a/tools/eslint/lib/rules/no-caller.js b/tools/eslint/lib/rules/no-caller.js index 0405fdaeb90303..75cfb63f65c114 100644 --- a/tools/eslint/lib/rules/no-caller.js +++ b/tools/eslint/lib/rules/no-caller.js @@ -25,7 +25,7 @@ module.exports = { return { MemberExpression: function(node) { - var objectName = node.object.name, + let objectName = node.object.name, propertyName = node.property.name; if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/)) { diff --git a/tools/eslint/lib/rules/no-case-declarations.js b/tools/eslint/lib/rules/no-case-declarations.js index 8ef202538ec573..6538674d41e92e 100644 --- a/tools/eslint/lib/rules/no-case-declarations.js +++ b/tools/eslint/lib/rules/no-case-declarations.js @@ -40,8 +40,8 @@ module.exports = { return { SwitchCase: function(node) { - for (var i = 0; i < node.consequent.length; i++) { - var statement = node.consequent[i]; + for (let i = 0; i < node.consequent.length; i++) { + let statement = node.consequent[i]; if (isLexicalDeclaration(statement)) { context.report({ diff --git a/tools/eslint/lib/rules/no-catch-shadow.js b/tools/eslint/lib/rules/no-catch-shadow.js index 4a206833c08928..919ad3bc37d884 100644 --- a/tools/eslint/lib/rules/no-catch-shadow.js +++ b/tools/eslint/lib/rules/no-catch-shadow.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -34,7 +34,7 @@ module.exports = { /** * Check if the parameters are been shadowed - * @param {object} scope current scope + * @param {Object} scope current scope * @param {string} name parameter name * @returns {boolean} True is its been shadowed */ @@ -49,7 +49,7 @@ module.exports = { return { CatchClause: function(node) { - var scope = context.getScope(); + let scope = context.getScope(); // When blockBindings is enabled, CatchClause creates its own scope // so start from one upper scope to exclude the current node diff --git a/tools/eslint/lib/rules/no-class-assign.js b/tools/eslint/lib/rules/no-class-assign.js index 1e4d3243d8b918..e12d3a065a6cae 100644 --- a/tools/eslint/lib/rules/no-class-assign.js +++ b/tools/eslint/lib/rules/no-class-assign.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition diff --git a/tools/eslint/lib/rules/no-cond-assign.js b/tools/eslint/lib/rules/no-cond-assign.js index e0979ddaf29be4..5cba25e8c78be5 100644 --- a/tools/eslint/lib/rules/no-cond-assign.js +++ b/tools/eslint/lib/rules/no-cond-assign.js @@ -4,7 +4,7 @@ */ "use strict"; -var NODE_DESCRIPTIONS = { +let NODE_DESCRIPTIONS = { DoWhileStatement: "a 'do...while' statement", ForStatement: "a 'for' statement", IfStatement: "an 'if' statement", @@ -32,9 +32,9 @@ module.exports = { create: function(context) { - var prohibitAssign = (context.options[0] || "except-parens"); + let prohibitAssign = (context.options[0] || "except-parens"); - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Check whether an AST node is the test expression for a conditional statement. @@ -53,7 +53,7 @@ module.exports = { * @returns {?Object} The closest ancestor node that represents a conditional statement. */ function findConditionalAncestor(node) { - var currentAncestor = node; + let currentAncestor = node; do { if (isConditionalTestExpression(currentAncestor)) { @@ -70,7 +70,7 @@ module.exports = { * @returns {boolean} `true` if the code is enclosed in parentheses; otherwise, `false`. */ function isParenthesised(node) { - var previousToken = sourceCode.getTokenBefore(node), + let previousToken = sourceCode.getTokenBefore(node), nextToken = sourceCode.getTokenAfter(node); return previousToken.value === "(" && previousToken.range[1] <= node.range[0] && @@ -83,7 +83,7 @@ module.exports = { * @returns {boolean} `true` if the code is enclosed in two sets of parentheses; otherwise, `false`. */ function isParenthesisedTwice(node) { - var previousToken = sourceCode.getTokenBefore(node, 1), + let previousToken = sourceCode.getTokenBefore(node, 1), nextToken = sourceCode.getTokenAfter(node, 1); return isParenthesised(node) && @@ -120,7 +120,7 @@ module.exports = { * @returns {void} */ function testForConditionalAncestor(node) { - var ancestor = findConditionalAncestor(node); + let ancestor = findConditionalAncestor(node); if (ancestor) { context.report(ancestor, "Unexpected assignment within {{type}}.", { diff --git a/tools/eslint/lib/rules/no-confusing-arrow.js b/tools/eslint/lib/rules/no-confusing-arrow.js index 1f18aa356778ae..42d1f865e272fe 100644 --- a/tools/eslint/lib/rules/no-confusing-arrow.js +++ b/tools/eslint/lib/rules/no-confusing-arrow.js @@ -6,7 +6,7 @@ "use strict"; -var astUtils = require("../ast-utils.js"); +let astUtils = require("../ast-utils.js"); //------------------------------------------------------------------------------ // Helpers @@ -43,8 +43,8 @@ module.exports = { }, create: function(context) { - var config = context.options[0] || {}; - var sourceCode = context.getSourceCode(); + let config = context.options[0] || {}; + let sourceCode = context.getSourceCode(); /** * Reports if an arrow function contains an ambiguous conditional. @@ -52,7 +52,7 @@ module.exports = { * @returns {void} */ function checkArrowFunc(node) { - var body = node.body; + let body = node.body; if (isConditional(body) && !(config.allowParens && astUtils.isParenthesised(sourceCode, body))) { context.report(node, "Arrow function used ambiguously with a conditional expression."); diff --git a/tools/eslint/lib/rules/no-console.js b/tools/eslint/lib/rules/no-console.js index 18a897409f6586..553fc724607de0 100644 --- a/tools/eslint/lib/rules/no-console.js +++ b/tools/eslint/lib/rules/no-console.js @@ -42,12 +42,12 @@ module.exports = { MemberExpression: function(node) { if (node.object.name === "console") { - var blockConsole = true; + let blockConsole = true; if (context.options.length > 0) { - var allowedProperties = context.options[0].allow; - var passedProperty = node.property.name; - var propertyIsAllowed = (allowedProperties.indexOf(passedProperty) > -1); + let allowedProperties = context.options[0].allow; + let passedProperty = node.property.name; + let propertyIsAllowed = (allowedProperties.indexOf(passedProperty) > -1); if (propertyIsAllowed) { blockConsole = false; diff --git a/tools/eslint/lib/rules/no-const-assign.js b/tools/eslint/lib/rules/no-const-assign.js index 344e05a644ee67..8015225dbd87dc 100644 --- a/tools/eslint/lib/rules/no-const-assign.js +++ b/tools/eslint/lib/rules/no-const-assign.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition diff --git a/tools/eslint/lib/rules/no-constant-condition.js b/tools/eslint/lib/rules/no-constant-condition.js index 7c4ede7f78cf66..b2d3b647386ce8 100644 --- a/tools/eslint/lib/rules/no-constant-condition.js +++ b/tools/eslint/lib/rules/no-constant-condition.js @@ -32,7 +32,7 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}, + let options = context.options[0] || {}, checkLoops = options.checkLoops !== false; //-------------------------------------------------------------------------- @@ -85,13 +85,16 @@ module.exports = { return isConstant(node.left, false) && isConstant(node.right, false) && node.operator !== "in"; - case "LogicalExpression": - var isLeftConstant = isConstant(node.left, inBooleanPosition); - var isRightConstant = isConstant(node.right, inBooleanPosition); - var isLeftShortCircuit = (isLeftConstant && isLogicalIdentity(node.left, node.operator)); - var isRightShortCircuit = (isRightConstant && isLogicalIdentity(node.right, node.operator)); + + case "LogicalExpression": { + const isLeftConstant = isConstant(node.left, inBooleanPosition); + const isRightConstant = isConstant(node.right, inBooleanPosition); + const isLeftShortCircuit = (isLeftConstant && isLogicalIdentity(node.left, node.operator)); + const isRightShortCircuit = (isRightConstant && isLogicalIdentity(node.right, node.operator)); return (isLeftConstant && isRightConstant) || isLeftShortCircuit || isRightShortCircuit; + } + case "AssignmentExpression": return (node.operator === "=") && isConstant(node.right, inBooleanPosition); diff --git a/tools/eslint/lib/rules/no-continue.js b/tools/eslint/lib/rules/no-continue.js index 246df89ebe4283..5e8c059b0efd02 100644 --- a/tools/eslint/lib/rules/no-continue.js +++ b/tools/eslint/lib/rules/no-continue.js @@ -24,7 +24,7 @@ module.exports = { return { ContinueStatement: function(node) { - context.report(node, "Unexpected use of continue statement"); + context.report(node, "Unexpected use of continue statement."); } }; diff --git a/tools/eslint/lib/rules/no-control-regex.js b/tools/eslint/lib/rules/no-control-regex.js index 74e03f03c56f40..4032fb2af77004 100644 --- a/tools/eslint/lib/rules/no-control-regex.js +++ b/tools/eslint/lib/rules/no-control-regex.js @@ -33,7 +33,7 @@ module.exports = { return node.value; } else if (typeof node.value === "string") { - var parent = context.getAncestors().pop(); + let parent = context.getAncestors().pop(); if ((parent.type === "NewExpression" || parent.type === "CallExpression") && parent.callee.type === "Identifier" && parent.callee.name === "RegExp" @@ -53,22 +53,22 @@ module.exports = { /** * Check if given regex string has control characters in it - * @param {String} regexStr regex as string to check - * @returns {Boolean} returns true if finds control characters on given string + * @param {string} regexStr regex as string to check + * @returns {boolean} returns true if finds control characters on given string * @private */ function hasControlCharacters(regexStr) { // check control characters, if RegExp object used - var hasControlChars = /[\x00-\x1f]/.test(regexStr); // eslint-disable-line no-control-regex + let hasControlChars = /[\x00-\x1f]/.test(regexStr); // eslint-disable-line no-control-regex // check substr, if regex literal used - var subStrIndex = regexStr.search(/\\x[01][0-9a-f]/i); + let subStrIndex = regexStr.search(/\\x[01][0-9a-f]/i); if (!hasControlChars && subStrIndex > -1) { // is it escaped, check backslash count - var possibleEscapeCharacters = regexStr.substr(0, subStrIndex).match(/\\+$/gi); + let possibleEscapeCharacters = regexStr.substr(0, subStrIndex).match(/\\+$/gi); hasControlChars = possibleEscapeCharacters === null || !(possibleEscapeCharacters[0].length % 2); } @@ -78,7 +78,7 @@ module.exports = { return { Literal: function(node) { - var computedValue, + let computedValue, regex = getRegExp(node); if (regex) { diff --git a/tools/eslint/lib/rules/no-div-regex.js b/tools/eslint/lib/rules/no-div-regex.js index 75a6085595739b..f54a534b2266a2 100644 --- a/tools/eslint/lib/rules/no-div-regex.js +++ b/tools/eslint/lib/rules/no-div-regex.js @@ -21,12 +21,12 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { Literal: function(node) { - var token = sourceCode.getFirstToken(node); + let token = sourceCode.getFirstToken(node); if (token.type === "RegularExpression" && token.value[1] === "=") { context.report(node, "A regular expression literal can be confused with '/='."); diff --git a/tools/eslint/lib/rules/no-dupe-args.js b/tools/eslint/lib/rules/no-dupe-args.js index e927ce2b3a8576..f63fab5bb24b86 100644 --- a/tools/eslint/lib/rules/no-dupe-args.js +++ b/tools/eslint/lib/rules/no-dupe-args.js @@ -42,13 +42,13 @@ module.exports = { * @private */ function checkParams(node) { - var variables = context.getDeclaredVariables(node); + let variables = context.getDeclaredVariables(node); - for (var i = 0; i < variables.length; ++i) { - var variable = variables[i]; + for (let i = 0; i < variables.length; ++i) { + let variable = variables[i]; // Checks and reports duplications. - var defs = variable.defs.filter(isParameter); + let defs = variable.defs.filter(isParameter); if (defs.length >= 2) { context.report({ diff --git a/tools/eslint/lib/rules/no-dupe-class-members.js b/tools/eslint/lib/rules/no-dupe-class-members.js index 883020bdfe5e96..102072b8bbeccb 100644 --- a/tools/eslint/lib/rules/no-dupe-class-members.js +++ b/tools/eslint/lib/rules/no-dupe-class-members.js @@ -21,20 +21,20 @@ module.exports = { }, create: function(context) { - var stack = []; + let stack = []; /** * Gets state of a given member name. * @param {string} name - A name of a member. * @param {boolean} isStatic - A flag which specifies that is a static member. - * @returns {object} A state of a given member name. + * @returns {Object} A state of a given member name. * - retv.init {boolean} A flag which shows the name is declared as normal member. * - retv.get {boolean} A flag which shows the name is declared as getter. * - retv.set {boolean} A flag which shows the name is declared as setter. */ function getState(name, isStatic) { - var stateMap = stack[stack.length - 1]; - var key = "$" + name; // to avoid "__proto__". + let stateMap = stack[stack.length - 1]; + let key = "$" + name; // to avoid "__proto__". if (!stateMap[key]) { stateMap[key] = { @@ -85,9 +85,9 @@ module.exports = { return; } - var name = getName(node.key); - var state = getState(name, node.static); - var isDuplicate = false; + let name = getName(node.key); + let state = getState(name, node.static); + let isDuplicate = false; if (node.kind === "get") { isDuplicate = (state.init || state.get); diff --git a/tools/eslint/lib/rules/no-dupe-keys.js b/tools/eslint/lib/rules/no-dupe-keys.js index 26f009b3bfe0ca..d2a3fc67738a49 100644 --- a/tools/eslint/lib/rules/no-dupe-keys.js +++ b/tools/eslint/lib/rules/no-dupe-keys.js @@ -28,7 +28,7 @@ module.exports = { // Object that will be a map of properties--safe because we will // prefix all of the keys. - var nodeProps = Object.create(null); + let nodeProps = Object.create(null); node.properties.forEach(function(property) { @@ -36,7 +36,7 @@ module.exports = { return; } - var keyName = property.key.name || property.key.value, + let keyName = property.key.name || property.key.value, key = property.kind + "-" + keyName, checkProperty = (!property.computed || property.key.type === "Literal"); diff --git a/tools/eslint/lib/rules/no-duplicate-case.js b/tools/eslint/lib/rules/no-duplicate-case.js index 8c877ed4e82c43..9e9b8b5cd8bec2 100644 --- a/tools/eslint/lib/rules/no-duplicate-case.js +++ b/tools/eslint/lib/rules/no-duplicate-case.js @@ -22,14 +22,14 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { SwitchStatement: function(node) { - var mapping = {}; + let mapping = {}; node.cases.forEach(function(switchCase) { - var key = sourceCode.getText(switchCase.test); + let key = sourceCode.getText(switchCase.test); if (mapping[key]) { context.report(switchCase, "Duplicate case label."); diff --git a/tools/eslint/lib/rules/no-duplicate-imports.js b/tools/eslint/lib/rules/no-duplicate-imports.js index 44432f48635982..8594541b14a5d1 100644 --- a/tools/eslint/lib/rules/no-duplicate-imports.js +++ b/tools/eslint/lib/rules/no-duplicate-imports.js @@ -60,7 +60,7 @@ function checkAndReport(context, node, value, array, message) { */ function handleImports(context, includeExports, importsInFile, exportsInFile) { return function(node) { - var value = getValue(node); + let value = getValue(node); if (value) { checkAndReport(context, node, value, importsInFile, "import is duplicated."); @@ -85,7 +85,7 @@ function handleImports(context, includeExports, importsInFile, exportsInFile) { */ function handleExports(context, importsInFile, exportsInFile) { return function(node) { - var value = getValue(node); + let value = getValue(node); if (value) { checkAndReport(context, node, value, exportsInFile, "export is duplicated."); @@ -116,11 +116,11 @@ module.exports = { }, create: function(context) { - var includeExports = (context.options[0] || {}).includeExports, + let includeExports = (context.options[0] || {}).includeExports, importsInFile = [], exportsInFile = []; - var handlers = { + let handlers = { ImportDeclaration: handleImports(context, includeExports, importsInFile, exportsInFile) }; diff --git a/tools/eslint/lib/rules/no-else-return.js b/tools/eslint/lib/rules/no-else-return.js index 528d4ca566de23..05ead21586be4c 100644 --- a/tools/eslint/lib/rules/no-else-return.js +++ b/tools/eslint/lib/rules/no-else-return.js @@ -56,7 +56,7 @@ module.exports = { */ function naiveHasReturn(node) { if (node.type === "BlockStatement") { - var body = node.body, + let body = node.body, lastChildNode = body[body.length - 1]; return lastChildNode && checkForReturn(lastChildNode); @@ -128,7 +128,7 @@ module.exports = { return { IfStatement: function(node) { - var parent = context.getAncestors().pop(), + let parent = context.getAncestors().pop(), consequents, alternate; diff --git a/tools/eslint/lib/rules/no-empty-character-class.js b/tools/eslint/lib/rules/no-empty-character-class.js index 34ef78a396fcba..4a1ae8f92f6ac7 100644 --- a/tools/eslint/lib/rules/no-empty-character-class.js +++ b/tools/eslint/lib/rules/no-empty-character-class.js @@ -21,7 +21,7 @@ plain-English description of the following regexp: 4. `[gimuy]*`: optional regexp flags 5. `$`: fix the match at the end of the string */ -var regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimuy]*$/; +let regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimuy]*$/; //------------------------------------------------------------------------------ // Rule Definition @@ -39,12 +39,12 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { Literal: function(node) { - var token = sourceCode.getFirstToken(node); + let token = sourceCode.getFirstToken(node); if (token.type === "RegularExpression" && !regex.test(token.value)) { context.report(node, "Empty class."); diff --git a/tools/eslint/lib/rules/no-empty-function.js b/tools/eslint/lib/rules/no-empty-function.js index 0102acff5164cb..d7d8c2e886cd59 100644 --- a/tools/eslint/lib/rules/no-empty-function.js +++ b/tools/eslint/lib/rules/no-empty-function.js @@ -9,7 +9,7 @@ // Helpers //------------------------------------------------------------------------------ -var ALLOW_OPTIONS = Object.freeze([ +let ALLOW_OPTIONS = Object.freeze([ "functions", "arrowFunctions", "generatorFunctions", @@ -19,7 +19,7 @@ var ALLOW_OPTIONS = Object.freeze([ "setters", "constructors" ]); -var SHOW_KIND = Object.freeze({ +let SHOW_KIND = Object.freeze({ functions: "function", arrowFunctions: "arrow function", generatorFunctions: "generator function", @@ -44,8 +44,8 @@ var SHOW_KIND = Object.freeze({ * "constructors". */ function getKind(node) { - var parent = node.parent; - var kind = ""; + let parent = node.parent; + let kind = ""; if (node.type === "ArrowFunctionExpression") { return "arrowFunctions"; @@ -78,7 +78,7 @@ function getKind(node) { } // Detects prefix. - var prefix = ""; + let prefix = ""; if (node.generator) { prefix = "generator"; @@ -118,10 +118,10 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; - var allowed = options.allow || []; + let options = context.options[0] || {}; + let allowed = options.allow || []; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Reports a given function node if the node matches the following patterns. @@ -136,7 +136,7 @@ module.exports = { * @returns {void} */ function reportIfEmpty(node) { - var kind = getKind(node); + let kind = getKind(node); if (allowed.indexOf(kind) === -1 && node.body.type === "BlockStatement" && diff --git a/tools/eslint/lib/rules/no-empty.js b/tools/eslint/lib/rules/no-empty.js index 1302a907533986..8897cce02b3490 100644 --- a/tools/eslint/lib/rules/no-empty.js +++ b/tools/eslint/lib/rules/no-empty.js @@ -5,10 +5,14 @@ "use strict"; //------------------------------------------------------------------------------ -// Rule Definition +// Requirements //------------------------------------------------------------------------------ -var FUNCTION_TYPE = /^(?:ArrowFunctionExpression|Function(?:Declaration|Expression))$/; +let astUtils = require("../ast-utils"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ module.exports = { meta: { @@ -32,10 +36,10 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}, + let options = context.options[0] || {}, allowEmptyCatch = options.allowEmptyCatch || false; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { BlockStatement: function(node) { @@ -46,7 +50,7 @@ module.exports = { } // a function is generally allowed to be empty - if (FUNCTION_TYPE.test(node.parent.type)) { + if (astUtils.isFunction(node.parent)) { return; } diff --git a/tools/eslint/lib/rules/no-eq-null.js b/tools/eslint/lib/rules/no-eq-null.js index da039bb9d7de4c..743f2908035355 100644 --- a/tools/eslint/lib/rules/no-eq-null.js +++ b/tools/eslint/lib/rules/no-eq-null.js @@ -26,7 +26,7 @@ module.exports = { return { BinaryExpression: function(node) { - var badOperator = node.operator === "==" || node.operator === "!="; + let badOperator = node.operator === "==" || node.operator === "!="; if (node.right.type === "Literal" && node.right.raw === "null" && badOperator || node.left.type === "Literal" && node.left.raw === "null" && badOperator) { diff --git a/tools/eslint/lib/rules/no-eval.js b/tools/eslint/lib/rules/no-eval.js index 04db4b96b477aa..67ac1017cf4323 100644 --- a/tools/eslint/lib/rules/no-eval.js +++ b/tools/eslint/lib/rules/no-eval.js @@ -9,13 +9,13 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var candidatesOfGlobalObject = Object.freeze([ +let candidatesOfGlobalObject = Object.freeze([ "global", "window" ]); @@ -94,12 +94,12 @@ module.exports = { }, create: function(context) { - var allowIndirect = Boolean( + let allowIndirect = Boolean( context.options[0] && context.options[0].allowIndirect ); - var sourceCode = context.getSourceCode(); - var funcInfo = null; + let sourceCode = context.getSourceCode(); + let funcInfo = null; /** * Pushs a variable scope (Program or Function) information to the stack. @@ -112,7 +112,7 @@ module.exports = { * @returns {void} */ function enterVarScope(node) { - var strict = context.getScope().isStrict; + let strict = context.getScope().isStrict; funcInfo = { upper: funcInfo, @@ -146,8 +146,8 @@ module.exports = { * @returns {void} */ function report(node) { - var locationNode = node; - var parent = node.parent; + let locationNode = node; + let parent = node.parent; if (node.type === "MemberExpression") { locationNode = node.property; @@ -170,19 +170,19 @@ module.exports = { * @returns {void} */ function reportAccessingEvalViaGlobalObject(globalScope) { - for (var i = 0; i < candidatesOfGlobalObject.length; ++i) { - var name = candidatesOfGlobalObject[i]; - var variable = astUtils.getVariableByName(globalScope, name); + for (let i = 0; i < candidatesOfGlobalObject.length; ++i) { + let name = candidatesOfGlobalObject[i]; + let variable = astUtils.getVariableByName(globalScope, name); if (!variable) { continue; } - var references = variable.references; + let references = variable.references; - for (var j = 0; j < references.length; ++j) { - var identifier = references[j].identifier; - var node = identifier.parent; + for (let j = 0; j < references.length; ++j) { + let identifier = references[j].identifier; + let node = identifier.parent; // To detect code like `window.window.eval`. while (isMember(node, name)) { @@ -204,17 +204,17 @@ module.exports = { * @returns {void} */ function reportAccessingEval(globalScope) { - var variable = astUtils.getVariableByName(globalScope, "eval"); + let variable = astUtils.getVariableByName(globalScope, "eval"); if (!variable) { return; } - var references = variable.references; + let references = variable.references; - for (var i = 0; i < references.length; ++i) { - var reference = references[i]; - var id = reference.identifier; + for (let i = 0; i < references.length; ++i) { + let reference = references[i]; + let id = reference.identifier; if (id.name === "eval" && !astUtils.isCallee(id)) { @@ -229,7 +229,7 @@ module.exports = { // Checks only direct calls to eval. It's simple! return { "CallExpression:exit": function(node) { - var callee = node.callee; + let callee = node.callee; if (isIdentifier(callee, "eval")) { report(callee); @@ -240,7 +240,7 @@ module.exports = { return { "CallExpression:exit": function(node) { - var callee = node.callee; + let callee = node.callee; if (isIdentifier(callee, "eval")) { report(callee); @@ -248,7 +248,7 @@ module.exports = { }, Program: function(node) { - var scope = context.getScope(), + let scope = context.getScope(), features = context.parserOptions.ecmaFeatures || {}, strict = scope.isStrict || @@ -265,7 +265,7 @@ module.exports = { }, "Program:exit": function() { - var globalScope = context.getScope(); + let globalScope = context.getScope(); exitVarScope(); reportAccessingEval(globalScope); diff --git a/tools/eslint/lib/rules/no-ex-assign.js b/tools/eslint/lib/rules/no-ex-assign.js index bf3afc6cd3f485..42aea52723cf40 100644 --- a/tools/eslint/lib/rules/no-ex-assign.js +++ b/tools/eslint/lib/rules/no-ex-assign.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition diff --git a/tools/eslint/lib/rules/no-extend-native.js b/tools/eslint/lib/rules/no-extend-native.js index 69d4931ab6e82b..c58e5c355408ba 100644 --- a/tools/eslint/lib/rules/no-extend-native.js +++ b/tools/eslint/lib/rules/no-extend-native.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var globals = require("globals"); +let globals = require("globals"); //------------------------------------------------------------------------------ // Rule Definition @@ -42,9 +42,9 @@ module.exports = { create: function(context) { - var config = context.options[0] || {}; - var exceptions = config.exceptions || []; - var modifiedBuiltins = Object.keys(globals.builtin).filter(function(builtin) { + let config = context.options[0] || {}; + let exceptions = config.exceptions || []; + let modifiedBuiltins = Object.keys(globals.builtin).filter(function(builtin) { return builtin[0].toUpperCase() === builtin[0]; }); @@ -58,7 +58,7 @@ module.exports = { // handle the Array.prototype.extra style case AssignmentExpression: function(node) { - var lhs = node.left, + let lhs = node.left, affectsProto; if (lhs.type !== "MemberExpression" || lhs.object.type !== "MemberExpression") { @@ -83,7 +83,7 @@ module.exports = { // handle the Object.definePropert[y|ies](Array.prototype) case CallExpression: function(node) { - var callee = node.callee, + let callee = node.callee, subject, object; diff --git a/tools/eslint/lib/rules/no-extra-bind.js b/tools/eslint/lib/rules/no-extra-bind.js index f75e2fcc25782d..bdafaf040f1dbd 100644 --- a/tools/eslint/lib/rules/no-extra-bind.js +++ b/tools/eslint/lib/rules/no-extra-bind.js @@ -20,7 +20,7 @@ module.exports = { }, create: function(context) { - var scopeInfo = null; + let scopeInfo = null; /** * Reports a given function node. @@ -73,8 +73,8 @@ module.exports = { * @returns {boolean} `true` if the node is the callee of `.bind()` method. */ function isCalleeOfBindMethod(node) { - var parent = node.parent; - var grandparent = parent.parent; + let parent = node.parent; + let grandparent = parent.parent; return ( grandparent && diff --git a/tools/eslint/lib/rules/no-extra-boolean-cast.js b/tools/eslint/lib/rules/no-extra-boolean-cast.js index f14da0821dbbed..890f7cb6051265 100644 --- a/tools/eslint/lib/rules/no-extra-boolean-cast.js +++ b/tools/eslint/lib/rules/no-extra-boolean-cast.js @@ -23,7 +23,7 @@ module.exports = { create: function(context) { // Node types which have a test which will coerce values to booleans. - var BOOLEAN_NODE_TYPES = [ + let BOOLEAN_NODE_TYPES = [ "IfStatement", "DoWhileStatement", "WhileStatement", @@ -36,7 +36,7 @@ module.exports = { * * @param {Object} node The node * @param {Object} parent Its parent - * @returns {Boolean} If it is in a boolean context + * @returns {boolean} If it is in a boolean context */ function isInBooleanContext(node, parent) { return ( @@ -52,7 +52,7 @@ module.exports = { return { UnaryExpression: function(node) { - var ancestors = context.getAncestors(), + let ancestors = context.getAncestors(), parent = ancestors.pop(), grandparent = ancestors.pop(); @@ -74,7 +74,7 @@ module.exports = { } }, CallExpression: function(node) { - var parent = node.parent; + let parent = node.parent; if (node.callee.type !== "Identifier" || node.callee.name !== "Boolean") { return; diff --git a/tools/eslint/lib/rules/no-extra-label.js b/tools/eslint/lib/rules/no-extra-label.js index f1a48e3688e96d..5b72209bf2de9b 100644 --- a/tools/eslint/lib/rules/no-extra-label.js +++ b/tools/eslint/lib/rules/no-extra-label.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -27,7 +27,7 @@ module.exports = { }, create: function(context) { - var scopeInfo = null; + let scopeInfo = null; /** * Creates a new scope with a breakable statement. @@ -98,9 +98,9 @@ module.exports = { return; } - var labelNode = node.label; - var label = labelNode.name; - var info = scopeInfo; + let labelNode = node.label; + let label = labelNode.name; + let info = scopeInfo; while (info) { if (info.breakable || info.label === label) { diff --git a/tools/eslint/lib/rules/no-extra-parens.js b/tools/eslint/lib/rules/no-extra-parens.js index c33a64920ff10f..86ef6ddc0f8686 100644 --- a/tools/eslint/lib/rules/no-extra-parens.js +++ b/tools/eslint/lib/rules/no-extra-parens.js @@ -8,7 +8,7 @@ // Rule Definition //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils.js"); +let astUtils = require("../ast-utils.js"); module.exports = { meta: { @@ -54,14 +54,14 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); - var isParenthesised = astUtils.isParenthesised.bind(astUtils, sourceCode); - var precedence = astUtils.getPrecedence; - var ALL_NODES = context.options[0] !== "functions"; - var EXCEPT_COND_ASSIGN = ALL_NODES && context.options[1] && context.options[1].conditionalAssign === false; - var NESTED_BINARY = ALL_NODES && context.options[1] && context.options[1].nestedBinaryExpressions === false; - var EXCEPT_RETURN_ASSIGN = ALL_NODES && context.options[1] && context.options[1].returnAssign === false; + let isParenthesised = astUtils.isParenthesised.bind(astUtils, sourceCode); + let precedence = astUtils.getPrecedence; + let ALL_NODES = context.options[0] !== "functions"; + let EXCEPT_COND_ASSIGN = ALL_NODES && context.options[1] && context.options[1].conditionalAssign === false; + let NESTED_BINARY = ALL_NODES && context.options[1] && context.options[1].nestedBinaryExpressions === false; + let EXCEPT_RETURN_ASSIGN = ALL_NODES && context.options[1] && context.options[1].returnAssign === false; /** * Determines if this rule should be enforced for a node given the current configuration. @@ -80,7 +80,7 @@ module.exports = { * @private */ function isParenthesisedTwice(node) { - var previousToken = sourceCode.getTokenBefore(node, 1), + let previousToken = sourceCode.getTokenBefore(node, 1), nextToken = sourceCode.getTokenAfter(node, 1); return isParenthesised(node) && previousToken && nextToken && @@ -199,7 +199,7 @@ module.exports = { * @returns {boolean} `true` if the node is located at the head of ExpressionStatement. */ function isHeadOfExpressionStatement(node) { - var parent = node.parent; + let parent = node.parent; while (parent) { switch (parent.type) { @@ -263,7 +263,7 @@ module.exports = { * @private */ function report(node) { - var previousToken = sourceCode.getTokenBefore(node); + let previousToken = sourceCode.getTokenBefore(node); context.report(node, previousToken.loc.start, "Gratuitous parentheses around expression."); } @@ -317,7 +317,7 @@ module.exports = { */ function dryBinaryLogical(node) { if (!NESTED_BINARY) { - var prec = precedence(node); + let prec = precedence(node); if (hasExcessParens(node.left) && precedence(node.left) >= prec) { report(node.left); @@ -394,7 +394,7 @@ module.exports = { }, ExpressionStatement: function(node) { - var firstToken, secondToken, firstTokens; + let firstToken, secondToken, firstTokens; if (hasExcessParens(node.expression)) { firstTokens = sourceCode.getFirstTokens(node.expression, 2); @@ -484,7 +484,7 @@ module.exports = { ObjectExpression: function(node) { [].forEach.call(node.properties, function(e) { - var v = e.value; + let v = e.value; if (v && hasExcessParens(v) && precedence(v) >= precedence({type: "AssignmentExpression"})) { report(v); @@ -493,7 +493,7 @@ module.exports = { }, ReturnStatement: function(node) { - var returnToken = sourceCode.getFirstToken(node); + let returnToken = sourceCode.getFirstToken(node); if (isReturnAssignException(node)) { return; @@ -529,7 +529,7 @@ module.exports = { }, ThrowStatement: function(node) { - var throwToken = sourceCode.getFirstToken(node); + let throwToken = sourceCode.getFirstToken(node); if (hasExcessParensNoLineTerminator(throwToken, node.argument)) { report(node.argument); @@ -562,7 +562,7 @@ module.exports = { }, YieldExpression: function(node) { - var yieldToken; + let yieldToken; if (node.argument) { yieldToken = sourceCode.getFirstToken(node); diff --git a/tools/eslint/lib/rules/no-extra-semi.js b/tools/eslint/lib/rules/no-extra-semi.js index 679a16641b7132..37f2253c26addc 100644 --- a/tools/eslint/lib/rules/no-extra-semi.js +++ b/tools/eslint/lib/rules/no-extra-semi.js @@ -22,7 +22,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Reports an unnecessary semicolon error. @@ -47,7 +47,7 @@ module.exports = { * @returns {void} */ function checkForPartOfClassBody(firstToken) { - for (var token = firstToken; + for (let token = firstToken; token.type === "Punctuator" && token.value !== "}"; token = sourceCode.getTokenAfter(token) ) { @@ -65,7 +65,7 @@ module.exports = { * @returns {void} */ EmptyStatement: function(node) { - var parent = node.parent, + let parent = node.parent, allowedParentTypes = [ "ForStatement", "ForInStatement", diff --git a/tools/eslint/lib/rules/no-fallthrough.js b/tools/eslint/lib/rules/no-fallthrough.js index 2edb4972bafd0a..24f3642fa163b9 100644 --- a/tools/eslint/lib/rules/no-fallthrough.js +++ b/tools/eslint/lib/rules/no-fallthrough.js @@ -8,13 +8,13 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"); +let lodash = require("lodash"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/i; +let DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/i; /** * Checks whether or not a given node has a fallthrough comment. @@ -24,8 +24,8 @@ var DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/i; * @returns {boolean} `true` if the node has a valid fallthrough comment. */ function hasFallthroughComment(node, context, fallthroughCommentPattern) { - var sourceCode = context.getSourceCode(); - var comment = lodash.last(sourceCode.getComments(node).leading); + let sourceCode = context.getSourceCode(); + let comment = lodash.last(sourceCode.getComments(node).leading); return Boolean(comment && fallthroughCommentPattern.test(comment.value)); } @@ -75,16 +75,16 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; - var currentCodePath = null; - var sourceCode = context.getSourceCode(); + let options = context.options[0] || {}; + let currentCodePath = null; + let sourceCode = context.getSourceCode(); /* * We need to use leading comments of the next SwitchCase node because * trailing comments is wrong if semicolons are omitted. */ - var fallthroughCase = null; - var fallthroughCommentPattern = null; + let fallthroughCase = null; + let fallthroughCommentPattern = null; if (options.commentPattern) { fallthroughCommentPattern = new RegExp(options.commentPattern); @@ -117,7 +117,7 @@ module.exports = { }, "SwitchCase:exit": function(node) { - var nextToken = sourceCode.getTokenAfter(node); + let nextToken = sourceCode.getTokenAfter(node); /* * `reachable` meant fall through because statements preceded by diff --git a/tools/eslint/lib/rules/no-func-assign.js b/tools/eslint/lib/rules/no-func-assign.js index ac3afe55c05533..2266a044fc32a9 100644 --- a/tools/eslint/lib/rules/no-func-assign.js +++ b/tools/eslint/lib/rules/no-func-assign.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition diff --git a/tools/eslint/lib/rules/no-implicit-coercion.js b/tools/eslint/lib/rules/no-implicit-coercion.js index 113c205855eb45..ee11bd008769b8 100644 --- a/tools/eslint/lib/rules/no-implicit-coercion.js +++ b/tools/eslint/lib/rules/no-implicit-coercion.js @@ -9,13 +9,13 @@ // Helpers //------------------------------------------------------------------------------ -var INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/; -var ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"]; +let INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/; +let ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"]; /** * Parses and normalizes an option object. - * @param {object} options - An option object to parse. - * @returns {object} The parsed and normalized option object. + * @param {Object} options - An option object to parse. + * @returns {Object} The parsed and normalized option object. */ function parseOptions(options) { options = options || {}; @@ -91,7 +91,7 @@ function isNumeric(node) { * @returns {ASTNode|null} The first non-numeric item in the BinaryExpression tree or null */ function getNonNumericOperand(node) { - var left = node.left, + let left = node.left, right = node.right; if (right.type !== "BinaryExpression" && !isNumeric(right)) { @@ -176,10 +176,10 @@ module.exports = { }, create: function(context) { - var options = parseOptions(context.options[0]), + let options = parseOptions(context.options[0]), operatorAllowed = false; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { UnaryExpression: function(node) { @@ -220,7 +220,7 @@ module.exports = { // 1 * foo operatorAllowed = options.allow.indexOf("*") >= 0; - var nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && getNonNumericOperand(node); + let nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && getNonNumericOperand(node); if (nonNumericOperand) { context.report( diff --git a/tools/eslint/lib/rules/no-implicit-globals.js b/tools/eslint/lib/rules/no-implicit-globals.js index c2768ea1a0951f..9f8180394f1105 100644 --- a/tools/eslint/lib/rules/no-implicit-globals.js +++ b/tools/eslint/lib/rules/no-implicit-globals.js @@ -23,7 +23,7 @@ module.exports = { create: function(context) { return { Program: function() { - var scope = context.getScope(); + let scope = context.getScope(); scope.variables.forEach(function(variable) { if (variable.writeable) { @@ -38,7 +38,7 @@ module.exports = { }); scope.implicit.variables.forEach(function(variable) { - var scopeVariable = scope.set.get(variable.name); + let scopeVariable = scope.set.get(variable.name); if (scopeVariable && scopeVariable.writeable) { return; diff --git a/tools/eslint/lib/rules/no-implied-eval.js b/tools/eslint/lib/rules/no-implied-eval.js index 7c1ed2fb6eb989..ec660fa08f3097 100644 --- a/tools/eslint/lib/rules/no-implied-eval.js +++ b/tools/eslint/lib/rules/no-implied-eval.js @@ -21,13 +21,13 @@ module.exports = { }, create: function(context) { - var CALLEE_RE = /set(?:Timeout|Interval)|execScript/; + let CALLEE_RE = /set(?:Timeout|Interval)|execScript/; /* * Figures out if we should inspect a given binary expression. Is a stack * of stacks, where the first element in each substack is a CallExpression. */ - var impliedEvalAncestorsStack = []; + let impliedEvalAncestorsStack = []; //-------------------------------------------------------------------------- // Helpers @@ -50,7 +50,7 @@ module.exports = { * @private */ function isImpliedEvalMemberExpression(node) { - var object = node.object, + let object = node.object, property = node.property, hasImpliedEvalName = CALLEE_RE.test(property.name) || CALLEE_RE.test(property.value); @@ -67,7 +67,7 @@ module.exports = { * @private */ function isImpliedEvalCallExpression(node) { - var isMemberExpression = (node.callee.type === "MemberExpression"), + let isMemberExpression = (node.callee.type === "MemberExpression"), isIdentifier = (node.callee.type === "Identifier"), isImpliedEvalCallee = (isIdentifier && CALLEE_RE.test(node.callee.name)) || @@ -103,7 +103,7 @@ module.exports = { if (hasImpliedEvalParent(node)) { // remove the entire substack, to avoid duplicate reports - var substack = impliedEvalAncestorsStack.pop(); + let substack = impliedEvalAncestorsStack.pop(); context.report(substack[0], "Implied eval. Consider passing a function instead of a string."); } diff --git a/tools/eslint/lib/rules/no-inline-comments.js b/tools/eslint/lib/rules/no-inline-comments.js index e313eac06f01fb..87039d46971826 100644 --- a/tools/eslint/lib/rules/no-inline-comments.js +++ b/tools/eslint/lib/rules/no-inline-comments.js @@ -4,7 +4,7 @@ */ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -22,7 +22,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Will check that comments are not on lines starting with or ending with code @@ -33,16 +33,16 @@ module.exports = { function testCodeAroundComment(node) { // Get the whole line and cut it off at the start of the comment - var startLine = String(sourceCode.lines[node.loc.start.line - 1]); - var endLine = String(sourceCode.lines[node.loc.end.line - 1]); + let startLine = String(sourceCode.lines[node.loc.start.line - 1]); + let endLine = String(sourceCode.lines[node.loc.end.line - 1]); - var preamble = startLine.slice(0, node.loc.start.column).trim(); + let preamble = startLine.slice(0, node.loc.start.column).trim(); // Also check after the comment - var postamble = endLine.slice(node.loc.end.column).trim(); + let postamble = endLine.slice(node.loc.end.column).trim(); // Check that this comment isn't an ESLint directive - var isDirective = astUtils.isDirectiveComment(node); + let isDirective = astUtils.isDirectiveComment(node); // Should be empty if there was only whitespace around the comment if (!isDirective && (preamble || postamble)) { diff --git a/tools/eslint/lib/rules/no-inner-declarations.js b/tools/eslint/lib/rules/no-inner-declarations.js index 3471ce8cc735b8..3e21385a59b73e 100644 --- a/tools/eslint/lib/rules/no-inner-declarations.js +++ b/tools/eslint/lib/rules/no-inner-declarations.js @@ -31,7 +31,7 @@ module.exports = { * @returns {Object} Ancestor's type and distance from node. */ function nearestBody() { - var ancestors = context.getAncestors(), + let ancestors = context.getAncestors(), ancestor = ancestors.pop(), generation = 1; @@ -58,7 +58,7 @@ module.exports = { * @returns {void} */ function check(node) { - var body = nearestBody(node), + let body = nearestBody(node), valid = ((body.type === "Program" && body.distance === 1) || body.distance === 2); diff --git a/tools/eslint/lib/rules/no-invalid-regexp.js b/tools/eslint/lib/rules/no-invalid-regexp.js index 6f8b8673786532..eb693c55c6c9c5 100644 --- a/tools/eslint/lib/rules/no-invalid-regexp.js +++ b/tools/eslint/lib/rules/no-invalid-regexp.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var espree = require("espree"); +let espree = require("espree"); //------------------------------------------------------------------------------ // Rule Definition @@ -38,7 +38,7 @@ module.exports = { create: function(context) { - var options = context.options[0], + let options = context.options[0], allowedFlags = ""; if (options && options.allowConstructorFlags) { @@ -63,7 +63,7 @@ module.exports = { */ function check(node) { if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(node.arguments[0])) { - var flags = isString(node.arguments[1]) ? node.arguments[1].value : ""; + let flags = isString(node.arguments[1]) ? node.arguments[1].value : ""; if (allowedFlags) { flags = flags.replace(new RegExp("[" + allowedFlags + "]", "gi"), ""); @@ -72,7 +72,7 @@ module.exports = { try { void new RegExp(node.arguments[0].value); } catch (e) { - context.report(node, e.message); + context.report(node, e.message + "."); } if (flags) { @@ -80,7 +80,7 @@ module.exports = { try { espree.parse("/./" + flags, context.parserOptions); } catch (ex) { - context.report(node, "Invalid flags supplied to RegExp constructor '" + flags + "'"); + context.report(node, "Invalid flags supplied to RegExp constructor '" + flags + "'."); } } diff --git a/tools/eslint/lib/rules/no-invalid-this.js b/tools/eslint/lib/rules/no-invalid-this.js index 198bfd706ad49d..e41c47469915ba 100644 --- a/tools/eslint/lib/rules/no-invalid-this.js +++ b/tools/eslint/lib/rules/no-invalid-this.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -27,7 +27,7 @@ module.exports = { }, create: function(context) { - var stack = [], + let stack = [], sourceCode = context.getSourceCode(); /** @@ -40,7 +40,7 @@ module.exports = { * an object which has a flag that whether or not `this` keyword is valid. */ stack.getCurrent = function() { - var current = this[this.length - 1]; + let current = this[this.length - 1]; if (!current.init) { current.init = true; @@ -86,7 +86,7 @@ module.exports = { * Modules is always strict mode. */ Program: function(node) { - var scope = context.getScope(), + let scope = context.getScope(), features = context.parserOptions.ecmaFeatures || {}; stack.push({ @@ -111,7 +111,7 @@ module.exports = { // Reports if `this` of the current context is invalid. ThisExpression: function(node) { - var current = stack.getCurrent(); + let current = stack.getCurrent(); if (current && !current.valid) { context.report(node, "Unexpected 'this'."); diff --git a/tools/eslint/lib/rules/no-irregular-whitespace.js b/tools/eslint/lib/rules/no-irregular-whitespace.js index 032dd96c113928..0049de3dde91f8 100644 --- a/tools/eslint/lib/rules/no-irregular-whitespace.js +++ b/tools/eslint/lib/rules/no-irregular-whitespace.js @@ -10,10 +10,10 @@ // Constants //------------------------------------------------------------------------------ -var ALL_IRREGULARS = /[\f\v\u0085\u00A0\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/; -var IRREGULAR_WHITESPACE = /[\f\v\u0085\u00A0\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/mg; -var IRREGULAR_LINE_TERMINATORS = /[\u2028\u2029]/mg; -var LINE_BREAK = /\r\n|\r|\n|\u2028|\u2029/g; +let ALL_IRREGULARS = /[\f\v\u0085\u00A0\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/; +let IRREGULAR_WHITESPACE = /[\f\v\u0085\u00A0\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/mg; +let IRREGULAR_LINE_TERMINATORS = /[\u2028\u2029]/mg; +let LINE_BREAK = /\r\n|\r|\n|\u2028|\u2029/g; //------------------------------------------------------------------------------ // Rule Definition @@ -52,19 +52,19 @@ module.exports = { create: function(context) { // Module store of errors that we have found - var errors = []; + let errors = []; // Comment nodes. We accumulate these as we go, so we can be sure to trigger them after the whole `Program` entity is parsed, even for top-of-file comments. - var commentNodes = []; + let commentNodes = []; // Lookup the `skipComments` option, which defaults to `false`. - var options = context.options[0] || {}; - var skipComments = !!options.skipComments; - var skipStrings = options.skipStrings !== false; - var skipRegExps = !!options.skipRegExps; - var skipTemplates = !!options.skipTemplates; + let options = context.options[0] || {}; + let skipComments = !!options.skipComments; + let skipStrings = options.skipStrings !== false; + let skipRegExps = !!options.skipRegExps; + let skipTemplates = !!options.skipTemplates; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Removes errors that occur inside a string node @@ -73,11 +73,11 @@ module.exports = { * @private */ function removeWhitespaceError(node) { - var locStart = node.loc.start; - var locEnd = node.loc.end; + let locStart = node.loc.start; + let locEnd = node.loc.end; errors = errors.filter(function(error) { - var errorLoc = error[1]; + let errorLoc = error[1]; if (errorLoc.line >= locStart.line && errorLoc.line <= locEnd.line) { if (errorLoc.column >= locStart.column && (errorLoc.column <= locEnd.column || errorLoc.line < locEnd.line)) { @@ -95,8 +95,8 @@ module.exports = { * @private */ function removeInvalidNodeErrorsInIdentifierOrLiteral(node) { - var shouldCheckStrings = skipStrings && (typeof node.value === "string"); - var shouldCheckRegExps = skipRegExps && (node.value instanceof RegExp); + let shouldCheckStrings = skipStrings && (typeof node.value === "string"); + let shouldCheckRegExps = skipRegExps && (node.value instanceof RegExp); if (shouldCheckStrings || shouldCheckRegExps) { @@ -140,10 +140,10 @@ module.exports = { * @private */ function checkForIrregularWhitespace(node) { - var sourceLines = sourceCode.lines; + let sourceLines = sourceCode.lines; sourceLines.forEach(function(sourceLine, lineIndex) { - var lineNumber = lineIndex + 1, + let lineNumber = lineIndex + 1, location, match; @@ -153,7 +153,7 @@ module.exports = { column: match.index }; - errors.push([node, location, "Irregular whitespace not allowed"]); + errors.push([node, location, "Irregular whitespace not allowed."]); } }); } @@ -165,7 +165,7 @@ module.exports = { * @private */ function checkForIrregularLineTerminators(node) { - var source = sourceCode.getText(), + let source = sourceCode.getText(), sourceLines = sourceCode.lines, linebreaks = source.match(LINE_BREAK), lastLineIndex = -1, @@ -181,7 +181,7 @@ module.exports = { column: sourceLines[lineIndex].length }; - errors.push([node, location, "Irregular whitespace not allowed"]); + errors.push([node, location, "Irregular whitespace not allowed."]); lastLineIndex = lineIndex; } } @@ -203,7 +203,7 @@ module.exports = { */ function noop() {} - var nodes = {}; + let nodes = {}; if (ALL_IRREGULARS.test(sourceCode.getText())) { nodes.Program = function(node) { diff --git a/tools/eslint/lib/rules/no-label-var.js b/tools/eslint/lib/rules/no-label-var.js index 7c6d56f3552a3a..a203324f147d64 100644 --- a/tools/eslint/lib/rules/no-label-var.js +++ b/tools/eslint/lib/rules/no-label-var.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -34,7 +34,7 @@ module.exports = { /** * Check if the identifier is present inside current scope - * @param {object} scope current scope + * @param {Object} scope current scope * @param {string} name To evaluate * @returns {boolean} True if its present * @private @@ -52,7 +52,7 @@ module.exports = { LabeledStatement: function(node) { // Fetch the innermost scope. - var scope = context.getScope(); + let scope = context.getScope(); // Recursively find the identifier walking up the scope, starting // with the innermost scope. diff --git a/tools/eslint/lib/rules/no-labels.js b/tools/eslint/lib/rules/no-labels.js index da0cd8e7426643..adc5bc0f81be09 100644 --- a/tools/eslint/lib/rules/no-labels.js +++ b/tools/eslint/lib/rules/no-labels.js @@ -5,10 +5,10 @@ "use strict"; //------------------------------------------------------------------------------ -// Constants +// Requirements //------------------------------------------------------------------------------ -var LOOP_TYPES = /^(?:While|DoWhile|For|ForIn|ForOf)Statement$/; +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -39,10 +39,10 @@ module.exports = { }, create: function(context) { - var options = context.options[0]; - var allowLoop = Boolean(options && options.allowLoop); - var allowSwitch = Boolean(options && options.allowSwitch); - var scopeInfo = null; + let options = context.options[0]; + let allowLoop = Boolean(options && options.allowLoop); + let allowSwitch = Boolean(options && options.allowSwitch); + let scopeInfo = null; /** * Gets the kind of a given node. @@ -51,12 +51,10 @@ module.exports = { * @returns {string} The kind of the node. */ function getBodyKind(node) { - var type = node.type; - - if (LOOP_TYPES.test(type)) { + if (astUtils.isLoop(node)) { return "loop"; } - if (type === "SwitchStatement") { + if (node.type === "SwitchStatement") { return "switch"; } return "other"; @@ -83,7 +81,7 @@ module.exports = { * @returns {boolean} `true` if the name is a label of a loop. */ function getKind(label) { - var info = scopeInfo; + let info = scopeInfo; while (info) { if (info.label === label) { diff --git a/tools/eslint/lib/rules/no-lone-blocks.js b/tools/eslint/lib/rules/no-lone-blocks.js index 113cd89b937c66..e93f1d0809b6cd 100644 --- a/tools/eslint/lib/rules/no-lone-blocks.js +++ b/tools/eslint/lib/rules/no-lone-blocks.js @@ -23,7 +23,7 @@ module.exports = { create: function(context) { // A stack of lone blocks to be checked for block-level bindings - var loneBlocks = [], + let loneBlocks = [], ruleDef; /** @@ -32,7 +32,7 @@ module.exports = { * @returns {void} */ function report(node) { - var parent = context.getAncestors().pop(); + let parent = context.getAncestors().pop(); context.report(node, parent.type === "Program" ? "Block is redundant." : @@ -45,7 +45,7 @@ module.exports = { * @returns {boolean} True if the current node is a lone block. */ function isLoneBlock() { - var parent = context.getAncestors().pop(); + let parent = context.getAncestors().pop(); return parent.type === "BlockStatement" || parent.type === "Program"; } @@ -60,7 +60,7 @@ module.exports = { return; } - var block = context.getAncestors().pop(); + let block = context.getAncestors().pop(); if (loneBlocks[loneBlocks.length - 1] === block) { loneBlocks.pop(); diff --git a/tools/eslint/lib/rules/no-lonely-if.js b/tools/eslint/lib/rules/no-lonely-if.js index 1efd1acc018265..4c99bca8389019 100644 --- a/tools/eslint/lib/rules/no-lonely-if.js +++ b/tools/eslint/lib/rules/no-lonely-if.js @@ -23,7 +23,7 @@ module.exports = { return { IfStatement: function(node) { - var ancestors = context.getAncestors(), + let ancestors = context.getAncestors(), parent = ancestors.pop(), grandparent = ancestors.pop(); diff --git a/tools/eslint/lib/rules/no-loop-func.js b/tools/eslint/lib/rules/no-loop-func.js index 247dc52cd47516..e9409338961f3a 100644 --- a/tools/eslint/lib/rules/no-loop-func.js +++ b/tools/eslint/lib/rules/no-loop-func.js @@ -20,7 +20,7 @@ * `null`. */ function getContainingLoopNode(node) { - var parent = node.parent; + let parent = node.parent; while (parent) { switch (parent.type) { @@ -73,8 +73,8 @@ function getContainingLoopNode(node) { * @returns {ASTNode} The most outer loop node. */ function getTopLoopNode(node, excludedNode) { - var retv = node; - var border = excludedNode ? excludedNode.range[1] : 0; + let retv = node; + let border = excludedNode ? excludedNode.range[1] : 0; while (node && node.range[0] >= border) { retv = node; @@ -94,10 +94,10 @@ function getTopLoopNode(node, excludedNode) { * @returns {boolean} `true` if the reference is safe or not. */ function isSafe(funcNode, loopNode, reference) { - var variable = reference.resolved; - var definition = variable && variable.defs[0]; - var declaration = definition && definition.parent; - var kind = (declaration && declaration.type === "VariableDeclaration") + let variable = reference.resolved; + let definition = variable && variable.defs[0]; + let declaration = definition && definition.parent; + let kind = (declaration && declaration.type === "VariableDeclaration") ? declaration.kind : ""; @@ -117,7 +117,7 @@ function isSafe(funcNode, loopNode, reference) { // WriteReferences which exist after this border are unsafe because those // can modify the variable. - var border = getTopLoopNode( + let border = getTopLoopNode( loopNode, (kind === "let") ? declaration : null ).range[0]; @@ -135,7 +135,7 @@ function isSafe(funcNode, loopNode, reference) { * @returns {boolean} `true` if the reference is safe. */ function isSafeReference(upperRef) { - var id = upperRef.identifier; + let id = upperRef.identifier; return ( !upperRef.isWrite() || @@ -174,18 +174,18 @@ module.exports = { * @returns {boolean} Whether or not the node is within a loop. */ function checkForLoops(node) { - var loopNode = getContainingLoopNode(node); + let loopNode = getContainingLoopNode(node); if (!loopNode) { return; } - var references = context.getScope().through; + let references = context.getScope().through; if (references.length > 0 && !references.every(isSafe.bind(null, node, loopNode)) ) { - context.report(node, "Don't make functions within a loop"); + context.report(node, "Don't make functions within a loop."); } } diff --git a/tools/eslint/lib/rules/no-magic-numbers.js b/tools/eslint/lib/rules/no-magic-numbers.js index 2e7434c1a58f16..76d71c1e6ce526 100644 --- a/tools/eslint/lib/rules/no-magic-numbers.js +++ b/tools/eslint/lib/rules/no-magic-numbers.js @@ -42,7 +42,7 @@ module.exports = { }, create: function(context) { - var config = context.options[0] || {}, + let config = context.options[0] || {}, detectObjects = !!config.detectObjects, enforceConst = !!config.enforceConst, ignore = config.ignore || [], @@ -100,7 +100,7 @@ module.exports = { return { Literal: function(node) { - var parent = node.parent, + let parent = node.parent, value = node.value, raw = node.raw, okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"]; @@ -128,14 +128,14 @@ module.exports = { if (enforceConst && parent.parent.kind !== "const") { context.report({ node: node, - message: "Number constants declarations must use 'const'" + message: "Number constants declarations must use 'const'." }); } } else if (okTypes.indexOf(parent.type) === -1 || (parent.type === "AssignmentExpression" && parent.operator !== "=")) { context.report({ node: node, - message: "No magic number: " + raw + message: "No magic number: " + raw + "." }); } } diff --git a/tools/eslint/lib/rules/no-mixed-operators.js b/tools/eslint/lib/rules/no-mixed-operators.js index 9a8b1c3925198b..f6e686521df85c 100644 --- a/tools/eslint/lib/rules/no-mixed-operators.js +++ b/tools/eslint/lib/rules/no-mixed-operators.js @@ -9,43 +9,43 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils.js"); +let astUtils = require("../ast-utils.js"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var ARITHMETIC_OPERATORS = ["+", "-", "*", "/", "%", "**"]; -var BITWISE_OPERATORS = ["&", "|", "^", "~", "<<", ">>", ">>>"]; -var COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="]; -var LOGICAL_OPERATORS = ["&&", "||"]; -var RELATIONAL_OPERATORS = ["in", "instanceof"]; -var ALL_OPERATORS = [].concat( +let ARITHMETIC_OPERATORS = ["+", "-", "*", "/", "%", "**"]; +let BITWISE_OPERATORS = ["&", "|", "^", "~", "<<", ">>", ">>>"]; +let COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="]; +let LOGICAL_OPERATORS = ["&&", "||"]; +let RELATIONAL_OPERATORS = ["in", "instanceof"]; +let ALL_OPERATORS = [].concat( ARITHMETIC_OPERATORS, BITWISE_OPERATORS, COMPARISON_OPERATORS, LOGICAL_OPERATORS, RELATIONAL_OPERATORS ); -var DEFAULT_GROUPS = [ +let DEFAULT_GROUPS = [ ARITHMETIC_OPERATORS, BITWISE_OPERATORS, COMPARISON_OPERATORS, LOGICAL_OPERATORS, RELATIONAL_OPERATORS ]; -var TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/; +let TARGET_NODE_TYPE = /^(?:Binary|Logical)Expression$/; /** * Normalizes options. * - * @param {object|undefined} options - A options object to normalize. - * @returns {object} Normalized option object. + * @param {Object|undefined} options - A options object to normalize. + * @returns {Object} Normalized option object. */ function normalizeOptions(options) { - var hasGroups = (options && options.groups && options.groups.length > 0); - var groups = hasGroups ? options.groups : DEFAULT_GROUPS; - var allowSamePrecedence = (options && options.allowSamePrecedence) !== false; + let hasGroups = (options && options.groups && options.groups.length > 0); + let groups = hasGroups ? options.groups : DEFAULT_GROUPS; + let allowSamePrecedence = (options && options.allowSamePrecedence) !== false; return { groups: groups, @@ -102,8 +102,8 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); - var options = normalizeOptions(context.options[0]); + let sourceCode = context.getSourceCode(); + let options = normalizeOptions(context.options[0]); /** * Checks whether a given node should be ignored by options or not. @@ -114,8 +114,8 @@ module.exports = { * @returns {boolean} `true` if the node should be ignored. */ function shouldIgnore(node) { - var a = node; - var b = node.parent; + let a = node; + let b = node.parent; return ( !includesBothInAGroup(options.groups, a.operator, b.operator) || @@ -150,7 +150,7 @@ module.exports = { * @returns {Token} The operator token of the node. */ function getOperatorToken(node) { - var token = sourceCode.getTokenAfter(node.left); + let token = sourceCode.getTokenAfter(node.left); while (token.value === ")") { token = sourceCode.getTokenAfter(token); @@ -169,10 +169,10 @@ module.exports = { * @returns {void} */ function reportBothOperators(node) { - var parent = node.parent; - var left = (parent.left === node) ? node : parent; - var right = (parent.left !== node) ? node : parent; - var message = + let parent = node.parent; + let left = (parent.left === node) ? node : parent; + let right = (parent.left !== node) ? node : parent; + let message = "Unexpected mix of '" + left.operator + "' and '" + right.operator + "'."; diff --git a/tools/eslint/lib/rules/no-mixed-requires.js b/tools/eslint/lib/rules/no-mixed-requires.js index b6d365a9dbb52d..68ce51f56fcece 100644 --- a/tools/eslint/lib/rules/no-mixed-requires.js +++ b/tools/eslint/lib/rules/no-mixed-requires.js @@ -42,7 +42,7 @@ module.exports = { create: function(context) { - var grouping = false, + let grouping = false, allowCall = false, options = context.options[0]; @@ -74,13 +74,13 @@ module.exports = { ]; } - var BUILTIN_MODULES = getBuiltinModules(); + let BUILTIN_MODULES = getBuiltinModules(); - var DECL_REQUIRE = "require", + let DECL_REQUIRE = "require", DECL_UNINITIALIZED = "uninitialized", DECL_OTHER = "other"; - var REQ_CORE = "core", + let REQ_CORE = "core", REQ_FILE = "file", REQ_MODULE = "module", REQ_COMPUTED = "computed"; @@ -137,7 +137,7 @@ module.exports = { return REQ_COMPUTED; } - var arg = initExpression.arguments[0]; + let arg = initExpression.arguments[0]; if (arg.type !== "Literal" || typeof arg.value !== "string") { @@ -167,10 +167,10 @@ module.exports = { * @returns {boolean} True if the declarations are mixed, false if not. */ function isMixed(declarations) { - var contains = {}; + let contains = {}; declarations.forEach(function(declaration) { - var type = getDeclarationType(declaration.init); + let type = getDeclarationType(declaration.init); contains[type] = true; }); @@ -188,7 +188,7 @@ module.exports = { * @returns {boolean} True if the declarations are grouped, false if not. */ function isGrouped(declarations) { - var found = {}; + let found = {}; declarations.forEach(function(declaration) { if (getDeclarationType(declaration.init) === DECL_REQUIRE) { diff --git a/tools/eslint/lib/rules/no-mixed-spaces-and-tabs.js b/tools/eslint/lib/rules/no-mixed-spaces-and-tabs.js index 74553f65115cc7..19734b1b5d5d30 100644 --- a/tools/eslint/lib/rules/no-mixed-spaces-and-tabs.js +++ b/tools/eslint/lib/rules/no-mixed-spaces-and-tabs.js @@ -24,9 +24,9 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); - var smartTabs, + let smartTabs, ignoredLocs = []; switch (context.options[0]) { @@ -85,7 +85,7 @@ module.exports = { * or the reverse before non-tab/-space * characters begin. */ - var regex = /^(?=[\t ]*(\t | \t))/, + let regex = /^(?=[\t ]*(\t | \t))/, match, lines = sourceCode.lines, comments = sourceCode.getAllComments(); @@ -119,10 +119,10 @@ module.exports = { match = regex.exec(line); if (match) { - var lineNumber = i + 1, + let lineNumber = i + 1, column = match.index + 1; - for (var j = 0; j < ignoredLocs.length; j++) { + for (let j = 0; j < ignoredLocs.length; j++) { if (beforeLoc(ignoredLocs[j], lineNumber, column)) { continue; } diff --git a/tools/eslint/lib/rules/no-multi-spaces.js b/tools/eslint/lib/rules/no-multi-spaces.js index 2fd89ef4dc0d48..78d600c8848931 100644 --- a/tools/eslint/lib/rules/no-multi-spaces.js +++ b/tools/eslint/lib/rules/no-multi-spaces.js @@ -41,7 +41,7 @@ module.exports = { create: function(context) { // the index of the last comment that was checked - var exceptions = { Property: true }, + let exceptions = { Property: true }, hasExceptions = true, options = context.options[0], lastCommentIndex = 0; @@ -69,7 +69,7 @@ module.exports = { */ function isIndexInComment(index, comments) { - var comment; + let comment; while (lastCommentIndex < comments.length) { @@ -95,7 +95,7 @@ module.exports = { return { Program: function() { - var sourceCode = context.getSourceCode(), + let sourceCode = context.getSourceCode(), source = sourceCode.getText(), allComments = sourceCode.getAllComments(), pattern = /[^\n\r\u2028\u2029\t ].? {2,}/g, // note: repeating space @@ -108,7 +108,7 @@ module.exports = { * Creates a fix function that removes the multiple spaces between the two tokens * @param {RuleFixer} leftToken left token * @param {RuleFixer} rightToken right token - * @returns {function} fix function + * @returns {Function} fix function * @private */ function createFix(leftToken, rightToken) { diff --git a/tools/eslint/lib/rules/no-multi-str.js b/tools/eslint/lib/rules/no-multi-str.js index fe7fee4a60a38c..1d880104591f44 100644 --- a/tools/eslint/lib/rules/no-multi-str.js +++ b/tools/eslint/lib/rules/no-multi-str.js @@ -39,7 +39,7 @@ module.exports = { return { Literal: function(node) { - var lineBreak = /\n/; + let lineBreak = /\n/; if (lineBreak.test(node.raw) && !isJSXElement(node.parent)) { context.report(node, "Multiline support is limited to browsers supporting ES5 only."); diff --git a/tools/eslint/lib/rules/no-multiple-empty-lines.js b/tools/eslint/lib/rules/no-multiple-empty-lines.js index 7508164d38eb05..cede2d5e78abef 100644 --- a/tools/eslint/lib/rules/no-multiple-empty-lines.js +++ b/tools/eslint/lib/rules/no-multiple-empty-lines.js @@ -45,12 +45,12 @@ module.exports = { create: function(context) { // Use options.max or 2 as default - var max = 2, + let max = 2, maxEOF, maxBOF; // store lines that appear empty but really aren't - var notEmpty = []; + let notEmpty = []; if (context.options.length) { max = context.options[0].max; @@ -58,7 +58,7 @@ module.exports = { maxBOF = typeof context.options[0].maxBOF !== "undefined" ? context.options[0].maxBOF : max; } - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Public @@ -67,8 +67,8 @@ module.exports = { return { TemplateLiteral: function(node) { - var start = node.loc.start.line; - var end = node.loc.end.line; + let start = node.loc.start.line; + let end = node.loc.end.line; while (start <= end) { notEmpty.push(start); @@ -77,7 +77,7 @@ module.exports = { }, "Program:exit": function checkBlankLines(node) { - var lines = sourceCode.lines, + let lines = sourceCode.lines, fullLines = sourceCode.text.match(/.*(\r\n|\r|\n|\u2028|\u2029)/g) || [], firstNonBlankLine = -1, trimmedLines = [], @@ -98,7 +98,7 @@ module.exports = { linesRangeStart.push(0); lines.forEach(function(str, i) { - var length = i < fullLines.length ? fullLines[i].length : 0, + let length = i < fullLines.length ? fullLines[i].length : 0, trimmed = str.trim(); if ((firstNonBlankLine === -1) && (trimmed !== "")) { diff --git a/tools/eslint/lib/rules/no-native-reassign.js b/tools/eslint/lib/rules/no-native-reassign.js index 8b75f022a07163..aa8314dda67b92 100644 --- a/tools/eslint/lib/rules/no-native-reassign.js +++ b/tools/eslint/lib/rules/no-native-reassign.js @@ -33,8 +33,8 @@ module.exports = { }, create: function(context) { - var config = context.options[0]; - var exceptions = (config && config.exceptions) || []; + let config = context.options[0]; + let exceptions = (config && config.exceptions) || []; /** * Reports write references. @@ -44,7 +44,7 @@ module.exports = { * @returns {void} */ function checkReference(reference, index, references) { - var identifier = reference.identifier; + let identifier = reference.identifier; if (reference.init === false && reference.isWrite() && @@ -74,7 +74,7 @@ module.exports = { return { Program: function() { - var globalScope = context.getScope(); + let globalScope = context.getScope(); globalScope.variables.forEach(checkVariable); } diff --git a/tools/eslint/lib/rules/no-negated-in-lhs.js b/tools/eslint/lib/rules/no-negated-in-lhs.js index 891b75dd2f4171..46f6c1cad4321c 100644 --- a/tools/eslint/lib/rules/no-negated-in-lhs.js +++ b/tools/eslint/lib/rules/no-negated-in-lhs.js @@ -26,7 +26,7 @@ module.exports = { BinaryExpression: function(node) { if (node.operator === "in" && node.left.type === "UnaryExpression" && node.left.operator === "!") { - context.report(node, "The 'in' expression's left operand is negated"); + context.report(node, "The 'in' expression's left operand is negated."); } } }; diff --git a/tools/eslint/lib/rules/no-nested-ternary.js b/tools/eslint/lib/rules/no-nested-ternary.js index 34f9eaaa8dbc8a..d28ee693cf0631 100644 --- a/tools/eslint/lib/rules/no-nested-ternary.js +++ b/tools/eslint/lib/rules/no-nested-ternary.js @@ -26,7 +26,7 @@ module.exports = { ConditionalExpression: function(node) { if (node.alternate.type === "ConditionalExpression" || node.consequent.type === "ConditionalExpression") { - context.report(node, "Do not nest ternary expressions"); + context.report(node, "Do not nest ternary expressions."); } } }; diff --git a/tools/eslint/lib/rules/no-new-symbol.js b/tools/eslint/lib/rules/no-new-symbol.js index c7c524641ee6bd..d4c4e67b17b46b 100644 --- a/tools/eslint/lib/rules/no-new-symbol.js +++ b/tools/eslint/lib/rules/no-new-symbol.js @@ -24,12 +24,12 @@ module.exports = { return { "Program:exit": function() { - var globalScope = context.getScope(); - var variable = globalScope.set.get("Symbol"); + let globalScope = context.getScope(); + let variable = globalScope.set.get("Symbol"); if (variable && variable.defs.length === 0) { variable.references.forEach(function(ref) { - var node = ref.identifier; + let node = ref.identifier; if (node.parent && node.parent.type === "NewExpression") { context.report(node, "`Symbol` cannot be called as a constructor."); diff --git a/tools/eslint/lib/rules/no-new-wrappers.js b/tools/eslint/lib/rules/no-new-wrappers.js index eec774fdcad14f..756ee80076f754 100644 --- a/tools/eslint/lib/rules/no-new-wrappers.js +++ b/tools/eslint/lib/rules/no-new-wrappers.js @@ -25,7 +25,7 @@ module.exports = { return { NewExpression: function(node) { - var wrapperObjects = ["String", "Number", "Boolean", "Math", "JSON"]; + let wrapperObjects = ["String", "Number", "Boolean", "Math", "JSON"]; if (wrapperObjects.indexOf(node.callee.name) > -1) { context.report(node, "Do not use {{fn}} as a constructor.", { fn: node.callee.name }); diff --git a/tools/eslint/lib/rules/no-obj-calls.js b/tools/eslint/lib/rules/no-obj-calls.js index 0f58ab93dbd6d6..ba1c45a31fe75d 100644 --- a/tools/eslint/lib/rules/no-obj-calls.js +++ b/tools/eslint/lib/rules/no-obj-calls.js @@ -26,7 +26,7 @@ module.exports = { CallExpression: function(node) { if (node.callee.type === "Identifier") { - var name = node.callee.name; + let name = node.callee.name; if (name === "Math" || name === "JSON") { context.report(node, "'{{name}}' is not a function.", { name: name }); diff --git a/tools/eslint/lib/rules/no-octal-escape.js b/tools/eslint/lib/rules/no-octal-escape.js index 3ca01324b5ea2d..cf5953a986f914 100644 --- a/tools/eslint/lib/rules/no-octal-escape.js +++ b/tools/eslint/lib/rules/no-octal-escape.js @@ -29,7 +29,7 @@ module.exports = { return; } - var match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-3][0-7]{1,2}|[4-7][0-7]|[0-7])/), + let match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-3][0-7]{1,2}|[4-7][0-7]|[0-7])/), octalDigit; if (match) { diff --git a/tools/eslint/lib/rules/no-param-reassign.js b/tools/eslint/lib/rules/no-param-reassign.js index fad61fc0c1eb9b..3a59106a2d537e 100644 --- a/tools/eslint/lib/rules/no-param-reassign.js +++ b/tools/eslint/lib/rules/no-param-reassign.js @@ -8,7 +8,7 @@ // Rule Definition //------------------------------------------------------------------------------ -var stopNodePattern = /(?:Statement|Declaration|Function(?:Expression)?|Program)$/; +let stopNodePattern = /(?:Statement|Declaration|Function(?:Expression)?|Program)$/; module.exports = { meta: { @@ -30,7 +30,7 @@ module.exports = { }, create: function(context) { - var props = context.options[0] && Boolean(context.options[0].props); + let props = context.options[0] && Boolean(context.options[0].props); /** * Checks whether or not the reference modifies properties of its variable. @@ -38,8 +38,8 @@ module.exports = { * @returns {boolean} Whether or not the reference modifies properties of its variable. */ function isModifyingProp(reference) { - var node = reference.identifier; - var parent = node.parent; + let node = reference.identifier; + let parent = node.parent; while (parent && !stopNodePattern.test(parent.type)) { switch (parent.type) { @@ -92,7 +92,7 @@ module.exports = { * @returns {void} */ function checkReference(reference, index, references) { - var identifier = reference.identifier; + let identifier = reference.identifier; if (identifier && !reference.init && diff --git a/tools/eslint/lib/rules/no-path-concat.js b/tools/eslint/lib/rules/no-path-concat.js index 1412c6c32e3546..f13d94267455a0 100644 --- a/tools/eslint/lib/rules/no-path-concat.js +++ b/tools/eslint/lib/rules/no-path-concat.js @@ -21,7 +21,7 @@ module.exports = { create: function(context) { - var MATCHER = /^__(?:dir|file)name$/; + let MATCHER = /^__(?:dir|file)name$/; //-------------------------------------------------------------------------- // Public @@ -31,7 +31,7 @@ module.exports = { BinaryExpression: function(node) { - var left = node.left, + let left = node.left, right = node.right; if (node.operator === "+" && diff --git a/tools/eslint/lib/rules/no-plusplus.js b/tools/eslint/lib/rules/no-plusplus.js index 159a42be2c13d1..34e54001ae5885 100644 --- a/tools/eslint/lib/rules/no-plusplus.js +++ b/tools/eslint/lib/rules/no-plusplus.js @@ -33,7 +33,7 @@ module.exports = { create: function(context) { - var config = context.options[0], + let config = context.options[0], allowInForAfterthought = false; if (typeof config === "object") { diff --git a/tools/eslint/lib/rules/no-process-env.js b/tools/eslint/lib/rules/no-process-env.js index af48c78029880e..d1bf15a245db13 100644 --- a/tools/eslint/lib/rules/no-process-env.js +++ b/tools/eslint/lib/rules/no-process-env.js @@ -24,7 +24,7 @@ module.exports = { return { MemberExpression: function(node) { - var objectName = node.object.name, + let objectName = node.object.name, propertyName = node.property.name; if (objectName === "process" && !node.computed && propertyName && propertyName === "env") { diff --git a/tools/eslint/lib/rules/no-process-exit.js b/tools/eslint/lib/rules/no-process-exit.js index 6d8674418bb590..045214e7e74bc0 100644 --- a/tools/eslint/lib/rules/no-process-exit.js +++ b/tools/eslint/lib/rules/no-process-exit.js @@ -28,7 +28,7 @@ module.exports = { return { CallExpression: function(node) { - var callee = node.callee; + let callee = node.callee; if (callee.type === "MemberExpression" && callee.object.name === "process" && callee.property.name === "exit" diff --git a/tools/eslint/lib/rules/no-prototype-builtins.js b/tools/eslint/lib/rules/no-prototype-builtins.js index febb1459be67e9..08b0b6dcf9a68d 100644 --- a/tools/eslint/lib/rules/no-prototype-builtins.js +++ b/tools/eslint/lib/rules/no-prototype-builtins.js @@ -14,11 +14,13 @@ module.exports = { description: "disallow calling some `Object.prototype` methods directly on objects", category: "Possible Errors", recommended: false - } + }, + + schema: [] }, create: function(context) { - var DISALLOWED_PROPS = [ + let DISALLOWED_PROPS = [ "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable" @@ -33,7 +35,7 @@ module.exports = { if (node.callee.type !== "MemberExpression" || node.callee.computed) { return; } - var propName = node.callee.property.name; + let propName = node.callee.property.name; if (DISALLOWED_PROPS.indexOf(propName) > -1) { context.report({ diff --git a/tools/eslint/lib/rules/no-redeclare.js b/tools/eslint/lib/rules/no-redeclare.js index 4253cc85334658..8a1540ff79f575 100644 --- a/tools/eslint/lib/rules/no-redeclare.js +++ b/tools/eslint/lib/rules/no-redeclare.js @@ -29,7 +29,7 @@ module.exports = { }, create: function(context) { - var options = { + let options = { builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals) }; @@ -41,18 +41,18 @@ module.exports = { */ function findVariablesInScope(scope) { scope.variables.forEach(function(variable) { - var hasBuiltin = options.builtinGlobals && "writeable" in variable; - var count = (hasBuiltin ? 1 : 0) + variable.identifiers.length; + let hasBuiltin = options.builtinGlobals && "writeable" in variable; + let count = (hasBuiltin ? 1 : 0) + variable.identifiers.length; if (count >= 2) { variable.identifiers.sort(function(a, b) { return a.range[1] - b.range[1]; }); - for (var i = (hasBuiltin ? 0 : 1), l = variable.identifiers.length; i < l; i++) { + for (let i = (hasBuiltin ? 0 : 1), l = variable.identifiers.length; i < l; i++) { context.report( variable.identifiers[i], - "'{{a}}' is already defined", + "'{{a}}' is already defined.", {a: variable.name}); } } @@ -67,7 +67,7 @@ module.exports = { * @private */ function checkForGlobal(node) { - var scope = context.getScope(), + let scope = context.getScope(), parserOptions = context.parserOptions, ecmaFeatures = parserOptions.ecmaFeatures || {}; diff --git a/tools/eslint/lib/rules/no-regex-spaces.js b/tools/eslint/lib/rules/no-regex-spaces.js index a2f1d48f716e13..de179894b36c34 100644 --- a/tools/eslint/lib/rules/no-regex-spaces.js +++ b/tools/eslint/lib/rules/no-regex-spaces.js @@ -21,7 +21,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Validate regular expressions @@ -31,7 +31,7 @@ module.exports = { * @private */ function checkRegex(node, value) { - var multipleSpacesRegex = /( {2,})+?/, + let multipleSpacesRegex = /( {2,})+?/, regexResults = multipleSpacesRegex.exec(value); if (regexResults !== null) { @@ -46,7 +46,7 @@ module.exports = { * @private */ function checkLiteral(node) { - var token = sourceCode.getFirstToken(node), + let token = sourceCode.getFirstToken(node), nodeType = token.type, nodeValue = token.value; diff --git a/tools/eslint/lib/rules/no-restricted-globals.js b/tools/eslint/lib/rules/no-restricted-globals.js index 3292705b13b31d..19bd6a94aeca67 100644 --- a/tools/eslint/lib/rules/no-restricted-globals.js +++ b/tools/eslint/lib/rules/no-restricted-globals.js @@ -26,7 +26,7 @@ module.exports = { }, create: function(context) { - var restrictedGlobals = context.options; + let restrictedGlobals = context.options; // if no globals are restricted we don't need to check if (restrictedGlobals.length === 0) { @@ -40,7 +40,7 @@ module.exports = { * @private */ function reportReference(reference) { - context.report(reference.identifier, "Unexpected use of '{{name}}'", { + context.report(reference.identifier, "Unexpected use of '{{name}}'.", { name: reference.identifier.name }); } @@ -57,7 +57,7 @@ module.exports = { return { Program: function() { - var scope = context.getScope(); + let scope = context.getScope(); // Report variables declared elsewhere (ex: variables defined as "global" by eslint) scope.variables.forEach(function(variable) { @@ -77,4 +77,3 @@ module.exports = { }; } }; - diff --git a/tools/eslint/lib/rules/no-restricted-imports.js b/tools/eslint/lib/rules/no-restricted-imports.js index 3129ce72784b2a..da768c135c7b43 100644 --- a/tools/eslint/lib/rules/no-restricted-imports.js +++ b/tools/eslint/lib/rules/no-restricted-imports.js @@ -26,7 +26,7 @@ module.exports = { }, create: function(context) { - var restrictedImports = context.options; + let restrictedImports = context.options; // if no imports are restricted we don"t need to check if (restrictedImports.length === 0) { @@ -37,7 +37,7 @@ module.exports = { ImportDeclaration: function(node) { if (node && node.source && node.source.value) { - var value = node.source.value.trim(); + let value = node.source.value.trim(); if (restrictedImports.indexOf(value) !== -1) { context.report(node, "'{{importName}}' import is restricted from being used.", { diff --git a/tools/eslint/lib/rules/no-restricted-modules.js b/tools/eslint/lib/rules/no-restricted-modules.js index 43e53915628a77..eeb6bf270d36b4 100644 --- a/tools/eslint/lib/rules/no-restricted-modules.js +++ b/tools/eslint/lib/rules/no-restricted-modules.js @@ -28,7 +28,7 @@ module.exports = { create: function(context) { // trim restricted module names - var restrictedModules = context.options; + let restrictedModules = context.options; // if no modules are restricted we don't need to check the CallExpressions if (restrictedModules.length === 0) { @@ -56,14 +56,14 @@ module.exports = { /** * Function to check if a node has an argument that is an restricted module and return its name. * @param {ASTNode} node The node to check - * @returns {undefined|String} restricted module name or undefined if node argument isn't restricted. + * @returns {undefined|string} restricted module name or undefined if node argument isn't restricted. */ function getRestrictedModuleName(node) { - var moduleName; + let moduleName; // node has arguments and first argument is string if (node.arguments.length && isString(node.arguments[0])) { - var argumentValue = node.arguments[0].value.trim(); + let argumentValue = node.arguments[0].value.trim(); // check if argument value is in restricted modules array if (restrictedModules.indexOf(argumentValue) !== -1) { @@ -77,7 +77,7 @@ module.exports = { return { CallExpression: function(node) { if (isRequireCall(node)) { - var restrictedModuleName = getRestrictedModuleName(node); + let restrictedModuleName = getRestrictedModuleName(node); if (restrictedModuleName) { context.report(node, "'{{moduleName}}' module is restricted from being used.", { diff --git a/tools/eslint/lib/rules/no-restricted-syntax.js b/tools/eslint/lib/rules/no-restricted-syntax.js index cd9eb603f9870b..84c62d63ac0d1f 100644 --- a/tools/eslint/lib/rules/no-restricted-syntax.js +++ b/tools/eslint/lib/rules/no-restricted-syntax.js @@ -8,7 +8,7 @@ // Rule Definition //------------------------------------------------------------------------------ -var nodeTypes = require("espree").Syntax; +let nodeTypes = require("espree").Syntax; module.exports = { meta: { diff --git a/tools/eslint/lib/rules/no-return-assign.js b/tools/eslint/lib/rules/no-return-assign.js index 38fc1cb0ebbab5..54935060710e72 100644 --- a/tools/eslint/lib/rules/no-return-assign.js +++ b/tools/eslint/lib/rules/no-return-assign.js @@ -8,7 +8,7 @@ // Helpers //------------------------------------------------------------------------------ -var SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/; +let SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/; /** * Checks whether or not a node is enclosed in parentheses. @@ -17,8 +17,8 @@ var SENTINEL_TYPE = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExp * @returns {boolean} Whether or not the node is enclosed in parentheses. */ function isEnclosedInParens(node, sourceCode) { - var prevToken = sourceCode.getTokenBefore(node); - var nextToken = sourceCode.getTokenAfter(node); + let prevToken = sourceCode.getTokenBefore(node); + let nextToken = sourceCode.getTokenAfter(node); return prevToken && prevToken.value === "(" && nextToken && nextToken.value === ")"; } @@ -43,8 +43,8 @@ module.exports = { }, create: function(context) { - var always = (context.options[0] || "except-parens") !== "except-parens"; - var sourceCode = context.getSourceCode(); + let always = (context.options[0] || "except-parens") !== "except-parens"; + let sourceCode = context.getSourceCode(); return { AssignmentExpression: function(node) { @@ -52,7 +52,7 @@ module.exports = { return; } - var parent = node.parent; + let parent = node.parent; // Find ReturnStatement or ArrowFunctionExpression in ancestors. while (parent && !SENTINEL_TYPE.test(parent.type)) { diff --git a/tools/eslint/lib/rules/no-script-url.js b/tools/eslint/lib/rules/no-script-url.js index 1985cf3b95f51c..1c12490b4330f9 100644 --- a/tools/eslint/lib/rules/no-script-url.js +++ b/tools/eslint/lib/rules/no-script-url.js @@ -28,7 +28,7 @@ module.exports = { Literal: function(node) { - var value; + let value; if (node.value && typeof node.value === "string") { value = node.value.toLowerCase(); diff --git a/tools/eslint/lib/rules/no-self-assign.js b/tools/eslint/lib/rules/no-self-assign.js index bcccc3d8380a09..e3dc35e81e7cf4 100644 --- a/tools/eslint/lib/rules/no-self-assign.js +++ b/tools/eslint/lib/rules/no-self-assign.js @@ -16,11 +16,11 @@ * a Property. * @param {ASTNode|null} right - A right node to traverse. This is a Pattern or * a Property. - * @param {function} report - A callback function to report. + * @param {Function} report - A callback function to report. * @returns {void} */ function eachSelfAssignment(left, right, report) { - var i, j; + let i, j; if (!left || !right) { @@ -35,10 +35,10 @@ function eachSelfAssignment(left, right, report) { left.type === "ArrayPattern" && right.type === "ArrayExpression" ) { - var end = Math.min(left.elements.length, right.elements.length); + let end = Math.min(left.elements.length, right.elements.length); for (i = 0; i < end; ++i) { - var rightElement = right.elements[i]; + let rightElement = right.elements[i]; eachSelfAssignment(left.elements[i], rightElement, report); @@ -60,7 +60,7 @@ function eachSelfAssignment(left, right, report) { // Gets the index of the last spread property. // It's possible to overwrite properties followed by it. - var startJ = 0; + let startJ = 0; for (i = right.properties.length - 1; i >= 0; --i) { if (right.properties[i].type === "ExperimentalSpreadProperty") { diff --git a/tools/eslint/lib/rules/no-self-compare.js b/tools/eslint/lib/rules/no-self-compare.js index eef05080b75a15..c677e56ffdbd12 100644 --- a/tools/eslint/lib/rules/no-self-compare.js +++ b/tools/eslint/lib/rules/no-self-compare.js @@ -26,7 +26,7 @@ module.exports = { return { BinaryExpression: function(node) { - var operators = ["===", "==", "!==", "!=", ">", "<", ">=", "<="]; + let operators = ["===", "==", "!==", "!=", ">", "<", ">=", "<="]; if (operators.indexOf(node.operator) > -1 && (node.left.type === "Identifier" && node.right.type === "Identifier" && node.left.name === node.right.name || diff --git a/tools/eslint/lib/rules/no-sequences.js b/tools/eslint/lib/rules/no-sequences.js index b0d318c7d08ab6..51c3b8e8080b89 100644 --- a/tools/eslint/lib/rules/no-sequences.js +++ b/tools/eslint/lib/rules/no-sequences.js @@ -21,12 +21,12 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Parts of the grammar that are required to have parens. */ - var parenthesized = { + let parenthesized = { DoWhileStatement: "test", IfStatement: "test", SwitchStatement: "discriminant", @@ -57,7 +57,7 @@ module.exports = { * @returns {boolean} True if the node has a paren on each side. */ function isParenthesised(node) { - var previousToken = sourceCode.getTokenBefore(node), + let previousToken = sourceCode.getTokenBefore(node), nextToken = sourceCode.getTokenAfter(node); return previousToken && nextToken && @@ -71,7 +71,7 @@ module.exports = { * @returns {boolean} True if two parens surround the node on each side. */ function isParenthesisedTwice(node) { - var previousToken = sourceCode.getTokenBefore(node, 1), + let previousToken = sourceCode.getTokenBefore(node, 1), nextToken = sourceCode.getTokenAfter(node, 1); return isParenthesised(node) && previousToken && nextToken && @@ -99,7 +99,7 @@ module.exports = { } } - var child = sourceCode.getTokenAfter(node.expressions[0]); + let child = sourceCode.getTokenAfter(node.expressions[0]); context.report(node, child.loc.start, "Unexpected use of comma operator."); } diff --git a/tools/eslint/lib/rules/no-shadow-restricted-names.js b/tools/eslint/lib/rules/no-shadow-restricted-names.js index b7731d9d6767bb..d932363d6f7131 100644 --- a/tools/eslint/lib/rules/no-shadow-restricted-names.js +++ b/tools/eslint/lib/rules/no-shadow-restricted-names.js @@ -21,7 +21,7 @@ module.exports = { create: function(context) { - var RESTRICTED = ["undefined", "NaN", "Infinity", "arguments", "eval"]; + let RESTRICTED = ["undefined", "NaN", "Infinity", "arguments", "eval"]; /** * Check if the node name is present inside the restricted list diff --git a/tools/eslint/lib/rules/no-shadow.js b/tools/eslint/lib/rules/no-shadow.js index ee0dd69f3a571f..62f75047807b4b 100644 --- a/tools/eslint/lib/rules/no-shadow.js +++ b/tools/eslint/lib/rules/no-shadow.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -43,7 +43,7 @@ module.exports = { create: function(context) { - var options = { + let options = { builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals), hoist: (context.options[0] && context.options[0].hoist) || "functions", allow: (context.options[0] && context.options[0].allow) || [] @@ -69,7 +69,7 @@ module.exports = { * @returns {boolean} Whether or not the variable of the class name in the class scope of ClassDeclaration. */ function isDuplicatedClassNameVariable(variable) { - var block = variable.scope.block; + let block = variable.scope.block; return block.type === "ClassDeclaration" && block.id === variable.identifiers[0]; } @@ -85,12 +85,12 @@ module.exports = { * @returns {boolean} Whether or not the variable is inside initializer of scopeVar. */ function isOnInitializer(variable, scopeVar) { - var outerScope = scopeVar.scope; - var outerDef = scopeVar.defs[0]; - var outer = outerDef && outerDef.parent && outerDef.parent.range; - var innerScope = variable.scope; - var innerDef = variable.defs[0]; - var inner = innerDef && innerDef.name.range; + let outerScope = scopeVar.scope; + let outerDef = scopeVar.defs[0]; + let outer = outerDef && outerDef.parent && outerDef.parent.range; + let innerScope = variable.scope; + let innerDef = variable.defs[0]; + let inner = innerDef && innerDef.name.range; return ( outer && @@ -108,7 +108,7 @@ module.exports = { * @returns {Array|undefined} The range of the variable's identifier node. */ function getNameRange(variable) { - var def = variable.defs[0]; + let def = variable.defs[0]; return def && def.name.range; } @@ -120,9 +120,9 @@ module.exports = { * @returns {boolean} Whether or not the variable is in TDZ of scopeVar. */ function isInTdz(variable, scopeVar) { - var outerDef = scopeVar.defs[0]; - var inner = getNameRange(variable); - var outer = getNameRange(scopeVar); + let outerDef = scopeVar.defs[0]; + let inner = getNameRange(variable); + let outer = getNameRange(scopeVar); return ( inner && @@ -140,10 +140,10 @@ module.exports = { * @returns {void} */ function checkForShadows(scope) { - var variables = scope.variables; + let variables = scope.variables; - for (var i = 0; i < variables.length; ++i) { - var variable = variables[i]; + for (let i = 0; i < variables.length; ++i) { + let variable = variables[i]; // Skips "arguments" or variables of a class name in the class scope of ClassDeclaration. if (variable.identifiers.length === 0 || @@ -154,7 +154,7 @@ module.exports = { } // Gets shadowed variable. - var shadowed = astUtils.getVariableByName(scope.upper, variable.name); + let shadowed = astUtils.getVariableByName(scope.upper, variable.name); if (shadowed && (shadowed.identifiers.length > 0 || (options.builtinGlobals && "writeable" in shadowed)) && @@ -172,9 +172,9 @@ module.exports = { return { "Program:exit": function() { - var globalScope = context.getScope(); - var stack = globalScope.childScopes.slice(); - var scope; + let globalScope = context.getScope(); + let stack = globalScope.childScopes.slice(); + let scope; while (stack.length) { scope = stack.pop(); diff --git a/tools/eslint/lib/rules/no-spaced-func.js b/tools/eslint/lib/rules/no-spaced-func.js index f0a16121136cf6..90765645e87ad8 100644 --- a/tools/eslint/lib/rules/no-spaced-func.js +++ b/tools/eslint/lib/rules/no-spaced-func.js @@ -23,7 +23,7 @@ module.exports = { create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Check if open space is present in a function name @@ -32,7 +32,7 @@ module.exports = { * @private */ function detectOpenSpaces(node) { - var lastCalleeToken = sourceCode.getLastToken(node.callee), + let lastCalleeToken = sourceCode.getLastToken(node.callee), prevToken = lastCalleeToken, parenToken = sourceCode.getTokenAfter(lastCalleeToken); diff --git a/tools/eslint/lib/rules/no-sparse-arrays.js b/tools/eslint/lib/rules/no-sparse-arrays.js index b1ae0ba74036b4..4d4bfd9944c860 100644 --- a/tools/eslint/lib/rules/no-sparse-arrays.js +++ b/tools/eslint/lib/rules/no-sparse-arrays.js @@ -30,7 +30,7 @@ module.exports = { ArrayExpression: function(node) { - var emptySpot = node.elements.indexOf(null) > -1; + let emptySpot = node.elements.indexOf(null) > -1; if (emptySpot) { context.report(node, "Unexpected comma in middle of array."); diff --git a/tools/eslint/lib/rules/no-sync.js b/tools/eslint/lib/rules/no-sync.js index be6860e75af4ac..ddd1f9484b9103 100644 --- a/tools/eslint/lib/rules/no-sync.js +++ b/tools/eslint/lib/rules/no-sync.js @@ -27,7 +27,7 @@ module.exports = { return { MemberExpression: function(node) { - var propertyName = node.property.name, + let propertyName = node.property.name, syncRegex = /.*Sync$/; if (syncRegex.exec(propertyName) !== null) { diff --git a/tools/eslint/lib/rules/no-tabs.js b/tools/eslint/lib/rules/no-tabs.js new file mode 100644 index 00000000000000..ef873db2bdb0b8 --- /dev/null +++ b/tools/eslint/lib/rules/no-tabs.js @@ -0,0 +1,47 @@ +/** + * @fileoverview Rule to check for tabs inside a file + * @author Gyandeep Singh + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ +const regex = /\t/; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "Disallow tabs in file", + category: "Stylistic Issues", + recommended: false + }, + schema: [] + }, + + create(context) { + return { + Program(node) { + context.getSourceLines().forEach((line, index) => { + const match = regex.exec(line); + + if (match) { + context.report( + node, + { + line: index + 1, + column: match.index + 1 + }, + "Unexpected tab character." + ); + } + }); + } + }; + } +}; diff --git a/tools/eslint/lib/rules/no-this-before-super.js b/tools/eslint/lib/rules/no-this-before-super.js index fb172f47f3a6fa..82eda02160abfb 100644 --- a/tools/eslint/lib/rules/no-this-before-super.js +++ b/tools/eslint/lib/rules/no-this-before-super.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers @@ -55,7 +55,7 @@ module.exports = { * - scope: The scope of the owner class. * - codePath: The code path of this constructor. */ - var funcInfo = null; + let funcInfo = null; /* * Information for each code path segment. @@ -64,7 +64,7 @@ module.exports = { * - superCalled: The flag which shows `super()` called in all code paths. * - invalidNodes: The array of invalid ThisExpression and Super nodes. */ - var segInfoMap = Object.create(null); + let segInfoMap = Object.create(null); /** * Gets whether or not `super()` is called in a given code path segment. @@ -101,10 +101,10 @@ module.exports = { * @returns {void} */ function setInvalid(node) { - var segments = funcInfo.codePath.currentSegments; + let segments = funcInfo.codePath.currentSegments; - for (var i = 0; i < segments.length; ++i) { - var segment = segments[i]; + for (let i = 0; i < segments.length; ++i) { + let segment = segments[i]; if (segment.reachable) { segInfoMap[segment.id].invalidNodes.push(node); @@ -117,10 +117,10 @@ module.exports = { * @returns {void} */ function setSuperCalled() { - var segments = funcInfo.codePath.currentSegments; + let segments = funcInfo.codePath.currentSegments; - for (var i = 0; i < segments.length; ++i) { - var segment = segments[i]; + for (let i = 0; i < segments.length; ++i) { + let segment = segments[i]; if (segment.reachable) { segInfoMap[segment.id].superCalled = true; @@ -140,7 +140,7 @@ module.exports = { if (isConstructorFunction(node)) { // Class > ClassBody > MethodDefinition > FunctionExpression - var classNode = node.parent.parent.parent; + let classNode = node.parent.parent.parent; funcInfo = { upper: funcInfo, @@ -172,7 +172,7 @@ module.exports = { * @returns {void} */ onCodePathEnd: function(codePath) { - var isDerivedClass = funcInfo.hasExtends; + let isDerivedClass = funcInfo.hasExtends; funcInfo = funcInfo.upper; if (!isDerivedClass) { @@ -180,10 +180,10 @@ module.exports = { } codePath.traverseSegments(function(segment, controller) { - var info = segInfoMap[segment.id]; + let info = segInfoMap[segment.id]; - for (var i = 0; i < info.invalidNodes.length; ++i) { - var invalidNode = info.invalidNodes[i]; + for (let i = 0; i < info.invalidNodes.length; ++i) { + let invalidNode = info.invalidNodes[i]; context.report({ message: "'{{kind}}' is not allowed before 'super()'.", @@ -238,7 +238,7 @@ module.exports = { funcInfo.codePath.traverseSegments( {first: toSegment, last: fromSegment}, function(segment, controller) { - var info = segInfoMap[segment.id]; + let info = segInfoMap[segment.id]; if (info.superCalled) { info.invalidNodes = []; diff --git a/tools/eslint/lib/rules/no-throw-literal.js b/tools/eslint/lib/rules/no-throw-literal.js index bedf94379e81f3..69eda1c76545e8 100644 --- a/tools/eslint/lib/rules/no-throw-literal.js +++ b/tools/eslint/lib/rules/no-throw-literal.js @@ -27,10 +27,11 @@ function couldBeError(node) { case "AssignmentExpression": return couldBeError(node.right); - case "SequenceExpression": - var exprs = node.expressions; + case "SequenceExpression": { + const exprs = node.expressions; return exprs.length !== 0 && couldBeError(exprs[exprs.length - 1]); + } case "LogicalExpression": return couldBeError(node.left) || couldBeError(node.right); diff --git a/tools/eslint/lib/rules/no-trailing-spaces.js b/tools/eslint/lib/rules/no-trailing-spaces.js index a08907fc95f343..6b82cfc38cd5fd 100644 --- a/tools/eslint/lib/rules/no-trailing-spaces.js +++ b/tools/eslint/lib/rules/no-trailing-spaces.js @@ -32,13 +32,13 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); - var BLANK_CLASS = "[ \t\u00a0\u2000-\u200b\u2028\u2029\u3000]", + let BLANK_CLASS = "[ \t\u00a0\u2000-\u200b\u2028\u2029\u3000]", SKIP_BLANK = "^" + BLANK_CLASS + "*$", NONBLANK = BLANK_CLASS + "+$"; - var options = context.options[0] || {}, + let options = context.options[0] || {}, skipBlankLines = options.skipBlankLines || false; /** @@ -78,7 +78,7 @@ module.exports = { // Let's hack. Since Espree does not return whitespace nodes, // fetch the source code and do matching via regexps. - var re = new RegExp(NONBLANK), + let re = new RegExp(NONBLANK), skipMatch = new RegExp(SKIP_BLANK), matches, lines = sourceCode.lines, @@ -90,14 +90,14 @@ module.exports = { fixRange = [], containingNode; - for (var i = 0, ii = lines.length; i < ii; i++) { + for (let i = 0, ii = lines.length; i < ii; i++) { matches = re.exec(lines[i]); // Always add linebreak length to line length to accommodate for line break (\n or \r\n) // Because during the fix time they also reserve one spot in the array. // Usually linebreak length is 2 for \r\n (CRLF) and 1 for \n (LF) - var linebreakLength = linebreaks && linebreaks[i] ? linebreaks[i].length : 1; - var lineLength = lines[i].length + linebreakLength; + let linebreakLength = linebreaks && linebreaks[i] ? linebreaks[i].length : 1; + let lineLength = lines[i].length + linebreakLength; if (matches) { location = { diff --git a/tools/eslint/lib/rules/no-undef-init.js b/tools/eslint/lib/rules/no-undef-init.js index 8622e45701f0a1..2683f61e8aa0e4 100644 --- a/tools/eslint/lib/rules/no-undef-init.js +++ b/tools/eslint/lib/rules/no-undef-init.js @@ -25,7 +25,7 @@ module.exports = { return { VariableDeclarator: function(node) { - var name = node.id.name, + let name = node.id.name, init = node.init && node.init.name; if (init === "undefined" && node.parent.kind !== "const") { diff --git a/tools/eslint/lib/rules/no-undef.js b/tools/eslint/lib/rules/no-undef.js index b76ce4bb5bfefc..da9437157ceda3 100644 --- a/tools/eslint/lib/rules/no-undef.js +++ b/tools/eslint/lib/rules/no-undef.js @@ -14,7 +14,7 @@ * @returns {boolean} Whether or not the node is the argument of a typeof operator. */ function hasTypeOfOperator(node) { - var parent = node.parent; + let parent = node.parent; return parent.type === "UnaryExpression" && parent.operator === "typeof"; } @@ -45,15 +45,15 @@ module.exports = { }, create: function(context) { - var options = context.options[0]; - var considerTypeOf = options && options.typeof === true || false; + let options = context.options[0]; + let considerTypeOf = options && options.typeof === true || false; return { "Program:exit": function(/* node */) { - var globalScope = context.getScope(); + let globalScope = context.getScope(); globalScope.through.forEach(function(ref) { - var identifier = ref.identifier; + let identifier = ref.identifier; if (!considerTypeOf && hasTypeOfOperator(identifier)) { return; diff --git a/tools/eslint/lib/rules/no-undefined.js b/tools/eslint/lib/rules/no-undefined.js index 3ad2128b4efb0c..a34d665203f48a 100644 --- a/tools/eslint/lib/rules/no-undefined.js +++ b/tools/eslint/lib/rules/no-undefined.js @@ -25,7 +25,7 @@ module.exports = { Identifier: function(node) { if (node.name === "undefined") { - var parent = context.getAncestors().pop(); + let parent = context.getAncestors().pop(); if (!parent || parent.type !== "MemberExpression" || node !== parent.property || parent.computed) { context.report(node, "Unexpected use of undefined."); diff --git a/tools/eslint/lib/rules/no-underscore-dangle.js b/tools/eslint/lib/rules/no-underscore-dangle.js index 4217f8adc53b96..a6a3b174fc2bd4 100644 --- a/tools/eslint/lib/rules/no-underscore-dangle.js +++ b/tools/eslint/lib/rules/no-underscore-dangle.js @@ -29,6 +29,9 @@ module.exports = { }, allowAfterThis: { type: "boolean" + }, + allowAfterSuper: { + type: "boolean" } }, additionalProperties: false @@ -38,9 +41,10 @@ module.exports = { create: function(context) { - var options = context.options[0] || {}; - var ALLOWED_VARIABLES = options.allow ? options.allow : []; - var allowAfterThis = typeof options.allowAfterThis !== "undefined" ? options.allowAfterThis : false; + let options = context.options[0] || {}; + let ALLOWED_VARIABLES = options.allow ? options.allow : []; + let allowAfterThis = typeof options.allowAfterThis !== "undefined" ? options.allowAfterThis : false; + let allowAfterSuper = typeof options.allowAfterSuper !== "undefined" ? options.allowAfterSuper : false; //------------------------------------------------------------------------- // Helpers @@ -65,7 +69,7 @@ module.exports = { * @private */ function hasTrailingUnderscore(identifier) { - var len = identifier.length; + let len = identifier.length; return identifier !== "_" && (identifier[0] === "_" || identifier[len - 1] === "_"); } @@ -100,7 +104,7 @@ module.exports = { */ function checkForTrailingUnderscoreInFunctionDeclaration(node) { if (node.id) { - var identifier = node.id.name; + let identifier = node.id.name; if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !isAllowed(identifier)) { context.report(node, "Unexpected dangling '_' in '" + identifier + "'."); @@ -115,7 +119,7 @@ module.exports = { * @private */ function checkForTrailingUnderscoreInVariableExpression(node) { - var identifier = node.id.name; + let identifier = node.id.name; if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !isSpecialCaseIdentifierInVariableExpression(identifier) && !isAllowed(identifier)) { @@ -130,11 +134,13 @@ module.exports = { * @private */ function checkForTrailingUnderscoreInMemberExpression(node) { - var identifier = node.property.name, - isMemberOfThis = node.object.type === "ThisExpression"; + let identifier = node.property.name, + isMemberOfThis = node.object.type === "ThisExpression", + isMemberOfSuper = node.object.type === "Super"; if (typeof identifier !== "undefined" && hasTrailingUnderscore(identifier) && !(isMemberOfThis && allowAfterThis) && + !(isMemberOfSuper && allowAfterSuper) && !isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) { context.report(node, "Unexpected dangling '_' in '" + identifier + "'."); } diff --git a/tools/eslint/lib/rules/no-unexpected-multiline.js b/tools/eslint/lib/rules/no-unexpected-multiline.js index af0beb2c4dd697..6fcb8c681a9857 100644 --- a/tools/eslint/lib/rules/no-unexpected-multiline.js +++ b/tools/eslint/lib/rules/no-unexpected-multiline.js @@ -20,11 +20,11 @@ module.exports = { create: function(context) { - var FUNCTION_MESSAGE = "Unexpected newline between function and ( of function call."; - var PROPERTY_MESSAGE = "Unexpected newline between object and [ of property access."; - var TAGGED_TEMPLATE_MESSAGE = "Unexpected newline between template tag and template literal."; + let FUNCTION_MESSAGE = "Unexpected newline between function and ( of function call."; + let PROPERTY_MESSAGE = "Unexpected newline between object and [ of property access."; + let TAGGED_TEMPLATE_MESSAGE = "Unexpected newline between template tag and template literal."; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Check to see if there is a newline between the node and the following open bracket @@ -35,8 +35,8 @@ module.exports = { * @private */ function checkForBreakAfter(node, msg) { - var nodeExpressionEnd = node; - var openParen = sourceCode.getTokenAfter(node); + let nodeExpressionEnd = node; + let openParen = sourceCode.getTokenAfter(node); // Move along until the end of the wrapped expression while (openParen.value === ")") { diff --git a/tools/eslint/lib/rules/no-unmodified-loop-condition.js b/tools/eslint/lib/rules/no-unmodified-loop-condition.js index ed49b5996ef641..099dd5f955e999 100644 --- a/tools/eslint/lib/rules/no-unmodified-loop-condition.js +++ b/tools/eslint/lib/rules/no-unmodified-loop-condition.js @@ -9,27 +9,26 @@ // Requirements //------------------------------------------------------------------------------ -var Map = require("es6-map"), - Traverser = require("../util/traverser"), +let Traverser = require("../util/traverser"), astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var pushAll = Function.apply.bind(Array.prototype.push); -var SENTINEL_PATTERN = /(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/; -var LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/; -var GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/; -var SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/; -var DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/; +let pushAll = Function.apply.bind(Array.prototype.push); +let SENTINEL_PATTERN = /(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/; +let LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/; // for-in/of statements don't have `test` property. +let GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/; +let SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/; +let DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/; /** - * @typedef {object} LoopConditionInfo + * @typedef {Object} LoopConditionInfo * @property {escope.Reference} reference - The reference. * @property {ASTNode} group - BinaryExpression or ConditionalExpression nodes * that the reference is belonging to. - * @property {function} isInLoop - The predicate which checks a given reference + * @property {Function} isInLoop - The predicate which checks a given reference * is in this loop. * @property {boolean} modified - The flag that the reference is modified in * this loop. @@ -43,7 +42,7 @@ var DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/; */ function isWriteReference(reference) { if (reference.init) { - var def = reference.resolved && reference.resolved.defs[0]; + let def = reference.resolved && reference.resolved.defs[0]; if (!def || def.type !== "Variable" || def.parent.kind !== "var") { return false; @@ -82,8 +81,8 @@ function isUnmodifiedAndNotBelongToGroup(condition) { * @returns {boolean} `true` if the reference is inside of the node. */ function isInRange(node, reference) { - var or = node.range; - var ir = reference.identifier.range; + let or = node.range; + let ir = reference.identifier.range; return or[0] <= ir[0] && ir[1] <= or[1]; } @@ -96,7 +95,7 @@ function isInRange(node, reference) { * @returns {boolean} `true` if the reference is inside of the loop node's * condition. */ -var isInLoop = { +let isInLoop = { WhileStatement: isInRange, DoWhileStatement: isInRange, ForStatement: function(node, reference) { @@ -115,7 +114,7 @@ var isInLoop = { * @returns {boolean} `true` if the node is dynamic. */ function hasDynamicExpressions(root) { - var retv = false, + let retv = false, traverser = new Traverser(); traverser.traverse(root, { @@ -143,9 +142,9 @@ function toLoopCondition(reference) { return null; } - var group = null; - var child = reference.identifier; - var node = child.parent; + let group = null; + let child = reference.identifier; + let node = child.parent; while (node) { if (SENTINEL_PATTERN.test(node.type)) { @@ -193,7 +192,7 @@ function toLoopCondition(reference) { * @returns {ASTNode|null} The function node or null. */ function getEncloseFunctionDeclaration(reference) { - var node = reference.identifier; + let node = reference.identifier; while (node) { if (node.type === "FunctionDeclaration") { @@ -214,13 +213,13 @@ function getEncloseFunctionDeclaration(reference) { * @returns {void} */ function updateModifiedFlag(conditions, modifiers) { - var funcNode, funcVar; + let funcNode, funcVar; - for (var i = 0; i < conditions.length; ++i) { - var condition = conditions[i]; + for (let i = 0; i < conditions.length; ++i) { + let condition = conditions[i]; - for (var j = 0; !condition.modified && j < modifiers.length; ++j) { - var modifier = modifiers[j], + for (let j = 0; !condition.modified && j < modifiers.length; ++j) { + let modifier = modifiers[j], inLoop; /* @@ -255,7 +254,7 @@ module.exports = { }, create: function(context) { - var groupMap = null; + let groupMap = null; /** * Reports a given condition info. @@ -264,7 +263,7 @@ module.exports = { * @returns {void} */ function report(condition) { - var node = condition.reference.identifier; + let node = condition.reference.identifier; context.report({ node: node, @@ -281,11 +280,11 @@ module.exports = { * @returns {void} */ function registerConditionsToGroup(conditions) { - for (var i = 0; i < conditions.length; ++i) { - var condition = conditions[i]; + for (let i = 0; i < conditions.length; ++i) { + let condition = conditions[i]; if (condition.group) { - var group = groupMap.get(condition.group); + let group = groupMap.get(condition.group); if (!group) { group = []; @@ -318,7 +317,7 @@ module.exports = { function checkReferences(variable) { // Gets references that exist in loop conditions. - var conditions = variable + let conditions = variable .references .map(toLoopCondition) .filter(Boolean); @@ -331,7 +330,7 @@ module.exports = { registerConditionsToGroup(conditions); // Check the conditions are modified. - var modifiers = variable.references.filter(isWriteReference); + let modifiers = variable.references.filter(isWriteReference); if (modifiers.length > 0) { updateModifiedFlag(conditions, modifiers); @@ -348,11 +347,11 @@ module.exports = { return { "Program:exit": function() { - var queue = [context.getScope()]; + let queue = [context.getScope()]; groupMap = new Map(); - var scope; + let scope; while ((scope = queue.pop())) { pushAll(queue, scope.childScopes); diff --git a/tools/eslint/lib/rules/no-unneeded-ternary.js b/tools/eslint/lib/rules/no-unneeded-ternary.js index 1c344a42e615ea..64c767ed0eb2de 100644 --- a/tools/eslint/lib/rules/no-unneeded-ternary.js +++ b/tools/eslint/lib/rules/no-unneeded-ternary.js @@ -31,8 +31,8 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; - var defaultAssignment = options.defaultAssignment !== false; + let options = context.options[0] || {}; + let defaultAssignment = options.defaultAssignment !== false; /** * Test if the node is a boolean literal @@ -60,9 +60,9 @@ module.exports = { ConditionalExpression: function(node) { if (isBooleanLiteral(node.alternate) && isBooleanLiteral(node.consequent)) { - context.report(node, node.consequent.loc.start, "Unnecessary use of boolean literals in conditional expression"); + context.report(node, node.consequent.loc.start, "Unnecessary use of boolean literals in conditional expression."); } else if (!defaultAssignment && matchesDefaultAssignment(node)) { - context.report(node, node.consequent.loc.start, "Unnecessary use of conditional expression for default assignment"); + context.report(node, node.consequent.loc.start, "Unnecessary use of conditional expression for default assignment."); } } }; diff --git a/tools/eslint/lib/rules/no-unreachable.js b/tools/eslint/lib/rules/no-unreachable.js index c28a6d2f2fa787..d52b9f3517bc22 100644 --- a/tools/eslint/lib/rules/no-unreachable.js +++ b/tools/eslint/lib/rules/no-unreachable.js @@ -26,6 +26,75 @@ function isUnreachable(segment) { return !segment.reachable; } +/** + * The class to distinguish consecutive unreachable statements. + */ +class ConsecutiveRange { + constructor(sourceCode) { + this.sourceCode = sourceCode; + this.startNode = null; + this.endNode = null; + } + + /** + * The location object of this range. + * @type {Object} + */ + get location() { + return { + start: this.startNode.loc.start, + end: this.endNode.loc.end + }; + } + + /** + * `true` if this range is empty. + * @type {boolean} + */ + get isEmpty() { + return !(this.startNode && this.endNode); + } + + /** + * Checks whether the given node is inside of this range. + * @param {ASTNode|Token} node - The node to check. + * @returns {boolean} `true` if the node is inside of this range. + */ + contains(node) { + return ( + node.range[0] >= this.startNode.range[0] && + node.range[1] <= this.endNode.range[1] + ); + } + + /** + * Checks whether the given node is consecutive to this range. + * @param {ASTNode} node - The node to check. + * @returns {boolean} `true` if the node is consecutive to this range. + */ + isConsecutive(node) { + return this.contains(this.sourceCode.getTokenBefore(node)); + } + + /** + * Merges the given node to this range. + * @param {ASTNode} node - The node to merge. + * @returns {void} + */ + merge(node) { + this.endNode = node; + } + + /** + * Resets this range by the given node or null. + * @param {ASTNode|null} node - The node to reset, or null. + * @returns {void} + */ + reset(node) { + this.startNode = this.endNode = node; + } +} + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -42,7 +111,9 @@ module.exports = { }, create: function(context) { - var currentCodePath = null; + let currentCodePath = null; + + const range = new ConsecutiveRange(context.getSourceCode()); /** * Reports a given node if it's unreachable. @@ -50,9 +121,42 @@ module.exports = { * @returns {void} */ function reportIfUnreachable(node) { - if (currentCodePath.currentSegments.every(isUnreachable)) { - context.report({message: "Unreachable code.", node: node}); + let nextNode = null; + + if (node && currentCodePath.currentSegments.every(isUnreachable)) { + + // Store this statement to distinguish consecutive statements. + if (range.isEmpty) { + range.reset(node); + return; + } + + // Skip if this statement is inside of the current range. + if (range.contains(node)) { + return; + } + + // Merge if this statement is consecutive to the current range. + if (range.isConsecutive(node)) { + range.merge(node); + return; + } + + nextNode = node; + } + + // Report the current range since this statement is reachable or is + // not consecutive to the current range. + if (!range.isEmpty) { + context.report({ + message: "Unreachable code.", + loc: range.location, + node: range.startNode + }); } + + // Update the current range. + range.reset(nextNode); } return { @@ -96,7 +200,11 @@ module.exports = { WithStatement: reportIfUnreachable, ExportNamedDeclaration: reportIfUnreachable, ExportDefaultDeclaration: reportIfUnreachable, - ExportAllDeclaration: reportIfUnreachable + ExportAllDeclaration: reportIfUnreachable, + + "Program:exit": function() { + reportIfUnreachable(); + } }; } }; diff --git a/tools/eslint/lib/rules/no-unsafe-finally.js b/tools/eslint/lib/rules/no-unsafe-finally.js index 8c3815459c1aec..305cce28ad1d03 100644 --- a/tools/eslint/lib/rules/no-unsafe-finally.js +++ b/tools/eslint/lib/rules/no-unsafe-finally.js @@ -9,9 +9,9 @@ // Helpers //------------------------------------------------------------------------------ -var SENTINEL_NODE_TYPE_RETURN_THROW = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression)$/; -var SENTINEL_NODE_TYPE_BREAK = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement|SwitchStatement)$/; -var SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement)$/; +let SENTINEL_NODE_TYPE_RETURN_THROW = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression)$/; +let SENTINEL_NODE_TYPE_BREAK = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement|SwitchStatement)$/; +let SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement)$/; //------------------------------------------------------------------------------ @@ -24,7 +24,9 @@ module.exports = { description: "disallow control flow statements in `finally` blocks", category: "Possible Errors", recommended: true - } + }, + + schema: [] }, create: function(context) { @@ -32,7 +34,7 @@ module.exports = { * Checks if the node is the finalizer of a TryStatement * * @param {ASTNode} node - node to check. - * @returns {Boolean} - true if the node is the finalizer of a TryStatement + * @returns {boolean} - true if the node is the finalizer of a TryStatement */ function isFinallyBlock(node) { return node.parent.type === "TryStatement" && node.parent.finalizer === node; @@ -42,12 +44,12 @@ module.exports = { * Climbs up the tree if the node is not a sentinel node * * @param {ASTNode} node - node to check. - * @param {String} label - label of the break or continue statement - * @returns {Boolean} - return whether the node is a finally block or a sentinel node + * @param {string} label - label of the break or continue statement + * @returns {boolean} - return whether the node is a finally block or a sentinel node */ function isInFinallyBlock(node, label) { - var labelInside = false; - var sentinelNodeType; + let labelInside = false; + let sentinelNodeType; if (node.type === "BreakStatement" && !node.label) { sentinelNodeType = SENTINEL_NODE_TYPE_BREAK; @@ -81,7 +83,7 @@ module.exports = { function check(node) { if (isInFinallyBlock(node, node.label)) { context.report({ - message: "Unsafe usage of " + node.type, + message: "Unsafe usage of " + node.type + ".", node: node, line: node.loc.line, column: node.loc.column diff --git a/tools/eslint/lib/rules/no-unused-expressions.js b/tools/eslint/lib/rules/no-unused-expressions.js index 9438268ab24c33..d2bdda70f21ee6 100644 --- a/tools/eslint/lib/rules/no-unused-expressions.js +++ b/tools/eslint/lib/rules/no-unused-expressions.js @@ -33,7 +33,7 @@ module.exports = { }, create: function(context) { - var config = context.options[0] || {}, + let config = context.options[0] || {}, allowShortCircuit = config.allowShortCircuit || false, allowTernary = config.allowTernary || false; @@ -52,12 +52,12 @@ module.exports = { * @returns {a[]} the leading sequence of members in the given list that pass the given predicate */ function takeWhile(predicate, list) { - for (var i = 0, l = list.length; i < l; ++i) { + for (let i = 0; i < list.length; ++i) { if (!predicate(list[i])) { - break; + return list.slice(0, i); } } - return [].slice.call(list, 0, i); + return list.slice(); } /** @@ -74,7 +74,7 @@ module.exports = { * @returns {boolean} whether the given node is considered a directive in its current position */ function isDirective(node, ancestors) { - var parent = ancestors[ancestors.length - 1], + let parent = ancestors[ancestors.length - 1], grandparent = ancestors[ancestors.length - 2]; return (parent.type === "Program" || parent.type === "BlockStatement" && diff --git a/tools/eslint/lib/rules/no-unused-labels.js b/tools/eslint/lib/rules/no-unused-labels.js index 77713fc408bca4..ec13c6168e7896 100644 --- a/tools/eslint/lib/rules/no-unused-labels.js +++ b/tools/eslint/lib/rules/no-unused-labels.js @@ -21,7 +21,7 @@ module.exports = { }, create: function(context) { - var scopeInfo = null; + let scopeInfo = null; /** * Adds a scope info to the stack. @@ -68,8 +68,8 @@ module.exports = { return; } - var label = node.label.name; - var info = scopeInfo; + let label = node.label.name; + let info = scopeInfo; while (info) { if (info.label === label) { diff --git a/tools/eslint/lib/rules/no-unused-vars.js b/tools/eslint/lib/rules/no-unused-vars.js index 39b7703c3c189a..951330de9bb1b4 100644 --- a/tools/eslint/lib/rules/no-unused-vars.js +++ b/tools/eslint/lib/rules/no-unused-vars.js @@ -9,8 +9,8 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"); -var astUtils = require("../ast-utils"); +let lodash = require("lodash"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -60,15 +60,15 @@ module.exports = { create: function(context) { - var MESSAGE = "'{{name}}' is defined but never used"; + let MESSAGE = "'{{name}}' is defined but never used."; - var config = { + let config = { vars: "all", args: "after-used", caughtErrors: "none" }; - var firstOption = context.options[0]; + let firstOption = context.options[0]; if (firstOption) { if (typeof firstOption === "string") { @@ -96,7 +96,7 @@ module.exports = { // Helpers //-------------------------------------------------------------------------- - var STATEMENT_TYPE = /(?:Statement|Declaration)$/; + let STATEMENT_TYPE = /(?:Statement|Declaration)$/; /** * Determines if a given variable is being exported from a module. @@ -106,11 +106,11 @@ module.exports = { */ function isExported(variable) { - var definition = variable.defs[0]; + let definition = variable.defs[0]; if (definition) { - var node = definition.node; + let node = definition.node; if (node.type === "VariableDeclarator") { node = node.parent; @@ -142,7 +142,7 @@ module.exports = { * @private */ function isSelfReference(ref, nodes) { - var scope = ref.from; + let scope = ref.from; while (scope) { if (nodes.indexOf(scope.block) >= 0) { @@ -155,12 +155,35 @@ module.exports = { return false; } + /** + * Checks whether a given node is inside of a loop or not. + * + * @param {ASTNode} node - A node to check. + * @returns {boolean} `true` if the node is inside of a loop. + * @private + */ + function isInsideOfLoop(node) { + while (node) { + if (astUtils.isLoop(node)) { + return true; + } + if (astUtils.isFunction(node)) { + return false; + } + + node = node.parent; + } + + return false; + } + /** * Checks the position of given nodes. * * @param {ASTNode} inner - A node which is expected as inside. * @param {ASTNode} outer - A node which is expected as outside. * @returns {boolean} `true` if the `inner` node exists in the `outer` node. + * @private */ function isInside(inner, outer) { return ( @@ -173,17 +196,25 @@ module.exports = { * If a given reference is left-hand side of an assignment, this gets * the right-hand side node of the assignment. * + * In the following cases, this returns null. + * + * - The reference is not the LHS of an assignment expression. + * - The reference is inside of a loop. + * - The reference is inside of a function scope which is different from + * the declaration. + * * @param {escope.Reference} ref - A reference to check. * @param {ASTNode} prevRhsNode - The previous RHS node. - * @returns {ASTNode} The RHS node. + * @returns {ASTNode|null} The RHS node or null. + * @private */ function getRhsNode(ref, prevRhsNode) { - var id = ref.identifier; - var parent = id.parent; - var granpa = parent.parent; - var refScope = ref.from.variableScope; - var varScope = ref.resolved.scope.variableScope; - var canBeUsedLater = refScope !== varScope; + let id = ref.identifier; + let parent = id.parent; + let granpa = parent.parent; + let refScope = ref.from.variableScope; + let varScope = ref.resolved.scope.variableScope; + let canBeUsedLater = refScope !== varScope || isInsideOfLoop(id); /* * Inherits the previous node if this reference is in the node. @@ -213,10 +244,11 @@ module.exports = { * - the funcNode is assigned to a variable. * - the funcNode is bound as an argument of a function call. * - the function is bound to a property and the object satisfies above conditions. + * @private */ function isStorableFunction(funcNode, rhsNode) { - var node = funcNode; - var parent = funcNode.parent; + let node = funcNode; + let parent = funcNode.parent; while (parent && isInside(parent, rhsNode)) { switch (parent.type) { @@ -266,9 +298,10 @@ module.exports = { * @param {ASTNode} id - An Identifier node to check. * @param {ASTNode} rhsNode - The RHS node of the previous assignment. * @returns {boolean} `true` if the `id` node exists inside of a function node which can be used later. + * @private */ function isInsideOfStorableFunction(id, rhsNode) { - var funcNode = astUtils.getUpperFunction(id); + let funcNode = astUtils.getUpperFunction(id); return ( funcNode && @@ -283,11 +316,12 @@ module.exports = { * @param {escope.Reference} ref - A reference to check. * @param {ASTNode} rhsNode - The RHS node of the previous assignment. * @returns {boolean} The reference is a read to update itself. + * @private */ function isReadForItself(ref, rhsNode) { - var id = ref.identifier; - var parent = id.parent; - var granpa = parent.parent; + let id = ref.identifier; + let parent = id.parent; + let granpa = parent.parent; return ref.isRead() && ( @@ -319,7 +353,7 @@ module.exports = { * @private */ function isForInRef(ref) { - var target = ref.identifier.parent; + let target = ref.identifier.parent; // "for (var ...) { return; }" @@ -355,7 +389,7 @@ module.exports = { * @private */ function isUsedVariable(variable) { - var functionNodes = variable.defs.filter(function(def) { + let functionNodes = variable.defs.filter(function(def) { return def.type === "FunctionName"; }).map(function(def) { return def.node; @@ -368,7 +402,7 @@ module.exports = { return true; } - var forItself = isReadForItself(ref, rhsNode); + let forItself = isReadForItself(ref, rhsNode); rhsNode = getRhsNode(ref, rhsNode); @@ -388,13 +422,13 @@ module.exports = { * @private */ function collectUnusedVariables(scope, unusedVars) { - var variables = scope.variables; - var childScopes = scope.childScopes; - var i, l; + let variables = scope.variables; + let childScopes = scope.childScopes; + let i, l; if (scope.type !== "TDZ" && (scope.type !== "global" || config.vars === "all")) { for (i = 0, l = variables.length; i < l; ++i) { - var variable = variables[i]; + let variable = variables[i]; // skip a variable of class itself name in the class scope if (scope.type === "class" && scope.block.id === variable.identifiers[0]) { @@ -412,10 +446,10 @@ module.exports = { } // explicit global variables don't have definitions. - var def = variable.defs[0]; + let def = variable.defs[0]; if (def) { - var type = def.type; + let type = def.type; // skip catch variables if (type === "CatchClause") { @@ -480,13 +514,13 @@ module.exports = { * @private */ function getColumnInComment(variable, comment) { - var namePattern = new RegExp("[\\s,]" + lodash.escapeRegExp(variable.name) + "(?:$|[\\s,:])", "g"); + let namePattern = new RegExp("[\\s,]" + lodash.escapeRegExp(variable.name) + "(?:$|[\\s,:])", "g"); // To ignore the first text "global". namePattern.lastIndex = comment.value.indexOf("global") + 6; // Search a given variable name. - var match = namePattern.exec(comment.value); + let match = namePattern.exec(comment.value); return match ? match.index + 1 : 0; } @@ -500,11 +534,11 @@ module.exports = { * @private */ function getLocation(variable) { - var comment = variable.eslintExplicitGlobalComment; - var baseLoc = comment.loc.start; - var column = getColumnInComment(variable, comment); - var prefix = comment.value.slice(0, column); - var lineInComment = (prefix.match(/\n/g) || []).length; + let comment = variable.eslintExplicitGlobalComment; + let baseLoc = comment.loc.start; + let column = getColumnInComment(variable, comment); + let prefix = comment.value.slice(0, column); + let lineInComment = (prefix.match(/\n/g) || []).length; if (lineInComment > 0) { column -= 1 + prefix.lastIndexOf("\n"); @@ -526,10 +560,10 @@ module.exports = { return { "Program:exit": function(programNode) { - var unusedVars = collectUnusedVariables(context.getScope(), []); + let unusedVars = collectUnusedVariables(context.getScope(), []); - for (var i = 0, l = unusedVars.length; i < l; ++i) { - var unusedVar = unusedVars[i]; + for (let i = 0, l = unusedVars.length; i < l; ++i) { + let unusedVar = unusedVars[i]; if (unusedVar.eslintExplicitGlobal) { context.report({ diff --git a/tools/eslint/lib/rules/no-use-before-define.js b/tools/eslint/lib/rules/no-use-before-define.js index 889e709948259c..90dd05c8b1bbf6 100644 --- a/tools/eslint/lib/rules/no-use-before-define.js +++ b/tools/eslint/lib/rules/no-use-before-define.js @@ -9,17 +9,18 @@ // Helpers //------------------------------------------------------------------------------ -var SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/; +let SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/; +let FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/; /** * Parses a given value as options. * * @param {any} options - A value to parse. - * @returns {object} The parsed options. + * @returns {Object} The parsed options. */ function parseOptions(options) { - var functions = true; - var classes = true; + let functions = true; + let classes = true; if (typeof options === "string") { functions = (options !== "nofunc"); @@ -87,6 +88,14 @@ function isInRange(node, location) { /** * Checks whether or not a given reference is inside of the initializers of a given variable. * + * This returns `true` in the following cases: + * + * var a = a + * var [a = a] = list + * var {a = a} = obj + * for (var a in a) {} + * for (var a of a) {} + * * @param {Variable} variable - A variable to check. * @param {Reference} reference - A reference to check. * @returns {boolean} `true` if the reference is inside of the initializers. @@ -96,14 +105,19 @@ function isInInitializer(variable, reference) { return false; } - var node = variable.identifiers[0].parent; - var location = reference.identifier.range[1]; + let node = variable.identifiers[0].parent; + let location = reference.identifier.range[1]; while (node) { if (node.type === "VariableDeclarator") { if (isInRange(node.init, location)) { return true; } + if (FOR_IN_OF_TYPE.test(node.parent.parent.type) && + isInRange(node.parent.parent.right, location) + ) { + return true; + } break; } else if (node.type === "AssignmentPattern") { if (isInRange(node.right, location)) { @@ -151,10 +165,10 @@ module.exports = { }, create: function(context) { - var options = parseOptions(context.options[0]); + let options = parseOptions(context.options[0]); // Defines a function which checks whether or not a reference is allowed according to the option. - var isAllowed; + let isAllowed; if (options.functions && options.classes) { isAllowed = alwaysFalse; @@ -174,7 +188,7 @@ module.exports = { */ function findVariablesInScope(scope) { scope.references.forEach(function(reference) { - var variable = reference.resolved; + let variable = reference.resolved; // Skips when the reference is: // - initialization's. @@ -194,7 +208,7 @@ module.exports = { // Reports. context.report({ node: reference.identifier, - message: "'{{name}}' was used before it was defined", + message: "'{{name}}' was used before it was defined.", data: reference.identifier }); }); @@ -207,14 +221,14 @@ module.exports = { * @private */ function findVariables() { - var scope = context.getScope(); + let scope = context.getScope(); findVariablesInScope(scope); } - var ruleDefinition = { + let ruleDefinition = { "Program:exit": function(node) { - var scope = context.getScope(), + let scope = context.getScope(), ecmaFeatures = context.parserOptions.ecmaFeatures || {}; findVariablesInScope(scope); diff --git a/tools/eslint/lib/rules/no-useless-call.js b/tools/eslint/lib/rules/no-useless-call.js index 49cbbc5401c7f5..b05292ff79ee71 100644 --- a/tools/eslint/lib/rules/no-useless-call.js +++ b/tools/eslint/lib/rules/no-useless-call.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers @@ -36,13 +36,13 @@ function isCallOrNonVariadicApply(node) { * @returns {boolean} the source code for the given node. */ function equalTokens(left, right, sourceCode) { - var tokensL = sourceCode.getTokens(left); - var tokensR = sourceCode.getTokens(right); + let tokensL = sourceCode.getTokens(left); + let tokensR = sourceCode.getTokens(right); if (tokensL.length !== tokensR.length) { return false; } - for (var i = 0; i < tokensL.length; ++i) { + for (let i = 0; i < tokensL.length; ++i) { if (tokensL[i].type !== tokensR[i].type || tokensL[i].value !== tokensR[i].value ) { @@ -83,7 +83,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { CallExpression: function(node) { @@ -91,9 +91,9 @@ module.exports = { return; } - var applied = node.callee.object; - var expectedThis = (applied.type === "MemberExpression") ? applied.object : null; - var thisArg = node.arguments[0]; + let applied = node.callee.object; + let expectedThis = (applied.type === "MemberExpression") ? applied.object : null; + let thisArg = node.arguments[0]; if (isValidThisArg(expectedThis, thisArg, sourceCode)) { context.report( diff --git a/tools/eslint/lib/rules/no-useless-computed-key.js b/tools/eslint/lib/rules/no-useless-computed-key.js index 2e0ac18019a70e..f25b9e547433ed 100644 --- a/tools/eslint/lib/rules/no-useless-computed-key.js +++ b/tools/eslint/lib/rules/no-useless-computed-key.js @@ -8,7 +8,7 @@ // Rule Definition //------------------------------------------------------------------------------ -var MESSAGE_UNNECESSARY_COMPUTED = "Unnecessarily computed property [{{property}}] found."; +let MESSAGE_UNNECESSARY_COMPUTED = "Unnecessarily computed property [{{property}}] found."; module.exports = { meta: { @@ -16,10 +16,12 @@ module.exports = { description: "disallow unnecessary computed property keys in object literals", category: "ECMAScript 6", recommended: false - } + }, + + schema: [] }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { Property: function(node) { @@ -27,7 +29,7 @@ module.exports = { return; } - var key = node.key, + let key = node.key, nodeType = typeof key.value; if (key.type === "Literal" && (nodeType === "string" || nodeType === "number")) { diff --git a/tools/eslint/lib/rules/no-useless-concat.js b/tools/eslint/lib/rules/no-useless-concat.js index 8569d4276a4454..6c4cecd7b67139 100644 --- a/tools/eslint/lib/rules/no-useless-concat.js +++ b/tools/eslint/lib/rules/no-useless-concat.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers @@ -29,7 +29,7 @@ function isConcatenation(node) { * @returns {ASTNode} node */ function getLeft(node) { - var left = node.left; + let left = node.left; while (isConcatenation(left)) { left = left.right; @@ -43,7 +43,7 @@ function getLeft(node) { * @returns {ASTNode} node */ function getRight(node) { - var right = node.right; + let right = node.right; while (isConcatenation(right)) { right = right.left; @@ -67,7 +67,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { BinaryExpression: function(node) { @@ -78,8 +78,8 @@ module.exports = { } // account for the `foo + "a" + "b"` case - var left = getLeft(node); - var right = getRight(node); + let left = getLeft(node); + let right = getRight(node); if (astUtils.isStringLiteral(left) && astUtils.isStringLiteral(right) && @@ -87,7 +87,7 @@ module.exports = { ) { // move warning location to operator - var operatorToken = sourceCode.getTokenAfter(left); + let operatorToken = sourceCode.getTokenAfter(left); while (operatorToken.value !== "+") { operatorToken = sourceCode.getTokenAfter(operatorToken); diff --git a/tools/eslint/lib/rules/no-useless-constructor.js b/tools/eslint/lib/rules/no-useless-constructor.js index b91ab4bcae5866..f6be08f69da43d 100644 --- a/tools/eslint/lib/rules/no-useless-constructor.js +++ b/tools/eslint/lib/rules/no-useless-constructor.js @@ -109,7 +109,7 @@ function isPassingThrough(ctorParams, superArgs) { return false; } - for (var i = 0; i < ctorParams.length; ++i) { + for (let i = 0; i < ctorParams.length; ++i) { if (!isValidPair(ctorParams[i], superArgs[i])) { return false; } @@ -163,9 +163,9 @@ module.exports = { return; } - var body = node.value.body.body; - var ctorParams = node.value.params; - var superClass = node.parent.parent.superClass; + let body = node.value.body.body; + let ctorParams = node.value.params; + let superClass = node.parent.parent.superClass; if (superClass ? isRedundantSuperCall(body, ctorParams) : (body.length === 0)) { context.report({ diff --git a/tools/eslint/lib/rules/no-useless-escape.js b/tools/eslint/lib/rules/no-useless-escape.js index 036831fc394f4f..226a9da16590d2 100644 --- a/tools/eslint/lib/rules/no-useless-escape.js +++ b/tools/eslint/lib/rules/no-useless-escape.js @@ -9,7 +9,7 @@ // Rule Definition //------------------------------------------------------------------------------ -var VALID_STRING_ESCAPES = [ +let VALID_STRING_ESCAPES = [ "\\", "n", "r", @@ -23,7 +23,7 @@ var VALID_STRING_ESCAPES = [ "\r" ]; -var VALID_REGEX_ESCAPES = [ +let VALID_REGEX_ESCAPES = [ "\\", ".", "-", @@ -80,8 +80,8 @@ module.exports = { * @returns {void} */ function validate(escapes, node, elm) { - var escapeNotFound = escapes.indexOf(elm[0][1]) === -1; - var isQuoteEscape = elm[0][1] === node.raw[0]; + let escapeNotFound = escapes.indexOf(elm[0][1]) === -1; + let isQuoteEscape = elm[0][1] === node.raw[0]; if (escapeNotFound && !isQuoteEscape) { context.report({ @@ -90,7 +90,7 @@ module.exports = { line: node.loc.start.line, column: node.loc.start.column + elm.index }, - message: "Unnecessary escape character: " + elm[0] + message: "Unnecessary escape character: " + elm[0] + "." }); } } @@ -102,8 +102,8 @@ module.exports = { * @returns {void} */ function check(node) { - var nodeEscapes, match; - var pattern = /\\[^\d]/g; + let nodeEscapes, match; + let pattern = /\\[^\d]/g; if (typeof node.value === "string") { diff --git a/tools/eslint/lib/rules/no-useless-rename.js b/tools/eslint/lib/rules/no-useless-rename.js index ec2282784b572c..80539e57723ad3 100644 --- a/tools/eslint/lib/rules/no-useless-rename.js +++ b/tools/eslint/lib/rules/no-useless-rename.js @@ -31,7 +31,7 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}, + let options = context.options[0] || {}, ignoreDestructuring = options.ignoreDestructuring === true, ignoreImport = options.ignoreImport === true, ignoreExport = options.ignoreExport === true; @@ -49,7 +49,7 @@ module.exports = { * @returns {void} */ function reportError(node, initial, result, type) { - var name = initial.type === "Identifier" ? initial.name : initial.value; + let name = initial.type === "Identifier" ? initial.name : initial.value; return context.report({ node: node, @@ -73,7 +73,7 @@ module.exports = { * @returns {void} */ function checkDestructured(node) { - var properties, + let properties, i; if (ignoreDestructuring) { diff --git a/tools/eslint/lib/rules/no-var.js b/tools/eslint/lib/rules/no-var.js index 2e9948a330e190..fc7783d7160e40 100644 --- a/tools/eslint/lib/rules/no-var.js +++ b/tools/eslint/lib/rules/no-var.js @@ -5,6 +5,72 @@ "use strict"; +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +let SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/; + +/** + * Gets the scope node which directly contains a given node. + * + * @param {ASTNode} node - A node to get. This is a `VariableDeclaration` or + * an `Identifier`. + * @returns {ASTNode} A scope node. This is one of `Program`, `BlockStatement`, + * `SwitchStatement`, `ForStatement`, `ForInStatement`, and + * `ForOfStatement`. + */ +function getScopeNode(node) { + while (node) { + if (SCOPE_NODE_TYPE.test(node.type)) { + return node; + } + + node = node.parent; + } + + /* istanbul ignore next : unreachable */ + return null; +} + +/** + * Checks whether a given variable is redeclared or not. + * + * @param {escope.Variable} variable - A variable to check. + * @returns {boolean} `true` if the variable is redeclared. + */ +function isRedeclared(variable) { + return variable.defs.length >= 2; +} + +/** + * Checks whether a given variable is used from outside of the specified scope. + * + * @param {ASTNode} scopeNode - A scope node to check. + * @returns {Function} The predicate function which checks whether a given + * variable is used from outside of the specified scope. + */ +function isUsedFromOutsideOf(scopeNode) { + + /** + * Checks whether a given reference is inside of the specified scope or not. + * + * @param {escope.Reference} reference - A reference to check. + * @returns {boolean} `true` if the reference is inside of the specified + * scope. + */ + function isOutsideOfScope(reference) { + let scope = scopeNode.range; + let id = reference.identifier.range; + + return id[0] < scope[0] || id[1] > scope[1]; + } + + return function(variable) { + return variable.references.some(isOutsideOfScope); + }; +} + //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ @@ -17,19 +83,80 @@ module.exports = { recommended: false }, - schema: [] + schema: [], + fixable: "code" }, create: function(context) { + let sourceCode = context.getSourceCode(); + + /** + * Checks whether it can fix a given variable declaration or not. + * It cannot fix if the following cases: + * + * - A variable is declared on a SwitchCase node. + * - A variable is redeclared. + * - A variable is used from outside the scope. + * + * ## A variable is declared on a SwitchCase node. + * + * If this rule modifies 'var' declarations on a SwitchCase node, it + * would generate the warnings of 'no-case-declarations' rule. And the + * 'eslint:recommended' preset includes 'no-case-declarations' rule, so + * this rule doesn't modify those declarations. + * + * ## A variable is redeclared. + * + * The language spec disallows redeclarations of `let` declarations. + * Those variables would cause syntax errors. + * + * ## A variable is used from outside the scope. + * + * The language spec disallows accesses from outside of the scope for + * `let` declarations. Those variables would cause reference errors. + * + * @param {ASTNode} node - A variable declaration node to check. + * @returns {boolean} `true` if it can fix the node. + */ + function canFix(node) { + let variables = context.getDeclaredVariables(node); + let scopeNode = getScopeNode(node); + + return !( + node.parent.type === "SwitchCase" || + variables.some(isRedeclared) || + variables.some(isUsedFromOutsideOf(scopeNode)) + ); + } + + /** + * Reports a given variable declaration node. + * + * @param {ASTNode} node - A variable declaration node to report. + * @returns {void} + */ + function report(node) { + let varToken = sourceCode.getFirstToken(node); + + context.report({ + node: node, + message: "Unexpected var, use let or const instead.", + + fix: function(fixer) { + if (canFix(node)) { + return fixer.replaceText(varToken, "let"); + } + return null; + } + }); + } return { VariableDeclaration: function(node) { if (node.kind === "var") { - context.report(node, "Unexpected var, use let or const instead."); + report(node); } } - }; - } }; diff --git a/tools/eslint/lib/rules/no-warning-comments.js b/tools/eslint/lib/rules/no-warning-comments.js index dadf231f5c39f0..7db6ed1234b830 100644 --- a/tools/eslint/lib/rules/no-warning-comments.js +++ b/tools/eslint/lib/rules/no-warning-comments.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -40,7 +40,7 @@ module.exports = { create: function(context) { - var configuration = context.options[0] || {}, + let configuration = context.options[0] || {}, warningTerms = configuration.terms || ["todo", "fixme", "xxx"], location = configuration.location || "start", selfConfigRegEx = /\bno-warning-comments\b/, @@ -51,11 +51,11 @@ module.exports = { * location ("start" or "anywhere"). If the term starts or ends with non word characters, then the match will not * require word boundaries on that side. * - * @param {String} term A term to convert to a RegExp + * @param {string} term A term to convert to a RegExp * @returns {RegExp} The term converted to a RegExp */ function convertToRegExp(term) { - var escaped = term.replace(/[-\/\\$\^*+?.()|\[\]{}]/g, "\\$&"), + let escaped = term.replace(/[-\/\\$\^*+?.()|\[\]{}]/g, "\\$&"), suffix, prefix; @@ -89,11 +89,11 @@ module.exports = { /** * Checks the specified comment for matches of the configured warning terms and returns the matches. - * @param {String} comment The comment which is checked. + * @param {string} comment The comment which is checked. * @returns {Array} All matched warning terms for this comment. */ function commentContainsWarningTerm(comment) { - var matches = []; + let matches = []; warningRegExps.forEach(function(regex, index) { if (regex.test(comment)) { @@ -114,7 +114,7 @@ module.exports = { return; } - var matches = commentContainsWarningTerm(node.value); + let matches = commentContainsWarningTerm(node.value); matches.forEach(function(matchedTerm) { context.report(node, "Unexpected '" + matchedTerm + "' comment."); diff --git a/tools/eslint/lib/rules/no-whitespace-before-property.js b/tools/eslint/lib/rules/no-whitespace-before-property.js index 347c63d934f166..fd13ba9d5d530c 100644 --- a/tools/eslint/lib/rules/no-whitespace-before-property.js +++ b/tools/eslint/lib/rules/no-whitespace-before-property.js @@ -4,7 +4,7 @@ */ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -23,7 +23,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers @@ -36,7 +36,7 @@ module.exports = { * @private */ function findOpeningBracket(node) { - var token = sourceCode.getTokenBefore(node.property); + let token = sourceCode.getTokenBefore(node.property); while (token.value !== "[") { token = sourceCode.getTokenBefore(token); @@ -53,7 +53,7 @@ module.exports = { * @private */ function reportError(node, leftToken, rightToken) { - var replacementText = node.computed ? "" : "."; + let replacementText = node.computed ? "" : "."; context.report({ node: node, @@ -73,8 +73,8 @@ module.exports = { return { MemberExpression: function(node) { - var rightToken; - var leftToken; + let rightToken; + let leftToken; if (!astUtils.isTokenOnSameLine(node.object, node.property)) { return; diff --git a/tools/eslint/lib/rules/object-curly-newline.js b/tools/eslint/lib/rules/object-curly-newline.js index aaa4af02a28f55..b69bd190447af0 100644 --- a/tools/eslint/lib/rules/object-curly-newline.js +++ b/tools/eslint/lib/rules/object-curly-newline.js @@ -9,14 +9,14 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ // Schema objects. -var OPTION_VALUE = { +let OPTION_VALUE = { oneOf: [ { enum: ["always", "never"] @@ -41,12 +41,12 @@ var OPTION_VALUE = { /** * Normalizes a given option value. * - * @param {string|object|undefined} value - An option value to parse. + * @param {string|Object|undefined} value - An option value to parse. * @returns {{multiline: boolean, minProperties: number}} Normalized option object. */ function normalizeOptionValue(value) { - var multiline = false; - var minProperties = Number.POSITIVE_INFINITY; + let multiline = false; + let minProperties = Number.POSITIVE_INFINITY; if (value) { if (value === "always") { @@ -67,7 +67,7 @@ function normalizeOptionValue(value) { /** * Normalizes a given option value. * - * @param {string|object|undefined} options - An option value to parse. + * @param {string|Object|undefined} options - An option value to parse. * @returns {{ObjectExpression: {multiline: boolean, minProperties: number}, ObjectPattern: {multiline: boolean, minProperties: number}}} Normalized option object. */ function normalizeOptions(options) { @@ -78,7 +78,7 @@ function normalizeOptions(options) { }; } - var value = normalizeOptionValue(options); + let value = normalizeOptionValue(options); return {ObjectExpression: value, ObjectPattern: value}; } @@ -114,8 +114,8 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); - var normalizedOptions = normalizeOptions(context.options[0]); + let sourceCode = context.getSourceCode(); + let normalizedOptions = normalizeOptions(context.options[0]); /** * Reports a given node if it violated this rule. @@ -125,12 +125,12 @@ module.exports = { * @returns {void} */ function check(node) { - var options = normalizedOptions[node.type]; - var openBrace = sourceCode.getFirstToken(node); - var closeBrace = sourceCode.getLastToken(node); - var first = sourceCode.getTokenOrCommentAfter(openBrace); - var last = sourceCode.getTokenOrCommentBefore(closeBrace); - var needsLinebreaks = ( + let options = normalizedOptions[node.type]; + let openBrace = sourceCode.getFirstToken(node); + let closeBrace = sourceCode.getLastToken(node); + let first = sourceCode.getTokenOrCommentAfter(openBrace); + let last = sourceCode.getTokenOrCommentBefore(closeBrace); + let needsLinebreaks = ( node.properties.length >= options.minProperties || ( options.multiline && @@ -153,7 +153,7 @@ module.exports = { if (needsLinebreaks) { if (astUtils.isTokenOnSameLine(openBrace, first)) { context.report({ - message: "Expected a line break after this open brace.", + message: "Expected a line break after this opening brace.", node: node, loc: openBrace.loc.start, fix: function(fixer) { @@ -163,7 +163,7 @@ module.exports = { } if (astUtils.isTokenOnSameLine(last, closeBrace)) { context.report({ - message: "Expected a line break before this close brace.", + message: "Expected a line break before this closing brace.", node: node, loc: closeBrace.loc.start, fix: function(fixer) { @@ -174,7 +174,7 @@ module.exports = { } else { if (!astUtils.isTokenOnSameLine(openBrace, first)) { context.report({ - message: "Unexpected a line break after this open brace.", + message: "Unexpected line break after this opening brace.", node: node, loc: openBrace.loc.start, fix: function(fixer) { @@ -187,7 +187,7 @@ module.exports = { } if (!astUtils.isTokenOnSameLine(last, closeBrace)) { context.report({ - message: "Unexpected a line break before this close brace.", + message: "Unexpected line break before this closing brace.", node: node, loc: closeBrace.loc.start, fix: function(fixer) { diff --git a/tools/eslint/lib/rules/object-curly-spacing.js b/tools/eslint/lib/rules/object-curly-spacing.js index e5dfb8d036cb04..4fe1f85758be67 100644 --- a/tools/eslint/lib/rules/object-curly-spacing.js +++ b/tools/eslint/lib/rules/object-curly-spacing.js @@ -4,7 +4,7 @@ */ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -40,7 +40,7 @@ module.exports = { }, create: function(context) { - var spaced = context.options[0] === "always", + let spaced = context.options[0] === "always", sourceCode = context.getSourceCode(); /** @@ -54,7 +54,7 @@ module.exports = { return context.options[1] ? context.options[1][option] === !spaced : false; } - var options = { + let options = { spaced: spaced, arraysInObjectsException: isOptionSet("arraysInObjects"), objectsInObjectsException: isOptionSet("objectsInObjects") @@ -74,9 +74,9 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "There should be no space after '" + token.value + "'", + message: "There should be no space after '" + token.value + "'.", fix: function(fixer) { - var nextToken = context.getSourceCode().getTokenAfter(token); + let nextToken = context.getSourceCode().getTokenAfter(token); return fixer.removeRange([token.range[1], nextToken.range[0]]); } @@ -93,9 +93,9 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "There should be no space before '" + token.value + "'", + message: "There should be no space before '" + token.value + "'.", fix: function(fixer) { - var previousToken = context.getSourceCode().getTokenBefore(token); + let previousToken = context.getSourceCode().getTokenBefore(token); return fixer.removeRange([previousToken.range[1], token.range[0]]); } @@ -112,7 +112,7 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "A space is required after '" + token.value + "'", + message: "A space is required after '" + token.value + "'.", fix: function(fixer) { return fixer.insertTextAfter(token, " "); } @@ -129,7 +129,7 @@ module.exports = { context.report({ node: node, loc: token.loc.start, - message: "A space is required before '" + token.value + "'", + message: "A space is required before '" + token.value + "'.", fix: function(fixer) { return fixer.insertTextBefore(token, " "); } @@ -146,7 +146,7 @@ module.exports = { * @returns {void} */ function validateBraceSpacing(node, first, second, penultimate, last) { - var shouldCheckPenultimate, + let shouldCheckPenultimate, penultimateType, closingCurlyBraceMustBeSpaced, firstSpaced, @@ -195,7 +195,7 @@ module.exports = { return; } - var first = sourceCode.getFirstToken(node), + let first = sourceCode.getFirstToken(node), last = sourceCode.getLastToken(node), second = sourceCode.getTokenAfter(first), penultimate = sourceCode.getTokenBefore(last); @@ -213,7 +213,7 @@ module.exports = { return; } - var firstSpecifier = node.specifiers[0], + let firstSpecifier = node.specifiers[0], lastSpecifier = node.specifiers[node.specifiers.length - 1]; if (lastSpecifier.type !== "ImportSpecifier") { @@ -223,7 +223,7 @@ module.exports = { firstSpecifier = node.specifiers[1]; } - var first = sourceCode.getTokenBefore(firstSpecifier), + let first = sourceCode.getTokenBefore(firstSpecifier), last = sourceCode.getTokenAfter(lastSpecifier); // to support a trailing comma. @@ -231,7 +231,7 @@ module.exports = { last = sourceCode.getTokenAfter(last); } - var second = sourceCode.getTokenAfter(first), + let second = sourceCode.getTokenAfter(first), penultimate = sourceCode.getTokenBefore(last); validateBraceSpacing(node, first, second, penultimate, last); @@ -247,7 +247,7 @@ module.exports = { return; } - var firstSpecifier = node.specifiers[0], + let firstSpecifier = node.specifiers[0], lastSpecifier = node.specifiers[node.specifiers.length - 1], first = sourceCode.getTokenBefore(firstSpecifier), last = sourceCode.getTokenAfter(lastSpecifier); @@ -257,7 +257,7 @@ module.exports = { last = sourceCode.getTokenAfter(last); } - var second = sourceCode.getTokenAfter(first), + let second = sourceCode.getTokenAfter(first), penultimate = sourceCode.getTokenBefore(last); validateBraceSpacing(node, first, second, penultimate, last); diff --git a/tools/eslint/lib/rules/object-property-newline.js b/tools/eslint/lib/rules/object-property-newline.js index eb96152bb167cb..fef7b871b442e1 100644 --- a/tools/eslint/lib/rules/object-property-newline.js +++ b/tools/eslint/lib/rules/object-property-newline.js @@ -31,21 +31,21 @@ module.exports = { }, create: function(context) { - var allowSameLine = context.options[0] && Boolean(context.options[0].allowMultiplePropertiesPerLine); - var errorMessage = allowSameLine ? - "Object properties must go on a new line if they aren't all on the same line" : - "Object properties must go on a new line"; + let allowSameLine = context.options[0] && Boolean(context.options[0].allowMultiplePropertiesPerLine); + let errorMessage = allowSameLine ? + "Object properties must go on a new line if they aren't all on the same line." : + "Object properties must go on a new line."; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { ObjectExpression: function(node) { - var lastTokenOfPreviousProperty, firstTokenOfCurrentProperty; + let lastTokenOfPreviousProperty, firstTokenOfCurrentProperty; if (allowSameLine) { if (node.properties.length > 1) { - var firstTokenOfFirstProperty = sourceCode.getFirstToken(node.properties[0]); - var lastTokenOfLastProperty = sourceCode.getLastToken(node.properties[node.properties.length - 1]); + let firstTokenOfFirstProperty = sourceCode.getFirstToken(node.properties[0]); + let lastTokenOfLastProperty = sourceCode.getLastToken(node.properties[node.properties.length - 1]); if (firstTokenOfFirstProperty.loc.end.line === lastTokenOfLastProperty.loc.start.line) { @@ -55,7 +55,7 @@ module.exports = { } } - for (var i = 1; i < node.properties.length; i++) { + for (let i = 1; i < node.properties.length; i++) { lastTokenOfPreviousProperty = sourceCode.getLastToken(node.properties[i - 1]); firstTokenOfCurrentProperty = sourceCode.getFirstToken(node.properties[i]); diff --git a/tools/eslint/lib/rules/object-shorthand.js b/tools/eslint/lib/rules/object-shorthand.js index a528c00d38f0a8..1d08178d57e58f 100644 --- a/tools/eslint/lib/rules/object-shorthand.js +++ b/tools/eslint/lib/rules/object-shorthand.js @@ -5,7 +5,7 @@ "use strict"; -var OPTIONS = { +let OPTIONS = { always: "always", never: "never", methods: "methods", @@ -83,14 +83,14 @@ module.exports = { }, create: function(context) { - var APPLY = context.options[0] || OPTIONS.always; - var APPLY_TO_METHODS = APPLY === OPTIONS.methods || APPLY === OPTIONS.always; - var APPLY_TO_PROPS = APPLY === OPTIONS.properties || APPLY === OPTIONS.always; - var APPLY_NEVER = APPLY === OPTIONS.never; + let APPLY = context.options[0] || OPTIONS.always; + let APPLY_TO_METHODS = APPLY === OPTIONS.methods || APPLY === OPTIONS.always; + let APPLY_TO_PROPS = APPLY === OPTIONS.properties || APPLY === OPTIONS.always; + let APPLY_NEVER = APPLY === OPTIONS.never; - var PARAMS = context.options[1] || {}; - var IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors; - var AVOID_QUOTES = PARAMS.avoidQuotes; + let PARAMS = context.options[1] || {}; + let IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors; + let AVOID_QUOTES = PARAMS.avoidQuotes; //-------------------------------------------------------------------------- // Helpers @@ -103,7 +103,7 @@ module.exports = { * @private */ function isConstructor(name) { - var firstChar = name.charAt(0); + let firstChar = name.charAt(0); return firstChar === firstChar.toUpperCase(); } @@ -123,7 +123,7 @@ module.exports = { return { Property: function(node) { - var isConciseProperty = node.method || node.shorthand, + let isConciseProperty = node.method || node.shorthand, type; // Ignore destructuring assignment diff --git a/tools/eslint/lib/rules/one-var-declaration-per-line.js b/tools/eslint/lib/rules/one-var-declaration-per-line.js index f4cdb84b187fa2..e7a29fb115dc5c 100644 --- a/tools/eslint/lib/rules/one-var-declaration-per-line.js +++ b/tools/eslint/lib/rules/one-var-declaration-per-line.js @@ -25,8 +25,8 @@ module.exports = { create: function(context) { - var ERROR_MESSAGE = "Expected variable declaration to be on a new line."; - var always = context.options[0] === "always"; + let ERROR_MESSAGE = "Expected variable declaration to be on a new line."; + let always = context.options[0] === "always"; //-------------------------------------------------------------------------- // Helpers @@ -54,8 +54,8 @@ module.exports = { return; } - var declarations = node.declarations; - var prev; + let declarations = node.declarations; + let prev; declarations.forEach(function(current) { if (prev && prev.loc.end.line === current.loc.start.line) { diff --git a/tools/eslint/lib/rules/one-var.js b/tools/eslint/lib/rules/one-var.js index 2bd49f511f4f15..10cdb626e57dd0 100644 --- a/tools/eslint/lib/rules/one-var.js +++ b/tools/eslint/lib/rules/one-var.js @@ -57,12 +57,12 @@ module.exports = { create: function(context) { - var MODE_ALWAYS = "always", + let MODE_ALWAYS = "always", MODE_NEVER = "never"; - var mode = context.options[0] || MODE_ALWAYS; + let mode = context.options[0] || MODE_ALWAYS; - var options = { + let options = { }; if (typeof mode === "string") { // simple options configuration with just a string @@ -113,8 +113,8 @@ module.exports = { // Helpers //-------------------------------------------------------------------------- - var functionStack = []; - var blockStack = []; + let functionStack = []; + let blockStack = []; /** * Increments the blockStack counter. @@ -166,7 +166,7 @@ module.exports = { * @private */ function recordTypes(statementType, declarations, currentScope) { - for (var i = 0; i < declarations.length; i++) { + for (let i = 0; i < declarations.length; i++) { if (declarations[i].init === null) { if (options[statementType] && options[statementType].uninitialized === MODE_ALWAYS) { currentScope.uninitialized = true; @@ -185,7 +185,7 @@ module.exports = { * @returns {Object} The scope associated with statementType */ function getCurrentScope(statementType) { - var currentScope; + let currentScope; if (statementType === "var") { currentScope = functionStack[functionStack.length - 1]; @@ -204,9 +204,9 @@ module.exports = { * @private */ function countDeclarations(declarations) { - var counts = { uninitialized: 0, initialized: 0 }; + let counts = { uninitialized: 0, initialized: 0 }; - for (var i = 0; i < declarations.length; i++) { + for (let i = 0; i < declarations.length; i++) { if (declarations[i].init === null) { counts.uninitialized++; } else { @@ -225,9 +225,9 @@ module.exports = { */ function hasOnlyOneStatement(statementType, declarations) { - var declarationCounts = countDeclarations(declarations); - var currentOptions = options[statementType] || {}; - var currentScope = getCurrentScope(statementType); + let declarationCounts = countDeclarations(declarations); + let currentOptions = options[statementType] || {}; + let currentScope = getCurrentScope(statementType); if (currentOptions.uninitialized === MODE_ALWAYS && currentOptions.initialized === MODE_ALWAYS) { if (currentScope.uninitialized || currentScope.initialized) { @@ -266,7 +266,7 @@ module.exports = { SwitchStatement: startBlock, VariableDeclaration: function(node) { - var parent = node.parent, + let parent = node.parent, type, declarations, declarationCounts; type = node.kind; @@ -296,7 +296,7 @@ module.exports = { // never if (parent.type !== "ForStatement" || parent.init !== node) { - var totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized; + let totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized; if (totalDeclarations > 1) { diff --git a/tools/eslint/lib/rules/operator-assignment.js b/tools/eslint/lib/rules/operator-assignment.js index 7e60c9efd40801..3088ff174f52aa 100644 --- a/tools/eslint/lib/rules/operator-assignment.js +++ b/tools/eslint/lib/rules/operator-assignment.js @@ -93,7 +93,7 @@ module.exports = { * @returns {void} */ function verify(node) { - var expr, left, operator; + let expr, left, operator; if (node.operator !== "=" || node.right.type !== "BinaryExpression") { return; diff --git a/tools/eslint/lib/rules/operator-linebreak.js b/tools/eslint/lib/rules/operator-linebreak.js index 8f17155b862711..2b2f1274aa11b8 100644 --- a/tools/eslint/lib/rules/operator-linebreak.js +++ b/tools/eslint/lib/rules/operator-linebreak.js @@ -5,7 +5,7 @@ "use strict"; -var lodash = require("lodash"), +let lodash = require("lodash"), astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ @@ -44,10 +44,10 @@ module.exports = { create: function(context) { - var usedDefaultGlobal = !context.options[0]; - var globalStyle = context.options[0] || "after"; - var options = context.options[1] || {}; - var styleOverrides = options.overrides ? lodash.assign({}, options.overrides) : {}; + let usedDefaultGlobal = !context.options[0]; + let globalStyle = context.options[0] || "after"; + let options = context.options[1] || {}; + let styleOverrides = options.overrides ? lodash.assign({}, options.overrides) : {}; if (usedDefaultGlobal && !styleOverrides["?"]) { styleOverrides["?"] = "before"; @@ -57,7 +57,7 @@ module.exports = { styleOverrides[":"] = "before"; } - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers @@ -71,8 +71,8 @@ module.exports = { * @returns {void} */ function validateNode(node, leftSide) { - var leftToken = sourceCode.getLastToken(leftSide); - var operatorToken = sourceCode.getTokenAfter(leftToken); + let leftToken = sourceCode.getLastToken(leftSide); + let operatorToken = sourceCode.getTokenAfter(leftToken); // When the left part of a binary expression is a single expression wrapped in // parentheses (ex: `(a) + b`), leftToken will be the last token of the expression @@ -84,10 +84,10 @@ module.exports = { operatorToken = sourceCode.getTokenAfter(operatorToken); } - var rightToken = sourceCode.getTokenAfter(operatorToken); - var operator = operatorToken.value; - var operatorStyleOverride = styleOverrides[operator]; - var style = operatorStyleOverride || globalStyle; + let rightToken = sourceCode.getTokenAfter(operatorToken); + let operator = operatorToken.value; + let operatorStyleOverride = styleOverrides[operator]; + let style = operatorStyleOverride || globalStyle; // if single line if (astUtils.isTokenOnSameLine(leftToken, operatorToken) && @@ -123,7 +123,7 @@ module.exports = { context.report(node, { line: operatorToken.loc.end.line, column: operatorToken.loc.end.column - }, "There should be no line break before or after '" + operator + "'"); + }, "There should be no line break before or after '" + operator + "'."); } } diff --git a/tools/eslint/lib/rules/padded-blocks.js b/tools/eslint/lib/rules/padded-blocks.js index 7ec24c65d7dba6..2754cda4de689c 100644 --- a/tools/eslint/lib/rules/padded-blocks.js +++ b/tools/eslint/lib/rules/padded-blocks.js @@ -47,8 +47,8 @@ module.exports = { }, create: function(context) { - var options = {}; - var config = context.options[0] || "always"; + let options = {}; + let config = context.options[0] || "always"; if (typeof config === "string") { options.blocks = config === "always"; @@ -64,10 +64,10 @@ module.exports = { } } - var ALWAYS_MESSAGE = "Block must be padded by blank lines.", + let ALWAYS_MESSAGE = "Block must be padded by blank lines.", NEVER_MESSAGE = "Block must not be padded by blank lines."; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Gets the open brace token from a given node. @@ -96,7 +96,7 @@ module.exports = { * @returns {boolean} Whether or not the token is followed by a blank line. */ function isTokenTopPadded(token) { - var tokenStartLine = token.loc.start.line, + let tokenStartLine = token.loc.start.line, expectedFirstLine = tokenStartLine + 2, first, firstLine; @@ -116,7 +116,7 @@ module.exports = { * @returns {boolean} Whether or not the token is preceeded by a blank line */ function isTokenBottomPadded(token) { - var blockEnd = token.loc.end.line, + let blockEnd = token.loc.end.line, expectedLastLine = blockEnd - 2, last, lastLine; @@ -156,7 +156,7 @@ module.exports = { * @returns {void} undefined. */ function checkPadding(node) { - var openBrace = getOpenBrace(node), + let openBrace = getOpenBrace(node), closeBrace = sourceCode.getLastToken(node), blockHasTopPadding = isTokenTopPadded(openBrace), blockHasBottomPadding = isTokenBottomPadded(closeBrace); @@ -184,7 +184,7 @@ module.exports = { } } else { if (blockHasTopPadding) { - var nextToken = sourceCode.getTokenOrCommentAfter(openBrace); + let nextToken = sourceCode.getTokenOrCommentAfter(openBrace); context.report({ node: node, @@ -197,7 +197,7 @@ module.exports = { } if (blockHasBottomPadding) { - var previousToken = sourceCode.getTokenOrCommentBefore(closeBrace); + let previousToken = sourceCode.getTokenOrCommentBefore(closeBrace); context.report({ node: node, @@ -211,7 +211,7 @@ module.exports = { } } - var rule = {}; + let rule = {}; if (options.hasOwnProperty("switches")) { rule.SwitchStatement = function(node) { diff --git a/tools/eslint/lib/rules/prefer-arrow-callback.js b/tools/eslint/lib/rules/prefer-arrow-callback.js index 4c4c2e6f2b10b6..185bf160576ad3 100644 --- a/tools/eslint/lib/rules/prefer-arrow-callback.js +++ b/tools/eslint/lib/rules/prefer-arrow-callback.js @@ -35,10 +35,10 @@ function checkMetaProperty(node, metaName, propertyName) { * @returns {escope.Variable} The found variable object. */ function getVariableOfArguments(scope) { - var variables = scope.variables; + let variables = scope.variables; - for (var i = 0; i < variables.length; ++i) { - var variable = variables[i]; + for (let i = 0; i < variables.length; ++i) { + let variable = variables[i]; if (variable.name === "arguments") { @@ -58,13 +58,13 @@ function getVariableOfArguments(scope) { /** * Checkes whether or not a given node is a callback. * @param {ASTNode} node - A node to check. - * @returns {object} + * @returns {Object} * {boolean} retv.isCallback - `true` if the node is a callback. * {boolean} retv.isLexicalThis - `true` if the node is with `.bind(this)`. */ function getCallbackInfo(node) { - var retv = {isCallback: false, isLexicalThis: false}; - var parent = node.parent; + let retv = {isCallback: false, isLexicalThis: false}; + let parent = node.parent; while (node) { switch (parent.type) { @@ -144,10 +144,10 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; + let options = context.options[0] || {}; - var allowUnboundThis = options.allowUnboundThis !== false; // default to true - var allowNamedFunctions = options.allowNamedFunctions; + let allowUnboundThis = options.allowUnboundThis !== false; // default to true + let allowNamedFunctions = options.allowNamedFunctions; /* * {Array<{this: boolean, super: boolean, meta: boolean}>} @@ -155,7 +155,7 @@ module.exports = { * - super - A flag which shows there are one or more Super. * - meta - A flag which shows there are one or more MethProperty. */ - var stack = []; + let stack = []; /** * Pushes new function scope with all `false` flags. @@ -182,7 +182,7 @@ module.exports = { // If there are below, it cannot replace with arrow functions merely. ThisExpression: function() { - var info = stack[stack.length - 1]; + let info = stack[stack.length - 1]; if (info) { info.this = true; @@ -190,7 +190,7 @@ module.exports = { }, Super: function() { - var info = stack[stack.length - 1]; + let info = stack[stack.length - 1]; if (info) { info.super = true; @@ -198,7 +198,7 @@ module.exports = { }, MetaProperty: function(node) { - var info = stack[stack.length - 1]; + let info = stack[stack.length - 1]; if (info && checkMetaProperty(node, "new", "target")) { info.meta = true; @@ -212,7 +212,7 @@ module.exports = { // Main. FunctionExpression: enterScope, "FunctionExpression:exit": function(node) { - var scopeInfo = exitScope(); + let scopeInfo = exitScope(); // Skip named function expressions if (allowNamedFunctions && node.id && node.id.name) { @@ -225,21 +225,21 @@ module.exports = { } // Skip recursive functions. - var nameVar = context.getDeclaredVariables(node)[0]; + let nameVar = context.getDeclaredVariables(node)[0]; if (isFunctionName(nameVar) && nameVar.references.length > 0) { return; } // Skip if it's using arguments. - var variable = getVariableOfArguments(context.getScope()); + let variable = getVariableOfArguments(context.getScope()); if (variable && variable.references.length > 0) { return; } // Reports if it's a callback which can replace with arrows. - var callbackInfo = getCallbackInfo(node); + let callbackInfo = getCallbackInfo(node); if (callbackInfo.isCallback && (!allowUnboundThis || !scopeInfo.this || callbackInfo.isLexicalThis) && diff --git a/tools/eslint/lib/rules/prefer-const.js b/tools/eslint/lib/rules/prefer-const.js index 7b8ac425193b85..5935e02b2c3b28 100644 --- a/tools/eslint/lib/rules/prefer-const.js +++ b/tools/eslint/lib/rules/prefer-const.js @@ -9,16 +9,15 @@ // Requirements //------------------------------------------------------------------------------ -var Map = require("es6-map"); -var lodash = require("lodash"); +let lodash = require("lodash"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var PATTERN_TYPE = /^(?:.+?Pattern|RestElement|Property)$/; -var DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/; -var DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/; +let PATTERN_TYPE = /^(?:.+?Pattern|RestElement|Property)$/; +let DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/; +let DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/; /** * Adds multiple items to the tail of an array. @@ -27,7 +26,7 @@ var DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/; * @param {any[]} values - Items to be added. * @returns {void} */ -var pushAll = Function.apply.bind(Array.prototype.push); +let pushAll = Function.apply.bind(Array.prototype.push); /** * Checks whether a given node is located at `ForStatement.init` or not. @@ -46,7 +45,7 @@ function isInitOfForStatement(node) { * @returns {boolean} `true` if the node can become a VariableDeclaration. */ function canBecomeVariableDeclaration(identifier) { - var node = identifier.parent; + let node = identifier.parent; while (PATTERN_TYPE.test(node.type)) { node = node.parent; @@ -88,15 +87,15 @@ function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) { } // Finds the unique WriteReference. - var writer = null; - var isReadBeforeInit = false; - var references = variable.references; + let writer = null; + let isReadBeforeInit = false; + let references = variable.references; - for (var i = 0; i < references.length; ++i) { - var reference = references[i]; + for (let i = 0; i < references.length; ++i) { + let reference = references[i]; if (reference.isWrite()) { - var isReassigned = ( + let isReassigned = ( writer !== null && writer.identifier !== reference.identifier ); @@ -116,7 +115,7 @@ function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) { // If the assignment is from a different scope, ignore it. // If the assignment cannot change to a declaration, ignore it. - var shouldBeConst = ( + let shouldBeConst = ( writer !== null && writer.from === variable.scope && canBecomeVariableDeclaration(writer.identifier) @@ -145,7 +144,7 @@ function getDestructuringHost(reference) { if (!reference.isWrite()) { return null; } - var node = reference.identifier.parent; + let node = reference.identifier.parent; while (PATTERN_TYPE.test(node.type)) { node = node.parent; @@ -169,17 +168,17 @@ function getDestructuringHost(reference) { * @returns {Map} Grouped identifier nodes. */ function groupByDestructuring(variables, ignoreReadBeforeAssign) { - var identifierMap = new Map(); + let identifierMap = new Map(); - for (var i = 0; i < variables.length; ++i) { - var variable = variables[i]; - var references = variable.references; - var identifier = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign); - var prevId = null; + for (let i = 0; i < variables.length; ++i) { + let variable = variables[i]; + let references = variable.references; + let identifier = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign); + let prevId = null; - for (var j = 0; j < references.length; ++j) { - var reference = references[j]; - var id = reference.identifier; + for (let j = 0; j < references.length; ++j) { + let reference = references[j]; + let id = reference.identifier; // Avoid counting a reference twice or more for default values of // destructuring. @@ -189,7 +188,7 @@ function groupByDestructuring(variables, ignoreReadBeforeAssign) { prevId = id; // Add the identifier node into the destructuring group. - var group = getDestructuringHost(reference); + let group = getDestructuringHost(reference); if (group) { if (identifierMap.has(group)) { @@ -209,7 +208,7 @@ function groupByDestructuring(variables, ignoreReadBeforeAssign) { * * @param {ASTNode} node – The node to search from. * @param {string} type – The type field of the parent node. - * @param {function} shouldStop – a predicate that returns true if the traversal should stop, and false otherwise. + * @param {Function} shouldStop – a predicate that returns true if the traversal should stop, and false otherwise. * @returns {ASTNode} The closest ancestor with the specified type; null if no such ancestor exists. */ function findUp(node, type, shouldStop) { @@ -249,10 +248,10 @@ module.exports = { }, create: function(context) { - var options = context.options[0] || {}; - var checkingMixedDestructuring = options.destructuring !== "all"; - var ignoreReadBeforeAssign = options.ignoreReadBeforeAssign === true; - var variables = null; + let options = context.options[0] || {}; + let checkingMixedDestructuring = options.destructuring !== "all"; + let ignoreReadBeforeAssign = options.ignoreReadBeforeAssign === true; + let variables = null; /** * Reports a given Identifier node. @@ -261,7 +260,7 @@ module.exports = { * @returns {void} */ function report(node) { - var reportArgs = { + let reportArgs = { node: node, message: "'{{name}}' is never reassigned. Use 'const' instead.", data: node @@ -318,7 +317,7 @@ module.exports = { * @returns {void} */ function checkVariable(variable) { - var node = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign); + let node = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign); if (node) { report(node); diff --git a/tools/eslint/lib/rules/prefer-reflect.js b/tools/eslint/lib/rules/prefer-reflect.js index 38bb093ba6f509..b2b0b9abda821d 100644 --- a/tools/eslint/lib/rules/prefer-reflect.js +++ b/tools/eslint/lib/rules/prefer-reflect.js @@ -45,7 +45,7 @@ module.exports = { }, create: function(context) { - var existingNames = { + let existingNames = { apply: "Function.prototype.apply", call: "Function.prototype.call", defineProperty: "Object.defineProperty", @@ -57,7 +57,7 @@ module.exports = { preventExtensions: "Object.preventExtensions" }; - var reflectSubsitutes = { + let reflectSubsitutes = { apply: "Reflect.apply", call: "Reflect.apply", defineProperty: "Reflect.defineProperty", @@ -69,7 +69,7 @@ module.exports = { preventExtensions: "Reflect.preventExtensions" }; - var exceptions = (context.options[0] || {}).exceptions || []; + let exceptions = (context.options[0] || {}).exceptions || []; /** * Reports the Reflect violation based on the `existing` and `substitute` @@ -79,7 +79,7 @@ module.exports = { * @returns {void} */ function report(node, existing, substitute) { - context.report(node, "Avoid using {{existing}}, instead use {{substitute}}", { + context.report(node, "Avoid using {{existing}}, instead use {{substitute}}.", { existing: existing, substitute: substitute }); @@ -87,19 +87,19 @@ module.exports = { return { CallExpression: function(node) { - var methodName = (node.callee.property || {}).name; - var isReflectCall = (node.callee.object || {}).name === "Reflect"; - var hasReflectSubsitute = reflectSubsitutes.hasOwnProperty(methodName); - var userConfiguredException = exceptions.indexOf(methodName) !== -1; + let methodName = (node.callee.property || {}).name; + let isReflectCall = (node.callee.object || {}).name === "Reflect"; + let hasReflectSubsitute = reflectSubsitutes.hasOwnProperty(methodName); + let userConfiguredException = exceptions.indexOf(methodName) !== -1; if (hasReflectSubsitute && !isReflectCall && !userConfiguredException) { report(node, existingNames[methodName], reflectSubsitutes[methodName]); } }, UnaryExpression: function(node) { - var isDeleteOperator = node.operator === "delete"; - var targetsIdentifier = node.argument.type === "Identifier"; - var userConfiguredException = exceptions.indexOf("delete") !== -1; + let isDeleteOperator = node.operator === "delete"; + let targetsIdentifier = node.argument.type === "Identifier"; + let userConfiguredException = exceptions.indexOf("delete") !== -1; if (isDeleteOperator && !targetsIdentifier && !userConfiguredException) { report(node, "the delete keyword", "Reflect.deleteProperty"); diff --git a/tools/eslint/lib/rules/prefer-rest-params.js b/tools/eslint/lib/rules/prefer-rest-params.js index 0ce1d8a1220b28..5a9164ed7f4e47 100644 --- a/tools/eslint/lib/rules/prefer-rest-params.js +++ b/tools/eslint/lib/rules/prefer-rest-params.js @@ -15,10 +15,10 @@ * @returns {escope.Variable} The found variable object. */ function getVariableOfArguments(scope) { - var variables = scope.variables; + let variables = scope.variables; - for (var i = 0; i < variables.length; ++i) { - var variable = variables[i]; + for (let i = 0; i < variables.length; ++i) { + let variable = variables[i]; if (variable.name === "arguments") { @@ -68,7 +68,7 @@ module.exports = { * @returns {void} */ function checkForArguments() { - var argumentsVar = getVariableOfArguments(context.getScope()); + let argumentsVar = getVariableOfArguments(context.getScope()); if (argumentsVar) { argumentsVar.references.forEach(report); diff --git a/tools/eslint/lib/rules/prefer-spread.js b/tools/eslint/lib/rules/prefer-spread.js index 67f1e855b00644..58fc85ca907355 100644 --- a/tools/eslint/lib/rules/prefer-spread.js +++ b/tools/eslint/lib/rules/prefer-spread.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers @@ -35,13 +35,13 @@ function isVariadicApplyCalling(node) { * @returns {boolean} the source code for the given node. */ function equalTokens(left, right, sourceCode) { - var tokensL = sourceCode.getTokens(left); - var tokensR = sourceCode.getTokens(right); + let tokensL = sourceCode.getTokens(left); + let tokensR = sourceCode.getTokens(right); if (tokensL.length !== tokensR.length) { return false; } - for (var i = 0; i < tokensL.length; ++i) { + for (let i = 0; i < tokensL.length; ++i) { if (tokensL[i].type !== tokensR[i].type || tokensL[i].value !== tokensR[i].value ) { @@ -82,7 +82,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { CallExpression: function(node) { @@ -90,9 +90,9 @@ module.exports = { return; } - var applied = node.callee.object; - var expectedThis = (applied.type === "MemberExpression") ? applied.object : null; - var thisArg = node.arguments[0]; + let applied = node.callee.object; + let expectedThis = (applied.type === "MemberExpression") ? applied.object : null; + let thisArg = node.arguments[0]; if (isValidThisArg(expectedThis, thisArg, sourceCode)) { context.report(node, "use the spread operator instead of the '.apply()'."); diff --git a/tools/eslint/lib/rules/prefer-template.js b/tools/eslint/lib/rules/prefer-template.js index 0165aaecd65d8c..4a0da8e197d5d0 100644 --- a/tools/eslint/lib/rules/prefer-template.js +++ b/tools/eslint/lib/rules/prefer-template.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers @@ -66,7 +66,7 @@ module.exports = { }, create: function(context) { - var done = Object.create(null); + let done = Object.create(null); /** * Reports if a given node is string concatenation with non string literals. @@ -79,7 +79,7 @@ module.exports = { return; } - var topBinaryExpr = getTopConcatBinaryExpression(node.parent); + let topBinaryExpr = getTopConcatBinaryExpression(node.parent); // Checks whether or not this node had been checked already. if (done[topBinaryExpr.range[0]]) { diff --git a/tools/eslint/lib/rules/quote-props.js b/tools/eslint/lib/rules/quote-props.js index 1fd2e74a5a34c4..ec65647450cfe5 100644 --- a/tools/eslint/lib/rules/quote-props.js +++ b/tools/eslint/lib/rules/quote-props.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var espree = require("espree"), +let espree = require("espree"), keywords = require("../util/keywords"); //------------------------------------------------------------------------------ @@ -66,7 +66,7 @@ module.exports = { create: function(context) { - var MODE = context.options[0], + let MODE = context.options[0], KEYWORDS = context.options[1] && context.options[1].keywords, CHECK_UNNECESSARY = !context.options[1] || context.options[1].unnecessary !== false, NUMBERS = context.options[1] && context.options[1].numbers, @@ -106,7 +106,7 @@ module.exports = { * @returns {void} */ function checkUnnecessaryQuotes(node) { - var key = node.key, + let key = node.key, isKeywordToken, tokens; @@ -147,7 +147,7 @@ module.exports = { * @returns {void} */ function checkOmittedQuotes(node) { - var key = node.key; + let key = node.key; if (!node.method && !node.computed && !node.shorthand && !(key.type === "Literal" && typeof key.value === "string")) { context.report(node, MESSAGE_UNQUOTED, { @@ -163,12 +163,12 @@ module.exports = { * @returns {void} */ function checkConsistency(node, checkQuotesRedundancy) { - var quotes = false, + let quotes = false, lackOfQuotes = false, necessaryQuotes = false; node.properties.forEach(function(property) { - var key = property.key, + let key = property.key, tokens; if (!key || property.method || property.computed || property.shorthand) { diff --git a/tools/eslint/lib/rules/quotes.js b/tools/eslint/lib/rules/quotes.js index d4e9203811cf7f..18635da537fa53 100644 --- a/tools/eslint/lib/rules/quotes.js +++ b/tools/eslint/lib/rules/quotes.js @@ -9,13 +9,13 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ -var QUOTE_SETTINGS = { +let QUOTE_SETTINGS = { double: { quote: "\"", alternateQuote: "'", @@ -45,8 +45,8 @@ var QUOTE_SETTINGS = { QUOTE_SETTINGS.double.convert = QUOTE_SETTINGS.single.convert = QUOTE_SETTINGS.backtick.convert = function(str) { - var newQuote = this.quote; - var oldQuote = str[0]; + let newQuote = this.quote; + let oldQuote = str[0]; if (newQuote === oldQuote) { return str; @@ -65,8 +65,7 @@ QUOTE_SETTINGS.backtick.convert = function(str) { }) + newQuote; }; -var AVOID_ESCAPE = "avoid-escape", - FUNCTION_TYPE = /^(?:Arrow)?Function(?:Declaration|Expression)$/; +let AVOID_ESCAPE = "avoid-escape"; //------------------------------------------------------------------------------ // Rule Definition @@ -110,7 +109,7 @@ module.exports = { create: function(context) { - var quoteOption = context.options[0], + let quoteOption = context.options[0], settings = QUOTE_SETTINGS[quoteOption || "double"], options = context.options[1], avoidEscape = options && options.avoidEscape === true, @@ -155,15 +154,15 @@ module.exports = { * @private */ function isPartOfDirectivePrologue(node) { - var block = node.parent.parent; + let block = node.parent.parent; - if (block.type !== "Program" && (block.type !== "BlockStatement" || !FUNCTION_TYPE.test(block.parent.type))) { + if (block.type !== "Program" && (block.type !== "BlockStatement" || !astUtils.isFunction(block.parent))) { return false; } // Check the node is at a prologue. - for (var i = 0; i < block.body.length; ++i) { - var statement = block.body[i]; + for (let i = 0; i < block.body.length; ++i) { + let statement = block.body[i]; if (statement === node.parent) { return true; @@ -183,7 +182,7 @@ module.exports = { * @private */ function isAllowedAsNonBacktick(node) { - var parent = node.parent; + let parent = node.parent; switch (parent.type) { @@ -210,7 +209,7 @@ module.exports = { return { Literal: function(node) { - var val = node.value, + let val = node.value, rawVal = node.raw, isValid; @@ -242,7 +241,7 @@ module.exports = { return; } - var shouldWarn = node.quasis.length === 1 && (node.quasis[0].value.cooked.indexOf("\n") === -1); + let shouldWarn = node.quasis.length === 1 && (node.quasis[0].value.cooked.indexOf("\n") === -1); if (shouldWarn) { context.report({ diff --git a/tools/eslint/lib/rules/radix.js b/tools/eslint/lib/rules/radix.js index 05a1c130a9f4df..4c9cb73bebc569 100644 --- a/tools/eslint/lib/rules/radix.js +++ b/tools/eslint/lib/rules/radix.js @@ -9,13 +9,13 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var MODE_ALWAYS = "always", +let MODE_ALWAYS = "always", MODE_AS_NEEDED = "as-needed"; /** @@ -92,7 +92,7 @@ module.exports = { }, create: function(context) { - var mode = context.options[0] || MODE_ALWAYS; + let mode = context.options[0] || MODE_ALWAYS; /** * Checks the arguments of a given CallExpression node and reports it if it @@ -102,7 +102,7 @@ module.exports = { * @returns {void} */ function checkArguments(node) { - var args = node.arguments; + let args = node.arguments; switch (args.length) { case 0: @@ -139,14 +139,14 @@ module.exports = { return { "Program:exit": function() { - var scope = context.getScope(); - var variable; + let scope = context.getScope(); + let variable; // Check `parseInt()` variable = astUtils.getVariableByName(scope, "parseInt"); if (!isShadowed(variable)) { variable.references.forEach(function(reference) { - var node = reference.identifier; + let node = reference.identifier; if (astUtils.isCallee(node)) { checkArguments(node.parent); @@ -158,7 +158,7 @@ module.exports = { variable = astUtils.getVariableByName(scope, "Number"); if (!isShadowed(variable)) { variable.references.forEach(function(reference) { - var node = reference.identifier.parent; + let node = reference.identifier.parent; if (isParseIntMethod(node) && astUtils.isCallee(node)) { checkArguments(node.parent); diff --git a/tools/eslint/lib/rules/require-jsdoc.js b/tools/eslint/lib/rules/require-jsdoc.js index 083e79b1f55ccb..1503c0ff886b60 100644 --- a/tools/eslint/lib/rules/require-jsdoc.js +++ b/tools/eslint/lib/rules/require-jsdoc.js @@ -4,7 +4,7 @@ */ "use strict"; -var lodash = require("lodash"); +let lodash = require("lodash"); module.exports = { meta: { @@ -40,13 +40,13 @@ module.exports = { }, create: function(context) { - var source = context.getSourceCode(); - var DEFAULT_OPTIONS = { + let source = context.getSourceCode(); + let DEFAULT_OPTIONS = { FunctionDeclaration: true, MethodDefinition: false, ClassDeclaration: false }; - var options = lodash.assign(DEFAULT_OPTIONS, context.options[0] && context.options[0].require || {}); + let options = lodash.assign(DEFAULT_OPTIONS, context.options[0] && context.options[0].require || {}); /** * Report the error message @@ -64,7 +64,7 @@ module.exports = { */ function checkClassMethodJsDoc(node) { if (node.parent.type === "MethodDefinition") { - var jsdocComment = source.getJSDocComment(node); + let jsdocComment = source.getJSDocComment(node); if (!jsdocComment) { report(node); @@ -78,7 +78,7 @@ module.exports = { * @returns {void} */ function checkJsDoc(node) { - var jsdocComment = source.getJSDocComment(node); + let jsdocComment = source.getJSDocComment(node); if (!jsdocComment) { report(node); diff --git a/tools/eslint/lib/rules/require-yield.js b/tools/eslint/lib/rules/require-yield.js index cde7d8c2c48e00..a4bb292b7a981b 100644 --- a/tools/eslint/lib/rules/require-yield.js +++ b/tools/eslint/lib/rules/require-yield.js @@ -21,7 +21,7 @@ module.exports = { }, create: function(context) { - var stack = []; + let stack = []; /** * If the node is a generator function, start counting `yield` keywords. @@ -45,7 +45,7 @@ module.exports = { return; } - var countYield = stack.pop(); + let countYield = stack.pop(); if (countYield === 0 && node.body.body.length > 0) { context.report( diff --git a/tools/eslint/lib/rules/rest-spread-spacing.js b/tools/eslint/lib/rules/rest-spread-spacing.js index 7ffafa53199b46..3be2a434210a72 100644 --- a/tools/eslint/lib/rules/rest-spread-spacing.js +++ b/tools/eslint/lib/rules/rest-spread-spacing.js @@ -25,7 +25,7 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(), + let sourceCode = context.getSourceCode(), alwaysSpace = context.options[0] === "always"; //-------------------------------------------------------------------------- @@ -38,7 +38,7 @@ module.exports = { * @returns {void} */ function checkWhiteSpace(node) { - var operator = sourceCode.getFirstToken(node), + let operator = sourceCode.getFirstToken(node), nextToken = sourceCode.getTokenAfter(operator), hasWhitespace = sourceCode.isSpaceBetweenTokens(operator, nextToken), type; @@ -67,7 +67,7 @@ module.exports = { line: operator.loc.end.line, column: operator.loc.end.column }, - message: "Expected whitespace after {{type}} operator", + message: "Expected whitespace after {{type}} operator.", data: { type: type }, @@ -82,7 +82,7 @@ module.exports = { line: operator.loc.end.line, column: operator.loc.end.column }, - message: "Unexpected whitespace after {{type}} operator", + message: "Unexpected whitespace after {{type}} operator.", data: { type: type }, diff --git a/tools/eslint/lib/rules/semi-spacing.js b/tools/eslint/lib/rules/semi-spacing.js index 830044d2f3f960..261905f96fa75f 100644 --- a/tools/eslint/lib/rules/semi-spacing.js +++ b/tools/eslint/lib/rules/semi-spacing.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -39,7 +39,7 @@ module.exports = { create: function(context) { - var config = context.options[0], + let config = context.options[0], requireSpaceBefore = false, requireSpaceAfter = true, sourceCode = context.getSourceCode(); @@ -59,7 +59,7 @@ module.exports = { * @returns {boolean} True if the given token has leading space, false if not. */ function hasLeadingSpace(token) { - var tokenBefore = sourceCode.getTokenBefore(token); + let tokenBefore = sourceCode.getTokenBefore(token); return tokenBefore && astUtils.isTokenOnSameLine(tokenBefore, token) && sourceCode.isSpaceBetweenTokens(tokenBefore, token); } @@ -70,7 +70,7 @@ module.exports = { * @returns {boolean} True if the given token has trailing space, false if not. */ function hasTrailingSpace(token) { - var tokenAfter = sourceCode.getTokenAfter(token); + let tokenAfter = sourceCode.getTokenAfter(token); return tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter) && sourceCode.isSpaceBetweenTokens(token, tokenAfter); } @@ -81,7 +81,7 @@ module.exports = { * @returns {boolean} Whether or not the token is the last in its line. */ function isLastTokenInCurrentLine(token) { - var tokenAfter = sourceCode.getTokenAfter(token); + let tokenAfter = sourceCode.getTokenAfter(token); return !(tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter)); } @@ -92,7 +92,7 @@ module.exports = { * @returns {boolean} Whether or not the token is the first in its line. */ function isFirstTokenInCurrentLine(token) { - var tokenBefore = sourceCode.getTokenBefore(token); + let tokenBefore = sourceCode.getTokenBefore(token); return !(tokenBefore && astUtils.isTokenOnSameLine(token, tokenBefore)); } @@ -103,7 +103,7 @@ module.exports = { * @returns {boolean} Whether or not the next token of a given token is a closing parenthesis. */ function isBeforeClosingParen(token) { - var nextToken = sourceCode.getTokenAfter(token); + let nextToken = sourceCode.getTokenAfter(token); return ( nextToken && @@ -128,7 +128,7 @@ module.exports = { * @returns {void} */ function checkSemicolonSpacing(token, node) { - var location; + let location; if (isSemicolon(token)) { location = token.loc.start; @@ -140,7 +140,7 @@ module.exports = { loc: location, message: "Unexpected whitespace before semicolon.", fix: function(fixer) { - var tokenBefore = sourceCode.getTokenBefore(token); + let tokenBefore = sourceCode.getTokenBefore(token); return fixer.removeRange([tokenBefore.range[1], token.range[0]]); } @@ -167,7 +167,7 @@ module.exports = { loc: location, message: "Unexpected whitespace after semicolon.", fix: function(fixer) { - var tokenAfter = sourceCode.getTokenAfter(token); + let tokenAfter = sourceCode.getTokenAfter(token); return fixer.removeRange([token.range[1], tokenAfter.range[0]]); } @@ -195,7 +195,7 @@ module.exports = { * @returns {void} */ function checkNode(node) { - var token = sourceCode.getLastToken(node); + let token = sourceCode.getLastToken(node); checkSemicolonSpacing(token, node); } diff --git a/tools/eslint/lib/rules/semi.js b/tools/eslint/lib/rules/semi.js index d530725040ba83..80b1e9d00256dc 100644 --- a/tools/eslint/lib/rules/semi.js +++ b/tools/eslint/lib/rules/semi.js @@ -53,9 +53,9 @@ module.exports = { create: function(context) { - var OPT_OUT_PATTERN = /[\[\(\/\+\-]/; // One of [(/+- - var options = context.options[1]; - var never = context.options[0] === "never", + let OPT_OUT_PATTERN = /[\[\(\/\+\-]/; // One of [(/+- + let options = context.options[1]; + let never = context.options[0] === "never", exceptOneLine = options && options.omitLastInOneLineBlock === true, sourceCode = context.getSourceCode(); @@ -70,7 +70,7 @@ module.exports = { * @returns {void} */ function report(node, missing) { - var message, + let message, fix, lastToken = sourceCode.getLastToken(node), loc = lastToken.loc; @@ -115,7 +115,7 @@ module.exports = { * @returns {boolean} whether the semicolon is unnecessary. */ function isUnnecessarySemicolon(lastToken) { - var isDivider, isOptOutToken, lastTokenLine, nextToken, nextTokenLine; + let isDivider, isOptOutToken, lastTokenLine, nextToken, nextTokenLine; if (!isSemicolon(lastToken)) { return false; @@ -141,13 +141,13 @@ module.exports = { * @returns {boolean} whether the node is in a one-liner block statement. */ function isOneLinerBlock(node) { - var nextToken = sourceCode.getTokenAfter(node); + let nextToken = sourceCode.getTokenAfter(node); if (!nextToken || nextToken.value !== "}") { return false; } - var parent = node.parent; + let parent = node.parent; return parent && parent.type === "BlockStatement" && parent.loc.start.line === parent.loc.end.line; @@ -159,7 +159,7 @@ module.exports = { * @returns {void} */ function checkForSemicolon(node) { - var lastToken = sourceCode.getLastToken(node); + let lastToken = sourceCode.getLastToken(node); if (never) { if (isUnnecessarySemicolon(lastToken)) { @@ -184,7 +184,7 @@ module.exports = { * @returns {void} */ function checkForSemicolonForVariableDeclaration(node) { - var ancestors = context.getAncestors(), + let ancestors = context.getAncestors(), parentIndex = ancestors.length - 1, parent = ancestors[parentIndex]; diff --git a/tools/eslint/lib/rules/sort-imports.js b/tools/eslint/lib/rules/sort-imports.js index 18b34f86a09659..c8d3340b0cd198 100644 --- a/tools/eslint/lib/rules/sort-imports.js +++ b/tools/eslint/lib/rules/sort-imports.js @@ -44,7 +44,7 @@ module.exports = { create: function(context) { - var configuration = context.options[0] || {}, + let configuration = context.options[0] || {}, ignoreCase = configuration.ignoreCase || false, ignoreMemberSort = configuration.ignoreMemberSort || false, memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"], @@ -98,7 +98,7 @@ module.exports = { return { ImportDeclaration: function(node) { if (previousDeclaration) { - var currentLocalMemberName = getFirstLocalMemberName(node), + let currentLocalMemberName = getFirstLocalMemberName(node), currentMemberSyntaxGroupIndex = getMemberParameterGroupIndex(node), previousLocalMemberName = getFirstLocalMemberName(previousDeclaration), previousMemberSyntaxGroupIndex = getMemberParameterGroupIndex(previousDeclaration); @@ -137,17 +137,17 @@ module.exports = { // Multiple members of an import declaration should also be sorted alphabetically. if (!ignoreMemberSort && node.specifiers.length > 1) { - var previousSpecifier = null; - var previousSpecifierName = null; + let previousSpecifier = null; + let previousSpecifierName = null; - for (var i = 0; i < node.specifiers.length; ++i) { - var currentSpecifier = node.specifiers[i]; + for (let i = 0; i < node.specifiers.length; ++i) { + let currentSpecifier = node.specifiers[i]; if (currentSpecifier.type !== "ImportSpecifier") { continue; } - var currentSpecifierName = currentSpecifier.local.name; + let currentSpecifierName = currentSpecifier.local.name; if (ignoreCase) { currentSpecifierName = currentSpecifierName.toLowerCase(); diff --git a/tools/eslint/lib/rules/sort-vars.js b/tools/eslint/lib/rules/sort-vars.js index 8a7b0e710a7524..4b8187f36a9c98 100644 --- a/tools/eslint/lib/rules/sort-vars.js +++ b/tools/eslint/lib/rules/sort-vars.js @@ -32,7 +32,7 @@ module.exports = { create: function(context) { - var configuration = context.options[0] || {}, + let configuration = context.options[0] || {}, ignoreCase = configuration.ignoreCase || false; return { @@ -42,7 +42,7 @@ module.exports = { return memo; } - var lastVariableName = memo.id.name, + let lastVariableName = memo.id.name, currenVariableName = decl.id.name; if (ignoreCase) { @@ -51,7 +51,7 @@ module.exports = { } if (currenVariableName < lastVariableName) { - context.report(decl, "Variables within the same declaration block should be sorted alphabetically"); + context.report(decl, "Variables within the same declaration block should be sorted alphabetically."); return memo; } else { return decl; diff --git a/tools/eslint/lib/rules/space-before-blocks.js b/tools/eslint/lib/rules/space-before-blocks.js index 468b320447043c..b695e7ac12e62a 100644 --- a/tools/eslint/lib/rules/space-before-blocks.js +++ b/tools/eslint/lib/rules/space-before-blocks.js @@ -5,7 +5,7 @@ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -48,7 +48,7 @@ module.exports = { }, create: function(context) { - var config = context.options[0], + let config = context.options[0], sourceCode = context.getSourceCode(), checkFunctions = true, checkKeywords = true, @@ -81,7 +81,7 @@ module.exports = { * @returns {void} undefined. */ function checkPrecedingSpace(node) { - var precedingToken = sourceCode.getTokenBefore(node), + let precedingToken = sourceCode.getTokenBefore(node), hasSpace, parent, requireSpace; @@ -127,7 +127,7 @@ module.exports = { * @returns {void} undefined. */ function checkSpaceBeforeCaseBlock(node) { - var cases = node.cases, + let cases = node.cases, firstCase, openingBrace; diff --git a/tools/eslint/lib/rules/space-before-function-paren.js b/tools/eslint/lib/rules/space-before-function-paren.js index 2d26e41e4a9a14..b43d11ed13f776 100644 --- a/tools/eslint/lib/rules/space-before-function-paren.js +++ b/tools/eslint/lib/rules/space-before-function-paren.js @@ -43,7 +43,7 @@ module.exports = { create: function(context) { - var configuration = context.options[0], + let configuration = context.options[0], sourceCode = context.getSourceCode(), requireAnonymousFunctionSpacing = true, forbidAnonymousFunctionSpacing = false, @@ -70,7 +70,7 @@ module.exports = { * @returns {boolean} Whether the function has a name. */ function isNamedFunction(node) { - var parent; + let parent; if (node.id) { return true; @@ -93,7 +93,7 @@ module.exports = { * @returns {void} */ function validateSpacingBeforeParentheses(node) { - var isNamed = isNamedFunction(node), + let isNamed = isNamedFunction(node), leftToken, rightToken, location; diff --git a/tools/eslint/lib/rules/space-in-parens.js b/tools/eslint/lib/rules/space-in-parens.js index 11361aec1202f3..bd8c6eb3af847f 100644 --- a/tools/eslint/lib/rules/space-in-parens.js +++ b/tools/eslint/lib/rules/space-in-parens.js @@ -4,7 +4,7 @@ */ "use strict"; -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Rule Definition @@ -42,7 +42,7 @@ module.exports = { create: function(context) { - var MISSING_SPACE_MESSAGE = "There must be a space inside this paren.", + let MISSING_SPACE_MESSAGE = "There must be a space inside this paren.", REJECTED_SPACE_MESSAGE = "There should be no spaces inside this paren.", ALWAYS = context.options[0] === "always", @@ -64,7 +64,7 @@ module.exports = { * @private */ function getExceptions() { - var openers = [], + let openers = [], closers = []; if (options.braceException) { @@ -96,7 +96,7 @@ module.exports = { //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Determines if a token is one of the exceptions for the opener paren @@ -217,7 +217,7 @@ module.exports = { return { Program: function checkParenSpaces(node) { - var tokens, prevToken, nextToken; + let tokens, prevToken, nextToken; exceptions = getExceptions(); tokens = sourceCode.tokensAndComments; diff --git a/tools/eslint/lib/rules/space-infix-ops.js b/tools/eslint/lib/rules/space-infix-ops.js index bea82ba0b65439..9f5b08773a480c 100644 --- a/tools/eslint/lib/rules/space-infix-ops.js +++ b/tools/eslint/lib/rules/space-infix-ops.js @@ -32,29 +32,29 @@ module.exports = { }, create: function(context) { - var int32Hint = context.options[0] ? context.options[0].int32Hint === true : false; + let int32Hint = context.options[0] ? context.options[0].int32Hint === true : false; - var OPERATORS = [ + let OPERATORS = [ "*", "/", "%", "+", "-", "<<", ">>", ">>>", "<", "<=", ">", ">=", "in", "instanceof", "==", "!=", "===", "!==", "&", "^", "|", "&&", "||", "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "&=", "^=", "|=", "?", ":", ",", "**" ]; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Returns the first token which violates the rule * @param {ASTNode} left - The left node of the main node * @param {ASTNode} right - The right node of the main node - * @returns {object} The violator token or null + * @returns {Object} The violator token or null * @private */ function getFirstNonSpacedToken(left, right) { - var op, + let op, tokens = sourceCode.getTokensBetween(left, right, 1); - for (var i = 1, l = tokens.length - 1; i < l; ++i) { + for (let i = 1, l = tokens.length - 1; i < l; ++i) { op = tokens[i]; if ( op.type === "Punctuator" && @@ -70,7 +70,7 @@ module.exports = { /** * Reports an AST node as a rule violation * @param {ASTNode} mainNode - The node to report - * @param {object} culpritToken - The token which has a problem + * @param {Object} culpritToken - The token which has a problem * @returns {void} * @private */ @@ -80,9 +80,9 @@ module.exports = { loc: culpritToken.loc.start, message: "Infix operators must be spaced.", fix: function(fixer) { - var previousToken = sourceCode.getTokenBefore(culpritToken); - var afterToken = sourceCode.getTokenAfter(culpritToken); - var fixString = ""; + let previousToken = sourceCode.getTokenBefore(culpritToken); + let afterToken = sourceCode.getTokenAfter(culpritToken); + let fixString = ""; if (culpritToken.range[0] - previousToken.range[1] === 0) { fixString = " "; @@ -106,7 +106,11 @@ module.exports = { * @private */ function checkBinary(node) { - var nonSpacedNode = getFirstNonSpacedToken(node.left, node.right); + if (node.left.typeAnnotation) { + return; + } + + let nonSpacedNode = getFirstNonSpacedToken(node.left, node.right); if (nonSpacedNode) { if (!(int32Hint && sourceCode.getText(node).substr(-2) === "|0")) { @@ -122,8 +126,8 @@ module.exports = { * @private */ function checkConditional(node) { - var nonSpacedConsequesntNode = getFirstNonSpacedToken(node.test, node.consequent); - var nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate); + let nonSpacedConsequesntNode = getFirstNonSpacedToken(node.test, node.consequent); + let nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate); if (nonSpacedConsequesntNode) { report(node, nonSpacedConsequesntNode); @@ -139,7 +143,7 @@ module.exports = { * @private */ function checkVar(node) { - var nonSpacedNode; + let nonSpacedNode; if (node.init) { nonSpacedNode = getFirstNonSpacedToken(node.id, node.init); diff --git a/tools/eslint/lib/rules/space-unary-ops.js b/tools/eslint/lib/rules/space-unary-ops.js index fdb1c03e9876b3..77a98150b86542 100644 --- a/tools/eslint/lib/rules/space-unary-ops.js +++ b/tools/eslint/lib/rules/space-unary-ops.js @@ -41,9 +41,9 @@ module.exports = { }, create: function(context) { - var options = context.options && Array.isArray(context.options) && context.options[0] || { words: true, nonwords: false }; + let options = context.options && Array.isArray(context.options) && context.options[0] || { words: true, nonwords: false }; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); //-------------------------------------------------------------------------- // Helpers @@ -91,8 +91,8 @@ module.exports = { /** * Verify Unary Word Operator has spaces after the word operator * @param {ASTnode} node AST node - * @param {object} firstToken first token from the AST node - * @param {object} secondToken second token from the AST node + * @param {Object} firstToken first token from the AST node + * @param {Object} secondToken second token from the AST node * @param {string} word The word to be used for reporting * @returns {void} */ @@ -111,8 +111,8 @@ module.exports = { /** * Verify Unary Word Operator doesn't have spaces after the word operator * @param {ASTnode} node AST node - * @param {object} firstToken first token from the AST node - * @param {object} secondToken second token from the AST node + * @param {Object} firstToken first token from the AST node + * @param {Object} secondToken second token from the AST node * @param {string} word The word to be used for reporting * @returns {void} */ @@ -133,8 +133,8 @@ module.exports = { /** * Check Unary Word Operators for spaces after the word operator * @param {ASTnode} node AST node - * @param {object} firstToken first token from the AST node - * @param {object} secondToken second token from the AST node + * @param {Object} firstToken first token from the AST node + * @param {Object} secondToken second token from the AST node * @param {string} word The word to be used for reporting * @returns {void} */ @@ -160,7 +160,7 @@ module.exports = { * @returns {void} */ function checkForSpacesAfterYield(node) { - var tokens = sourceCode.getFirstTokens(node, 3), + let tokens = sourceCode.getFirstTokens(node, 3), word = "yield"; if (!node.argument || node.delegate) { @@ -173,8 +173,8 @@ module.exports = { /** * Verifies UnaryExpression, UpdateExpression and NewExpression have spaces before or after the operator * @param {ASTnode} node AST node - * @param {object} firstToken First token in the expression - * @param {object} secondToken Second token in the expression + * @param {Object} firstToken First token in the expression + * @param {Object} secondToken Second token in the expression * @returns {void} */ function verifyNonWordsHaveSpaces(node, firstToken, secondToken) { @@ -207,8 +207,8 @@ module.exports = { /** * Verifies UnaryExpression, UpdateExpression and NewExpression don't have spaces before or after the operator * @param {ASTnode} node AST node - * @param {object} firstToken First token in the expression - * @param {object} secondToken Second token in the expression + * @param {Object} firstToken First token in the expression + * @param {Object} secondToken Second token in the expression * @returns {void} */ function verifyNonWordsDontHaveSpaces(node, firstToken, secondToken) { @@ -241,7 +241,7 @@ module.exports = { * @returns {void} */ function checkForSpaces(node) { - var tokens = sourceCode.getFirstTokens(node, 2), + let tokens = sourceCode.getFirstTokens(node, 2), firstToken = tokens[0], secondToken = tokens[1]; @@ -250,7 +250,7 @@ module.exports = { return; } - var operator = node.prefix ? tokens[0].value : tokens[1].value; + let operator = node.prefix ? tokens[0].value : tokens[1].value; if (overrideExistsForOperator(node, operator)) { if (overrideEnforcesSpaces(node, operator)) { diff --git a/tools/eslint/lib/rules/spaced-comment.js b/tools/eslint/lib/rules/spaced-comment.js index 149862024c2b3c..7141ba1f423c86 100644 --- a/tools/eslint/lib/rules/spaced-comment.js +++ b/tools/eslint/lib/rules/spaced-comment.js @@ -4,7 +4,7 @@ */ "use strict"; -var lodash = require("lodash"); +let lodash = require("lodash"); //------------------------------------------------------------------------------ // Helpers @@ -16,7 +16,7 @@ var lodash = require("lodash"); * @returns {string} An escaped string. */ function escape(s) { - var isOneChar = s.length === 1; + let isOneChar = s.length === 1; s = lodash.escapeRegExp(s); return isOneChar ? s : "(?:" + s + ")"; @@ -50,38 +50,16 @@ function parseMarkersOption(markers) { } /** - * Creates RegExp object for `always` mode. - * Generated pattern is below: + * Creates string pattern for exceptions. + * Generated pattern: * - * 1. First, a marker or nothing. - * 2. Next, a space or an exception pattern sequence. + * 1. A space or an exception pattern sequence. * - * @param {string[]} markers - A marker list. - * @param {string[]} exceptions - A exception pattern list. - * @returns {RegExp} A RegExp object for `always` mode. + * @param {string[]} exceptions - An exception pattern list. + * @returns {string} A regular expression string for exceptions. */ -function createAlwaysStylePattern(markers, exceptions) { - var pattern = "^"; - - /* - * A marker or nothing. - * ["*"] ==> "\*?" - * ["*", "!"] ==> "(?:\*|!)?" - * ["*", "/", "!<"] ==> "(?:\*|\/|(?:!<))?" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5C*%7C%5C%2F%7C(%3F%3A!%3C))%3F - */ - if (markers.length === 1) { - - // the marker. - pattern += escape(markers[0]); - } else { - - // one of markers. - pattern += "(?:"; - pattern += markers.map(escape).join("|"); - pattern += ")"; - } - - pattern += "?"; // or nothing. +function createExceptionsPattern(exceptions) { + let pattern = ""; /* * A space or an exception pattern sequence. @@ -105,21 +83,59 @@ function createAlwaysStylePattern(markers, exceptions) { pattern += escapeAndRepeat(exceptions[0]); } else { - // a sequence of one of exception patterns. + // a sequence of one of the exception patterns. pattern += "(?:"; pattern += exceptions.map(escapeAndRepeat).join("|"); pattern += ")"; } - pattern += "(?:$|[\n\r]))"; // the sequence continues until the end. + pattern += "(?:$|[\n\r]))"; } + return pattern; +} + +/** + * Creates RegExp object for `always` mode. + * Generated pattern for beginning of comment: + * + * 1. First, a marker or nothing. + * 2. Next, a space or an exception pattern sequence. + * + * @param {string[]} markers - A marker list. + * @param {string[]} exceptions - An exception pattern list. + * @returns {RegExp} A RegExp object for the beginning of a comment in `always` mode. + */ +function createAlwaysStylePattern(markers, exceptions) { + let pattern = "^"; + + /* + * A marker or nothing. + * ["*"] ==> "\*?" + * ["*", "!"] ==> "(?:\*|!)?" + * ["*", "/", "!<"] ==> "(?:\*|\/|(?:!<))?" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5C*%7C%5C%2F%7C(%3F%3A!%3C))%3F + */ + if (markers.length === 1) { + + // the marker. + pattern += escape(markers[0]); + } else { + + // one of markers. + pattern += "(?:"; + pattern += markers.map(escape).join("|"); + pattern += ")"; + } + + pattern += "?"; // or nothing. + pattern += createExceptionsPattern(exceptions); + return new RegExp(pattern); } /** * Creates RegExp object for `never` mode. - * Generated pattern is below: + * Generated pattern for beginning of comment: * * 1. First, a marker or nothing (captured). * 2. Next, a space or a tab. @@ -128,7 +144,7 @@ function createAlwaysStylePattern(markers, exceptions) { * @returns {RegExp} A RegExp object for `never` mode. */ function createNeverStylePattern(markers) { - var pattern = "^(" + markers.map(escape).join("|") + ")?[ \t]+"; + let pattern = "^(" + markers.map(escape).join("|") + ")?[ \t]+"; return new RegExp(pattern); } @@ -198,6 +214,9 @@ module.exports = { items: { type: "string" } + }, + balanced: { + type: "boolean" } }, additionalProperties: false @@ -211,21 +230,25 @@ module.exports = { create: function(context) { // Unless the first option is never, require a space - var requireSpace = context.options[0] !== "never"; + let requireSpace = context.options[0] !== "never"; /* * Parse the second options. * If markers don't include `"*"`, it's added automatically for JSDoc * comments. */ - var config = context.options[1] || {}; - var styleRules = ["block", "line"].reduce(function(rule, type) { - var markers = parseMarkersOption(config[type] && config[type].markers || config.markers); - var exceptions = config[type] && config[type].exceptions || config.exceptions || []; + let config = context.options[1] || {}; + let balanced = config.block && config.block.balanced; + + let styleRules = ["block", "line"].reduce(function(rule, type) { + let markers = parseMarkersOption(config[type] && config[type].markers || config.markers); + let exceptions = config[type] && config[type].exceptions || config.exceptions || []; + let endNeverPattern = "[ \t]+$"; // Create RegExp object for valid patterns. rule[type] = { - regex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers), + beginRegex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers), + endRegex: balanced && requireSpace ? new RegExp(createExceptionsPattern(exceptions) + "$") : new RegExp(endNeverPattern), hasExceptions: exceptions.length > 0, markers: new RegExp("^(" + markers.map(escape).join("|") + ")") }; @@ -234,20 +257,20 @@ module.exports = { }, {}); /** - * Reports a spacing error with an appropriate message. + * Reports a beginning spacing error with an appropriate message. * @param {ASTNode} node - A comment node to check. - * @param {string} message - An error message to report + * @param {string} message - An error message to report. * @param {Array} match - An array of match results for markers. * @returns {void} */ - function report(node, message, match) { - var type = node.type.toLowerCase(), + function reportBegin(node, message, match) { + let type = node.type.toLowerCase(), commentIdentifier = type === "block" ? "/*" : "//"; context.report({ node: node, fix: function(fixer) { - var start = node.range[0], + let start = node.range[0], end = start + 2; if (requireSpace) { @@ -264,13 +287,37 @@ module.exports = { }); } + /** + * Reports an ending spacing error with an appropriate message. + * @param {ASTNode} node - A comment node to check. + * @param {string} message - An error message to report. + * @param {string} match - An array of the matched whitespace characters. + * @returns {void} + */ + function reportEnd(node, message, match) { + context.report({ + node: node, + fix: function(fixer) { + if (requireSpace) { + return fixer.insertTextAfterRange([node.start, node.end - 2], " "); + } else { + let end = node.end - 2, + start = end - match[0].length; + + return fixer.replaceTextRange([start, end], ""); + } + }, + message: message + }); + } + /** * Reports a given comment if it's invalid. * @param {ASTNode} node - a comment node to check. * @returns {void} */ function checkCommentForSpace(node) { - var type = node.type.toLowerCase(), + let type = node.type.toLowerCase(), rule = styleRules[type], commentIdentifier = type === "block" ? "/*" : "//"; @@ -279,28 +326,37 @@ module.exports = { return; } + let beginMatch = rule.beginRegex.exec(node.value); + let endMatch = rule.endRegex.exec(node.value); + // Checks. if (requireSpace) { - if (!rule.regex.test(node.value)) { - var hasMarker = rule.markers.exec(node.value); - var marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier; + if (!beginMatch) { + let hasMarker = rule.markers.exec(node.value); + let marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier; if (rule.hasExceptions) { - report(node, "Expected exception block, space or tab after '" + marker + "' in comment.", hasMarker); + reportBegin(node, "Expected exception block, space or tab after '" + marker + "' in comment.", hasMarker); } else { - report(node, "Expected space or tab after '" + marker + "' in comment.", hasMarker); + reportBegin(node, "Expected space or tab after '" + marker + "' in comment.", hasMarker); } } - } else { - var matched = rule.regex.exec(node.value); - if (matched) { - if (!matched[1]) { - report(node, "Unexpected space or tab after '" + commentIdentifier + "' in comment.", matched); + if (balanced && type === "block" && !endMatch) { + reportEnd(node, "Expected space or tab before '*/' in comment."); + } + } else { + if (beginMatch) { + if (!beginMatch[1]) { + reportBegin(node, "Unexpected space or tab after '" + commentIdentifier + "' in comment.", beginMatch); } else { - report(node, "Unexpected space or tab after marker (" + matched[1] + ") in comment.", matched); + reportBegin(node, "Unexpected space or tab after marker (" + beginMatch[1] + ") in comment.", beginMatch); } } + + if (balanced && type === "block" && endMatch) { + reportEnd(node, "Unexpected space or tab before '*/' in comment.", endMatch); + } } } diff --git a/tools/eslint/lib/rules/strict.js b/tools/eslint/lib/rules/strict.js index 45021517c70251..5f54b15e799150 100644 --- a/tools/eslint/lib/rules/strict.js +++ b/tools/eslint/lib/rules/strict.js @@ -9,13 +9,13 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"); +let lodash = require("lodash"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var messages = { +let messages = { function: "Use the function form of 'use strict'.", global: "Use the global form of 'use strict'.", multiple: "Multiple 'use strict' directives.", @@ -35,7 +35,7 @@ var messages = { * @returns {ASTNode[]} All of the Use Strict Directives. */ function getUseStrictDirectives(statements) { - var directives = [], + let directives = [], i, statement; for (i = 0; i < statements.length; i++) { @@ -96,7 +96,7 @@ module.exports = { create: function(context) { - var mode = context.options[0] || "safe", + let mode = context.options[0] || "safe", ecmaFeatures = context.parserOptions.ecmaFeatures || {}, scopes = [], classScopes = [], @@ -117,7 +117,7 @@ module.exports = { * @returns {void} */ function reportSlice(nodes, start, end, message) { - var i; + let i; for (i = start; i < end; i++) { context.report(nodes[i], message); @@ -152,7 +152,7 @@ module.exports = { * @returns {void} */ function enterFunctionInFunctionMode(node, useStrictDirectives) { - var isInClass = classScopes.length > 0, + let isInClass = classScopes.length > 0, isParentGlobal = scopes.length === 0 && classScopes.length === 0, isParentStrict = scopes.length > 0 && scopes[scopes.length - 1], isStrict = useStrictDirectives.length > 0; @@ -194,7 +194,7 @@ module.exports = { * @returns {void} */ function enterFunction(node) { - var isBlock = node.body.type === "BlockStatement", + let isBlock = node.body.type === "BlockStatement", useStrictDirectives = isBlock ? getUseStrictDirectives(node.body.body) : []; @@ -212,7 +212,7 @@ module.exports = { rule = { Program: function(node) { - var useStrictDirectives = getUseStrictDirectives(node.body); + let useStrictDirectives = getUseStrictDirectives(node.body); if (node.sourceType === "module") { mode = "module"; diff --git a/tools/eslint/lib/rules/template-curly-spacing.js b/tools/eslint/lib/rules/template-curly-spacing.js index 144a03536907a0..36c33e533098ef 100644 --- a/tools/eslint/lib/rules/template-curly-spacing.js +++ b/tools/eslint/lib/rules/template-curly-spacing.js @@ -9,14 +9,14 @@ // Requirements //------------------------------------------------------------------------------ -var astUtils = require("../ast-utils"); +let astUtils = require("../ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var OPEN_PAREN = /\$\{$/; -var CLOSE_PAREN = /^\}/; +let OPEN_PAREN = /\$\{$/; +let CLOSE_PAREN = /^\}/; //------------------------------------------------------------------------------ // Rule Definition @@ -38,9 +38,9 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); - var always = context.options[0] === "always"; - var prefix = always ? "Expected" : "Unexpected"; + let sourceCode = context.getSourceCode(); + let always = context.options[0] === "always"; + let prefix = always ? "Expected" : "Unexpected"; /** * Checks spacing before `}` of a given token. @@ -48,7 +48,7 @@ module.exports = { * @returns {void} */ function checkSpacingBefore(token) { - var prevToken = sourceCode.getTokenBefore(token); + let prevToken = sourceCode.getTokenBefore(token); if (prevToken && CLOSE_PAREN.test(token.value) && @@ -77,7 +77,7 @@ module.exports = { * @returns {void} */ function checkSpacingAfter(token) { - var nextToken = sourceCode.getTokenAfter(token); + let nextToken = sourceCode.getTokenAfter(token); if (nextToken && OPEN_PAREN.test(token.value) && @@ -105,7 +105,7 @@ module.exports = { return { TemplateElement: function(node) { - var token = sourceCode.getFirstToken(node); + let token = sourceCode.getFirstToken(node); checkSpacingBefore(token); checkSpacingAfter(token); diff --git a/tools/eslint/lib/rules/unicode-bom.js b/tools/eslint/lib/rules/unicode-bom.js index a152b03ac99206..931d840b55c768 100644 --- a/tools/eslint/lib/rules/unicode-bom.js +++ b/tools/eslint/lib/rules/unicode-bom.js @@ -35,7 +35,7 @@ module.exports = { Program: function checkUnicodeBOM(node) { - var sourceCode = context.getSourceCode(), + let sourceCode = context.getSourceCode(), location = {column: 0, line: 1}, requireBOM = context.options[0] || "never"; diff --git a/tools/eslint/lib/rules/valid-jsdoc.js b/tools/eslint/lib/rules/valid-jsdoc.js index 65ed539d55fa5b..8af117e30eb478 100644 --- a/tools/eslint/lib/rules/valid-jsdoc.js +++ b/tools/eslint/lib/rules/valid-jsdoc.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var doctrine = require("doctrine"); +let doctrine = require("doctrine"); //------------------------------------------------------------------------------ // Rule Definition @@ -61,7 +61,7 @@ module.exports = { create: function(context) { - var options = context.options[0] || {}, + let options = context.options[0] || {}, prefer = options.prefer || {}, sourceCode = context.getSourceCode(), @@ -78,7 +78,7 @@ module.exports = { //-------------------------------------------------------------------------- // Using a stack to store if a function returns or not (handling nested functions) - var fns = []; + let fns = []; /** * Check if node type is a Class @@ -110,7 +110,7 @@ module.exports = { * @private */ function addReturn(node) { - var functionState = fns[fns.length - 1]; + let functionState = fns[fns.length - 1]; if (functionState && node.argument !== null) { functionState.returnPresent = true; @@ -148,8 +148,8 @@ module.exports = { * @private */ function getCurrentExpectedTypes(type) { - var currentType; - var expectedType; + let currentType; + let expectedType; if (type.name) { currentType = type.name; @@ -177,8 +177,8 @@ module.exports = { return; } - var typesToCheck = []; - var elements = []; + let typesToCheck = []; + let elements = []; switch (type.type) { case "TypeApplication": // {Array.} @@ -223,7 +223,7 @@ module.exports = { * @private */ function checkJSDoc(node) { - var jsdocNode = sourceCode.getJSDocComment(node), + let jsdocNode = sourceCode.getJSDocComment(node), functionData = fns.pop(), hasReturns = false, hasConstructor = false, @@ -336,7 +336,7 @@ module.exports = { } // check the parameters - var jsdocParams = Object.keys(params); + let jsdocParams = Object.keys(params); if (node.params) { node.params.forEach(function(param, i) { @@ -344,7 +344,7 @@ module.exports = { param = param.left; } - var name = param.name; + let name = param.name; // TODO(nzakas): Figure out logical things to do with destructured, default, rest params if (param.type === "Identifier") { @@ -363,7 +363,7 @@ module.exports = { } if (options.matchDescription) { - var regex = new RegExp(options.matchDescription); + let regex = new RegExp(options.matchDescription); if (!regex.test(jsdoc.description)) { context.report(jsdocNode, "JSDoc description does not satisfy the regex pattern."); diff --git a/tools/eslint/lib/rules/valid-typeof.js b/tools/eslint/lib/rules/valid-typeof.js index 289375a88bac3b..dc378d9401d79c 100644 --- a/tools/eslint/lib/rules/valid-typeof.js +++ b/tools/eslint/lib/rules/valid-typeof.js @@ -21,7 +21,7 @@ module.exports = { create: function(context) { - var VALID_TYPES = ["symbol", "undefined", "object", "boolean", "number", "string", "function"], + let VALID_TYPES = ["symbol", "undefined", "object", "boolean", "number", "string", "function"], OPERATORS = ["==", "===", "!=", "!=="]; //-------------------------------------------------------------------------- @@ -31,7 +31,7 @@ module.exports = { return { UnaryExpression: function(node) { - var parent, sibling; + let parent, sibling; if (node.operator === "typeof") { parent = context.getAncestors().pop(); @@ -40,7 +40,7 @@ module.exports = { sibling = parent.left === node ? parent.right : parent.left; if (sibling.type === "Literal" && VALID_TYPES.indexOf(sibling.value) === -1) { - context.report(sibling, "Invalid typeof comparison value"); + context.report(sibling, "Invalid typeof comparison value."); } } } diff --git a/tools/eslint/lib/rules/vars-on-top.js b/tools/eslint/lib/rules/vars-on-top.js index 25bef0411dba78..e94e4875593088 100644 --- a/tools/eslint/lib/rules/vars-on-top.js +++ b/tools/eslint/lib/rules/vars-on-top.js @@ -21,7 +21,7 @@ module.exports = { }, create: function(context) { - var errorMessage = "All 'var' declarations must be at the top of the function scope."; + let errorMessage = "All 'var' declarations must be at the top of the function scope."; //-------------------------------------------------------------------------- // Helpers @@ -29,7 +29,7 @@ module.exports = { /** * @param {ASTNode} node - any node - * @returns {Boolean} whether the given node structurally represents a directive + * @returns {boolean} whether the given node structurally represents a directive */ function looksLikeDirective(node) { return node.type === "ExpressionStatement" && @@ -39,7 +39,7 @@ module.exports = { /** * Check to see if its a ES6 import declaration * @param {ASTNode} node - any node - * @returns {Boolean} whether the given node represents a import declaration + * @returns {boolean} whether the given node represents a import declaration */ function looksLikeImport(node) { return node.type === "ImportDeclaration" || node.type === "ImportSpecifier" || @@ -67,10 +67,10 @@ module.exports = { * Checks whether this variable is on top of the block body * @param {ASTNode} node - The node to check * @param {ASTNode[]} statements - collection of ASTNodes for the parent node block - * @returns {Boolean} True if var is on top otherwise false + * @returns {boolean} True if var is on top otherwise false */ function isVarOnTop(node, statements) { - var i = 0, + let i = 0, l = statements.length; // skip over directives @@ -125,9 +125,9 @@ module.exports = { return { VariableDeclaration: function(node) { - var ancestors = context.getAncestors(); - var parent = ancestors.pop(); - var grandParent = ancestors.pop(); + let ancestors = context.getAncestors(); + let parent = ancestors.pop(); + let grandParent = ancestors.pop(); if (node.kind === "var") { // check variable is `var` type and not `let` or `const` if (parent.type === "ExportNamedDeclaration") { diff --git a/tools/eslint/lib/rules/wrap-iife.js b/tools/eslint/lib/rules/wrap-iife.js index 2f73699a429571..78554091c9964f 100644 --- a/tools/eslint/lib/rules/wrap-iife.js +++ b/tools/eslint/lib/rules/wrap-iife.js @@ -26,9 +26,9 @@ module.exports = { create: function(context) { - var style = context.options[0] || "outside"; + let style = context.options[0] || "outside"; - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Check if the node is wrapped in () @@ -37,7 +37,7 @@ module.exports = { * @private */ function wrapped(node) { - var previousToken = sourceCode.getTokenBefore(node), + let previousToken = sourceCode.getTokenBefore(node), nextToken = sourceCode.getTokenAfter(node); return previousToken && previousToken.value === "(" && @@ -48,7 +48,7 @@ module.exports = { CallExpression: function(node) { if (node.callee.type === "FunctionExpression") { - var callExpressionWrapped = wrapped(node), + let callExpressionWrapped = wrapped(node), functionExpressionWrapped = wrapped(node.callee); if (!callExpressionWrapped && !functionExpressionWrapped) { diff --git a/tools/eslint/lib/rules/wrap-regex.js b/tools/eslint/lib/rules/wrap-regex.js index 1aed713bdd0850..44750a3fbd1e1c 100644 --- a/tools/eslint/lib/rules/wrap-regex.js +++ b/tools/eslint/lib/rules/wrap-regex.js @@ -21,12 +21,12 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); return { Literal: function(node) { - var token = sourceCode.getFirstToken(node), + let token = sourceCode.getFirstToken(node), nodeType = token.type, source, grandparent, diff --git a/tools/eslint/lib/rules/yield-star-spacing.js b/tools/eslint/lib/rules/yield-star-spacing.js index e2911b7200524c..c9ca64e0c255e3 100644 --- a/tools/eslint/lib/rules/yield-star-spacing.js +++ b/tools/eslint/lib/rules/yield-star-spacing.js @@ -39,9 +39,9 @@ module.exports = { }, create: function(context) { - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); - var mode = (function(option) { + let mode = (function(option) { if (!option || typeof option === "string") { return { before: { before: true, after: false }, @@ -64,11 +64,11 @@ module.exports = { */ function checkSpacing(side, leftToken, rightToken) { if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken) !== mode[side]) { - var after = leftToken.value === "*"; - var spaceRequired = mode[side]; - var node = after ? leftToken : rightToken; - var type = spaceRequired ? "Missing" : "Unexpected"; - var message = type + " space " + side + " *."; + let after = leftToken.value === "*"; + let spaceRequired = mode[side]; + let node = after ? leftToken : rightToken; + let type = spaceRequired ? "Missing" : "Unexpected"; + let message = type + " space " + side + " *."; context.report({ node: node, @@ -96,10 +96,10 @@ module.exports = { return; } - var tokens = sourceCode.getFirstTokens(node, 3); - var yieldToken = tokens[0]; - var starToken = tokens[1]; - var nextToken = tokens[2]; + let tokens = sourceCode.getFirstTokens(node, 3); + let yieldToken = tokens[0]; + let starToken = tokens[1]; + let nextToken = tokens[2]; checkSpacing("before", yieldToken, starToken); checkSpacing("after", starToken, nextToken); diff --git a/tools/eslint/lib/rules/yoda.js b/tools/eslint/lib/rules/yoda.js index 0373e91a4a999c..29f0602b98de7e 100644 --- a/tools/eslint/lib/rules/yoda.js +++ b/tools/eslint/lib/rules/yoda.js @@ -10,7 +10,7 @@ /** * Determines whether an operator is a comparison operator. - * @param {String} operator The operator to check. + * @param {string} operator The operator to check. * @returns {boolean} Whether or not it is a comparison operator. */ function isComparisonOperator(operator) { @@ -19,7 +19,7 @@ function isComparisonOperator(operator) { /** * Determines whether an operator is an equality operator. - * @param {String} operator The operator to check. + * @param {string} operator The operator to check. * @returns {boolean} Whether or not it is an equality operator. */ function isEqualityOperator(operator) { @@ -29,7 +29,7 @@ function isEqualityOperator(operator) { /** * Determines whether an operator is one used in a range test. * Allowed operators are `<` and `<=`. - * @param {String} operator The operator to check. + * @param {string} operator The operator to check. * @returns {boolean} Whether the operator is used in range tests. */ function isRangeTestOperator(operator) { @@ -147,11 +147,11 @@ module.exports = { create: function(context) { // Default to "never" (!always) if no option - var always = (context.options[0] === "always"); - var exceptRange = (context.options[1] && context.options[1].exceptRange); - var onlyEquality = (context.options[1] && context.options[1].onlyEquality); + let always = (context.options[0] === "always"); + let exceptRange = (context.options[1] && context.options[1].exceptRange); + let onlyEquality = (context.options[1] && context.options[1].onlyEquality); - var sourceCode = context.getSourceCode(); + let sourceCode = context.getSourceCode(); /** * Determines whether node represents a range test. @@ -161,18 +161,18 @@ module.exports = { * must be less than or equal to the literal on the right side so that the * test makes any sense. * @param {ASTNode} node LogicalExpression node to test. - * @returns {Boolean} Whether node is a range test. + * @returns {boolean} Whether node is a range test. */ function isRangeTest(node) { - var left = node.left, + let left = node.left, right = node.right; /** * Determines whether node is of the form `0 <= x && x < 1`. - * @returns {Boolean} Whether node is a "between" range test. + * @returns {boolean} Whether node is a "between" range test. */ function isBetweenTest() { - var leftLiteral, rightLiteral; + let leftLiteral, rightLiteral; return (node.operator === "&&" && (leftLiteral = getNormalizedLiteral(left.left)) && @@ -183,10 +183,10 @@ module.exports = { /** * Determines whether node is of the form `x < 0 || 1 <= x`. - * @returns {Boolean} Whether node is an "outside" range test. + * @returns {boolean} Whether node is an "outside" range test. */ function isOutsideTest() { - var leftLiteral, rightLiteral; + let leftLiteral, rightLiteral; return (node.operator === "||" && (leftLiteral = getNormalizedLiteral(left.right)) && @@ -197,12 +197,12 @@ module.exports = { /** * Determines whether node is wrapped in parentheses. - * @returns {Boolean} Whether node is preceded immediately by an open + * @returns {boolean} Whether node is preceded immediately by an open * paren token and followed immediately by a close * paren token. */ function isParenWrapped() { - var tokenBefore, tokenAfter; + let tokenBefore, tokenAfter; return ((tokenBefore = sourceCode.getTokenBefore(node)) && tokenBefore.value === "(" && diff --git a/tools/eslint/lib/testers/event-generator-tester.js b/tools/eslint/lib/testers/event-generator-tester.js index 00b2d03307a883..f77152c0bba3fa 100644 --- a/tools/eslint/lib/testers/event-generator-tester.js +++ b/tools/eslint/lib/testers/event-generator-tester.js @@ -10,7 +10,7 @@ // Requirements //------------------------------------------------------------------------------ -var assert = require("assert"); +let assert = require("assert"); //------------------------------------------------------------------------------ // Public Interface @@ -21,7 +21,7 @@ module.exports = { /** * Overrideable `describe` function to test. * @param {string} text - A description. - * @param {function} method - A test logic. + * @param {Function} method - A test logic. * @returns {any} The returned value with the test logic. */ describe: (typeof describe === "function") ? describe : /* istanbul ignore next */ function(text, method) { @@ -31,7 +31,7 @@ module.exports = { /** * Overrideable `it` function to test. * @param {string} text - A description. - * @param {function} method - A test logic. + * @param {Function} method - A test logic. * @returns {any} The returned value with the test logic. */ it: (typeof it === "function") ? it : /* istanbul ignore next */ function(text, method) { @@ -40,7 +40,7 @@ module.exports = { /** * Does some tests to check a given object implements the EventGenerator interface. - * @param {object} instance - An object to check. + * @param {Object} instance - An object to check. * @returns {void} */ testEventGeneratorInterface: function(instance) { diff --git a/tools/eslint/lib/testers/rule-tester.js b/tools/eslint/lib/testers/rule-tester.js index 2ee87eca6d4f27..703129ca057e53 100644 --- a/tools/eslint/lib/testers/rule-tester.js +++ b/tools/eslint/lib/testers/rule-tester.js @@ -40,7 +40,7 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"), +let lodash = require("lodash"), assert = require("assert"), util = require("util"), validator = require("../config/config-validator"), @@ -58,14 +58,14 @@ var lodash = require("lodash"), * testerDefaultConfig must not be modified as it allows to reset the tester to * the initial default configuration */ -var testerDefaultConfig = { rules: {} }; -var defaultConfig = { rules: {} }; +let testerDefaultConfig = { rules: {} }; +let defaultConfig = { rules: {} }; /* * List every parameters possible on a test case that are not related to eslint * configuration */ -var RuleTesterParameters = [ +let RuleTesterParameters = [ "code", "filename", "options", @@ -73,9 +73,9 @@ var RuleTesterParameters = [ "errors" ]; -var validateSchema = validate(metaSchema, { verbose: true }); +let validateSchema = validate(metaSchema, { verbose: true }); -var hasOwnProperty = Function.call.bind(Object.hasOwnProperty); +let hasOwnProperty = Function.call.bind(Object.hasOwnProperty); /** * Clones a given value deeply. @@ -90,9 +90,9 @@ function cloneDeeplyExcludesParent(x) { return x.map(cloneDeeplyExcludesParent); } - var retv = {}; + let retv = {}; - for (var key in x) { + for (let key in x) { if (key !== "parent" && hasOwnProperty(x, key)) { retv[key] = cloneDeeplyExcludesParent(x[key]); } @@ -115,7 +115,7 @@ function freezeDeeply(x) { if (Array.isArray(x)) { x.forEach(freezeDeeply); } else { - for (var key in x) { + for (let key in x) { if (key !== "parent" && hasOwnProperty(x, key)) { freezeDeeply(x[key]); } @@ -211,7 +211,7 @@ RuleTester.prototype = { */ run: function(ruleName, rule, test) { - var testerConfig = this.testerConfig, + let testerConfig = this.testerConfig, result = {}; /* eslint-disable no-shadow */ @@ -219,12 +219,12 @@ RuleTester.prototype = { /** * Run the rule for the given item * @param {string} ruleName name of the rule - * @param {string|object} item Item to run the rule against - * @returns {object} Eslint run result + * @param {string|Object} item Item to run the rule against + * @returns {Object} Eslint run result * @private */ function runRuleForItem(ruleName, item) { - var config = lodash.cloneDeep(testerConfig), + let config = lodash.cloneDeep(testerConfig), code, filename, schema, beforeAST, afterAST; if (typeof item === "string") { @@ -234,7 +234,7 @@ RuleTester.prototype = { // Assumes everything on the item is a config except for the // parameters used by this tester - var itemConfig = lodash.omit(item, RuleTesterParameters); + let itemConfig = lodash.omit(item, RuleTesterParameters); // Create the config object from the tester config and this item // specific configurations. @@ -249,7 +249,7 @@ RuleTester.prototype = { } if (item.options) { - var options = item.options.concat(); + let options = item.options.concat(); options.unshift(1); config.rules[ruleName] = options; @@ -290,11 +290,11 @@ RuleTester.prototype = { }); // Freezes rule-context properties. - var originalGet = rules.get; + let originalGet = rules.get; try { rules.get = function(ruleId) { - var rule = originalGet(ruleId); + let rule = originalGet(ruleId); if (typeof rule === "function") { return function(context) { @@ -349,13 +349,13 @@ RuleTester.prototype = { * Check if the template is valid or not * all valid cases go through this * @param {string} ruleName name of the rule - * @param {string|object} item Item to run the rule against + * @param {string|Object} item Item to run the rule against * @returns {void} * @private */ function testValidTemplate(ruleName, item) { - var result = runRuleForItem(ruleName, item); - var messages = result.messages; + let result = runRuleForItem(ruleName, item); + let messages = result.messages; assert.equal(messages.length, 0, util.format("Should have no errors but had %d: %s", messages.length, util.inspect(messages))); @@ -367,7 +367,7 @@ RuleTester.prototype = { * Check if the template is invalid or not * all invalid cases go through this. * @param {string} ruleName name of the rule - * @param {string|object} item Item to run the rule against + * @param {string|Object} item Item to run the rule against * @returns {void} * @private */ @@ -375,8 +375,8 @@ RuleTester.prototype = { assert.ok(item.errors || item.errors === 0, "Did not specify errors for an invalid test of " + ruleName); - var result = runRuleForItem(ruleName, item); - var messages = result.messages; + let result = runRuleForItem(ruleName, item); + let messages = result.messages; @@ -388,14 +388,14 @@ RuleTester.prototype = { util.format("Should have %d error%s but had %d: %s", item.errors.length, item.errors.length === 1 ? "" : "s", messages.length, util.inspect(messages))); - for (var i = 0, l = item.errors.length; i < l; i++) { + for (let i = 0, l = item.errors.length; i < l; i++) { assert.ok(!("fatal" in messages[i]), "A fatal parsing error occurred: " + messages[i].message); assert.equal(messages[i].ruleId, ruleName, "Error rule name should be the same as the name of the rule being tested"); if (typeof item.errors[i] === "string") { // Just an error message. - assert.equal(messages[i].message, item.errors[i], "Error message should be " + item.errors[i]); + assert.equal(messages[i].message, item.errors[i]); } else if (typeof item.errors[i] === "object") { /* @@ -404,7 +404,7 @@ RuleTester.prototype = { * column. */ if (item.errors[i].message) { - assert.equal(messages[i].message, item.errors[i].message, "Error message should be " + item.errors[i].message); + assert.equal(messages[i].message, item.errors[i].message); } if (item.errors[i].type) { @@ -418,6 +418,14 @@ RuleTester.prototype = { if (item.errors[i].hasOwnProperty("column")) { assert.equal(messages[i].column, item.errors[i].column, "Error column should be " + item.errors[i].column); } + + if (item.errors[i].hasOwnProperty("endLine")) { + assert.equal(messages[i].endLine, item.errors[i].endLine, "Error endLine should be " + item.errors[i].endLine); + } + + if (item.errors[i].hasOwnProperty("endColumn")) { + assert.equal(messages[i].endColumn, item.errors[i].endColumn, "Error endColumn should be " + item.errors[i].endColumn); + } } else { // Only string or object errors are valid. @@ -426,7 +434,7 @@ RuleTester.prototype = { } if (item.hasOwnProperty("output")) { - var fixResult = SourceCodeFixer.applyFixes(eslint.getSourceCode(), messages); + let fixResult = SourceCodeFixer.applyFixes(eslint.getSourceCode(), messages); assert.equal(fixResult.output, item.output, "Output is incorrect."); } diff --git a/tools/eslint/lib/timing.js b/tools/eslint/lib/timing.js index 6dfffc19d979eb..ff0dd7ffb27918 100644 --- a/tools/eslint/lib/timing.js +++ b/tools/eslint/lib/timing.js @@ -39,23 +39,23 @@ function alignRight(str, len, ch) { // Module definition //------------------------------------------------------------------------------ -var enabled = !!process.env.TIMING; +let enabled = !!process.env.TIMING; -var HEADERS = ["Rule", "Time (ms)", "Relative"]; -var ALIGN = [alignLeft, alignRight, alignRight]; +let HEADERS = ["Rule", "Time (ms)", "Relative"]; +let ALIGN = [alignLeft, alignRight, alignRight]; /* istanbul ignore next */ /** * display the data - * @param {object} data Data object to be displayed + * @param {Object} data Data object to be displayed * @returns {string} modified string * @private */ function display(data) { - var total = 0; - var rows = Object.keys(data) + let total = 0; + let rows = Object.keys(data) .map(function(key) { - var time = data[key]; + let time = data[key]; total += time; return [key, time]; @@ -72,10 +72,10 @@ function display(data) { rows.unshift(HEADERS); - var widths = []; + let widths = []; rows.forEach(function(row) { - var len = row.length, + let len = row.length, i, n; @@ -87,7 +87,7 @@ function display(data) { } }); - var table = rows.map(function(row) { + let table = rows.map(function(row) { return row.map(function(cell, index) { return ALIGN[index](cell, widths[index]); }).join(" | "); @@ -107,7 +107,7 @@ function display(data) { /* istanbul ignore next */ module.exports = (function() { - var data = Object.create(null); + let data = Object.create(null); /** * Time the run @@ -122,7 +122,7 @@ module.exports = (function() { } return function() { - var t = process.hrtime(); + let t = process.hrtime(); fn.apply(null, Array.prototype.slice.call(arguments)); t = process.hrtime(t); diff --git a/tools/eslint/lib/token-store.js b/tools/eslint/lib/token-store.js index 0262b69a521107..183c7363ec9560 100644 --- a/tools/eslint/lib/token-store.js +++ b/tools/eslint/lib/token-store.js @@ -9,7 +9,7 @@ //------------------------------------------------------------------------------ module.exports = function(tokens) { - var api = {}, + let api = {}, starts = Object.create(null), ends = Object.create(null), index, length, range; @@ -21,7 +21,7 @@ module.exports = function(tokens) { * @returns {Token[]} Tokens in the interval. */ function get(start, end) { - var result = [], + let result = [], i; for (i = Math.max(0, start); i < end && i < length; i++) { @@ -39,7 +39,7 @@ module.exports = function(tokens) { * @returns {int} Index in the tokens array of the node's last token. */ function lastTokenIndex(node) { - var end = node.range[1], + let end = node.range[1], cursor = ends[end]; // If the node extends beyond its last token, get the token before the @@ -73,7 +73,7 @@ module.exports = function(tokens) { * @returns {Token[]} Array of objects representing tokens. */ api.getTokensBefore = function(node, beforeCount) { - var first = starts[node.range[0]]; + let first = starts[node.range[0]]; return get(first - (beforeCount || 0), first); }; @@ -98,7 +98,7 @@ module.exports = function(tokens) { * @returns {Token[]} Array of objects representing tokens. */ api.getTokensAfter = function(node, afterCount) { - var start = lastTokenIndex(node) + 1; + let start = lastTokenIndex(node) + 1; return get(start, start + (afterCount || 0)); }; @@ -135,7 +135,7 @@ module.exports = function(tokens) { * @returns {Token[]} Array of objects representing tokens. */ api.getFirstTokens = function(node, count) { - var first = starts[node.range[0]]; + let first = starts[node.range[0]]; return get( first, @@ -160,7 +160,7 @@ module.exports = function(tokens) { * @returns {Token[]} Array of objects representing tokens. */ api.getLastTokens = function(node, count) { - var last = lastTokenIndex(node) + 1; + let last = lastTokenIndex(node) + 1; return get(Math.max(starts[node.range[0]], last - (count || 0)), last); }; diff --git a/tools/eslint/lib/util/comment-event-generator.js b/tools/eslint/lib/util/comment-event-generator.js index 2989f4ee26ae39..40771790b7f6ea 100644 --- a/tools/eslint/lib/util/comment-event-generator.js +++ b/tools/eslint/lib/util/comment-event-generator.js @@ -21,7 +21,7 @@ function emitComments(comments, emitter, locs, eventName) { if (comments.length > 0) { comments.forEach(function(node) { - var index = locs.indexOf(node.loc); + let index = locs.indexOf(node.loc); if (index >= 0) { locs.splice(index, 1); @@ -91,7 +91,7 @@ CommentEventGenerator.prototype = { * @returns {void} */ enterNode: function enterNode(node) { - var comments = this.sourceCode.getComments(node); + let comments = this.sourceCode.getComments(node); emitCommentsEnter(this, comments.leading); this.original.enterNode(node); @@ -104,7 +104,7 @@ CommentEventGenerator.prototype = { * @returns {void} */ leaveNode: function leaveNode(node) { - var comments = this.sourceCode.getComments(node); + let comments = this.sourceCode.getComments(node); emitCommentsExit(this, comments.trailing); this.original.leaveNode(node); diff --git a/tools/eslint/lib/util/glob-util.js b/tools/eslint/lib/util/glob-util.js index 1209dabd6a1ede..30784b2bfc1d31 100644 --- a/tools/eslint/lib/util/glob-util.js +++ b/tools/eslint/lib/util/glob-util.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var debug = require("debug"), +let debug = require("debug"), fs = require("fs"), path = require("path"), glob = require("glob"), @@ -33,7 +33,7 @@ debug = debug("eslint:glob-util"); * * Also makes sure all path separators are POSIX style for `glob` compatibility. * - * @param {object} [options] An options object + * @param {Object} [options] An options object * @param {string[]} [options.extensions=[".js"]] An array of accepted extensions * @param {string} [options.cwd=process.cwd()] The cwd to use to resolve relative pathnames * @returns {Function} A function that takes a pathname and returns a glob that @@ -41,14 +41,14 @@ debug = debug("eslint:glob-util"); * pathname is a directory. */ function processPath(options) { - var cwd = (options && options.cwd) || process.cwd(); - var extensions = (options && options.extensions) || [".js"]; + let cwd = (options && options.cwd) || process.cwd(); + let extensions = (options && options.extensions) || [".js"]; extensions = extensions.map(function(ext) { return ext.charAt(0) === "." ? ext.substr(1) : ext; }); - var suffix = "/**"; + let suffix = "/**"; if (extensions.length === 1) { suffix += "/*." + extensions[0]; @@ -64,8 +64,8 @@ function processPath(options) { * @private */ return function(pathname) { - var newPath = pathname; - var resolvedPath = path.resolve(cwd, pathname); + let newPath = pathname; + let resolvedPath = path.resolve(cwd, pathname); if (shell.test("-d", resolvedPath)) { newPath = pathname.replace(/[\/\\]$/, "") + suffix; @@ -87,7 +87,7 @@ function processPath(options) { */ function resolveFileGlobPatterns(patterns, options) { - var processPathExtensions = processPath(options); + let processPathExtensions = processPath(options); return patterns.map(processPathExtensions); } @@ -105,12 +105,12 @@ function resolveFileGlobPatterns(patterns, options) { * @returns {string[]} Resolved absolute filenames. */ function listFilesToProcess(globPatterns, options) { - var ignoredPaths, + let ignoredPaths, files = [], added = {}, globOptions; - var cwd = (options && options.cwd) || process.cwd(); + let cwd = (options && options.cwd) || process.cwd(); /** * Executes the linter on a file defined by the `filename`. Skips @@ -121,8 +121,8 @@ function listFilesToProcess(globPatterns, options) { * @returns {void} */ function addFile(filename, shouldWarnIgnored) { - var ignored = false; - var isSilentlyIgnored; + let ignored = false; + let isSilentlyIgnored; if (ignoredPaths.contains(filename, "default")) { ignored = (options.ignore !== false) && shouldWarnIgnored; @@ -160,7 +160,7 @@ function listFilesToProcess(globPatterns, options) { debug("Creating list of files to process."); globPatterns.forEach(function(pattern) { - var file = path.resolve(cwd, pattern); + let file = path.resolve(cwd, pattern); if (shell.test("-f", file)) { addFile(fs.realpathSync(file), !shell.test("-d", file)); diff --git a/tools/eslint/lib/util/hash.js b/tools/eslint/lib/util/hash.js index 9f3b734c278e73..092c56e8633e1c 100644 --- a/tools/eslint/lib/util/hash.js +++ b/tools/eslint/lib/util/hash.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var murmur = require("imurmurhash"); +let murmur = require("imurmurhash"); //------------------------------------------------------------------------------ // Helpers diff --git a/tools/eslint/lib/util/module-resolver.js b/tools/eslint/lib/util/module-resolver.js index 251292280dd3d8..964988ec6ebcbe 100644 --- a/tools/eslint/lib/util/module-resolver.js +++ b/tools/eslint/lib/util/module-resolver.js @@ -9,14 +9,14 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"), +let lodash = require("lodash"), Module = require("module"); //------------------------------------------------------------------------------ // Private //------------------------------------------------------------------------------ -var DEFAULT_OPTIONS = { +let DEFAULT_OPTIONS = { /* * module.paths is an array of paths to search for resolving things relative @@ -60,7 +60,7 @@ ModuleResolver.prototype = { * subsequent calls to this function. Then, move the extraLookupPath to the * top of the lookup paths list so it will be searched first. */ - var lookupPaths = this.options.lookupPaths.concat(); + let lookupPaths = this.options.lookupPaths.concat(); lookupPaths.unshift(extraLookupPath); @@ -69,7 +69,7 @@ ModuleResolver.prototype = { * lookup file paths when require() is called. So, we are hooking into the * exact same logic that Node.js uses. */ - var result = Module._findPath(name, lookupPaths); // eslint-disable-line no-underscore-dangle + let result = Module._findPath(name, lookupPaths); // eslint-disable-line no-underscore-dangle if (!result) { throw new Error("Cannot find module '" + name + "'"); diff --git a/tools/eslint/lib/util/npm-util.js b/tools/eslint/lib/util/npm-util.js index 9f28dc2b7edc5a..e888f8feb61032 100644 --- a/tools/eslint/lib/util/npm-util.js +++ b/tools/eslint/lib/util/npm-util.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var fs = require("fs"), +let fs = require("fs"), path = require("path"), shell = require("shelljs"), log = require("../logging"); @@ -26,10 +26,10 @@ var fs = require("fs"), * @returns {string} Absolute path to closest package.json file */ function findPackageJson(startDir) { - var dir = path.resolve(startDir || process.cwd()); + let dir = path.resolve(startDir || process.cwd()); do { - var pkgfile = path.join(dir, "package.json"); + let pkgfile = path.join(dir, "package.json"); if (!fs.existsSync(pkgfile)) { dir = path.join(dir, ".."); @@ -68,9 +68,9 @@ function installSyncSaveDev(packages) { * and values are booleans indicating installation. */ function check(packages, opt) { - var deps = []; - var pkgJson = (opt) ? findPackageJson(opt.startDir) : findPackageJson(); - var fileJson; + let deps = []; + let pkgJson = (opt) ? findPackageJson(opt.startDir) : findPackageJson(); + let fileJson; if (!pkgJson) { throw new Error("Could not find a package.json file. Run 'npm init' to create one."); diff --git a/tools/eslint/lib/util/path-util.js b/tools/eslint/lib/util/path-util.js index a199046bb77b69..8add2064adcb95 100644 --- a/tools/eslint/lib/util/path-util.js +++ b/tools/eslint/lib/util/path-util.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var path = require("path"); +let path = require("path"); //------------------------------------------------------------------------------ // Private @@ -21,8 +21,8 @@ var path = require("path"); * @returns {string} Converted filepath */ function convertPathToPosix(filepath) { - var normalizedFilepath = path.normalize(filepath); - var posixFilepath = normalizedFilepath.replace(/\\/g, "/"); + let normalizedFilepath = path.normalize(filepath); + let posixFilepath = normalizedFilepath.replace(/\\/g, "/"); return posixFilepath; } @@ -48,7 +48,7 @@ function convertPathToPosix(filepath) { * @returns {string} Relative filepath */ function getRelativePath(filepath, baseDir) { - var relativePath; + let relativePath; if (!path.isAbsolute(filepath)) { filepath = path.resolve(filepath); diff --git a/tools/eslint/lib/util/source-code-fixer.js b/tools/eslint/lib/util/source-code-fixer.js index 042eff591f3ea0..d855edb206bef8 100644 --- a/tools/eslint/lib/util/source-code-fixer.js +++ b/tools/eslint/lib/util/source-code-fixer.js @@ -8,13 +8,13 @@ // Requirements //------------------------------------------------------------------------------ -var debug = require("debug")("eslint:text-fixer"); +let debug = require("debug")("eslint:text-fixer"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var BOM = "\uFEFF"; +let BOM = "\uFEFF"; /** * Compares items in a messages array by line and column. @@ -24,7 +24,7 @@ var BOM = "\uFEFF"; * @private */ function compareMessagesByLocation(a, b) { - var lineDiff = a.line - b.line; + let lineDiff = a.line - b.line; if (lineDiff === 0) { return a.column - b.column; @@ -66,7 +66,7 @@ SourceCodeFixer.applyFixes = function(sourceCode, messages) { } // clone the array - var remainingMessages = [], + let remainingMessages = [], fixes = [], text = sourceCode.text, lastFixPos = text.length + 1, @@ -89,13 +89,13 @@ SourceCodeFixer.applyFixes = function(sourceCode, messages) { }); // split into array of characters for easier manipulation - var chars = text.split(""); + let chars = text.split(""); fixes.forEach(function(problem) { - var fix = problem.fix; - var start = fix.range[0]; - var end = fix.range[1]; - var insertionText = fix.text; + let fix = problem.fix; + let start = fix.range[0]; + let end = fix.range[1]; + let insertionText = fix.text; if (end < lastFixPos) { if (start < 0) { diff --git a/tools/eslint/lib/util/source-code-util.js b/tools/eslint/lib/util/source-code-util.js index e51c1c124c798f..f07f61192b909e 100644 --- a/tools/eslint/lib/util/source-code-util.js +++ b/tools/eslint/lib/util/source-code-util.js @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"), +let lodash = require("lodash"), debug = require("debug"), CLIEngine = require("../cli-engine"), eslint = require("../eslint"), @@ -31,16 +31,16 @@ debug = debug("eslint:source-code-util"); */ function getSourceCodeOfFile(filename, options) { debug("getting sourceCode of", filename); - var opts = lodash.assign({}, options, { rules: {}}); - var cli = new CLIEngine(opts); - var results = cli.executeOnFiles([filename]); + let opts = lodash.assign({}, options, { rules: {}}); + let cli = new CLIEngine(opts); + let results = cli.executeOnFiles([filename]); if (results && results.results[0] && results.results[0].messages[0] && results.results[0].messages[0].fatal) { - var msg = results.results[0].messages[0]; + let msg = results.results[0].messages[0]; throw new Error("(" + filename + ":" + msg.line + ":" + msg.column + ") " + msg.message); } - var sourceCode = eslint.getSourceCode(); + let sourceCode = eslint.getSourceCode(); return sourceCode; } @@ -66,7 +66,7 @@ function getSourceCodeOfFile(filename, options) { * @returns {Object} The SourceCode of all processed files. */ function getSourceCodeOfFiles(patterns, options, cb) { - var sourceCodes = {}, + let sourceCodes = {}, filenames, opts; @@ -94,7 +94,7 @@ function getSourceCodeOfFiles(patterns, options, cb) { debug("Did not find any files matching pattern(s): " + patterns); } filenames.forEach(function(filename) { - var sourceCode = getSourceCodeOfFile(filename, opts); + let sourceCode = getSourceCodeOfFile(filename, opts); if (sourceCode) { debug("got sourceCode of", filename); diff --git a/tools/eslint/lib/util/source-code.js b/tools/eslint/lib/util/source-code.js index adf4df93a6b3ae..b8ed5841cd1764 100644 --- a/tools/eslint/lib/util/source-code.js +++ b/tools/eslint/lib/util/source-code.js @@ -8,7 +8,7 @@ // Requirements //------------------------------------------------------------------------------ -var lodash = require("lodash"), +let lodash = require("lodash"), createTokenStore = require("../token-store.js"), Traverser = require("./traverser"); @@ -52,7 +52,7 @@ function validate(ast) { function findJSDocComment(comments, line) { if (comments) { - for (var i = comments.length - 1; i >= 0; i--) { + for (let i = comments.length - 1; i >= 0; i--) { if (comments[i].type === "Block" && comments[i].value.charAt(0) === "*") { if (line - comments[i].loc.end.line <= 1) { @@ -123,13 +123,13 @@ function SourceCode(text, ast) { }); // create token store methods - var tokenStore = createTokenStore(ast.tokens); + let tokenStore = createTokenStore(ast.tokens); Object.keys(tokenStore).forEach(function(methodName) { this[methodName] = tokenStore[methodName]; }, this); - var tokensAndCommentsStore = createTokenStore(this.tokensAndComments); + let tokensAndCommentsStore = createTokenStore(this.tokensAndComments); this.getTokenOrCommentBefore = tokensAndCommentsStore.getTokenBefore; this.getTokenOrCommentAfter = tokensAndCommentsStore.getTokenAfter; @@ -193,7 +193,7 @@ SourceCode.prototype = { */ getComments: function(node) { - var leadingComments = node.leadingComments || [], + let leadingComments = node.leadingComments || [], trailingComments = node.trailingComments || []; /* @@ -222,7 +222,7 @@ SourceCode.prototype = { */ getJSDocComment: function(node) { - var parent = node.parent; + let parent = node.parent; switch (node.type) { case "ClassDeclaration": @@ -261,7 +261,7 @@ SourceCode.prototype = { * @returns {ASTNode} The node if found or null if not found. */ getNodeByRangeIndex: function(index) { - var result = null, + let result = null, resultParent = null, traverser = new Traverser(); @@ -294,7 +294,7 @@ SourceCode.prototype = { * if there is anything other than whitespace between tokens. */ isSpaceBetweenTokens: function(first, second) { - var text = this.text.slice(first.range[1], second.range[0]); + let text = this.text.slice(first.range[1], second.range[0]); return /\s/.test(text.replace(/\/\*.*?\*\//g, "")); } diff --git a/tools/eslint/lib/util/traverser.js b/tools/eslint/lib/util/traverser.js index 03a1c376e153fd..b68d0993af3ab5 100644 --- a/tools/eslint/lib/util/traverser.js +++ b/tools/eslint/lib/util/traverser.js @@ -8,13 +8,13 @@ // Requirements //------------------------------------------------------------------------------ -var estraverse = require("estraverse"); +let estraverse = require("estraverse"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -var KEY_BLACKLIST = [ +let KEY_BLACKLIST = [ "parent", "leadingComments", "trailingComments" @@ -27,7 +27,7 @@ var KEY_BLACKLIST = [ */ function Traverser() { - var controller = Object.create(new estraverse.Controller()), + let controller = Object.create(new estraverse.Controller()), originalTraverse = controller.traverse; // intercept call to traverse() and add the fallback key to the visitor diff --git a/tools/eslint/lib/util/xml-escape.js b/tools/eslint/lib/util/xml-escape.js new file mode 100644 index 00000000000000..2c3abd39d5b482 --- /dev/null +++ b/tools/eslint/lib/util/xml-escape.js @@ -0,0 +1,34 @@ +/** + * @fileoverview XML character escaper + * @author George Chung + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Returns the escaped value for a character + * @param {string} s string to examine + * @returns {string} severity level + * @private + */ +module.exports = function(s) { + return ("" + s).replace(/[<>&"'\x00-\x1F\x7F\u0080-\uFFFF]/g, function(c) { // eslint-disable-line no-control-regex + switch (c) { + case "<": + return "<"; + case ">": + return ">"; + case "&": + return "&"; + case "\"": + return """; + case "'": + return "'"; + default: + return "&#" + c.charCodeAt(0) + ";"; + } + }); +}; diff --git a/tools/eslint/node_modules/acorn-jsx/package.json b/tools/eslint/node_modules/acorn-jsx/package.json index 1982020ad52c2b..ecb4920524a435 100644 --- a/tools/eslint/node_modules/acorn-jsx/package.json +++ b/tools/eslint/node_modules/acorn-jsx/package.json @@ -1,7 +1,15 @@ { "_args": [ [ - "acorn-jsx@^3.0.0", + { + "raw": "acorn-jsx@^3.0.0", + "scope": null, + "escapedName": "acorn-jsx", + "name": "acorn-jsx", + "rawSpec": "^3.0.0", + "spec": ">=3.0.0 <4.0.0", + "type": "range" + }, "/Users/trott/io.js/tools/node_modules/espree" ] ], @@ -16,16 +24,17 @@ "tmp": "tmp/acorn-jsx-3.0.1.tgz_1462206645285_0.17844340158626437" }, "_npmUser": { - "email": "me@rreverser.com", - "name": "rreverser" + "name": "rreverser", + "email": "me@rreverser.com" }, "_npmVersion": "3.8.6", "_phantomChildren": {}, "_requested": { - "name": "acorn-jsx", "raw": "acorn-jsx@^3.0.0", - "rawSpec": "^3.0.0", "scope": null, + "escapedName": "acorn-jsx", + "name": "acorn-jsx", + "rawSpec": "^3.0.0", "spec": ">=3.0.0 <4.0.0", "type": "range" }, @@ -58,8 +67,8 @@ "license": "MIT", "maintainers": [ { - "email": "me@rreverser.com", - "name": "rreverser" + "name": "rreverser", + "email": "me@rreverser.com" } ], "name": "acorn-jsx", diff --git a/tools/eslint/node_modules/acorn/AUTHORS b/tools/eslint/node_modules/acorn/AUTHORS index c459c44642f3e1..1b2061cd4b3021 100644 --- a/tools/eslint/node_modules/acorn/AUTHORS +++ b/tools/eslint/node_modules/acorn/AUTHORS @@ -1,7 +1,8 @@ --e List of Acorn contributors. Updated before every release. +List of Acorn contributors. Updated before every release. Adrian Rakovsky Alistair Braidwood +Amila Welihinda Andres Suarez Angelo Aparajita Fishman @@ -10,6 +11,7 @@ Artem Govorov Brandon Mills Charles Hughes Conrad Irwin +Daniel Tschinder David Bonnet Domenico Matteo ForbesLindesay @@ -26,6 +28,7 @@ Jordan Klassen Jürg Lehni keeyipchan Keheliya Gallaba +Kevin Irish Kevin Kwok krator Marijn Haverbeke @@ -49,6 +52,7 @@ ReadmeCritic r-e-d Richard Gibson Rich Harris +Rich-Harris Sebastian McKenzie Timothy Gu Toru Nagashima diff --git a/tools/eslint/node_modules/acorn/bin/acorn b/tools/eslint/node_modules/acorn/bin/acorn index 63b7615e359ab7..cf4acd563179ad 100755 --- a/tools/eslint/node_modules/acorn/bin/acorn +++ b/tools/eslint/node_modules/acorn/bin/acorn @@ -1,71 +1,65 @@ #!/usr/bin/env node -"use strict"; +'use strict'; -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } } +var path = require('path'); +var fs = require('fs'); +var acorn = require('../dist/acorn.js'); -var _path = require("path"); - -var _fs = require("fs"); - -var _distAcornJs = require("../dist/acorn.js"); - -var acorn = _interopRequireWildcard(_distAcornJs); - -var infile = undefined, - forceFile = undefined, - silent = false, - compact = false, - tokenize = false; -var options = {}; +var infile; +var forceFile; +var silent = false; +var compact = false; +var tokenize = false; +var options = {} function help(status) { - var print = status == 0 ? console.log : console.error; - print("usage: " + (0, _path.basename)(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7]"); - print(" [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]"); - process.exit(status); + var print = (status == 0) ? console.log : console.error + print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7]") + print(" [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]") + process.exit(status) } for (var i = 2; i < process.argv.length; ++i) { - var arg = process.argv[i]; - if ((arg == "-" || arg[0] != "-") && !infile) infile = arg;else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i];else if (arg == "--ecma3") options.ecmaVersion = 3;else if (arg == "--ecma5") options.ecmaVersion = 5;else if (arg == "--ecma6") options.ecmaVersion = 6;else if (arg == "--ecma7") options.ecmaVersion = 7;else if (arg == "--locations") options.locations = true;else if (arg == "--allow-hash-bang") options.allowHashBang = true;else if (arg == "--silent") silent = true;else if (arg == "--compact") compact = true;else if (arg == "--help") help(0);else if (arg == "--tokenize") tokenize = true;else if (arg == "--module") options.sourceType = 'module';else help(1); + var arg = process.argv[i] + if ((arg == "-" || arg[0] != "-") && !infile) infile = arg + else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i] + else if (arg == "--ecma3") options.ecmaVersion = 3 + else if (arg == "--ecma5") options.ecmaVersion = 5 + else if (arg == "--ecma6") options.ecmaVersion = 6 + else if (arg == "--ecma7") options.ecmaVersion = 7 + else if (arg == "--locations") options.locations = true + else if (arg == "--allow-hash-bang") options.allowHashBang = true + else if (arg == "--silent") silent = true + else if (arg == "--compact") compact = true + else if (arg == "--help") help(0) + else if (arg == "--tokenize") tokenize = true + else if (arg == "--module") options.sourceType = 'module' + else help(1) } function run(code) { - var result = undefined; + var result if (!tokenize) { - try { - result = acorn.parse(code, options); - } catch (e) { - console.error(e.message);process.exit(1); - } + try { result = acorn.parse(code, options) } + catch(e) { console.error(e.message); process.exit(1) } } else { - result = []; - var tokenizer = acorn.tokenizer(code, options), - token = undefined; + result = [] + var tokenizer = acorn.tokenizer(code, options), token while (true) { - try { - token = tokenizer.getToken(); - } catch (e) { - console.error(e.message);process.exit(1); - } - result.push(token); - if (token.type == acorn.tokTypes.eof) break; + try { token = tokenizer.getToken() } + catch(e) { console.error(e.message); process.exit(1) } + result.push(token) + if (token.type == acorn.tokTypes.eof) break } } - if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2)); + if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2)) } if (forceFile || infile && infile != "-") { - run((0, _fs.readFileSync)(infile, "utf8")); + run(fs.readFileSync(infile, "utf8")) } else { - (function () { - var code = ""; - process.stdin.resume(); - process.stdin.on("data", function (chunk) { - return code += chunk; - }); - process.stdin.on("end", function () { - return run(code); - }); - })(); + var code = "" + process.stdin.resume() + process.stdin.on("data", function (chunk) { return code += chunk; }) + process.stdin.on("end", function () { return run(code); }) } \ No newline at end of file diff --git a/tools/eslint/node_modules/acorn/bin/build-acorn.js b/tools/eslint/node_modules/acorn/bin/build-acorn.js deleted file mode 100644 index 71f2cf941f5b4d..00000000000000 --- a/tools/eslint/node_modules/acorn/bin/build-acorn.js +++ /dev/null @@ -1,82 +0,0 @@ -var fs = require("fs"), path = require("path") -var stream = require("stream") - -var browserify = require("browserify") -var babel = require('babel-core') -var babelify = require("babelify").configure({loose: "all"}) - -process.chdir(path.resolve(__dirname, "..")) - -browserify({standalone: "acorn"}) - .plugin(require('browserify-derequire')) - .transform(babelify) - .require("./src/index.js", {entry: true}) - .bundle() - .on("error", function (err) { console.log("Error: " + err.message) }) - .pipe(fs.createWriteStream("dist/acorn.js")) - -var ACORN_PLACEHOLDER = "this_function_call_should_be_replaced_with_a_call_to_load_acorn()"; -function acornShimPrepare(file) { - var tr = new stream.Transform - if (file == path.resolve(__dirname, "../src/index.js")) { - var sent = false - tr._transform = function(chunk, _, callback) { - if (!sent) { - sent = true - callback(null, ACORN_PLACEHOLDER); - } else { - callback() - } - } - } else { - tr._transform = function(chunk, _, callback) { callback(null, chunk) } - } - return tr -} -function acornShimComplete() { - var tr = new stream.Transform - var buffer = ""; - tr._transform = function(chunk, _, callback) { - buffer += chunk.toString("utf8"); - callback(); - }; - tr._flush = function (callback) { - tr.push(buffer.replace(ACORN_PLACEHOLDER, "module.exports = typeof acorn != 'undefined' ? acorn : require(\"./acorn\")")); - callback(null); - }; - return tr; -} - -browserify({standalone: "acorn.loose"}) - .plugin(require('browserify-derequire')) - .transform(acornShimPrepare) - .transform(babelify) - .require("./src/loose/index.js", {entry: true}) - .bundle() - .on("error", function (err) { console.log("Error: " + err.message) }) - .pipe(acornShimComplete()) - .pipe(fs.createWriteStream("dist/acorn_loose.js")) - -browserify({standalone: "acorn.walk"}) - .plugin(require('browserify-derequire')) - .transform(acornShimPrepare) - .transform(babelify) - .require("./src/walk/index.js", {entry: true}) - .bundle() - .on("error", function (err) { console.log("Error: " + err.message) }) - .pipe(acornShimComplete()) - .pipe(fs.createWriteStream("dist/walk.js")) - -babel.transformFile("./src/bin/acorn.js", function (err, result) { - if (err) return console.log("Error: " + err.message) - fs.writeFile("bin/acorn", result.code, function (err) { - if (err) return console.log("Error: " + err.message) - - // Make bin/acorn executable - if (process.platform === 'win32') - return - var stat = fs.statSync("bin/acorn") - var newPerm = stat.mode | parseInt('111', 8) - fs.chmodSync("bin/acorn", newPerm) - }) -}) diff --git a/tools/eslint/node_modules/acorn/bin/generate-identifier-regex.js b/tools/eslint/node_modules/acorn/bin/generate-identifier-regex.js index e9f355103234da..100e8cf280fc56 100644 --- a/tools/eslint/node_modules/acorn/bin/generate-identifier-regex.js +++ b/tools/eslint/node_modules/acorn/bin/generate-identifier-regex.js @@ -1,11 +1,13 @@ +'use strict'; + // Which Unicode version should be used? -var version = '8.0.0'; +var version = '9.0.0'; -var start = require('unicode-' + version + '/properties/ID_Start/code-points') - .filter(function(ch) { return ch > 127; }); +var start = require('unicode-' + version + '/Binary_Property/ID_Start/code-points.js') + .filter(function(ch) { return ch > 0x7f; }); var last = -1; -var cont = [0x200c, 0x200d].concat(require('unicode-' + version + '/properties/ID_Continue/code-points') - .filter(function(ch) { return ch > 127 && search(start, ch, last + 1) == -1; })); +var cont = [0x200c, 0x200d].concat(require('unicode-' + version + '/Binary_Property/ID_Continue/code-points.js') + .filter(function(ch) { return ch > 0x7f && search(start, ch, last + 1) == -1; })); function search(arr, ch, starting) { for (var i = starting; arr[i] <= ch && i < arr.length; last = i++) diff --git a/tools/eslint/node_modules/acorn/dist/acorn.es.js b/tools/eslint/node_modules/acorn/dist/acorn.es.js new file mode 100644 index 00000000000000..4460957fd78f1a --- /dev/null +++ b/tools/eslint/node_modules/acorn/dist/acorn.es.js @@ -0,0 +1,3112 @@ +// Reserved word lists for various dialects of the language + +var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + 7: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" +} + +// And the keywords + +var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this" + +var keywords = { + 5: ecma5AndLessKeywords, + 6: ecma5AndLessKeywords + " const class extends export import super" +} + +// ## Character categories + +// Big ugly regular expressions that match characters in the +// whitespace, identifier, and identifier-start categories. These +// are only applied when a character is found to actually have a +// code point above 128. +// Generated by `bin/generate-identifier-regex.js`. + +var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fd5\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ae\ua7b0-\ua7b7\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc" +var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d4-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f" + +var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]") +var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]") + +nonASCIIidentifierStartChars = nonASCIIidentifierChars = null + +// These are a run-length and offset encoded representation of the +// >0xffff code points that are a valid part of identifiers. The +// offset starts at 0x10000, and each pair of numbers represents an +// offset to the next range, and then a size of the range. They were +// generated by bin/generate-identifier-regex.js +var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,785,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,25,391,63,32,0,449,56,264,8,2,36,18,0,50,29,881,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,65,0,32,6124,20,754,9486,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,10591,541] +var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,10,2,4,9,83,11,7,0,161,11,6,9,7,3,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,87,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,423,9,838,7,2,7,17,9,57,21,2,13,19882,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239] + +// This has a complexity linear to the value of the code. The +// assumption is that looking up astral identifier characters is +// rare. +function isInAstralSet(code, set) { + var pos = 0x10000 + for (var i = 0; i < set.length; i += 2) { + pos += set[i] + if (pos > code) return false + pos += set[i + 1] + if (pos >= code) return true + } +} + +// Test whether a given character code starts an identifier. + +function isIdentifierStart(code, astral) { + if (code < 65) return code === 36 + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) +} + +// Test whether a given character is part of an identifier. + +function isIdentifierChar(code, astral) { + if (code < 48) return code === 36 + if (code < 58) return true + if (code < 65) return false + if (code < 91) return true + if (code < 97) return code === 95 + if (code < 123) return true + if (code <= 0xffff) return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) + if (astral === false) return false + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) +} + +// ## Token types + +// The assignment of fine-grained, information-carrying type objects +// allows the tokenizer to store the information it has about a +// token in a way that is very cheap for the parser to look up. + +// All token type variables start with an underscore, to make them +// easy to recognize. + +// The `beforeExpr` property is used to disambiguate between regular +// expressions and divisions. It is set on all token types that can +// be followed by an expression (thus, a slash after them would be a +// regular expression). +// +// The `startsExpr` property is used to check if the token ends a +// `yield` expression. It is set on all token types that either can +// directly start an expression (like a quotation mark) or can +// continue an expression (like the body of a string). +// +// `isLoop` marks a keyword as starting a loop, which is important +// to know when parsing a label, in order to allow or disallow +// continue jumps to that label. + +var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + + this.label = label + this.keyword = conf.keyword + this.beforeExpr = !!conf.beforeExpr + this.startsExpr = !!conf.startsExpr + this.isLoop = !!conf.isLoop + this.isAssign = !!conf.isAssign + this.prefix = !!conf.prefix + this.postfix = !!conf.postfix + this.binop = conf.binop || null + this.updateContext = null +}; + +function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) +} +var beforeExpr = {beforeExpr: true}; +var startsExpr = {startsExpr: true}; +// Map keyword names to token types. + +var keywordTypes = {} + +// Succinct definitions of keyword token types +function kw(name, options) { + if ( options === void 0 ) options = {}; + + options.keyword = name + return keywordTypes[name] = new TokenType(name, options) +} + +var tt = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + eof: new TokenType("eof"), + + // Punctuation token types. + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=", 6), + relational: binop("", 7), + bitShift: binop("<>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + + // Keyword token types. + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class"), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import"), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) +} + +// Matches a whole line break (where CRLF is considered a single +// line break). Used to count lines. + +var lineBreak = /\r\n?|\n|\u2028|\u2029/ +var lineBreakG = new RegExp(lineBreak.source, "g") + +function isNewLine(code) { + return code === 10 || code === 13 || code === 0x2028 || code == 0x2029 +} + +var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/ + +var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g + +function isArray(obj) { + return Object.prototype.toString.call(obj) === "[object Array]" +} + +// Checks if an object has a property. + +function has(obj, propName) { + return Object.prototype.hasOwnProperty.call(obj, propName) +} + +// These are used when `options.locations` is on, for the +// `startLoc` and `endLoc` properties. + +var Position = function Position(line, col) { + this.line = line + this.column = col +}; + +Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) +}; + +var SourceLocation = function SourceLocation(p, start, end) { + this.start = start + this.end = end + if (p.sourceFile !== null) this.source = p.sourceFile +}; + +// The `getLineInfo` function is mostly useful when the +// `locations` option is off (for performance reasons) and you +// want to find the line/column position for a given character +// offset. `input` should be the code string that the offset refers +// into. + +function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur + var match = lineBreakG.exec(input) + if (match && match.index < offset) { + ++line + cur = match.index + match[0].length + } else { + return new Position(line, offset - cur) + } + } +} + +// A second optional argument can be given to further configure +// the parser process. These options are recognized: + +var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must + // be either 3, or 5, or 6. This influences support for strict + // mode, the set of reserved words, support for getters and + // setters and other features. The default is 6. + ecmaVersion: 6, + // Source type ("script" or "module") for different semantics + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // th position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false, + plugins: {} +} + +// Interpret and default an options object + +function getOptions(opts) { + var options = {} + for (var opt in defaultOptions) + options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt] + if (options.allowReserved == null) + options.allowReserved = options.ecmaVersion < 5 + + if (isArray(options.onToken)) { + var tokens = options.onToken + options.onToken = function (token) { return tokens.push(token); } + } + if (isArray(options.onComment)) + options.onComment = pushComment(options, options.onComment) + + return options +} + +function pushComment(options, array) { + return function (block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? 'Block' : 'Line', + value: text, + start: start, + end: end + } + if (options.locations) + comment.loc = new SourceLocation(this, startLoc, endLoc) + if (options.ranges) + comment.range = [start, end] + array.push(comment) + } +} + +// Registered plugins +var plugins = {} + +function keywordRegexp(words) { + return new RegExp("^(" + words.replace(/ /g, "|") + ")$") +} + +var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options) + this.sourceFile = options.sourceFile + this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]) + var reserved = options.allowReserved ? "" : + reservedWords[options.ecmaVersion] + (options.sourceType == "module" ? " await" : "") + this.reservedWords = keywordRegexp(reserved) + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict + this.reservedWordsStrict = keywordRegexp(reservedStrict) + this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind) + this.input = String(input) + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false + + // Load plugins + this.loadPlugins(options.plugins) + + // Set up token state + + // The current position of the tokenizer in the input. + if (startPos) { + this.pos = startPos + this.lineStart = Math.max(0, this.input.lastIndexOf("\n", startPos)) + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length + } else { + this.pos = this.lineStart = 0 + this.curLine = 1 + } + + // Properties of the current token: + // Its type + this.type = tt.eof + // For tokens that include more information than their type, the value + this.value = null + // Its start and end offset + this.start = this.end = this.pos + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition() + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null + this.lastTokStart = this.lastTokEnd = this.pos + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext() + this.exprAllowed = true + + // Figure out if it's a module code. + this.strict = this.inModule = options.sourceType === "module" + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1 + + // Flags to track whether we are in a function, a generator. + this.inFunction = this.inGenerator = false + // Labels in scope. + this.labels = [] + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === '#!') + this.skipLineComment(2) +}; + +// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them +Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; +Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; + +Parser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]) +}; + +Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; + + for (var name in pluginConfigs) { + var plugin = plugins[name] + if (!plugin) throw new Error("Plugin '" + name + "' not found") + plugin(this$1, pluginConfigs[name]) + } +}; + +Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode() + this.nextToken() + return this.parseTopLevel(node) +}; + +var pp = Parser.prototype + +// ## Parser utilities + +// Test whether a statement node is the string literal `"use strict"`. + +pp.isUseStrict = function(stmt) { + return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && + stmt.expression.type === "Literal" && + stmt.expression.raw.slice(1, -1) === "use strict" +} + +// Predicate that tests whether the next token is of the given +// type, and if yes, consumes it as a side effect. + +pp.eat = function(type) { + if (this.type === type) { + this.next() + return true + } else { + return false + } +} + +// Tests whether parsed token is a contextual keyword. + +pp.isContextual = function(name) { + return this.type === tt.name && this.value === name +} + +// Consumes contextual keyword if possible. + +pp.eatContextual = function(name) { + return this.value === name && this.eat(tt.name) +} + +// Asserts that following token is given contextual keyword. + +pp.expectContextual = function(name) { + if (!this.eatContextual(name)) this.unexpected() +} + +// Test whether a semicolon can be inserted at the current position. + +pp.canInsertSemicolon = function() { + return this.type === tt.eof || + this.type === tt.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) +} + +pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc) + return true + } +} + +// Consume a semicolon, or, failing that, see if we are allowed to +// pretend that there is a semicolon at this position. + +pp.semicolon = function() { + if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected() +} + +pp.afterTrailingComma = function(tokType) { + if (this.type == tokType) { + if (this.options.onTrailingComma) + this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc) + this.next() + return true + } +} + +// Expect a token of a given type. If found, consume it, otherwise, +// raise an unexpected token error. + +pp.expect = function(type) { + this.eat(type) || this.unexpected() +} + +// Raise an unexpected token error. + +pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token") +} + +var DestructuringErrors = function DestructuringErrors() { + this.shorthandAssign = 0 + this.trailingComma = 0 +}; + +pp.checkPatternErrors = function(refDestructuringErrors, andThrow) { + var trailing = refDestructuringErrors && refDestructuringErrors.trailingComma + if (!andThrow) return !!trailing + if (trailing) this.raise(trailing, "Comma is not permitted after the rest element") +} + +pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + var pos = refDestructuringErrors && refDestructuringErrors.shorthandAssign + if (!andThrow) return !!pos + if (pos) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns") +} + +var pp$1 = Parser.prototype + +// ### Statement parsing + +// Parse a program. Initializes the parser, reads any number of +// statements, and wraps them in a Program node. Optionally takes a +// `program` argument. If present, the statements will be appended +// to its body instead of creating a new node. + +pp$1.parseTopLevel = function(node) { + var this$1 = this; + + var first = true + if (!node.body) node.body = [] + while (this.type !== tt.eof) { + var stmt = this$1.parseStatement(true, true) + node.body.push(stmt) + if (first) { + if (this$1.isUseStrict(stmt)) this$1.setStrict(true) + first = false + } + } + this.next() + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType + } + return this.finishNode(node, "Program") +} + +var loopLabel = {kind: "loop"}; +var switchLabel = {kind: "switch"}; +pp$1.isLet = function() { + if (this.type !== tt.name || this.options.ecmaVersion < 6 || this.value != "let") return false + skipWhiteSpace.lastIndex = this.pos + var skip = skipWhiteSpace.exec(this.input) + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next) + if (nextCh === 91 || nextCh == 123) return true // '{' and '[' + if (isIdentifierStart(nextCh, true)) { + for (var pos = next + 1; isIdentifierChar(this.input.charCodeAt(pos), true); ++pos) {} + var ident = this.input.slice(next, pos) + if (!this.isKeyword(ident)) return true + } + return false +} + +// Parse a single statement. +// +// If expecting a statement and finding a slash operator, parse a +// regular expression literal. This is to handle cases like +// `if (foo) /blah/.exec(foo)`, where looking at the previous token +// does not help. + +pp$1.parseStatement = function(declaration, topLevel) { + var starttype = this.type, node = this.startNode(), kind + + if (this.isLet()) { + starttype = tt._var + kind = "let" + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + switch (starttype) { + case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case tt._debugger: return this.parseDebuggerStatement(node) + case tt._do: return this.parseDoStatement(node) + case tt._for: return this.parseForStatement(node) + case tt._function: + if (!declaration && this.options.ecmaVersion >= 6) this.unexpected() + return this.parseFunctionStatement(node) + case tt._class: + if (!declaration) this.unexpected() + return this.parseClass(node, true) + case tt._if: return this.parseIfStatement(node) + case tt._return: return this.parseReturnStatement(node) + case tt._switch: return this.parseSwitchStatement(node) + case tt._throw: return this.parseThrowStatement(node) + case tt._try: return this.parseTryStatement(node) + case tt._const: case tt._var: + kind = kind || this.value + if (!declaration && kind != "var") this.unexpected() + return this.parseVarStatement(node, kind) + case tt._while: return this.parseWhileStatement(node) + case tt._with: return this.parseWithStatement(node) + case tt.braceL: return this.parseBlock() + case tt.semi: return this.parseEmptyStatement(node) + case tt._export: + case tt._import: + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + this.raise(this.start, "'import' and 'export' may only appear at the top level") + if (!this.inModule) + this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'") + } + return starttype === tt._import ? this.parseImport(node) : this.parseExport(node) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + var maybeName = this.value, expr = this.parseExpression() + if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) + return this.parseLabeledStatement(node, maybeName, expr) + else return this.parseExpressionStatement(node, expr) + } +} + +pp$1.parseBreakContinueStatement = function(node, keyword) { + var this$1 = this; + + var isBreak = keyword == "break" + this.next() + if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null + else if (this.type !== tt.name) this.unexpected() + else { + node.label = this.parseIdent() + this.semicolon() + } + + // Verify that there is an actual destination to break or + // continue to. + for (var i = 0; i < this.labels.length; ++i) { + var lab = this$1.labels[i] + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) break + if (node.label && isBreak) break + } + } + if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword) + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") +} + +pp$1.parseDebuggerStatement = function(node) { + this.next() + this.semicolon() + return this.finishNode(node, "DebuggerStatement") +} + +pp$1.parseDoStatement = function(node) { + this.next() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + this.expect(tt._while) + node.test = this.parseParenExpression() + if (this.options.ecmaVersion >= 6) + this.eat(tt.semi) + else + this.semicolon() + return this.finishNode(node, "DoWhileStatement") +} + +// Disambiguating between a `for` and a `for`/`in` or `for`/`of` +// loop is non-trivial. Basically, we have to parse the init `var` +// statement or expression, disallowing the `in` operator (see +// the second parameter to `parseExpression`), and then check +// whether the next token is `in` or `of`. When there is no init +// part (semicolon immediately after the opening parenthesis), it +// is a regular `for` loop. + +pp$1.parseForStatement = function(node) { + this.next() + this.labels.push(loopLabel) + this.expect(tt.parenL) + if (this.type === tt.semi) return this.parseFor(node, null) + var isLet = this.isLet() + if (this.type === tt._var || this.type === tt._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value + this.next() + this.parseVar(init$1, true, kind) + this.finishNode(init$1, "VariableDeclaration") + if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && + !(kind !== "var" && init$1.declarations[0].init)) + return this.parseForIn(node, init$1) + return this.parseFor(node, init$1) + } + var refDestructuringErrors = new DestructuringErrors + var init = this.parseExpression(true, refDestructuringErrors) + if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + this.checkPatternErrors(refDestructuringErrors, true) + this.toAssignable(init) + this.checkLVal(init) + return this.parseForIn(node, init) + } else { + this.checkExpressionErrors(refDestructuringErrors, true) + } + return this.parseFor(node, init) +} + +pp$1.parseFunctionStatement = function(node) { + this.next() + return this.parseFunction(node, true) +} + +pp$1.parseIfStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + node.consequent = this.parseStatement(false) + node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null + return this.finishNode(node, "IfStatement") +} + +pp$1.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + this.raise(this.start, "'return' outside of function") + this.next() + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null + else { node.argument = this.parseExpression(); this.semicolon() } + return this.finishNode(node, "ReturnStatement") +} + +pp$1.parseSwitchStatement = function(node) { + var this$1 = this; + + this.next() + node.discriminant = this.parseParenExpression() + node.cases = [] + this.expect(tt.braceL) + this.labels.push(switchLabel) + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + for (var cur, sawDefault = false; this.type != tt.braceR;) { + if (this$1.type === tt._case || this$1.type === tt._default) { + var isCase = this$1.type === tt._case + if (cur) this$1.finishNode(cur, "SwitchCase") + node.cases.push(cur = this$1.startNode()) + cur.consequent = [] + this$1.next() + if (isCase) { + cur.test = this$1.parseExpression() + } else { + if (sawDefault) this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses") + sawDefault = true + cur.test = null + } + this$1.expect(tt.colon) + } else { + if (!cur) this$1.unexpected() + cur.consequent.push(this$1.parseStatement(true)) + } + } + if (cur) this.finishNode(cur, "SwitchCase") + this.next() // Closing brace + this.labels.pop() + return this.finishNode(node, "SwitchStatement") +} + +pp$1.parseThrowStatement = function(node) { + this.next() + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + this.raise(this.lastTokEnd, "Illegal newline after throw") + node.argument = this.parseExpression() + this.semicolon() + return this.finishNode(node, "ThrowStatement") +} + +// Reused empty array added for node fields that are always empty. + +var empty = [] + +pp$1.parseTryStatement = function(node) { + this.next() + node.block = this.parseBlock() + node.handler = null + if (this.type === tt._catch) { + var clause = this.startNode() + this.next() + this.expect(tt.parenL) + clause.param = this.parseBindingAtom() + this.checkLVal(clause.param, true) + this.expect(tt.parenR) + clause.body = this.parseBlock() + node.handler = this.finishNode(clause, "CatchClause") + } + node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null + if (!node.handler && !node.finalizer) + this.raise(node.start, "Missing catch or finally clause") + return this.finishNode(node, "TryStatement") +} + +pp$1.parseVarStatement = function(node, kind) { + this.next() + this.parseVar(node, false, kind) + this.semicolon() + return this.finishNode(node, "VariableDeclaration") +} + +pp$1.parseWhileStatement = function(node) { + this.next() + node.test = this.parseParenExpression() + this.labels.push(loopLabel) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "WhileStatement") +} + +pp$1.parseWithStatement = function(node) { + if (this.strict) this.raise(this.start, "'with' in strict mode") + this.next() + node.object = this.parseParenExpression() + node.body = this.parseStatement(false) + return this.finishNode(node, "WithStatement") +} + +pp$1.parseEmptyStatement = function(node) { + this.next() + return this.finishNode(node, "EmptyStatement") +} + +pp$1.parseLabeledStatement = function(node, maybeName, expr) { + var this$1 = this; + + for (var i = 0; i < this.labels.length; ++i) + if (this$1.labels[i].name === maybeName) this$1.raise(expr.start, "Label '" + maybeName + "' is already declared") + var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null + for (var i$1 = this.labels.length - 1; i$1 >= 0; i$1--) { + var label = this$1.labels[i$1] + if (label.statementStart == node.start) { + label.statementStart = this$1.start + label.kind = kind + } else break + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}) + node.body = this.parseStatement(true) + this.labels.pop() + node.label = expr + return this.finishNode(node, "LabeledStatement") +} + +pp$1.parseExpressionStatement = function(node, expr) { + node.expression = expr + this.semicolon() + return this.finishNode(node, "ExpressionStatement") +} + +// Parse a semicolon-enclosed block of statements, handling `"use +// strict"` declarations when `allowStrict` is true (used for +// function bodies). + +pp$1.parseBlock = function(allowStrict) { + var this$1 = this; + + var node = this.startNode(), first = true, oldStrict + node.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + var stmt = this$1.parseStatement(true) + node.body.push(stmt) + if (first && allowStrict && this$1.isUseStrict(stmt)) { + oldStrict = this$1.strict + this$1.setStrict(this$1.strict = true) + } + first = false + } + if (oldStrict === false) this.setStrict(false) + return this.finishNode(node, "BlockStatement") +} + +// Parse a regular `for` loop. The disambiguation code in +// `parseStatement` will already have parsed the init statement or +// expression. + +pp$1.parseFor = function(node, init) { + node.init = init + this.expect(tt.semi) + node.test = this.type === tt.semi ? null : this.parseExpression() + this.expect(tt.semi) + node.update = this.type === tt.parenR ? null : this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, "ForStatement") +} + +// Parse a `for`/`in` and `for`/`of` loop, which are almost +// same from parser's perspective. + +pp$1.parseForIn = function(node, init) { + var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement" + this.next() + node.left = init + node.right = this.parseExpression() + this.expect(tt.parenR) + node.body = this.parseStatement(false) + this.labels.pop() + return this.finishNode(node, type) +} + +// Parse a list of variable declarations. + +pp$1.parseVar = function(node, isFor, kind) { + var this$1 = this; + + node.declarations = [] + node.kind = kind + for (;;) { + var decl = this$1.startNode() + this$1.parseVarId(decl) + if (this$1.eat(tt.eq)) { + decl.init = this$1.parseMaybeAssign(isFor) + } else if (kind === "const" && !(this$1.type === tt._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { + this$1.unexpected() + } else if (decl.id.type != "Identifier" && !(isFor && (this$1.type === tt._in || this$1.isContextual("of")))) { + this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value") + } else { + decl.init = null + } + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")) + if (!this$1.eat(tt.comma)) break + } + return node +} + +pp$1.parseVarId = function(decl) { + decl.id = this.parseBindingAtom() + this.checkLVal(decl.id, true) +} + +// Parse a function declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseFunction = function(node, isStatement, allowExpressionBody) { + this.initFunction(node) + if (this.options.ecmaVersion >= 6) + node.generator = this.eat(tt.star) + var oldInGen = this.inGenerator + this.inGenerator = node.generator + if (isStatement || this.type === tt.name) + node.id = this.parseIdent() + this.parseFunctionParams(node) + this.parseFunctionBody(node, allowExpressionBody) + this.inGenerator = oldInGen + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") +} + +pp$1.parseFunctionParams = function(node) { + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, false, true) +} + +// Parse a class declaration or literal (depending on the +// `isStatement` parameter). + +pp$1.parseClass = function(node, isStatement) { + var this$1 = this; + + this.next() + this.parseClassId(node, isStatement) + this.parseClassSuper(node) + var classBody = this.startNode() + var hadConstructor = false + classBody.body = [] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (this$1.eat(tt.semi)) continue + var method = this$1.startNode() + var isGenerator = this$1.eat(tt.star) + var isMaybeStatic = this$1.type === tt.name && this$1.value === "static" + this$1.parsePropertyName(method) + method.static = isMaybeStatic && this$1.type !== tt.parenL + if (method.static) { + if (isGenerator) this$1.unexpected() + isGenerator = this$1.eat(tt.star) + this$1.parsePropertyName(method) + } + method.kind = "method" + var isGetSet = false + if (!method.computed) { + var key = method.key; + if (!isGenerator && key.type === "Identifier" && this$1.type !== tt.parenL && (key.name === "get" || key.name === "set")) { + isGetSet = true + method.kind = key.name + key = this$1.parsePropertyName(method) + } + if (!method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (hadConstructor) this$1.raise(key.start, "Duplicate constructor in the same class") + if (isGetSet) this$1.raise(key.start, "Constructor can't have get/set modifier") + if (isGenerator) this$1.raise(key.start, "Constructor can't be a generator") + method.kind = "constructor" + hadConstructor = true + } + } + this$1.parseClassMethod(classBody, method, isGenerator) + if (isGetSet) { + var paramCount = method.kind === "get" ? 0 : 1 + if (method.value.params.length !== paramCount) { + var start = method.value.start + if (method.kind === "get") + this$1.raiseRecoverable(start, "getter should have no params") + else + this$1.raiseRecoverable(start, "setter should have exactly one param") + } + if (method.kind === "set" && method.value.params[0].type === "RestElement") + this$1.raise(method.value.params[0].start, "Setter cannot use rest params") + } + } + node.body = this.finishNode(classBody, "ClassBody") + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") +} + +pp$1.parseClassMethod = function(classBody, method, isGenerator) { + method.value = this.parseMethod(isGenerator) + classBody.body.push(this.finishNode(method, "MethodDefinition")) +} + +pp$1.parseClassId = function(node, isStatement) { + node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null +} + +pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null +} + +// Parses module export declaration. + +pp$1.parseExport = function(node) { + var this$1 = this; + + this.next() + // export * from '...' + if (this.eat(tt.star)) { + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + this.semicolon() + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(tt._default)) { // export default ... + var parens = this.type == tt.parenL + var expr = this.parseMaybeAssign() + var needsSemi = true + if (!parens && (expr.type == "FunctionExpression" || + expr.type == "ClassExpression")) { + needsSemi = false + if (expr.id) { + expr.type = expr.type == "FunctionExpression" + ? "FunctionDeclaration" + : "ClassDeclaration" + } + } + node.declaration = expr + if (needsSemi) this.semicolon() + return this.finishNode(node, "ExportDefaultDeclaration") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(true) + node.specifiers = [] + node.source = null + } else { // export { x, y as z } [from '...'] + node.declaration = null + node.specifiers = this.parseExportSpecifiers() + if (this.eatContextual("from")) { + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } else { + // check for keywords used as local names + for (var i = 0; i < node.specifiers.length; i++) { + if (this$1.keywords.test(node.specifiers[i].local.name) || this$1.reservedWords.test(node.specifiers[i].local.name)) { + this$1.unexpected(node.specifiers[i].local.start) + } + } + + node.source = null + } + this.semicolon() + } + return this.finishNode(node, "ExportNamedDeclaration") +} + +pp$1.shouldParseExportStatement = function() { + return this.type.keyword || this.isLet() +} + +// Parses a comma-separated list of module exports. + +pp$1.parseExportSpecifiers = function() { + var this$1 = this; + + var nodes = [], first = true + // export { x, y as z } [from '...'] + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node = this$1.startNode() + node.local = this$1.parseIdent(this$1.type === tt._default) + node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local + nodes.push(this$1.finishNode(node, "ExportSpecifier")) + } + return nodes +} + +// Parses import declaration. + +pp$1.parseImport = function(node) { + this.next() + // import '...' + if (this.type === tt.string) { + node.specifiers = empty + node.source = this.parseExprAtom() + } else { + node.specifiers = this.parseImportSpecifiers() + this.expectContextual("from") + node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected() + } + this.semicolon() + return this.finishNode(node, "ImportDeclaration") +} + +// Parses a comma-separated list of module imports. + +pp$1.parseImportSpecifiers = function() { + var this$1 = this; + + var nodes = [], first = true + if (this.type === tt.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode() + node.local = this.parseIdent() + this.checkLVal(node.local, true) + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")) + if (!this.eat(tt.comma)) return nodes + } + if (this.type === tt.star) { + var node$1 = this.startNode() + this.next() + this.expectContextual("as") + node$1.local = this.parseIdent() + this.checkLVal(node$1.local, true) + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")) + return nodes + } + this.expect(tt.braceL) + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var node$2 = this$1.startNode() + node$2.imported = this$1.parseIdent(true) + if (this$1.eatContextual("as")) { + node$2.local = this$1.parseIdent() + } else { + node$2.local = node$2.imported + if (this$1.isKeyword(node$2.local.name)) this$1.unexpected(node$2.local.start) + if (this$1.reservedWordsStrict.test(node$2.local.name)) this$1.raise(node$2.local.start, "The keyword '" + node$2.local.name + "' is reserved") + } + this$1.checkLVal(node$2.local, true) + nodes.push(this$1.finishNode(node$2, "ImportSpecifier")) + } + return nodes +} + +var pp$2 = Parser.prototype + +// Convert existing expression atom to assignable pattern +// if possible. + +pp$2.toAssignable = function(node, isBinding) { + var this$1 = this; + + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + case "ObjectPattern": + case "ArrayPattern": + break + + case "ObjectExpression": + node.type = "ObjectPattern" + for (var i = 0; i < node.properties.length; i++) { + var prop = node.properties[i] + if (prop.kind !== "init") this$1.raise(prop.key.start, "Object pattern can't contain getter or setter") + this$1.toAssignable(prop.value, isBinding) + } + break + + case "ArrayExpression": + node.type = "ArrayPattern" + this.toAssignableList(node.elements, isBinding) + break + + case "AssignmentExpression": + if (node.operator === "=") { + node.type = "AssignmentPattern" + delete node.operator + // falls through to AssignmentPattern + } else { + this.raise(node.left.end, "Only '=' operator can be used for specifying default value.") + break + } + + case "AssignmentPattern": + if (node.right.type === "YieldExpression") + this.raise(node.right.start, "Yield expression cannot be a default value") + break + + case "ParenthesizedExpression": + node.expression = this.toAssignable(node.expression, isBinding) + break + + case "MemberExpression": + if (!isBinding) break + + default: + this.raise(node.start, "Assigning to rvalue") + } + } + return node +} + +// Convert list of expression atoms to binding list. + +pp$2.toAssignableList = function(exprList, isBinding) { + var this$1 = this; + + var end = exprList.length + if (end) { + var last = exprList[end - 1] + if (last && last.type == "RestElement") { + --end + } else if (last && last.type == "SpreadElement") { + last.type = "RestElement" + var arg = last.argument + this.toAssignable(arg, isBinding) + if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") + this.unexpected(arg.start) + --end + } + + if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + this.unexpected(last.argument.start) + } + for (var i = 0; i < end; i++) { + var elt = exprList[i] + if (elt) this$1.toAssignable(elt, isBinding) + } + return exprList +} + +// Parses spread element. + +pp$2.parseSpread = function(refDestructuringErrors) { + var node = this.startNode() + this.next() + node.argument = this.parseMaybeAssign(false, refDestructuringErrors) + return this.finishNode(node, "SpreadElement") +} + +pp$2.parseRest = function(allowNonIdent) { + var node = this.startNode() + this.next() + + // RestElement inside of a function parameter must be an identifier + if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected() + else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected() + + return this.finishNode(node, "RestElement") +} + +// Parses lvalue (assignable) atom. + +pp$2.parseBindingAtom = function() { + if (this.options.ecmaVersion < 6) return this.parseIdent() + switch (this.type) { + case tt.name: + return this.parseIdent() + + case tt.bracketL: + var node = this.startNode() + this.next() + node.elements = this.parseBindingList(tt.bracketR, true, true) + return this.finishNode(node, "ArrayPattern") + + case tt.braceL: + return this.parseObj(true) + + default: + this.unexpected() + } +} + +pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) { + var this$1 = this; + + var elts = [], first = true + while (!this.eat(close)) { + if (first) first = false + else this$1.expect(tt.comma) + if (allowEmpty && this$1.type === tt.comma) { + elts.push(null) + } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { + break + } else if (this$1.type === tt.ellipsis) { + var rest = this$1.parseRest(allowNonIdent) + this$1.parseBindingListItem(rest) + elts.push(rest) + if (this$1.type === tt.comma) this$1.raise(this$1.start, "Comma is not permitted after the rest element") + this$1.expect(close) + break + } else { + var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc) + this$1.parseBindingListItem(elem) + elts.push(elem) + } + } + return elts +} + +pp$2.parseBindingListItem = function(param) { + return param +} + +// Parses assignment pattern around given atom if possible. + +pp$2.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom() + if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.right = this.parseMaybeAssign() + return this.finishNode(node, "AssignmentPattern") +} + +// Verify that a node is an lval — something that can be assigned +// to. + +pp$2.checkLVal = function(expr, isBinding, checkClashes) { + var this$1 = this; + + switch (expr.type) { + case "Identifier": + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode") + if (checkClashes) { + if (has(checkClashes, expr.name)) + this.raiseRecoverable(expr.start, "Argument name clash") + checkClashes[expr.name] = true + } + break + + case "MemberExpression": + if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression") + break + + case "ObjectPattern": + for (var i = 0; i < expr.properties.length; i++) + this$1.checkLVal(expr.properties[i].value, isBinding, checkClashes) + break + + case "ArrayPattern": + for (var i$1 = 0; i$1 < expr.elements.length; i$1++) { + var elem = expr.elements[i$1] + if (elem) this$1.checkLVal(elem, isBinding, checkClashes) + } + break + + case "AssignmentPattern": + this.checkLVal(expr.left, isBinding, checkClashes) + break + + case "RestElement": + this.checkLVal(expr.argument, isBinding, checkClashes) + break + + case "ParenthesizedExpression": + this.checkLVal(expr.expression, isBinding, checkClashes) + break + + default: + this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue") + } +} + +var pp$3 = Parser.prototype + +// Check if property name clashes with already added. +// Object/class getters and setters are not allowed to clash — +// either with each other or with an init property — and in +// strict mode, init properties are also not allowed to be repeated. + +pp$3.checkPropClash = function(prop, propHash) { + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + return + var key = prop.key; + var name + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property") + propHash.proto = true + } + return + } + name = "$" + name + var other = propHash[name] + if (other) { + var isGetSet = kind !== "init" + if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) + this.raiseRecoverable(key.start, "Redefinition of property") + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + } + } + other[kind] = true +} + +// ### Expression parsing + +// These nest, from the most general expression type at the top to +// 'atomic', nondivisible expression types at the bottom. Most of +// the functions will simply let the function(s) below them parse, +// and, *if* the syntactic construct they handle is present, wrap +// the AST node that the inner parser gave them in another node. + +// Parse a full expression. The optional arguments are used to +// forbid the `in` operator (in for loops initalization expressions) +// and provide reference for storing '=' operator inside shorthand +// property assignment in contexts where both object expression +// and object pattern might appear (so it's possible to raise +// delayed syntax error at correct position). + +pp$3.parseExpression = function(noIn, refDestructuringErrors) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeAssign(noIn, refDestructuringErrors) + if (this.type === tt.comma) { + var node = this.startNodeAt(startPos, startLoc) + node.expressions = [expr] + while (this.eat(tt.comma)) node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)) + return this.finishNode(node, "SequenceExpression") + } + return expr +} + +// Parse an assignment expression. This includes applications of +// operators like `+=`. + +pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.inGenerator && this.isContextual("yield")) return this.parseYield() + + var ownDestructuringErrors = false + if (!refDestructuringErrors) { + refDestructuringErrors = new DestructuringErrors + ownDestructuringErrors = true + } + var startPos = this.start, startLoc = this.startLoc + if (this.type == tt.parenL || this.type == tt.name) + this.potentialArrowAt = this.start + var left = this.parseMaybeConditional(noIn, refDestructuringErrors) + if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc) + if (this.type.isAssign) { + this.checkPatternErrors(refDestructuringErrors, true) + if (!ownDestructuringErrors) DestructuringErrors.call(refDestructuringErrors) + var node = this.startNodeAt(startPos, startLoc) + node.operator = this.value + node.left = this.type === tt.eq ? this.toAssignable(left) : left + refDestructuringErrors.shorthandAssign = 0 // reset because shorthand default was used correctly + this.checkLVal(left) + this.next() + node.right = this.parseMaybeAssign(noIn) + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true) + } + return left +} + +// Parse a ternary conditional (`?:`) operator. + +pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprOps(noIn, refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + if (this.eat(tt.question)) { + var node = this.startNodeAt(startPos, startLoc) + node.test = expr + node.consequent = this.parseMaybeAssign() + this.expect(tt.colon) + node.alternate = this.parseMaybeAssign(noIn) + return this.finishNode(node, "ConditionalExpression") + } + return expr +} + +// Start the precedence parser. + +pp$3.parseExprOps = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseMaybeUnary(refDestructuringErrors, false) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + return this.parseExprOp(expr, startPos, startLoc, -1, noIn) +} + +// Parse binary operators with the operator precedence parsing +// algorithm. `left` is the left-hand side of the operator. +// `minPrec` provides context that allows the function to stop and +// defer further parser to one of its callers when it encounters an +// operator that has a lower precedence than the set it is parsing. + +pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + var prec = this.type.binop + if (prec != null && (!noIn || this.type !== tt._in)) { + if (prec > minPrec) { + var logical = this.type === tt.logicalOR || this.type === tt.logicalAND + var op = this.value + this.next() + var startPos = this.start, startLoc = this.startLoc + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn) + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical) + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + } + } + return left +} + +pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { + var node = this.startNodeAt(startPos, startLoc) + node.left = left + node.operator = op + node.right = right + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") +} + +// Parse unary operators, both prefix and postfix. + +pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, expr + if (this.type.prefix) { + var node = this.startNode(), update = this.type === tt.incDec + node.operator = this.value + node.prefix = true + this.next() + node.argument = this.parseMaybeUnary(null, true) + this.checkExpressionErrors(refDestructuringErrors, true) + if (update) this.checkLVal(node.argument) + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + this.raiseRecoverable(node.start, "Deleting local variable in strict mode") + else sawUnary = true + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression") + } else { + expr = this.parseExprSubscripts(refDestructuringErrors) + if (this.checkExpressionErrors(refDestructuringErrors)) return expr + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.operator = this$1.value + node$1.prefix = false + node$1.argument = expr + this$1.checkLVal(expr) + this$1.next() + expr = this$1.finishNode(node$1, "UpdateExpression") + } + } + + if (!sawUnary && this.eat(tt.starstar)) + return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) + else + return expr +} + +// Parse call, dot, and `[]`-subscript expressions. + +pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc + var expr = this.parseExprAtom(refDestructuringErrors) + var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")" + if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr + return this.parseSubscripts(expr, startPos, startLoc) +} + +pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { + var this$1 = this; + + for (;;) { + if (this$1.eat(tt.dot)) { + var node = this$1.startNodeAt(startPos, startLoc) + node.object = base + node.property = this$1.parseIdent(true) + node.computed = false + base = this$1.finishNode(node, "MemberExpression") + } else if (this$1.eat(tt.bracketL)) { + var node$1 = this$1.startNodeAt(startPos, startLoc) + node$1.object = base + node$1.property = this$1.parseExpression() + node$1.computed = true + this$1.expect(tt.bracketR) + base = this$1.finishNode(node$1, "MemberExpression") + } else if (!noCalls && this$1.eat(tt.parenL)) { + var node$2 = this$1.startNodeAt(startPos, startLoc) + node$2.callee = base + node$2.arguments = this$1.parseExprList(tt.parenR, false) + base = this$1.finishNode(node$2, "CallExpression") + } else if (this$1.type === tt.backQuote) { + var node$3 = this$1.startNodeAt(startPos, startLoc) + node$3.tag = base + node$3.quasi = this$1.parseTemplate() + base = this$1.finishNode(node$3, "TaggedTemplateExpression") + } else { + return base + } + } +} + +// Parse an atomic expression — either a single token that is an +// expression, an expression started by a keyword like `function` or +// `new`, or an expression wrapped in punctuation like `()`, `[]`, +// or `{}`. + +pp$3.parseExprAtom = function(refDestructuringErrors) { + var node, canBeArrow = this.potentialArrowAt == this.start + switch (this.type) { + case tt._super: + if (!this.inFunction) + this.raise(this.start, "'super' outside of function or class") + + case tt._this: + var type = this.type === tt._this ? "ThisExpression" : "Super" + node = this.startNode() + this.next() + return this.finishNode(node, type) + + case tt.name: + var startPos = this.start, startLoc = this.startLoc + var id = this.parseIdent(this.type !== tt.name) + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id]) + return id + + case tt.regexp: + var value = this.value + node = this.parseLiteral(value.value) + node.regex = {pattern: value.pattern, flags: value.flags} + return node + + case tt.num: case tt.string: + return this.parseLiteral(this.value) + + case tt._null: case tt._true: case tt._false: + node = this.startNode() + node.value = this.type === tt._null ? null : this.type === tt._true + node.raw = this.type.keyword + this.next() + return this.finishNode(node, "Literal") + + case tt.parenL: + return this.parseParenAndDistinguishExpression(canBeArrow) + + case tt.bracketL: + node = this.startNode() + this.next() + node.elements = this.parseExprList(tt.bracketR, true, true, refDestructuringErrors) + return this.finishNode(node, "ArrayExpression") + + case tt.braceL: + return this.parseObj(false, refDestructuringErrors) + + case tt._function: + node = this.startNode() + this.next() + return this.parseFunction(node, false) + + case tt._class: + return this.parseClass(this.startNode(), false) + + case tt._new: + return this.parseNew() + + case tt.backQuote: + return this.parseTemplate() + + default: + this.unexpected() + } +} + +pp$3.parseLiteral = function(value) { + var node = this.startNode() + node.value = value + node.raw = this.input.slice(this.start, this.end) + this.next() + return this.finishNode(node, "Literal") +} + +pp$3.parseParenExpression = function() { + this.expect(tt.parenL) + var val = this.parseExpression() + this.expect(tt.parenR) + return val +} + +pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { + var this$1 = this; + + var startPos = this.start, startLoc = this.startLoc, val + if (this.options.ecmaVersion >= 6) { + this.next() + + var innerStartPos = this.start, innerStartLoc = this.startLoc + var exprList = [], first = true + var refDestructuringErrors = new DestructuringErrors, spreadStart, innerParenStart + while (this.type !== tt.parenR) { + first ? first = false : this$1.expect(tt.comma) + if (this$1.type === tt.ellipsis) { + spreadStart = this$1.start + exprList.push(this$1.parseParenItem(this$1.parseRest())) + break + } else { + if (this$1.type === tt.parenL && !innerParenStart) { + innerParenStart = this$1.start + } + exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)) + } + } + var innerEndPos = this.start, innerEndLoc = this.startLoc + this.expect(tt.parenR) + + if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { + this.checkPatternErrors(refDestructuringErrors, true) + if (innerParenStart) this.unexpected(innerParenStart) + return this.parseParenArrowList(startPos, startLoc, exprList) + } + + if (!exprList.length) this.unexpected(this.lastTokStart) + if (spreadStart) this.unexpected(spreadStart) + this.checkExpressionErrors(refDestructuringErrors, true) + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc) + val.expressions = exprList + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc) + } else { + val = exprList[0] + } + } else { + val = this.parseParenExpression() + } + + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc) + par.expression = val + return this.finishNode(par, "ParenthesizedExpression") + } else { + return val + } +} + +pp$3.parseParenItem = function(item) { + return item +} + +pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) +} + +// New's precedence is slightly tricky. It must allow its argument to +// be a `[]` or dot subscript expression, but not a call — at least, +// not without wrapping it in parentheses. Thus, it uses the noCalls +// argument to parseSubscripts to prevent it from consuming the +// argument list. + +var empty$1 = [] + +pp$3.parseNew = function() { + var node = this.startNode() + var meta = this.parseIdent(true) + if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) { + node.meta = meta + node.property = this.parseIdent(true) + if (node.property.name !== "target") + this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target") + if (!this.inFunction) + this.raiseRecoverable(node.start, "new.target can only be used in functions") + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true) + if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, false) + else node.arguments = empty$1 + return this.finishNode(node, "NewExpression") +} + +// Parse template expression. + +pp$3.parseTemplateElement = function() { + var elem = this.startNode() + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'), + cooked: this.value + } + this.next() + elem.tail = this.type === tt.backQuote + return this.finishNode(elem, "TemplateElement") +} + +pp$3.parseTemplate = function() { + var this$1 = this; + + var node = this.startNode() + this.next() + node.expressions = [] + var curElt = this.parseTemplateElement() + node.quasis = [curElt] + while (!curElt.tail) { + this$1.expect(tt.dollarBraceL) + node.expressions.push(this$1.parseExpression()) + this$1.expect(tt.braceR) + node.quasis.push(curElt = this$1.parseTemplateElement()) + } + this.next() + return this.finishNode(node, "TemplateLiteral") +} + +// Parse an object literal or binding pattern. + +pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var this$1 = this; + + var node = this.startNode(), first = true, propHash = {} + node.properties = [] + this.next() + while (!this.eat(tt.braceR)) { + if (!first) { + this$1.expect(tt.comma) + if (this$1.afterTrailingComma(tt.braceR)) break + } else first = false + + var prop = this$1.startNode(), isGenerator, startPos, startLoc + if (this$1.options.ecmaVersion >= 6) { + prop.method = false + prop.shorthand = false + if (isPattern || refDestructuringErrors) { + startPos = this$1.start + startLoc = this$1.startLoc + } + if (!isPattern) + isGenerator = this$1.eat(tt.star) + } + this$1.parsePropertyName(prop) + this$1.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors) + this$1.checkPropClash(prop, propHash) + node.properties.push(this$1.finishNode(prop, "Property")) + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") +} + +pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, startPos, startLoc, refDestructuringErrors) { + if (this.eat(tt.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors) + prop.kind = "init" + } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) { + if (isPattern) this.unexpected() + prop.kind = "init" + prop.method = true + prop.value = this.parseMethod(isGenerator) + } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type != tt.comma && this.type != tt.braceR)) { + if (isGenerator || isPattern) this.unexpected() + prop.kind = prop.key.name + this.parsePropertyName(prop) + prop.value = this.parseMethod(false) + var paramCount = prop.kind === "get" ? 0 : 1 + if (prop.value.params.length !== paramCount) { + var start = prop.value.start + if (prop.kind === "get") + this.raiseRecoverable(start, "getter should have no params") + else + this.raiseRecoverable(start, "setter should have exactly one param") + } + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params") + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + if (this.keywords.test(prop.key.name) || + (this.strict ? this.reservedWordsStrictBind : this.reservedWords).test(prop.key.name) || + (this.inGenerator && prop.key.name == "yield")) + this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property") + prop.kind = "init" + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else if (this.type === tt.eq && refDestructuringErrors) { + if (!refDestructuringErrors.shorthandAssign) + refDestructuringErrors.shorthandAssign = this.start + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key) + } else { + prop.value = prop.key + } + prop.shorthand = true + } else this.unexpected() +} + +pp$3.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(tt.bracketL)) { + prop.computed = true + prop.key = this.parseMaybeAssign() + this.expect(tt.bracketR) + return prop.key + } else { + prop.computed = false + } + } + return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true) +} + +// Initialize empty function node. + +pp$3.initFunction = function(node) { + node.id = null + if (this.options.ecmaVersion >= 6) { + node.generator = false + node.expression = false + } +} + +// Parse object or class method. + +pp$3.parseMethod = function(isGenerator) { + var node = this.startNode(), oldInGen = this.inGenerator + this.inGenerator = isGenerator + this.initFunction(node) + this.expect(tt.parenL) + node.params = this.parseBindingList(tt.parenR, false, false) + if (this.options.ecmaVersion >= 6) + node.generator = isGenerator + this.parseFunctionBody(node, false) + this.inGenerator = oldInGen + return this.finishNode(node, "FunctionExpression") +} + +// Parse arrow function expression with given parameters. + +pp$3.parseArrowExpression = function(node, params) { + var oldInGen = this.inGenerator + this.inGenerator = false + this.initFunction(node) + node.params = this.toAssignableList(params, true) + this.parseFunctionBody(node, true) + this.inGenerator = oldInGen + return this.finishNode(node, "ArrowFunctionExpression") +} + +// Parse function body and check parameters. + +pp$3.parseFunctionBody = function(node, isArrowFunction) { + var isExpression = isArrowFunction && this.type !== tt.braceL + + if (isExpression) { + node.body = this.parseMaybeAssign() + node.expression = true + } else { + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldInFunc = this.inFunction, oldLabels = this.labels + this.inFunction = true; this.labels = [] + node.body = this.parseBlock(true) + node.expression = false + this.inFunction = oldInFunc; this.labels = oldLabels + } + + // If this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + var useStrict = (!isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) ? node.body.body[0] : null; + if (this.strict || useStrict) { + var oldStrict = this.strict + this.strict = true + if (node.id) + this.checkLVal(node.id, true) + this.checkParams(node, useStrict) + this.strict = oldStrict + } else if (isArrowFunction) { + this.checkParams(node, useStrict) + } +} + +// Checks function params for various disallowed patterns such as using "eval" +// or "arguments" and duplicate parameters. + +pp$3.checkParams = function(node, useStrict) { + var this$1 = this; + + var nameHash = {} + for (var i = 0; i < node.params.length; i++) { + if (useStrict && this$1.options.ecmaVersion >= 7 && node.params[i].type !== "Identifier") + this$1.raiseRecoverable(useStrict.start, "Illegal 'use strict' directive in function with non-simple parameter list"); + this$1.checkLVal(node.params[i], true, nameHash) + } +} + +// Parses a comma-separated list of expressions, and returns them as +// an array. `close` is the token type that ends the list, and +// `allowEmpty` can be turned on to allow subsequent commas with +// nothing in between them to be parsed as `null` (which is needed +// for array literals). + +pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var this$1 = this; + + var elts = [], first = true + while (!this.eat(close)) { + if (!first) { + this$1.expect(tt.comma) + if (allowTrailingComma && this$1.afterTrailingComma(close)) break + } else first = false + + var elt + if (allowEmpty && this$1.type === tt.comma) + elt = null + else if (this$1.type === tt.ellipsis) { + elt = this$1.parseSpread(refDestructuringErrors) + if (this$1.type === tt.comma && refDestructuringErrors && !refDestructuringErrors.trailingComma) { + refDestructuringErrors.trailingComma = this$1.lastTokStart + } + } else + elt = this$1.parseMaybeAssign(false, refDestructuringErrors) + elts.push(elt) + } + return elts +} + +// Parse the next token as an identifier. If `liberal` is true (used +// when parsing properties), it will also convert keywords into +// identifiers. + +pp$3.parseIdent = function(liberal) { + var node = this.startNode() + if (liberal && this.options.allowReserved == "never") liberal = false + if (this.type === tt.name) { + if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) && + (this.options.ecmaVersion >= 6 || + this.input.slice(this.start, this.end).indexOf("\\") == -1)) + this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved") + if (!liberal && this.inGenerator && this.value === "yield") + this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator") + node.name = this.value + } else if (liberal && this.type.keyword) { + node.name = this.type.keyword + } else { + this.unexpected() + } + this.next() + return this.finishNode(node, "Identifier") +} + +// Parses yield expression inside generator. + +pp$3.parseYield = function() { + var node = this.startNode() + this.next() + if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) { + node.delegate = false + node.argument = null + } else { + node.delegate = this.eat(tt.star) + node.argument = this.parseMaybeAssign() + } + return this.finishNode(node, "YieldExpression") +} + +var pp$4 = Parser.prototype + +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. + +pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos) + message += " (" + loc.line + ":" + loc.column + ")" + var err = new SyntaxError(message) + err.pos = pos; err.loc = loc; err.raisedAt = this.pos + throw err +} + +pp$4.raiseRecoverable = pp$4.raise + +pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } +} + +var Node = function Node(parser, pos, loc) { + this.type = "" + this.start = pos + this.end = 0 + if (parser.options.locations) + this.loc = new SourceLocation(parser, loc) + if (parser.options.directSourceFile) + this.sourceFile = parser.options.directSourceFile + if (parser.options.ranges) + this.range = [pos, 0] +}; + +// Start an AST node, attaching a start offset. + +var pp$5 = Parser.prototype + +pp$5.startNode = function() { + return new Node(this, this.start, this.startLoc) +} + +pp$5.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) +} + +// Finish an AST node, adding `type` and `end` properties. + +function finishNodeAt(node, type, pos, loc) { + node.type = type + node.end = pos + if (this.options.locations) + node.loc.end = loc + if (this.options.ranges) + node.range[1] = pos + return node +} + +pp$5.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) +} + +// Finish node at given position + +pp$5.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) +} + +var TokContext = function TokContext(token, isExpr, preserveSpace, override) { + this.token = token + this.isExpr = !!isExpr + this.preserveSpace = !!preserveSpace + this.override = override +}; + +var types = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", true), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.readTmplToken(); }), + f_expr: new TokContext("function", true) +} + +var pp$6 = Parser.prototype + +pp$6.initialContext = function() { + return [types.b_stat] +} + +pp$6.braceIsBlock = function(prevType) { + if (prevType === tt.colon) { + var parent = this.curContext() + if (parent === types.b_stat || parent === types.b_expr) + return !parent.isExpr + } + if (prevType === tt._return) + return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof || prevType === tt.parenR) + return true + if (prevType == tt.braceL) + return this.curContext() === types.b_stat + return !this.exprAllowed +} + +pp$6.updateContext = function(prevType) { + var update, type = this.type + if (type.keyword && prevType == tt.dot) + this.exprAllowed = false + else if (update = type.updateContext) + update.call(this, prevType) + else + this.exprAllowed = type.beforeExpr +} + +// Token-specific context update code + +tt.parenR.updateContext = tt.braceR.updateContext = function() { + if (this.context.length == 1) { + this.exprAllowed = true + return + } + var out = this.context.pop() + if (out === types.b_stat && this.curContext() === types.f_expr) { + this.context.pop() + this.exprAllowed = false + } else if (out === types.b_tmpl) { + this.exprAllowed = true + } else { + this.exprAllowed = !out.isExpr + } +} + +tt.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr) + this.exprAllowed = true +} + +tt.dollarBraceL.updateContext = function() { + this.context.push(types.b_tmpl) + this.exprAllowed = true +} + +tt.parenL.updateContext = function(prevType) { + var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while + this.context.push(statementParens ? types.p_stat : types.p_expr) + this.exprAllowed = true +} + +tt.incDec.updateContext = function() { + // tokExprAllowed stays unchanged +} + +tt._function.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== tt.semi && prevType !== tt._else && + !((prevType === tt.colon || prevType === tt.braceL) && this.curContext() === types.b_stat)) + this.context.push(types.f_expr) + this.exprAllowed = false +} + +tt.backQuote.updateContext = function() { + if (this.curContext() === types.q_tmpl) + this.context.pop() + else + this.context.push(types.q_tmpl) + this.exprAllowed = false +} + +// Object type used to represent tokens. Note that normally, tokens +// simply exist as properties on the parser object. This is only +// used for the onToken callback and the external tokenizer. + +var Token = function Token(p) { + this.type = p.type + this.value = p.value + this.start = p.start + this.end = p.end + if (p.options.locations) + this.loc = new SourceLocation(p, p.startLoc, p.endLoc) + if (p.options.ranges) + this.range = [p.start, p.end] +}; + +// ## Tokenizer + +var pp$7 = Parser.prototype + +// Are we running under Rhino? +var isRhino = typeof Packages == "object" && Object.prototype.toString.call(Packages) == "[object JavaPackage]" + +// Move to the next token + +pp$7.next = function() { + if (this.options.onToken) + this.options.onToken(new Token(this)) + + this.lastTokEnd = this.end + this.lastTokStart = this.start + this.lastTokEndLoc = this.endLoc + this.lastTokStartLoc = this.startLoc + this.nextToken() +} + +pp$7.getToken = function() { + this.next() + return new Token(this) +} + +// If we're in an ES6 environment, make parsers iterable +if (typeof Symbol !== "undefined") + pp$7[Symbol.iterator] = function () { + var self = this + return {next: function () { + var token = self.getToken() + return { + done: token.type === tt.eof, + value: token + } + }} + } + +// Toggle strict mode. Re-reads the next number or string to please +// pedantic tests (`"use strict"; 010;` should fail). + +pp$7.setStrict = function(strict) { + var this$1 = this; + + this.strict = strict + if (this.type !== tt.num && this.type !== tt.string) return + this.pos = this.start + if (this.options.locations) { + while (this.pos < this.lineStart) { + this$1.lineStart = this$1.input.lastIndexOf("\n", this$1.lineStart - 2) + 1 + --this$1.curLine + } + } + this.nextToken() +} + +pp$7.curContext = function() { + return this.context[this.context.length - 1] +} + +// Read a single token, updating the parser object's token-related +// properties. + +pp$7.nextToken = function() { + var curContext = this.curContext() + if (!curContext || !curContext.preserveSpace) this.skipSpace() + + this.start = this.pos + if (this.options.locations) this.startLoc = this.curPosition() + if (this.pos >= this.input.length) return this.finishToken(tt.eof) + + if (curContext.override) return curContext.override(this) + else this.readToken(this.fullCharCodeAtPos()) +} + +pp$7.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + return this.readWord() + + return this.getTokenFromCode(code) +} + +pp$7.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos) + if (code <= 0xd7ff || code >= 0xe000) return code + var next = this.input.charCodeAt(this.pos + 1) + return (code << 10) + next - 0x35fdc00 +} + +pp$7.skipBlockComment = function() { + var this$1 = this; + + var startLoc = this.options.onComment && this.curPosition() + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2) + if (end === -1) this.raise(this.pos - 2, "Unterminated comment") + this.pos = end + 2 + if (this.options.locations) { + lineBreakG.lastIndex = start + var match + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { + ++this$1.curLine + this$1.lineStart = match.index + match[0].length + } + } + if (this.options.onComment) + this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()) +} + +pp$7.skipLineComment = function(startSkip) { + var this$1 = this; + + var start = this.pos + var startLoc = this.options.onComment && this.curPosition() + var ch = this.input.charCodeAt(this.pos+=startSkip) + while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { + ++this$1.pos + ch = this$1.input.charCodeAt(this$1.pos) + } + if (this.options.onComment) + this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()) +} + +// Called at the start of the parse and after every token. Skips +// whitespace and comments, and. + +pp$7.skipSpace = function() { + var this$1 = this; + + loop: while (this.pos < this.input.length) { + var ch = this$1.input.charCodeAt(this$1.pos) + switch (ch) { + case 32: case 160: // ' ' + ++this$1.pos + break + case 13: + if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { + ++this$1.pos + } + case 10: case 8232: case 8233: + ++this$1.pos + if (this$1.options.locations) { + ++this$1.curLine + this$1.lineStart = this$1.pos + } + break + case 47: // '/' + switch (this$1.input.charCodeAt(this$1.pos + 1)) { + case 42: // '*' + this$1.skipBlockComment() + break + case 47: + this$1.skipLineComment(2) + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this$1.pos + } else { + break loop + } + } + } +} + +// Called at the end of every token. Sets `end`, `val`, and +// maintains `context` and `exprAllowed`, and skips the space after +// the token, so that the next one's `start` will point at the +// right position. + +pp$7.finishToken = function(type, val) { + this.end = this.pos + if (this.options.locations) this.endLoc = this.curPosition() + var prevType = this.type + this.type = type + this.value = val + + this.updateContext(prevType) +} + +// ### Token reading + +// This is the function that is called to fetch the next token. It +// is somewhat obscure, because it works in character codes rather +// than characters, and because operator parsing has been inlined +// into it. +// +// All in the name of speed. +// +pp$7.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1) + if (next >= 48 && next <= 57) return this.readNumber(true) + var next2 = this.input.charCodeAt(this.pos + 2) + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.' + this.pos += 3 + return this.finishToken(tt.ellipsis) + } else { + ++this.pos + return this.finishToken(tt.dot) + } +} + +pp$7.readToken_slash = function() { // '/' + var next = this.input.charCodeAt(this.pos + 1) + if (this.exprAllowed) {++this.pos; return this.readRegexp()} + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.slash, 1) +} + +pp$7.readToken_mult_modulo_exp = function(code) { // '%*' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + var tokentype = code === 42 ? tt.star : tt.modulo + + // exponentiation operator ** and **= + if (this.options.ecmaVersion >= 7 && next === 42) { + ++size + tokentype = tt.starstar + next = this.input.charCodeAt(this.pos + 2) + } + + if (next === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tokentype, size) +} + +pp$7.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1) + if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1) +} + +pp$7.readToken_caret = function() { // '^' + var next = this.input.charCodeAt(this.pos + 1) + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.bitwiseXOR, 1) +} + +pp$7.readToken_plus_min = function(code) { // '+-' + var next = this.input.charCodeAt(this.pos + 1) + if (next === code) { + if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && + lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) { + // A `-->` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) +} + +pp$7.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `` line comment + this.skipLineComment(3) + this.skipSpace() + return this.nextToken() + } + return this.finishOp(tt.incDec, 2) + } + if (next === 61) return this.finishOp(tt.assign, 2) + return this.finishOp(tt.plusMin, 1) + } -pp.readToken = function (code) { - // Identifier or keyword. '\uXXXX' sequences are allowed in - // identifiers, so '\' also dispatches to that. - if (_identifier.isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) return this.readWord(); - - return this.getTokenFromCode(code); -}; - -pp.fullCharCodeAtPos = function () { - var code = this.input.charCodeAt(this.pos); - if (code <= 0xd7ff || code >= 0xe000) return code; - var next = this.input.charCodeAt(this.pos + 1); - return (code << 10) + next - 0x35fdc00; -}; - -pp.skipBlockComment = function () { - var startLoc = this.options.onComment && this.curPosition(); - var start = this.pos, - end = this.input.indexOf("*/", this.pos += 2); - if (end === -1) this.raise(this.pos - 2, "Unterminated comment"); - this.pos = end + 2; - if (this.options.locations) { - _whitespace.lineBreakG.lastIndex = start; - var match = undefined; - while ((match = _whitespace.lineBreakG.exec(this.input)) && match.index < this.pos) { - ++this.curLine; - this.lineStart = match.index + match[0].length; - } - } - if (this.options.onComment) this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, startLoc, this.curPosition()); -}; - -pp.skipLineComment = function (startSkip) { - var start = this.pos; - var startLoc = this.options.onComment && this.curPosition(); - var ch = this.input.charCodeAt(this.pos += startSkip); - while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) { - ++this.pos; - ch = this.input.charCodeAt(this.pos); - } - if (this.options.onComment) this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, startLoc, this.curPosition()); -}; - -// Called at the start of the parse and after every token. Skips -// whitespace and comments, and. - -pp.skipSpace = function () { - loop: while (this.pos < this.input.length) { - var ch = this.input.charCodeAt(this.pos); - switch (ch) { - case 32:case 160: - // ' ' - ++this.pos; - break; - case 13: - if (this.input.charCodeAt(this.pos + 1) === 10) { - ++this.pos; - } - case 10:case 8232:case 8233: - ++this.pos; - if (this.options.locations) { - ++this.curLine; - this.lineStart = this.pos; - } - break; - case 47: - // '/' - switch (this.input.charCodeAt(this.pos + 1)) { - case 42: - // '*' - this.skipBlockComment(); - break; - case 47: - this.skipLineComment(2); - break; - default: - break loop; - } - break; - default: - if (ch > 8 && ch < 14 || ch >= 5760 && _whitespace.nonASCIIwhitespace.test(String.fromCharCode(ch))) { - ++this.pos; - } else { - break loop; - } + pp$7.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1) + var size = 1 + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2 + if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(tt.assign, size + 1) + return this.finishOp(tt.bitShift, size) + } + if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && + this.input.charCodeAt(this.pos + 3) == 45) { + if (this.inModule) this.unexpected() + // `` line comment - this.skipLineComment(3); - this.skipSpace(); - return this.nextToken(); - } - return this.finishOp(_tokentype.types.incDec, 2); - } - if (next === 61) return this.finishOp(_tokentype.types.assign, 2); - return this.finishOp(_tokentype.types.plusMin, 1); -}; - -pp.readToken_lt_gt = function (code) { - // '<>' - var next = this.input.charCodeAt(this.pos + 1); - var size = 1; - if (next === code) { - size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; - if (this.input.charCodeAt(this.pos + size) === 61) return this.finishOp(_tokentype.types.assign, size + 1); - return this.finishOp(_tokentype.types.bitShift, size); - } - if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && this.input.charCodeAt(this.pos + 3) == 45) { - if (this.inModule) this.unexpected(); - // ` + +When set to `1`, writes to `stdout` and `stderr` will be non-blocking and +asynchronous when outputting to a TTY on platforms which support async stdio. +Setting this will void any guarantee that stdio will not be interleaved or +dropped at program exit. **Use of this mode is not recommended.** + + [Buffer]: buffer.html#buffer_buffer [debugger]: debugger.html [REPL]: repl.html diff --git a/doc/api/process.md b/doc/api/process.md index b58a2f37e19cfe..df8dc095ea8ec6 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -880,10 +880,9 @@ if (someConditionNotMet()) { ``` The reason this is problematic is because writes to `process.stdout` in Node.js -are usually *non-blocking* and may occur over multiple ticks of the Node.js -event loop. -Calling `process.exit()`, however, forces the process to exit *before* those -additional writes to `stdout` can be performed. +are sometimes *non-blocking* and may occur over multiple ticks of the Node.js +event loop. Calling `process.exit()`, however, forces the process to exit +*before* those additional writes to `stdout` can be performed. Rather than calling `process.exit()` directly, the code *should* set the `process.exitCode` and allow the process to exit naturally by avoiding @@ -1451,15 +1450,20 @@ Android) The `process.stderr` property returns a [Writable][] stream equivalent to or associated with `stderr` (fd `2`). -`process.stderr` and `process.stdout` are unlike other streams in Node.js in -that they cannot be closed (calling [`end()`][] will throw an Error), they never -emit the [`'finish'`][] event, and writes can block when output is redirected to -a file (although disks are fast and operating systems normally employ write-back -caching so it should be a very rare occurrence indeed.) +Note: `process.stderr` and `process.stdout` differ from other Node.js streams +in several ways: +1. They cannot be closed ([`end()`][] will throw). +2. They never emit the [`'finish'`][] event. +3. Writes _can_ block when output is redirected to a file. + - Note that disks are fast and operating systems normally employ write-back + caching so this is very uncommon. +4. Writes on UNIX __will__ block by default if output is going to a TTY + (a terminal). +5. Windows functionality differs. Writes block except when output is going to a + TTY. -Additionally, `process.stderr` and `process.stdout` are blocking when outputting -to TTYs (terminals) on OS X as a workaround for the OS's very small, 1kb -buffer size. This is to prevent interleaving between `stdout` and `stderr`. +To check if Node.js is being run in a TTY context, read the `isTTY` property +on `process.stderr`, `process.stdout`, or `process.stdin`: ## process.stdin @@ -1504,11 +1508,17 @@ console.log = (msg) => { }; ``` -`process.stderr` and `process.stdout` are unlike other streams in Node.js in -that they cannot be closed (calling [`end()`][] will throw an Error), they never -emit the [`'finish'`][] event and that writes can block when output is -redirected to a file (although disks are fast and operating systems normally -employ write-back caching so it should be a very rare occurrence indeed.) +Note: `process.stderr` and `process.stdout` differ from other Node.js streams +in several ways: +1. They cannot be closed ([`end()`][] will throw). +2. They never emit the [`'finish'`][] event. +3. Writes _can_ block when output is redirected to a file. + - Note that disks are fast and operating systems normally employ write-back + caching so this is very uncommon. +4. Writes on UNIX __will__ block by default if output is going to a TTY + (a terminal). +5. Windows functionality differs. Writes block except when output is going to a + TTY. To check if Node.js is being run in a TTY context, read the `isTTY` property on `process.stderr`, `process.stdout`, or `process.stdin`: diff --git a/doc/node.1 b/doc/node.1 index bdc2c8ad008ae8..1ec0d0ea486b9a 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -194,6 +194,13 @@ Path to the file used to store the persistent REPL history. The default path is ~/.node_repl_history, which is overridden by this variable. Setting the value to an empty string ("" or " ") disables persistent REPL history. +.TP +.BR NODE_TTY_UNSAFE_ASYNC=1 +When set to 1, writes to stdout and stderr will be non-blocking and asynchronous +when outputting to a TTY on platforms which support async stdio. +Setting this will void any guarantee that stdio will not be interleaved or +dropped at program exit. \fBAvoid use.\fR + .SH RESOURCES AND DOCUMENTATION diff --git a/lib/tty.js b/lib/tty.js index fe0cc2e5219966..576144e4013064 100644 --- a/lib/tty.js +++ b/lib/tty.js @@ -48,12 +48,12 @@ function WriteStream(fd) { writable: true }); - // Prevents interleaved stdout/stderr output in OS X terminals. + // Prevents interleaved or dropped stdout/stderr output for terminals. // As noted in the following reference, local TTYs tend to be quite fast and // this behaviour has become expected due historical functionality on OS X, // even though it was originally intended to change in v1.0.2 (Libuv 1.2.1). // Ref: https://github.com/nodejs/node/pull/1771#issuecomment-119351671 - if (process.platform === 'darwin') this._handle.setBlocking(true); + this._handle.setBlocking(process.env.NODE_TTY_UNSAFE_ASYNC !== '1'); var winSize = []; var err = this._handle.getWindowSize(winSize); From 14b762f81f3e4969be91f653de3a51870b9581d6 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Wed, 10 Aug 2016 17:08:59 -0700 Subject: [PATCH 123/144] doc: move orangemocha to collaborators list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/8062 Reviewed-By: James M Snell Reviewed-By: Johan Bergström Reviewed-By: Anna Henningsen --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dc8363b492cc58..daf5da14dcf71d 100644 --- a/README.md +++ b/README.md @@ -179,8 +179,6 @@ more information about the governance of the Node.js project, see **Brian White** <mscdex@mscdex.net> * [ofrobots](https://github.com/ofrobots) - **Ali Ijaz Sheikh** <ofrobots@google.com> -* [orangemocha](https://github.com/orangemocha) - -**Alexis Campailla** <orangemocha@nodejs.org> * [rvagg](https://github.com/rvagg) - **Rod Vagg** <rod@vagg.org> * [shigeki](https://github.com/shigeki) - @@ -256,6 +254,8 @@ more information about the governance of the Node.js project, see **Christopher Monsanto** <chris@monsan.to> * [Olegas](https://github.com/Olegas) - **Oleg Elifantiev** <oleg@elifantiev.ru> +* [orangemocha](https://github.com/orangemocha) - +**Alexis Campailla** <orangemocha@nodejs.org> * [othiym23](https://github.com/othiym23) - **Forrest L Norvell** <ogd@aoaioxxysz.net> * [petkaantonov](https://github.com/petkaantonov) - From fb8840cac25ec4ddd42f1538acc5ee6d710c749f Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 1 Aug 2016 12:51:01 +0200 Subject: [PATCH 124/144] src: use RAII for mutexes in node_watchdog.cc PR-URL: https://github.com/nodejs/node/pull/7933 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- src/node_watchdog.cc | 62 ++++++++++++++++++-------------------------- src/node_watchdog.h | 5 ++-- 2 files changed, 28 insertions(+), 39 deletions(-) diff --git a/src/node_watchdog.cc b/src/node_watchdog.cc index 9c776973a2d630..af781392e8915e 100644 --- a/src/node_watchdog.cc +++ b/src/node_watchdog.cc @@ -160,7 +160,7 @@ BOOL WINAPI SigintWatchdogHelper::WinCtrlCHandlerRoutine(DWORD dwCtrlType) { bool SigintWatchdogHelper::InformWatchdogsAboutSignal() { - uv_mutex_lock(&instance.list_mutex_); + Mutex::ScopedLock list_lock(instance.list_mutex_); bool is_stopping = false; #ifdef __POSIX__ @@ -176,17 +176,15 @@ bool SigintWatchdogHelper::InformWatchdogsAboutSignal() { for (auto it : instance.watchdogs_) it->HandleSigint(); - uv_mutex_unlock(&instance.list_mutex_); return is_stopping; } int SigintWatchdogHelper::Start() { - int ret = 0; - uv_mutex_lock(&mutex_); + Mutex::ScopedLock lock(mutex_); if (start_stop_count_++ > 0) { - goto dont_start; + return 0; } #ifdef __POSIX__ @@ -197,10 +195,10 @@ int SigintWatchdogHelper::Start() { sigset_t sigmask; sigfillset(&sigmask); CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, &sigmask)); - ret = pthread_create(&thread_, nullptr, RunSigintWatchdog, nullptr); + int ret = pthread_create(&thread_, nullptr, RunSigintWatchdog, nullptr); CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, nullptr)); if (ret != 0) { - goto dont_start; + return ret; } has_running_thread_ = true; @@ -209,34 +207,36 @@ int SigintWatchdogHelper::Start() { SetConsoleCtrlHandler(WinCtrlCHandlerRoutine, TRUE); #endif - dont_start: - uv_mutex_unlock(&mutex_); - return ret; + return 0; } bool SigintWatchdogHelper::Stop() { - uv_mutex_lock(&mutex_); - uv_mutex_lock(&list_mutex_); + bool had_pending_signal; + Mutex::ScopedLock lock(mutex_); - bool had_pending_signal = has_pending_signal_; + { + Mutex::ScopedLock list_lock(list_mutex_); - if (--start_stop_count_ > 0) { - uv_mutex_unlock(&list_mutex_); - goto dont_stop; - } + had_pending_signal = has_pending_signal_; + + if (--start_stop_count_ > 0) { + has_pending_signal_ = false; + return had_pending_signal; + } #ifdef __POSIX__ - // Set stopping now because it's only protected by list_mutex_. - stopping_ = true; + // Set stopping now because it's only protected by list_mutex_. + stopping_ = true; #endif - watchdogs_.clear(); - uv_mutex_unlock(&list_mutex_); + watchdogs_.clear(); + } #ifdef __POSIX__ if (!has_running_thread_) { - goto dont_stop; + has_pending_signal_ = false; + return had_pending_signal; } // Wake up the helper thread. @@ -252,32 +252,26 @@ bool SigintWatchdogHelper::Stop() { #endif had_pending_signal = has_pending_signal_; - dont_stop: - uv_mutex_unlock(&mutex_); - has_pending_signal_ = false; + return had_pending_signal; } void SigintWatchdogHelper::Register(SigintWatchdog* wd) { - uv_mutex_lock(&list_mutex_); + Mutex::ScopedLock lock(list_mutex_); watchdogs_.push_back(wd); - - uv_mutex_unlock(&list_mutex_); } void SigintWatchdogHelper::Unregister(SigintWatchdog* wd) { - uv_mutex_lock(&list_mutex_); + Mutex::ScopedLock lock(list_mutex_); auto it = std::find(watchdogs_.begin(), watchdogs_.end(), wd); CHECK_NE(it, watchdogs_.end()); watchdogs_.erase(it); - - uv_mutex_unlock(&list_mutex_); } @@ -289,9 +283,6 @@ SigintWatchdogHelper::SigintWatchdogHelper() stopping_ = false; CHECK_EQ(0, uv_sem_init(&sem_, 0)); #endif - - CHECK_EQ(0, uv_mutex_init(&mutex_)); - CHECK_EQ(0, uv_mutex_init(&list_mutex_)); } @@ -303,9 +294,6 @@ SigintWatchdogHelper::~SigintWatchdogHelper() { CHECK_EQ(has_running_thread_, false); uv_sem_destroy(&sem_); #endif - - uv_mutex_destroy(&mutex_); - uv_mutex_destroy(&list_mutex_); } SigintWatchdogHelper SigintWatchdogHelper::instance; diff --git a/src/node_watchdog.h b/src/node_watchdog.h index d56b7624de9c12..43842147f9f480 100644 --- a/src/node_watchdog.h +++ b/src/node_watchdog.h @@ -5,6 +5,7 @@ #include "v8.h" #include "uv.h" +#include "node_mutex.h" #include #ifdef __POSIX__ @@ -75,8 +76,8 @@ class SigintWatchdogHelper { int start_stop_count_; - uv_mutex_t mutex_; - uv_mutex_t list_mutex_; + Mutex mutex_; + Mutex list_mutex_; std::vector watchdogs_; bool has_pending_signal_; From 4416ffab8a48a5b5433ff669b0739c3e15b7e2cc Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Mon, 1 Aug 2016 12:58:24 +0200 Subject: [PATCH 125/144] test,util: fix flaky test-util-sigint-watchdog Fix parallel/test-util-sigint-watchdog by polling until the signal has definitely been received instead of just using a timeout. Fixes: https://github.com/nodejs/node/issues/7919 PR-URL: https://github.com/nodejs/node/pull/7933 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- src/node_util.cc | 8 ++++++++ src/node_watchdog.cc | 7 +++++++ src/node_watchdog.h | 1 + test/parallel/test-util-sigint-watchdog.js | 19 +++++++++++++------ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/node_util.cc b/src/node_util.cc index 18e89b72642b5a..ee8584b94549a6 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -103,6 +103,13 @@ void StopSigintWatchdog(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(had_pending_signals); } + +void WatchdogHasPendingSigint(const FunctionCallbackInfo& args) { + bool ret = SigintWatchdogHelper::GetInstance()->HasPendingSignal(); + args.GetReturnValue().Set(ret); +} + + void Initialize(Local target, Local unused, Local context) { @@ -118,6 +125,7 @@ void Initialize(Local target, env->SetMethod(target, "startSigintWatchdog", StartSigintWatchdog); env->SetMethod(target, "stopSigintWatchdog", StopSigintWatchdog); + env->SetMethod(target, "watchdogHasPendingSigint", WatchdogHasPendingSigint); } } // namespace util diff --git a/src/node_watchdog.cc b/src/node_watchdog.cc index af781392e8915e..756ba64696a913 100644 --- a/src/node_watchdog.cc +++ b/src/node_watchdog.cc @@ -258,6 +258,13 @@ bool SigintWatchdogHelper::Stop() { } +bool SigintWatchdogHelper::HasPendingSignal() { + Mutex::ScopedLock lock(list_mutex_); + + return has_pending_signal_; +} + + void SigintWatchdogHelper::Register(SigintWatchdog* wd) { Mutex::ScopedLock lock(list_mutex_); diff --git a/src/node_watchdog.h b/src/node_watchdog.h index 43842147f9f480..dd97e4e735ccdf 100644 --- a/src/node_watchdog.h +++ b/src/node_watchdog.h @@ -63,6 +63,7 @@ class SigintWatchdogHelper { static SigintWatchdogHelper* GetInstance() { return &instance; } void Register(SigintWatchdog* watchdog); void Unregister(SigintWatchdog* watchdog); + bool HasPendingSignal(); int Start(); bool Stop(); diff --git a/test/parallel/test-util-sigint-watchdog.js b/test/parallel/test-util-sigint-watchdog.js index f9bb3ecd93d39b..42e4048bd74a36 100644 --- a/test/parallel/test-util-sigint-watchdog.js +++ b/test/parallel/test-util-sigint-watchdog.js @@ -20,24 +20,24 @@ if (common.isWindows) { // Test with one call to the watchdog, one signal. binding.startSigintWatchdog(); process.kill(process.pid, 'SIGINT'); - setTimeout(common.mustCall(() => { + waitForPendingSignal(common.mustCall(() => { const hadPendingSignals = binding.stopSigintWatchdog(); assert.strictEqual(hadPendingSignals, true); next(); - }), common.platformTimeout(100)); + })); }, (next) => { // Nested calls are okay. binding.startSigintWatchdog(); binding.startSigintWatchdog(); process.kill(process.pid, 'SIGINT'); - setTimeout(common.mustCall(() => { + waitForPendingSignal(common.mustCall(() => { const hadPendingSignals1 = binding.stopSigintWatchdog(); const hadPendingSignals2 = binding.stopSigintWatchdog(); assert.strictEqual(hadPendingSignals1, true); assert.strictEqual(hadPendingSignals2, false); next(); - }), common.platformTimeout(100)); + })); }, () => { // Signal comes in after first call to stop. @@ -45,9 +45,16 @@ if (common.isWindows) { binding.startSigintWatchdog(); const hadPendingSignals1 = binding.stopSigintWatchdog(); process.kill(process.pid, 'SIGINT'); - setTimeout(common.mustCall(() => { + waitForPendingSignal(common.mustCall(() => { const hadPendingSignals2 = binding.stopSigintWatchdog(); assert.strictEqual(hadPendingSignals1, false); assert.strictEqual(hadPendingSignals2, true); - }), common.platformTimeout(100)); + })); }].reduceRight((a, b) => common.mustCall(b).bind(null, a))(); + +function waitForPendingSignal(cb) { + if (binding.watchdogHasPendingSigint()) + cb(); + else + setTimeout(waitForPendingSignal, 10, cb); +} From 507c65d94a28f88242739d69f95a29db0f5ef782 Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Tue, 19 Jul 2016 12:23:57 -0700 Subject: [PATCH 126/144] deps: update v8_inspector To add a LICENSE file along with the v8_inspector code, we need to pick up v8_inspector from an intermediate repository: https://github.com/pavelfeldman/v8_inspector. This repo still tracks upstream code in Blink. This roll also picks up the latest v8_inspector from upstream fixing a few issues. * Pickup commit id bc60957 from pavelfeldman/v8_inspector * Update node.gyp to adapt to the new file paths * Update the DevTools hash for the devtools frontend. Fixes: https://github.com/nodejs/node/issues/7123 Fixes: https://github.com/nodejs/node/issues/7736 Fixes: https://github.com/nodejs/node/issues/7734 PR-URL: https://github.com/nodejs/node/pull/7796 Reviewed-By: bnoordhuis - Ben Noordhuis Reviewed-By: jasnell - James M Snell --- deps/v8_inspector/.gitignore | 1 - deps/v8_inspector/.gitmodules | 0 deps/v8_inspector/README.md | 12 +- .../platform/inspector_protocol/Collections.h | 23 - .../inspector_protocol/CollectionsSTL.h | 244 -------- .../inspector_protocol/CollectionsWTF.h | 193 ------- .../v8_inspector/V8DebuggerScript.cpp | 104 ---- .../v8_inspector/public/ConsoleAPITypes.h | 47 -- .../v8_inspector/public/ConsoleTypes.h | 55 -- .../v8_inspector/public/V8ToProtocolValue.h | 17 - .../{deps => third_party}/jinja2/.gitignore | 0 .../{deps => third_party}/jinja2/.travis.yml | 0 .../{deps => third_party}/jinja2/AUTHORS | 0 .../{deps => third_party}/jinja2/CHANGES | 0 .../{deps => third_party}/jinja2/LICENSE | 62 +- .../{deps => third_party}/jinja2/MANIFEST.in | 0 .../{deps => third_party}/jinja2/Makefile | 0 .../{deps => third_party}/jinja2/README.rst | 0 .../jinja2/artwork/jinjalogo.svg | 0 .../jinja2/docs/Makefile | 0 .../jinja2/docs/_static/.ignore | 0 .../jinja2/docs/_static/jinja-small.png | Bin .../jinja2/docs/_templates/sidebarintro.html | 0 .../jinja2/docs/_templates/sidebarlogo.html | 0 .../jinja2/docs/_themes/LICENSE | 0 .../jinja2/docs/_themes/README | 0 .../jinja2/docs/_themes/jinja/layout.html | 0 .../jinja2/docs/_themes/jinja/relations.html | 0 .../docs/_themes/jinja/static/jinja.css_t | 50 +- .../jinja2/docs/_themes/jinja/theme.conf | 0 .../{deps => third_party}/jinja2/docs/api.rst | 4 +- .../jinja2/docs/cache_extension.py | 0 .../jinja2/docs/changelog.rst | 0 .../{deps => third_party}/jinja2/docs/conf.py | 0 .../jinja2/docs/contents.rst.inc | 0 .../jinja2/docs/extensions.rst | 4 +- .../{deps => third_party}/jinja2/docs/faq.rst | 0 .../jinja2/docs/index.rst | 0 .../jinja2/docs/integration.rst | 0 .../jinja2/docs/intro.rst | 2 +- .../jinja2/docs/jinjaext.py | 0 .../jinja2/docs/jinjastyle.sty | 2 +- .../jinja2/docs/latexindex.rst | 0 .../jinja2/docs/logo.pdf | Bin .../jinja2/docs/sandbox.rst | 0 .../jinja2/docs/switching.rst | 0 .../jinja2/docs/templates.rst | 10 +- .../jinja2/docs/tricks.rst | 0 .../jinja2/examples/basic/cycle.py | 0 .../jinja2/examples/basic/debugger.py | 0 .../jinja2/examples/basic/inheritance.py | 0 .../examples/basic/templates/broken.html | 0 .../examples/basic/templates/subbroken.html | 0 .../jinja2/examples/basic/test.py | 0 .../basic/test_filter_and_linestatements.py | 0 .../jinja2/examples/basic/test_loop_filter.py | 0 .../jinja2/examples/basic/translate.py | 0 .../jinja2/examples/bench.py | 0 .../jinja2/examples/profile.py | 0 .../jinja2/examples/rwbench/django/_form.html | 0 .../examples/rwbench/django/_input_field.html | 0 .../examples/rwbench/django/_textarea.html | 0 .../jinja2/examples/rwbench/django/index.html | 0 .../examples/rwbench/django/layout.html | 0 .../jinja2/examples/rwbench/djangoext.py | 0 .../examples/rwbench/genshi/helpers.html | 0 .../jinja2/examples/rwbench/genshi/index.html | 0 .../examples/rwbench/genshi/layout.html | 0 .../examples/rwbench/jinja/helpers.html | 0 .../jinja2/examples/rwbench/jinja/index.html | 0 .../jinja2/examples/rwbench/jinja/layout.html | 0 .../jinja2/examples/rwbench/mako/helpers.html | 0 .../jinja2/examples/rwbench/mako/index.html | 0 .../jinja2/examples/rwbench/mako/layout.html | 0 .../jinja2/examples/rwbench/rwbench.py | 0 .../jinja2/ext/Vim/jinja.vim | 0 .../jinja2/ext/django2jinja/django2jinja.py | 28 +- .../jinja2/ext/django2jinja/example.py | 0 .../ext/django2jinja/templates/index.html | 0 .../ext/django2jinja/templates/layout.html | 0 .../django2jinja/templates/subtemplate.html | 0 .../jinja2/ext/djangojinja2.py | 0 .../jinja2/ext/inlinegettext.py | 0 .../{deps => third_party}/jinja2/ext/jinja.el | 0 .../jinja2/jinja2/__init__.py | 0 .../jinja2/jinja2/_compat.py | 0 .../jinja2/jinja2/_stringdefs.py | 0 .../jinja2/jinja2/bccache.py | 0 .../jinja2/jinja2/compiler.py | 0 .../jinja2/jinja2/constants.py | 0 .../jinja2/jinja2/debug.py | 0 .../jinja2/jinja2/defaults.py | 0 .../jinja2/jinja2/environment.py | 0 .../jinja2/jinja2/exceptions.py | 0 .../jinja2/jinja2/ext.py | 0 .../jinja2/jinja2/filters.py | 0 .../jinja2/jinja2/lexer.py | 0 .../jinja2/jinja2/loaders.py | 0 .../jinja2/jinja2/meta.py | 0 .../jinja2/jinja2/nodes.py | 0 .../jinja2/jinja2/optimizer.py | 0 .../jinja2/jinja2/parser.py | 0 .../jinja2/jinja2/runtime.py | 0 .../jinja2/jinja2/sandbox.py | 0 .../jinja2/jinja2/tests.py | 0 .../jinja2/jinja2/utils.py | 0 .../jinja2/jinja2/visitor.py | 0 .../jinja2/scripts/jinja2-debug.py | 0 .../jinja2/scripts/make-release.py | 0 .../jinja2/scripts/pylintrc | 22 +- .../{deps => third_party}/jinja2/setup.cfg | 0 .../{deps => third_party}/jinja2/setup.py | 0 .../jinja2/tests/conftest.py | 0 .../jinja2/tests/res/__init__.py | 0 .../jinja2/tests/res/templates/broken.html | 0 .../jinja2/tests/res/templates/foo/test.html | 0 .../tests/res/templates/syntaxerror.html | 0 .../jinja2/tests/res/templates/test.html | 0 .../jinja2/tests/test_api.py | 0 .../jinja2/tests/test_bytecode_cache.py | 0 .../jinja2/tests/test_core_tags.py | 0 .../jinja2/tests/test_debug.py | 0 .../jinja2/tests/test_ext.py | 0 .../jinja2/tests/test_filters.py | 0 .../jinja2/tests/test_imports.py | 0 .../jinja2/tests/test_inheritance.py | 0 .../jinja2/tests/test_lexnparse.py | 0 .../jinja2/tests/test_loader.py | 0 .../jinja2/tests/test_regression.py | 0 .../jinja2/tests/test_security.py | 0 .../jinja2/tests/test_tests.py | 0 .../jinja2/tests/test_utils.py | 0 .../{deps => third_party}/jinja2/tox.ini | 0 .../markupsafe/.gitignore | 0 .../markupsafe/.travis.yml | 0 .../{deps => third_party}/markupsafe/AUTHORS | 0 .../{deps => third_party}/markupsafe/CHANGES | 0 .../{deps => third_party}/markupsafe/LICENSE | 0 .../markupsafe/MANIFEST.in | 0 .../{deps => third_party}/markupsafe/Makefile | 0 .../markupsafe/README.rst | 0 .../markupsafe/bench/bench_basic.py | 0 .../markupsafe/bench/bench_largestring.py | 0 .../bench/bench_long_empty_string.py | 0 .../markupsafe/bench/bench_long_suffix.py | 0 .../bench/bench_short_empty_string.py | 0 .../markupsafe/bench/runbench.py | 0 .../markupsafe/markupsafe/__init__.py | 0 .../markupsafe/markupsafe/_compat.py | 0 .../markupsafe/markupsafe/_constants.py | 0 .../markupsafe/markupsafe/_native.py | 0 .../markupsafe/markupsafe/_speedups.c | 0 .../markupsafe/markupsafe/tests.py | 0 .../{deps => third_party}/markupsafe/setup.py | 0 .../{deps => third_party}/markupsafe/tox.ini | 0 .../third_party/v8_inspector/LICENSE | 27 + .../platform/inspector_protocol/Allocator.h | 0 .../platform/inspector_protocol/Array.h | 21 +- .../inspector_protocol/BackendCallback.h | 0 .../inspector_protocol/CodeGenerator.py | 10 +- .../platform/inspector_protocol/Collections.h | 46 ++ .../inspector_protocol/DispatcherBase.cpp | 16 +- .../inspector_protocol/DispatcherBase.h | 0 .../inspector_protocol/ErrorSupport.cpp | 8 +- .../inspector_protocol/ErrorSupport.h | 7 +- .../inspector_protocol/FrontendChannel.h | 0 .../platform/inspector_protocol/Maybe.h | 2 +- .../platform/inspector_protocol/OWNERS | 0 .../platform/inspector_protocol/Object.cpp | 0 .../platform/inspector_protocol/Object.h | 0 .../platform/inspector_protocol/Parser.cpp | 6 +- .../platform/inspector_protocol/Parser.h | 0 .../inspector_protocol/ParserTest.cpp | 74 +-- .../platform/inspector_protocol/Platform.h | 0 .../platform/inspector_protocol/PlatformSTL.h | 43 +- .../platform/inspector_protocol/PlatformWTF.h | 0 .../platform/inspector_protocol/String16.h | 0 .../inspector_protocol/String16STL.cpp | 10 +- .../platform/inspector_protocol/String16STL.h | 25 +- .../inspector_protocol/String16WTF.cpp | 0 .../platform/inspector_protocol/String16WTF.h | 17 +- .../TypeBuilder_cpp.template | 4 +- .../inspector_protocol/TypeBuilder_h.template | 0 .../inspector_protocol/ValueConversions.cpp | 0 .../inspector_protocol/ValueConversions.h | 8 +- .../platform/inspector_protocol/Values.cpp | 125 ++-- .../platform/inspector_protocol/Values.h | 46 +- .../generate-inspector-protocol-version | 10 +- .../platform/v8_inspector/Atomics.h | 0 .../platform/v8_inspector/DebuggerScript.js | 21 +- .../platform/v8_inspector/InjectedScript.cpp | 40 +- .../platform/v8_inspector/InjectedScript.h | 1 - .../v8_inspector/InjectedScriptNative.cpp | 26 +- .../v8_inspector/InjectedScriptNative.h | 4 +- .../v8_inspector/InjectedScriptSource.js | 114 ++-- .../v8_inspector/InspectedContext.cpp | 0 .../platform/v8_inspector/InspectedContext.h | 2 +- .../v8_inspector/JavaScriptCallFrame.cpp | 8 +- .../v8_inspector/JavaScriptCallFrame.h | 4 +- .../platform/v8_inspector/OWNERS | 0 .../platform/v8_inspector/RemoteObjectId.cpp | 8 +- .../platform/v8_inspector/RemoteObjectId.h | 0 .../platform/v8_inspector/ScriptBreakpoint.h | 0 .../platform/v8_inspector/V8Compat.h | 2 +- .../platform/v8_inspector/V8Console.cpp | 102 ++-- .../platform/v8_inspector/V8Console.h | 0 .../v8_inspector/V8ConsoleAgentImpl.cpp | 88 +++ .../v8_inspector/V8ConsoleAgentImpl.h | 45 ++ .../v8_inspector/V8ConsoleMessage.cpp | 440 ++++++++++++++ .../platform/v8_inspector/V8ConsoleMessage.h | 110 ++++ .../v8_inspector/V8DebuggerAgentImpl.cpp | 541 +++++------------- .../v8_inspector/V8DebuggerAgentImpl.h | 40 +- .../platform/v8_inspector/V8DebuggerImpl.cpp | 494 ++++++++++++---- .../platform/v8_inspector/V8DebuggerImpl.h | 60 +- .../v8_inspector/V8DebuggerScript.cpp | 121 ++++ .../platform/v8_inspector/V8DebuggerScript.h | 33 +- .../platform/v8_inspector/V8FunctionCall.cpp | 10 +- .../platform/v8_inspector/V8FunctionCall.h | 3 +- .../v8_inspector/V8HeapProfilerAgentImpl.cpp | 29 +- .../v8_inspector/V8HeapProfilerAgentImpl.h | 0 .../v8_inspector/V8InjectedScriptHost.cpp | 35 +- .../v8_inspector/V8InjectedScriptHost.h | 2 - .../v8_inspector/V8InspectorSessionImpl.cpp | 98 ++-- .../v8_inspector/V8InspectorSessionImpl.h | 20 +- .../v8_inspector/V8InternalValueType.cpp | 72 +++ .../v8_inspector/V8InternalValueType.h | 21 + .../v8_inspector/V8ProfilerAgentImpl.cpp | 39 +- .../v8_inspector/V8ProfilerAgentImpl.h | 4 +- .../platform/v8_inspector/V8Regex.cpp | 0 .../platform/v8_inspector/V8Regex.h | 0 .../v8_inspector/V8RuntimeAgentImpl.cpp | 47 +- .../v8_inspector/V8RuntimeAgentImpl.h | 6 + .../v8_inspector/V8StackTraceImpl.cpp | 68 ++- .../platform/v8_inspector/V8StackTraceImpl.h | 19 +- .../platform/v8_inspector/V8StringUtil.cpp | 28 +- .../platform/v8_inspector/V8StringUtil.h | 3 + .../platform/v8_inspector/build/rjsmin.py | 0 .../platform/v8_inspector/build/xxd.py | 0 .../v8_inspector/debugger_script_externs.js | 8 - .../v8_inspector/injected_script_externs.js | 6 - .../v8_inspector/js_protocol-1.1.json | 0 .../platform/v8_inspector/js_protocol.json | 222 +++---- .../v8_inspector/public/V8ConsoleTypes.h | 20 + .../v8_inspector/public/V8ContentSearchUtil.h | 1 + .../v8_inspector/public/V8ContextInfo.h | 2 +- .../platform/v8_inspector/public/V8Debugger.h | 30 +- .../v8_inspector/public/V8DebuggerClient.h | 17 +- .../v8_inspector/public/V8Inspector.cpp | 15 +- .../v8_inspector/public/V8Inspector.h | 30 +- .../v8_inspector/public/V8InspectorSession.h | 31 +- .../public/V8InspectorSessionClient.h | 10 +- .../v8_inspector/public/V8StackTrace.h | 12 +- .../platform/v8_inspector/v8_inspector.gyp | 24 +- node.gyp | 7 +- src/inspector_agent.cc | 2 +- 255 files changed, 2581 insertions(+), 2049 deletions(-) delete mode 100644 deps/v8_inspector/.gitignore delete mode 100644 deps/v8_inspector/.gitmodules delete mode 100644 deps/v8_inspector/platform/inspector_protocol/Collections.h delete mode 100644 deps/v8_inspector/platform/inspector_protocol/CollectionsSTL.h delete mode 100644 deps/v8_inspector/platform/inspector_protocol/CollectionsWTF.h delete mode 100644 deps/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp delete mode 100644 deps/v8_inspector/platform/v8_inspector/public/ConsoleAPITypes.h delete mode 100644 deps/v8_inspector/platform/v8_inspector/public/ConsoleTypes.h delete mode 100644 deps/v8_inspector/platform/v8_inspector/public/V8ToProtocolValue.h rename deps/v8_inspector/{deps => third_party}/jinja2/.gitignore (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/.travis.yml (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/AUTHORS (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/CHANGES (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/LICENSE (98%) rename deps/v8_inspector/{deps => third_party}/jinja2/MANIFEST.in (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/Makefile (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/README.rst (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/artwork/jinjalogo.svg (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/Makefile (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_static/.ignore (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_static/jinja-small.png (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_templates/sidebarintro.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_templates/sidebarlogo.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_themes/LICENSE (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_themes/README (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_themes/jinja/layout.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_themes/jinja/relations.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_themes/jinja/static/jinja.css_t (99%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/_themes/jinja/theme.conf (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/api.rst (99%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/cache_extension.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/changelog.rst (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/conf.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/contents.rst.inc (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/extensions.rst (99%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/faq.rst (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/index.rst (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/integration.rst (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/intro.rst (98%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/jinjaext.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/jinjastyle.sty (98%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/latexindex.rst (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/logo.pdf (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/sandbox.rst (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/switching.rst (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/templates.rst (99%) rename deps/v8_inspector/{deps => third_party}/jinja2/docs/tricks.rst (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/basic/cycle.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/basic/debugger.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/basic/inheritance.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/basic/templates/broken.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/basic/templates/subbroken.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/basic/test.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/basic/test_filter_and_linestatements.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/basic/test_loop_filter.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/basic/translate.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/bench.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/profile.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/django/_form.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/django/_input_field.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/django/_textarea.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/django/index.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/django/layout.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/djangoext.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/genshi/helpers.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/genshi/index.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/genshi/layout.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/jinja/helpers.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/jinja/index.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/jinja/layout.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/mako/helpers.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/mako/index.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/mako/layout.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/examples/rwbench/rwbench.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/ext/Vim/jinja.vim (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/ext/django2jinja/django2jinja.py (99%) rename deps/v8_inspector/{deps => third_party}/jinja2/ext/django2jinja/example.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/ext/django2jinja/templates/index.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/ext/django2jinja/templates/layout.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/ext/django2jinja/templates/subtemplate.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/ext/djangojinja2.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/ext/inlinegettext.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/ext/jinja.el (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/__init__.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/_compat.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/_stringdefs.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/bccache.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/compiler.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/constants.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/debug.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/defaults.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/environment.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/exceptions.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/ext.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/filters.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/lexer.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/loaders.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/meta.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/nodes.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/optimizer.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/parser.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/runtime.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/sandbox.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/tests.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/utils.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/jinja2/visitor.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/scripts/jinja2-debug.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/scripts/make-release.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/scripts/pylintrc (99%) rename deps/v8_inspector/{deps => third_party}/jinja2/setup.cfg (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/setup.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/conftest.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/res/__init__.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/res/templates/broken.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/res/templates/foo/test.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/res/templates/syntaxerror.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/res/templates/test.html (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_api.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_bytecode_cache.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_core_tags.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_debug.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_ext.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_filters.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_imports.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_inheritance.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_lexnparse.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_loader.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_regression.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_security.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_tests.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tests/test_utils.py (100%) rename deps/v8_inspector/{deps => third_party}/jinja2/tox.ini (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/.gitignore (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/.travis.yml (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/AUTHORS (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/CHANGES (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/LICENSE (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/MANIFEST.in (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/Makefile (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/README.rst (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/bench/bench_basic.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/bench/bench_largestring.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/bench/bench_long_empty_string.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/bench/bench_long_suffix.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/bench/bench_short_empty_string.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/bench/runbench.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/markupsafe/__init__.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/markupsafe/_compat.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/markupsafe/_constants.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/markupsafe/_native.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/markupsafe/_speedups.c (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/markupsafe/tests.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/setup.py (100%) rename deps/v8_inspector/{deps => third_party}/markupsafe/tox.ini (100%) create mode 100644 deps/v8_inspector/third_party/v8_inspector/LICENSE rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Allocator.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Array.h (87%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/BackendCallback.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/CodeGenerator.py (98%) create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Collections.h rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/DispatcherBase.cpp (94%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/DispatcherBase.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/ErrorSupport.cpp (91%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/ErrorSupport.h (86%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/FrontendChannel.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Maybe.h (98%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/OWNERS (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Object.cpp (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Object.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Parser.cpp (98%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Parser.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/ParserTest.cpp (88%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Platform.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/PlatformSTL.h (90%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/PlatformWTF.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/String16.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/String16STL.cpp (98%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/String16STL.h (91%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/String16WTF.cpp (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/String16WTF.h (91%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/TypeBuilder_cpp.template (98%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/TypeBuilder_h.template (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/ValueConversions.cpp (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/ValueConversions.h (95%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Values.cpp (72%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/Values.h (82%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/inspector_protocol/generate-inspector-protocol-version (99%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/Atomics.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/DebuggerScript.js (98%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/InjectedScript.cpp (92%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/InjectedScript.h (99%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/InjectedScriptNative.cpp (79%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/InjectedScriptNative.h (93%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/InjectedScriptSource.js (91%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/InspectedContext.cpp (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/InspectedContext.h (97%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/JavaScriptCallFrame.cpp (92%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/JavaScriptCallFrame.h (96%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/OWNERS (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/RemoteObjectId.cpp (85%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/RemoteObjectId.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/ScriptBreakpoint.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8Compat.h (97%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8Console.cpp (87%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8Console.h (100%) create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.cpp create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.h create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.cpp create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.h rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8DebuggerAgentImpl.cpp (66%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8DebuggerAgentImpl.h (82%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8DebuggerImpl.cpp (59%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8DebuggerImpl.h (69%) create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8DebuggerScript.h (77%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8FunctionCall.cpp (92%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8FunctionCall.h (95%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp (95%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8HeapProfilerAgentImpl.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8InjectedScriptHost.cpp (90%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8InjectedScriptHost.h (95%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8InspectorSessionImpl.cpp (81%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8InspectorSessionImpl.h (84%) create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InternalValueType.cpp create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InternalValueType.h rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8ProfilerAgentImpl.cpp (90%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8ProfilerAgentImpl.h (95%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8Regex.cpp (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8Regex.h (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8RuntimeAgentImpl.cpp (89%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8RuntimeAgentImpl.h (95%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8StackTraceImpl.cpp (70%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8StackTraceImpl.h (76%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8StringUtil.cpp (90%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/V8StringUtil.h (76%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/build/rjsmin.py (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/build/xxd.py (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/debugger_script_externs.js (98%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/injected_script_externs.js (92%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/js_protocol-1.1.json (100%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/js_protocol.json (90%) create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ConsoleTypes.h rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/public/V8ContentSearchUtil.h (94%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/public/V8ContextInfo.h (95%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/public/V8Debugger.h (50%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/public/V8DebuggerClient.h (73%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/public/V8Inspector.cpp (89%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/public/V8Inspector.h (73%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/public/V8InspectorSession.h (64%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/public/V8InspectorSessionClient.h (68%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/public/V8StackTrace.h (74%) rename deps/v8_inspector/{ => third_party/v8_inspector}/platform/v8_inspector/v8_inspector.gyp (90%) diff --git a/deps/v8_inspector/.gitignore b/deps/v8_inspector/.gitignore deleted file mode 100644 index 2a6b83e201c455..00000000000000 --- a/deps/v8_inspector/.gitignore +++ /dev/null @@ -1 +0,0 @@ -platform/v8_inspector/build/rjsmin.pyc diff --git a/deps/v8_inspector/.gitmodules b/deps/v8_inspector/.gitmodules deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/deps/v8_inspector/README.md b/deps/v8_inspector/README.md index e3e5e14cab4a7a..d99d25f94ce3aa 100644 --- a/deps/v8_inspector/README.md +++ b/deps/v8_inspector/README.md @@ -1,10 +1,10 @@ V8 Inspector support for Node.js ================================ -This directory is a gathering of dependencies for Node.js support for the -[Chrome Debug Protocol][https://developer.chrome.com/devtools/docs/debugger-protocol]. +This repository is an intermediate repository that gathers the dependencies for +Node.js support for the [Chrome Debug Protocol][https://developer.chrome.com/devtools/docs/debugger-protocol]. -* platform/v8_inspector: vendored from https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/platform/v8_inspector -* platform/inspector_protocol: vendored from https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/platform/inspector_protocol -* deps/jinja2: vendored from https://github.com/mitsuhiko/jinja2 -* deps/markupsafe: vendored from https://github.com/mitsuhiko/markupsafe +* third_party/v8_inspector/platform/v8_inspector: vendored from https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/platform/v8_inspector +* third_party/v8_inspector/platform/inspector_protocol: vendored from https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/platform/inspector_protocol +* third_party/jinja2: vendored from https://github.com/mitsuhiko/jinja2 +* third_party/markupsafe: vendored from https://github.com/mitsuhiko/markupsafe diff --git a/deps/v8_inspector/platform/inspector_protocol/Collections.h b/deps/v8_inspector/platform/inspector_protocol/Collections.h deleted file mode 100644 index 6309284488683e..00000000000000 --- a/deps/v8_inspector/platform/inspector_protocol/Collections.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef Collections_h -#define Collections_h - -#if V8_INSPECTOR_USE_STL -#include "platform/inspector_protocol/CollectionsSTL.h" -#else -#include "platform/inspector_protocol/CollectionsWTF.h" -#endif // V8_INSPECTOR_USE_STL - - -// Macro that returns a compile time constant with the length of an array, but gives an error if passed a non-array. -template char (&ArrayLengthHelperFunction(T (&)[Size]))[Size]; -// GCC needs some help to deduce a 0 length array. -#if defined(__GNUC__) -template char (&ArrayLengthHelperFunction(T (&)[0]))[0]; -#endif -#define PROTOCOL_ARRAY_LENGTH(array) sizeof(::ArrayLengthHelperFunction(array)) - -#endif // !defined(Collections_h) diff --git a/deps/v8_inspector/platform/inspector_protocol/CollectionsSTL.h b/deps/v8_inspector/platform/inspector_protocol/CollectionsSTL.h deleted file mode 100644 index ee99cfd8bd855b..00000000000000 --- a/deps/v8_inspector/platform/inspector_protocol/CollectionsSTL.h +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CollectionsSTL_h -#define CollectionsSTL_h - -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" - -#include -#include -#include - -namespace blink { -namespace protocol { - -template -class Vector { -public: - Vector() { } - Vector(size_t capacity) : m_impl(capacity) { } - typedef typename std::vector::iterator iterator; - typedef typename std::vector::const_iterator const_iterator; - - iterator begin() { return m_impl.begin(); } - iterator end() { return m_impl.end(); } - const_iterator begin() const { return m_impl.begin(); } - const_iterator end() const { return m_impl.end(); } - - void resize(size_t s) { m_impl.resize(s); } - size_t size() const { return m_impl.size(); } - bool isEmpty() const { return !m_impl.size(); } - T& operator[](size_t i) { return at(i); } - const T& operator[](size_t i) const { return at(i); } - T& at(size_t i) { return m_impl[i]; } - const T& at(size_t i) const { return m_impl.at(i); } - T& last() { return m_impl[m_impl.size() - 1]; } - const T& last() const { return m_impl[m_impl.size() - 1]; } - void append(const T& t) { m_impl.push_back(t); } - void prepend(const T& t) { m_impl.insert(m_impl.begin(), t); } - void remove(size_t i) { m_impl.erase(m_impl.begin() + i); } - void clear() { m_impl.clear(); } - void swap(Vector& other) { m_impl.swap(other.m_impl); } - void removeLast() { m_impl.pop_back(); } - -private: - std::vector m_impl; -}; - -template -class Vector> { -public: - Vector() { } - Vector(size_t capacity) : m_impl(capacity) { } - Vector(Vector&& other) { m_impl.swap(other.m_impl); } - ~Vector() { clear(); } - - typedef typename std::vector::iterator iterator; - typedef typename std::vector::const_iterator const_iterator; - - iterator begin() { return m_impl.begin(); } - iterator end() { return m_impl.end(); } - const_iterator begin() const { return m_impl.begin(); } - const_iterator end() const { return m_impl.end(); } - - void resize(size_t s) { m_impl.resize(s); } - size_t size() const { return m_impl.size(); } - bool isEmpty() const { return !m_impl.size(); } - T* operator[](size_t i) { return at(i); } - const T* operator[](size_t i) const { return at(i); } - T* at(size_t i) { return m_impl[i]; } - const T* at(size_t i) const { return m_impl.at(i); } - T* last() { return m_impl[m_impl.size() - 1]; } - const T* last() const { return m_impl[m_impl.size() - 1]; } - void append(std::unique_ptr t) { m_impl.push_back(t.release()); } - void prepend(std::unique_ptr t) { m_impl.insert(m_impl.begin(), t.release()); } - - void remove(size_t i) - { - delete m_impl[i]; - m_impl.erase(m_impl.begin() + i); - } - - void clear() - { - for (auto t : m_impl) - delete t; - m_impl.clear(); - } - - void swap(Vector& other) { m_impl.swap(other.m_impl); } - void swap(Vector&& other) { m_impl.swap(other.m_impl); } - void removeLast() - { - delete last(); - m_impl.pop_back(); - } - -private: - Vector(const Vector&) = delete; - Vector& operator=(const Vector&) = delete; - std::vector m_impl; -}; - -template -class HashMapIterator { -public: - HashMapIterator(const I& impl) : m_impl(impl) { } - std::pair* get() const { m_pair.first = m_impl->first; m_pair.second = &m_impl->second; return &m_pair; } - std::pair& operator*() const { return *get(); } - std::pair* operator->() const { return get(); } - - bool operator==(const HashMapIterator& other) const { return m_impl == other.m_impl; } - bool operator!=(const HashMapIterator& other) const { return m_impl != other.m_impl; } - - HashMapIterator& operator++() { ++m_impl; return *this; } - -private: - mutable std::pair m_pair; - I m_impl; -}; - -template -class HashMapIterator, I> { -public: - HashMapIterator(const I& impl) : m_impl(impl) { } - std::pair* get() const { m_pair.first = m_impl->first; m_pair.second = m_impl->second; return &m_pair; } - std::pair& operator*() const { return *get(); } - std::pair* operator->() const { return get(); } - - bool operator==(const HashMapIterator, I>& other) const { return m_impl == other.m_impl; } - bool operator!=(const HashMapIterator, I>& other) const { return m_impl != other.m_impl; } - - HashMapIterator, I>& operator++() { ++m_impl; return *this; } - -private: - mutable std::pair m_pair; - I m_impl; -}; - -template -class HashMap { -public: - HashMap() { } - ~HashMap() { } - - using iterator = HashMapIterator::iterator>; - using const_iterator = HashMapIterator::const_iterator>; - - iterator begin() { return iterator(m_impl.begin()); } - iterator end() { return iterator(m_impl.end()); } - iterator find(const K& k) { return iterator(m_impl.find(k)); } - const_iterator begin() const { return const_iterator(m_impl.begin()); } - const_iterator end() const { return const_iterator(m_impl.end()); } - const_iterator find(const K& k) const { return const_iterator(m_impl.find(k)); } - - size_t size() const { return m_impl.size(); } - bool isEmpty() const { return !m_impl.size(); } - bool set(const K& k, const V& v) - { - bool isNew = m_impl.find(k) == m_impl.end(); - m_impl[k] = v; - return isNew; - } - bool contains(const K& k) const { return m_impl.find(k) != m_impl.end(); } - V get(const K& k) const { auto it = m_impl.find(k); return it == m_impl.end() ? V() : it->second; } - void remove(const K& k) { m_impl.erase(k); } - void clear() { m_impl.clear(); } - V take(const K& k) - { - V result = m_impl[k]; - m_impl.erase(k); - return result; - } - -private: - std::map m_impl; -}; - -template -class HashMap> { -public: - HashMap() { } - ~HashMap() { clear(); } - - using iterator = HashMapIterator, typename std::map::iterator>; - using const_iterator = HashMapIterator, typename std::map::const_iterator>; - - iterator begin() { return iterator(m_impl.begin()); } - iterator end() { return iterator(m_impl.end()); } - iterator find(const K& k) { return iterator(m_impl.find(k)); } - const_iterator begin() const { return const_iterator(m_impl.begin()); } - const_iterator end() const { return const_iterator(m_impl.end()); } - const_iterator find(const K& k) const { return const_iterator(m_impl.find(k)); } - - size_t size() const { return m_impl.size(); } - bool isEmpty() const { return !m_impl.size(); } - bool set(const K& k, std::unique_ptr v) - { - bool isNew = m_impl.find(k) == m_impl.end(); - if (!isNew) - delete m_impl[k]; - m_impl[k] = v.release(); - return isNew; - } - bool contains(const K& k) const { return m_impl.find(k) != m_impl.end(); } - V* get(const K& k) const { auto it = m_impl.find(k); return it == m_impl.end() ? nullptr : it->second; } - std::unique_ptr take(const K& k) - { - if (!contains(k)) - return nullptr; - std::unique_ptr result(m_impl[k]); - delete m_impl[k]; - m_impl.erase(k); - return result; - } - void remove(const K& k) - { - delete m_impl[k]; - m_impl.erase(k); - } - - void clear() - { - for (auto pair : m_impl) - delete pair.second; - m_impl.clear(); - } - -private: - std::map m_impl; -}; - -template -class HashSet : public protocol::HashMap { -public: - void add(const K& k) { this->set(k, k); } -}; - -} // namespace platform -} // namespace blink - -#endif // !defined(CollectionsSTL_h) diff --git a/deps/v8_inspector/platform/inspector_protocol/CollectionsWTF.h b/deps/v8_inspector/platform/inspector_protocol/CollectionsWTF.h deleted file mode 100644 index 5d8fbf625f51b2..00000000000000 --- a/deps/v8_inspector/platform/inspector_protocol/CollectionsWTF.h +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CollectionsWTF_h -#define CollectionsWTF_h - -#include "wtf/Allocator.h" -#include "wtf/HashMap.h" -#include "wtf/PtrUtil.h" -#include "wtf/Vector.h" -#include "wtf/VectorTraits.h" - -namespace blink { -namespace protocol { - -template -class Vector { -public: - Vector() { } - Vector(size_t capacity) : m_impl(capacity) { } - typedef T* iterator; - typedef const T* const_iterator; - - iterator begin() { return m_impl.begin(); } - iterator end() { return m_impl.end(); } - const_iterator begin() const { return m_impl.begin(); } - const_iterator end() const { return m_impl.end(); } - - void resize(size_t s) { m_impl.resize(s); } - size_t size() const { return m_impl.size(); } - bool isEmpty() const { return m_impl.isEmpty(); } - T& operator[](size_t i) { return at(i); } - const T& operator[](size_t i) const { return at(i); } - T& at(size_t i) { return m_impl.at(i); } - const T& at(size_t i) const { return m_impl.at(i); } - T& last() { return m_impl.last(); } - const T& last() const { return m_impl.last(); } - void append(const T& t) { m_impl.append(t); } - void prepend(const T& t) { m_impl.prepend(t); } - void remove(size_t i) { m_impl.remove(i); } - void clear() { m_impl.clear(); } - void swap(Vector& other) { m_impl.swap(other.m_impl); } - void removeLast() { m_impl.removeLast(); } - -private: - WTF::Vector m_impl; -}; - -template -class Vector> { - WTF_MAKE_NONCOPYABLE(Vector); -public: - Vector() { } - Vector(size_t capacity) : m_impl(capacity) { } - Vector(Vector>&& other) : m_impl(std::move(other.m_impl)) { } - ~Vector() { } - - typedef std::unique_ptr* iterator; - typedef const std::unique_ptr* const_iterator; - - iterator begin() { return m_impl.begin(); } - iterator end() { return m_impl.end(); } - const_iterator begin() const { return m_impl.begin(); } - const_iterator end() const { return m_impl.end(); } - - void resize(size_t s) { m_impl.resize(s); } - size_t size() const { return m_impl.size(); } - bool isEmpty() const { return m_impl.isEmpty(); } - T* operator[](size_t i) { return m_impl.at(i).get(); } - const T* operator[](size_t i) const { return m_impl.at(i).get(); } - T* at(size_t i) { return m_impl.at(i).get(); } - const T* at(size_t i) const { return m_impl.at(i).get(); } - T* last() { return m_impl.last().get(); } - const T* last() const { return m_impl.last(); } - void append(std::unique_ptr t) { m_impl.append(std::move(t)); } - void prepend(std::unique_ptr t) { m_impl.prepend(std::move(t)); } - void remove(size_t i) { m_impl.remove(i); } - void clear() { m_impl.clear(); } - void swap(Vector>& other) { m_impl.swap(other.m_impl); } - void swap(Vector>&& other) { m_impl.swap(other.m_impl); } - void removeLast() { m_impl.removeLast(); } - -private: - WTF::Vector> m_impl; -}; - -template -class HashMapIterator { - STACK_ALLOCATED(); -public: - HashMapIterator(const I& impl) : m_impl(impl) { } - std::pair* get() const { m_pair = std::make_pair(m_impl->key, &m_impl->value); return &m_pair; } - std::pair& operator*() const { return *get(); } - std::pair* operator->() const { return get(); } - - bool operator==(const HashMapIterator& other) const { return m_impl == other.m_impl; } - bool operator!=(const HashMapIterator& other) const { return m_impl != other.m_impl; } - - HashMapIterator& operator++() { ++m_impl; return *this; } - -private: - mutable std::pair m_pair; - I m_impl; -}; - -template -class HashMapIterator, I> { - STACK_ALLOCATED(); -public: - HashMapIterator(const I& impl) : m_impl(impl) { } - std::pair* get() const { m_pair = std::make_pair(m_impl->key, m_impl->value.get()); return &m_pair; } - std::pair& operator*() const { return *get(); } - std::pair* operator->() const { return get(); } - - bool operator==(const HashMapIterator, I>& other) const { return m_impl == other.m_impl; } - bool operator!=(const HashMapIterator, I>& other) const { return m_impl != other.m_impl; } - - HashMapIterator, I>& operator++() { ++m_impl; return *this; } - -private: - mutable std::pair m_pair; - I m_impl; -}; - -template -class HashMap { -public: - HashMap() { } - ~HashMap() { } - - using iterator = HashMapIterator::iterator>; - using const_iterator = HashMapIterator::const_iterator>; - - iterator begin() { return iterator(m_impl.begin()); } - iterator end() { return iterator(m_impl.end()); } - iterator find(const K& k) { return iterator(m_impl.find(k)); } - const_iterator begin() const { return const_iterator(m_impl.begin()); } - const_iterator end() const { return const_iterator(m_impl.end()); } - const_iterator find(const K& k) const { return const_iterator(m_impl.find(k)); } - - size_t size() const { return m_impl.size(); } - bool isEmpty() const { return m_impl.isEmpty(); } - bool set(const K& k, const V& v) { return m_impl.set(k, v).isNewEntry; } - bool contains(const K& k) const { return m_impl.contains(k); } - V get(const K& k) const { return m_impl.get(k); } - void remove(const K& k) { m_impl.remove(k); } - void clear() { m_impl.clear(); } - V take(const K& k) { return m_impl.take(k); } - -private: - WTF::HashMap m_impl; -}; - -template -class HashMap> { -public: - HashMap() { } - ~HashMap() { } - - using iterator = HashMapIterator, typename WTF::HashMap>::iterator>; - using const_iterator = HashMapIterator, typename WTF::HashMap>::const_iterator>; - - iterator begin() { return iterator(m_impl.begin()); } - iterator end() { return iterator(m_impl.end()); } - iterator find(const K& k) { return iterator(m_impl.find(k)); } - const_iterator begin() const { return const_iterator(m_impl.begin()); } - const_iterator end() const { return const_iterator(m_impl.end()); } - const_iterator find(const K& k) const { return const_iterator(m_impl.find(k)); } - - size_t size() const { return m_impl.size(); } - bool isEmpty() const { return m_impl.isEmpty(); } - bool set(const K& k, std::unique_ptr v) { return m_impl.set(k, std::move(v)).isNewEntry; } - bool contains(const K& k) const { return m_impl.contains(k); } - V* get(const K& k) const { return m_impl.get(k); } - std::unique_ptr take(const K& k) { return m_impl.take(k); } - void remove(const K& k) { m_impl.remove(k); } - void clear() { m_impl.clear(); } - -private: - WTF::HashMap> m_impl; -}; - -template -class HashSet : public protocol::HashMap { -public: - void add(const K& k) { this->set(k, k); } -}; - -} // namespace platform -} // namespace blink - -#endif // !defined(CollectionsWTF_h) diff --git a/deps/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp b/deps/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp deleted file mode 100644 index 14dba693e97653..00000000000000 --- a/deps/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "platform/v8_inspector/V8DebuggerScript.h" - -namespace blink { - -V8DebuggerScript::V8DebuggerScript() - : m_startLine(0) - , m_startColumn(0) - , m_endLine(0) - , m_endColumn(0) - , m_executionContextId(0) - , m_isContentScript(false) - , m_isInternalScript(false) - , m_isLiveEdit(false) -{ -} - -String16 V8DebuggerScript::sourceURL() const -{ - return m_sourceURL.isEmpty() ? m_url : m_sourceURL; -} - -V8DebuggerScript& V8DebuggerScript::setURL(const String16& url) -{ - m_url = url; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setSourceURL(const String16& sourceURL) -{ - m_sourceURL = sourceURL; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setSourceMappingURL(const String16& sourceMappingURL) -{ - m_sourceMappingURL = sourceMappingURL; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setSource(const String16& source) -{ - m_source = source; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setHash(const String16& hash) -{ - m_hash = hash; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setStartLine(int startLine) -{ - m_startLine = startLine; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setStartColumn(int startColumn) -{ - m_startColumn = startColumn; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setEndLine(int endLine) -{ - m_endLine = endLine; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setEndColumn(int endColumn) -{ - m_endColumn = endColumn; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setExecutionContextId(int executionContextId) -{ - m_executionContextId = executionContextId; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setIsContentScript(bool isContentScript) -{ - m_isContentScript = isContentScript; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setIsInternalScript(bool isInternalScript) -{ - m_isInternalScript = isInternalScript; - return *this; -} - -V8DebuggerScript& V8DebuggerScript::setIsLiveEdit(bool isLiveEdit) -{ - m_isLiveEdit = isLiveEdit; - return *this; -} - -} // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/public/ConsoleAPITypes.h b/deps/v8_inspector/platform/v8_inspector/public/ConsoleAPITypes.h deleted file mode 100644 index 59487b86a9cfbb..00000000000000 --- a/deps/v8_inspector/platform/v8_inspector/public/ConsoleAPITypes.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ConsoleAPITypes_h -#define ConsoleAPITypes_h - -namespace blink { - -enum MessageType { - LogMessageType = 1, - DirMessageType, - DirXMLMessageType, - TableMessageType, - TraceMessageType, - StartGroupMessageType, - StartGroupCollapsedMessageType, - EndGroupMessageType, - ClearMessageType, - AssertMessageType, - TimeEndMessageType, - CountMessageType -}; - -} // namespace blink - -#endif // ConsoleAPITypes_h diff --git a/deps/v8_inspector/platform/v8_inspector/public/ConsoleTypes.h b/deps/v8_inspector/platform/v8_inspector/public/ConsoleTypes.h deleted file mode 100644 index fb06fb8ed017ec..00000000000000 --- a/deps/v8_inspector/platform/v8_inspector/public/ConsoleTypes.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2011 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ConsoleTypes_h -#define ConsoleTypes_h - -namespace blink { - -enum MessageSource { - XMLMessageSource, - JSMessageSource, - NetworkMessageSource, - ConsoleAPIMessageSource, - StorageMessageSource, - AppCacheMessageSource, - RenderingMessageSource, - SecurityMessageSource, - OtherMessageSource, - DeprecationMessageSource, -}; - -enum MessageLevel { - DebugMessageLevel = 4, - LogMessageLevel = 1, - InfoMessageLevel = 5, - WarningMessageLevel = 2, - ErrorMessageLevel = 3, - RevokedErrorMessageLevel = 6 -}; - -} // namespace blink - -#endif // ConsoleTypes_h diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8ToProtocolValue.h b/deps/v8_inspector/platform/v8_inspector/public/V8ToProtocolValue.h deleted file mode 100644 index c3c692f9959236..00000000000000 --- a/deps/v8_inspector/platform/v8_inspector/public/V8ToProtocolValue.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8ToProtocolValue_h -#define V8ToProtocolValue_h - -#include "platform/inspector_protocol/Values.h" -#include - -namespace blink { - -PLATFORM_EXPORT std::unique_ptr toProtocolValue(v8::Local, v8::Local, int maxDepth = protocol::Value::maxDepth); - -} // namespace blink - -#endif // V8ToProtocolValue_h diff --git a/deps/v8_inspector/deps/jinja2/.gitignore b/deps/v8_inspector/third_party/jinja2/.gitignore similarity index 100% rename from deps/v8_inspector/deps/jinja2/.gitignore rename to deps/v8_inspector/third_party/jinja2/.gitignore diff --git a/deps/v8_inspector/deps/jinja2/.travis.yml b/deps/v8_inspector/third_party/jinja2/.travis.yml similarity index 100% rename from deps/v8_inspector/deps/jinja2/.travis.yml rename to deps/v8_inspector/third_party/jinja2/.travis.yml diff --git a/deps/v8_inspector/deps/jinja2/AUTHORS b/deps/v8_inspector/third_party/jinja2/AUTHORS similarity index 100% rename from deps/v8_inspector/deps/jinja2/AUTHORS rename to deps/v8_inspector/third_party/jinja2/AUTHORS diff --git a/deps/v8_inspector/deps/jinja2/CHANGES b/deps/v8_inspector/third_party/jinja2/CHANGES similarity index 100% rename from deps/v8_inspector/deps/jinja2/CHANGES rename to deps/v8_inspector/third_party/jinja2/CHANGES diff --git a/deps/v8_inspector/deps/jinja2/LICENSE b/deps/v8_inspector/third_party/jinja2/LICENSE similarity index 98% rename from deps/v8_inspector/deps/jinja2/LICENSE rename to deps/v8_inspector/third_party/jinja2/LICENSE index 31bf900e58e30f..10145a264342b7 100644 --- a/deps/v8_inspector/deps/jinja2/LICENSE +++ b/deps/v8_inspector/third_party/jinja2/LICENSE @@ -1,31 +1,31 @@ -Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/deps/v8_inspector/deps/jinja2/MANIFEST.in b/deps/v8_inspector/third_party/jinja2/MANIFEST.in similarity index 100% rename from deps/v8_inspector/deps/jinja2/MANIFEST.in rename to deps/v8_inspector/third_party/jinja2/MANIFEST.in diff --git a/deps/v8_inspector/deps/jinja2/Makefile b/deps/v8_inspector/third_party/jinja2/Makefile similarity index 100% rename from deps/v8_inspector/deps/jinja2/Makefile rename to deps/v8_inspector/third_party/jinja2/Makefile diff --git a/deps/v8_inspector/deps/jinja2/README.rst b/deps/v8_inspector/third_party/jinja2/README.rst similarity index 100% rename from deps/v8_inspector/deps/jinja2/README.rst rename to deps/v8_inspector/third_party/jinja2/README.rst diff --git a/deps/v8_inspector/deps/jinja2/artwork/jinjalogo.svg b/deps/v8_inspector/third_party/jinja2/artwork/jinjalogo.svg similarity index 100% rename from deps/v8_inspector/deps/jinja2/artwork/jinjalogo.svg rename to deps/v8_inspector/third_party/jinja2/artwork/jinjalogo.svg diff --git a/deps/v8_inspector/deps/jinja2/docs/Makefile b/deps/v8_inspector/third_party/jinja2/docs/Makefile similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/Makefile rename to deps/v8_inspector/third_party/jinja2/docs/Makefile diff --git a/deps/v8_inspector/deps/jinja2/docs/_static/.ignore b/deps/v8_inspector/third_party/jinja2/docs/_static/.ignore similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/_static/.ignore rename to deps/v8_inspector/third_party/jinja2/docs/_static/.ignore diff --git a/deps/v8_inspector/deps/jinja2/docs/_static/jinja-small.png b/deps/v8_inspector/third_party/jinja2/docs/_static/jinja-small.png similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/_static/jinja-small.png rename to deps/v8_inspector/third_party/jinja2/docs/_static/jinja-small.png diff --git a/deps/v8_inspector/deps/jinja2/docs/_templates/sidebarintro.html b/deps/v8_inspector/third_party/jinja2/docs/_templates/sidebarintro.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/_templates/sidebarintro.html rename to deps/v8_inspector/third_party/jinja2/docs/_templates/sidebarintro.html diff --git a/deps/v8_inspector/deps/jinja2/docs/_templates/sidebarlogo.html b/deps/v8_inspector/third_party/jinja2/docs/_templates/sidebarlogo.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/_templates/sidebarlogo.html rename to deps/v8_inspector/third_party/jinja2/docs/_templates/sidebarlogo.html diff --git a/deps/v8_inspector/deps/jinja2/docs/_themes/LICENSE b/deps/v8_inspector/third_party/jinja2/docs/_themes/LICENSE similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/_themes/LICENSE rename to deps/v8_inspector/third_party/jinja2/docs/_themes/LICENSE diff --git a/deps/v8_inspector/deps/jinja2/docs/_themes/README b/deps/v8_inspector/third_party/jinja2/docs/_themes/README similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/_themes/README rename to deps/v8_inspector/third_party/jinja2/docs/_themes/README diff --git a/deps/v8_inspector/deps/jinja2/docs/_themes/jinja/layout.html b/deps/v8_inspector/third_party/jinja2/docs/_themes/jinja/layout.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/_themes/jinja/layout.html rename to deps/v8_inspector/third_party/jinja2/docs/_themes/jinja/layout.html diff --git a/deps/v8_inspector/deps/jinja2/docs/_themes/jinja/relations.html b/deps/v8_inspector/third_party/jinja2/docs/_themes/jinja/relations.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/_themes/jinja/relations.html rename to deps/v8_inspector/third_party/jinja2/docs/_themes/jinja/relations.html diff --git a/deps/v8_inspector/deps/jinja2/docs/_themes/jinja/static/jinja.css_t b/deps/v8_inspector/third_party/jinja2/docs/_themes/jinja/static/jinja.css_t similarity index 99% rename from deps/v8_inspector/deps/jinja2/docs/_themes/jinja/static/jinja.css_t rename to deps/v8_inspector/third_party/jinja2/docs/_themes/jinja/static/jinja.css_t index 7d3b244ae13bb6..3291ba6fd18605 100644 --- a/deps/v8_inspector/deps/jinja2/docs/_themes/jinja/static/jinja.css_t +++ b/deps/v8_inspector/third_party/jinja2/docs/_themes/jinja/static/jinja.css_t @@ -12,11 +12,11 @@ {% set sidebar_width = '220px' %} {% set font_family = 'Georgia, serif' %} {% set header_font_family = 'Crimson Text, ' ~ font_family %} - + @import url("basic.css"); - + /* -- page layout ----------------------------------------------------------- */ - + body { font-family: {{ font_family }}; font-size: 17px; @@ -47,7 +47,7 @@ div.sphinxsidebar { hr { border: 1px solid #B1B4B6; } - + div.body { background-color: #ffffff; color: #3E4349; @@ -58,7 +58,7 @@ img.floatingflask { padding: 0 0 10px 10px; float: right; } - + div.footer { width: {{ page_width }}; margin: 20px auto 30px auto; @@ -74,7 +74,7 @@ div.footer a { div.related { display: none; } - + div.sphinxsidebar a { color: #444; text-decoration: none; @@ -84,7 +84,7 @@ div.sphinxsidebar a { div.sphinxsidebar a:hover { border-bottom: 1px solid #999; } - + div.sphinxsidebar { font-size: 15px; line-height: 1.5; @@ -99,7 +99,7 @@ div.sphinxsidebarwrapper p.logo { margin: 0; text-align: center; } - + div.sphinxsidebar h3, div.sphinxsidebar h4 { font-family: {{ font_family }}; @@ -113,7 +113,7 @@ div.sphinxsidebar h4 { div.sphinxsidebar h4 { font-size: 20px; } - + div.sphinxsidebar h3 a { color: #444; } @@ -124,7 +124,7 @@ div.sphinxsidebar p.logo a:hover, div.sphinxsidebar h3 a:hover { border: none; } - + div.sphinxsidebar p { color: #555; margin: 10px 0; @@ -135,7 +135,7 @@ div.sphinxsidebar ul { padding: 0; color: #000; } - + div.sphinxsidebar input { border: 1px solid #ccc; font-family: {{ font_family }}; @@ -145,19 +145,19 @@ div.sphinxsidebar input { div.sphinxsidebar form.search input[name="q"] { width: 130px; } - + /* -- body styles ----------------------------------------------------------- */ - + a { color: #aa0000; text-decoration: underline; } - + a:hover { color: #dd0000; text-decoration: underline; } - + div.body h1, div.body h2, div.body h3, @@ -170,25 +170,25 @@ div.body h6 { padding: 0; color: black; } - + div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } div.body h2 { font-size: 180%; } div.body h3 { font-size: 150%; } div.body h4 { font-size: 130%; } div.body h5 { font-size: 100%; } div.body h6 { font-size: 100%; } - + a.headerlink { color: #ddd; padding: 0 4px; text-decoration: none; } - + a.headerlink:hover { color: #444; background: #eaeaea; } - + div.body p, div.body dd, div.body li { line-height: 1.4em; } @@ -235,20 +235,20 @@ div.note { background-color: #eee; border: 1px solid #ccc; } - + div.seealso { background-color: #ffc; border: 1px solid #ff6; } - + div.topic { background-color: #eee; } - + p.admonition-title { display: inline; } - + p.admonition-title:after { content: ":"; } @@ -342,7 +342,7 @@ ul, ol { margin: 10px 0 10px 30px; padding: 0; } - + pre { background: #eee; padding: 7px 30px; @@ -359,7 +359,7 @@ dl dl pre { margin-left: -90px; padding-left: 90px; } - + tt { background-color: #E8EFF0; color: #222; diff --git a/deps/v8_inspector/deps/jinja2/docs/_themes/jinja/theme.conf b/deps/v8_inspector/third_party/jinja2/docs/_themes/jinja/theme.conf similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/_themes/jinja/theme.conf rename to deps/v8_inspector/third_party/jinja2/docs/_themes/jinja/theme.conf diff --git a/deps/v8_inspector/deps/jinja2/docs/api.rst b/deps/v8_inspector/third_party/jinja2/docs/api.rst similarity index 99% rename from deps/v8_inspector/deps/jinja2/docs/api.rst rename to deps/v8_inspector/third_party/jinja2/docs/api.rst index 04ba157fbba31c..088c8673208087 100644 --- a/deps/v8_inspector/deps/jinja2/docs/api.rst +++ b/deps/v8_inspector/third_party/jinja2/docs/api.rst @@ -197,7 +197,7 @@ useful if you want to dig deeper into Jinja2 or :ref:`develop extensions For a more complex example you can provide a hint. For example the :func:`first` filter creates an undefined object that way:: - return environment.undefined('no first item, sequence was empty') + return environment.undefined('no first item, sequence was empty') If it the `name` or `obj` is known (for example because an attribute was accessed) it should be passed to the undefined object, even if @@ -714,7 +714,7 @@ Here a simple test that checks if a variable is a prime number:: if n % i == 0: return False return True - + You can register it on the template environment by updating the :attr:`~Environment.tests` dict on the environment:: diff --git a/deps/v8_inspector/deps/jinja2/docs/cache_extension.py b/deps/v8_inspector/third_party/jinja2/docs/cache_extension.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/cache_extension.py rename to deps/v8_inspector/third_party/jinja2/docs/cache_extension.py diff --git a/deps/v8_inspector/deps/jinja2/docs/changelog.rst b/deps/v8_inspector/third_party/jinja2/docs/changelog.rst similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/changelog.rst rename to deps/v8_inspector/third_party/jinja2/docs/changelog.rst diff --git a/deps/v8_inspector/deps/jinja2/docs/conf.py b/deps/v8_inspector/third_party/jinja2/docs/conf.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/conf.py rename to deps/v8_inspector/third_party/jinja2/docs/conf.py diff --git a/deps/v8_inspector/deps/jinja2/docs/contents.rst.inc b/deps/v8_inspector/third_party/jinja2/docs/contents.rst.inc similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/contents.rst.inc rename to deps/v8_inspector/third_party/jinja2/docs/contents.rst.inc diff --git a/deps/v8_inspector/deps/jinja2/docs/extensions.rst b/deps/v8_inspector/third_party/jinja2/docs/extensions.rst similarity index 99% rename from deps/v8_inspector/deps/jinja2/docs/extensions.rst rename to deps/v8_inspector/third_party/jinja2/docs/extensions.rst index 955708ba4e67d2..0825fd4f9b7343 100644 --- a/deps/v8_inspector/deps/jinja2/docs/extensions.rst +++ b/deps/v8_inspector/third_party/jinja2/docs/extensions.rst @@ -27,8 +27,8 @@ i18n Extension **Import name:** `jinja2.ext.i18n` -The i18n extension can be used in combination with `gettext`_ or `babel`_. If -the i18n extension is enabled Jinja2 provides a `trans` statement that marks +The i18n extension can be used in combination with `gettext`_ or `babel`_. If +the i18n extension is enabled Jinja2 provides a `trans` statement that marks the wrapped string as translatable and calls `gettext`. After enabling, dummy `_` function that forwards calls to `gettext` is added diff --git a/deps/v8_inspector/deps/jinja2/docs/faq.rst b/deps/v8_inspector/third_party/jinja2/docs/faq.rst similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/faq.rst rename to deps/v8_inspector/third_party/jinja2/docs/faq.rst diff --git a/deps/v8_inspector/deps/jinja2/docs/index.rst b/deps/v8_inspector/third_party/jinja2/docs/index.rst similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/index.rst rename to deps/v8_inspector/third_party/jinja2/docs/index.rst diff --git a/deps/v8_inspector/deps/jinja2/docs/integration.rst b/deps/v8_inspector/third_party/jinja2/docs/integration.rst similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/integration.rst rename to deps/v8_inspector/third_party/jinja2/docs/integration.rst diff --git a/deps/v8_inspector/deps/jinja2/docs/intro.rst b/deps/v8_inspector/third_party/jinja2/docs/intro.rst similarity index 98% rename from deps/v8_inspector/deps/jinja2/docs/intro.rst rename to deps/v8_inspector/third_party/jinja2/docs/intro.rst index b6da5ea5f12ad1..99c3582728f773 100644 --- a/deps/v8_inspector/deps/jinja2/docs/intro.rst +++ b/deps/v8_inspector/third_party/jinja2/docs/intro.rst @@ -64,7 +64,7 @@ which will install the package via `distribute` in development mode. This also has the advantage that the C extensions are compiled. .. _download page: http://pypi.python.org/pypi/Jinja2 -.. _distribute: http://pypi.python.org/pypi/distribute +.. _distribute: http://pypi.python.org/pypi/distribute .. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools .. _easy_install: http://peak.telecommunity.com/DevCenter/EasyInstall .. _pip: http://pypi.python.org/pypi/pip diff --git a/deps/v8_inspector/deps/jinja2/docs/jinjaext.py b/deps/v8_inspector/third_party/jinja2/docs/jinjaext.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/jinjaext.py rename to deps/v8_inspector/third_party/jinja2/docs/jinjaext.py diff --git a/deps/v8_inspector/deps/jinja2/docs/jinjastyle.sty b/deps/v8_inspector/third_party/jinja2/docs/jinjastyle.sty similarity index 98% rename from deps/v8_inspector/deps/jinja2/docs/jinjastyle.sty rename to deps/v8_inspector/third_party/jinja2/docs/jinjastyle.sty index e93c8d1c6974e9..da811ce376bd12 100644 --- a/deps/v8_inspector/deps/jinja2/docs/jinjastyle.sty +++ b/deps/v8_inspector/third_party/jinja2/docs/jinjastyle.sty @@ -22,7 +22,7 @@ %\sphinxlogo% {\center \vspace*{3cm} - \includegraphics{logo.pdf} + \includegraphics{logo.pdf} \vspace{3cm} \par {\rm\Huge \@title \par}% diff --git a/deps/v8_inspector/deps/jinja2/docs/latexindex.rst b/deps/v8_inspector/third_party/jinja2/docs/latexindex.rst similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/latexindex.rst rename to deps/v8_inspector/third_party/jinja2/docs/latexindex.rst diff --git a/deps/v8_inspector/deps/jinja2/docs/logo.pdf b/deps/v8_inspector/third_party/jinja2/docs/logo.pdf similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/logo.pdf rename to deps/v8_inspector/third_party/jinja2/docs/logo.pdf diff --git a/deps/v8_inspector/deps/jinja2/docs/sandbox.rst b/deps/v8_inspector/third_party/jinja2/docs/sandbox.rst similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/sandbox.rst rename to deps/v8_inspector/third_party/jinja2/docs/sandbox.rst diff --git a/deps/v8_inspector/deps/jinja2/docs/switching.rst b/deps/v8_inspector/third_party/jinja2/docs/switching.rst similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/switching.rst rename to deps/v8_inspector/third_party/jinja2/docs/switching.rst diff --git a/deps/v8_inspector/deps/jinja2/docs/templates.rst b/deps/v8_inspector/third_party/jinja2/docs/templates.rst similarity index 99% rename from deps/v8_inspector/deps/jinja2/docs/templates.rst rename to deps/v8_inspector/third_party/jinja2/docs/templates.rst index 3c169247219908..d9102ecc1b636b 100644 --- a/deps/v8_inspector/deps/jinja2/docs/templates.rst +++ b/deps/v8_inspector/third_party/jinja2/docs/templates.rst @@ -197,14 +197,14 @@ without the `trim_blocks` and `lstrip_blocks` options, this template:: gets rendered with blank lines inside the div::
- + yay - +
But with both `trim_blocks` and `lstrip_blocks` enabled, the template block lines are removed and other whitespace is preserved:: - +
yay
@@ -522,12 +522,12 @@ Working with Automatic Escaping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When automatic escaping is enabled, everything is escaped by default except -for values explicitly marked as safe. Variables and expressions +for values explicitly marked as safe. Variables and expressions can be marked as safe either in: a. the context dictionary by the application with `MarkupSafe.Markup`, or b. the template, with the `|safe` filter - + The main problem with this approach is that Python itself doesn't have the concept of tainted values; so whether a value is safe or unsafe can get lost. diff --git a/deps/v8_inspector/deps/jinja2/docs/tricks.rst b/deps/v8_inspector/third_party/jinja2/docs/tricks.rst similarity index 100% rename from deps/v8_inspector/deps/jinja2/docs/tricks.rst rename to deps/v8_inspector/third_party/jinja2/docs/tricks.rst diff --git a/deps/v8_inspector/deps/jinja2/examples/basic/cycle.py b/deps/v8_inspector/third_party/jinja2/examples/basic/cycle.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/basic/cycle.py rename to deps/v8_inspector/third_party/jinja2/examples/basic/cycle.py diff --git a/deps/v8_inspector/deps/jinja2/examples/basic/debugger.py b/deps/v8_inspector/third_party/jinja2/examples/basic/debugger.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/basic/debugger.py rename to deps/v8_inspector/third_party/jinja2/examples/basic/debugger.py diff --git a/deps/v8_inspector/deps/jinja2/examples/basic/inheritance.py b/deps/v8_inspector/third_party/jinja2/examples/basic/inheritance.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/basic/inheritance.py rename to deps/v8_inspector/third_party/jinja2/examples/basic/inheritance.py diff --git a/deps/v8_inspector/deps/jinja2/examples/basic/templates/broken.html b/deps/v8_inspector/third_party/jinja2/examples/basic/templates/broken.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/basic/templates/broken.html rename to deps/v8_inspector/third_party/jinja2/examples/basic/templates/broken.html diff --git a/deps/v8_inspector/deps/jinja2/examples/basic/templates/subbroken.html b/deps/v8_inspector/third_party/jinja2/examples/basic/templates/subbroken.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/basic/templates/subbroken.html rename to deps/v8_inspector/third_party/jinja2/examples/basic/templates/subbroken.html diff --git a/deps/v8_inspector/deps/jinja2/examples/basic/test.py b/deps/v8_inspector/third_party/jinja2/examples/basic/test.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/basic/test.py rename to deps/v8_inspector/third_party/jinja2/examples/basic/test.py diff --git a/deps/v8_inspector/deps/jinja2/examples/basic/test_filter_and_linestatements.py b/deps/v8_inspector/third_party/jinja2/examples/basic/test_filter_and_linestatements.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/basic/test_filter_and_linestatements.py rename to deps/v8_inspector/third_party/jinja2/examples/basic/test_filter_and_linestatements.py diff --git a/deps/v8_inspector/deps/jinja2/examples/basic/test_loop_filter.py b/deps/v8_inspector/third_party/jinja2/examples/basic/test_loop_filter.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/basic/test_loop_filter.py rename to deps/v8_inspector/third_party/jinja2/examples/basic/test_loop_filter.py diff --git a/deps/v8_inspector/deps/jinja2/examples/basic/translate.py b/deps/v8_inspector/third_party/jinja2/examples/basic/translate.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/basic/translate.py rename to deps/v8_inspector/third_party/jinja2/examples/basic/translate.py diff --git a/deps/v8_inspector/deps/jinja2/examples/bench.py b/deps/v8_inspector/third_party/jinja2/examples/bench.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/bench.py rename to deps/v8_inspector/third_party/jinja2/examples/bench.py diff --git a/deps/v8_inspector/deps/jinja2/examples/profile.py b/deps/v8_inspector/third_party/jinja2/examples/profile.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/profile.py rename to deps/v8_inspector/third_party/jinja2/examples/profile.py diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/django/_form.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/django/_form.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/django/_form.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/django/_form.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/django/_input_field.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/django/_input_field.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/django/_input_field.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/django/_input_field.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/django/_textarea.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/django/_textarea.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/django/_textarea.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/django/_textarea.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/django/index.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/django/index.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/django/index.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/django/index.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/django/layout.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/django/layout.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/django/layout.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/django/layout.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/djangoext.py b/deps/v8_inspector/third_party/jinja2/examples/rwbench/djangoext.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/djangoext.py rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/djangoext.py diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/genshi/helpers.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/genshi/helpers.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/genshi/helpers.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/genshi/helpers.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/genshi/index.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/genshi/index.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/genshi/index.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/genshi/index.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/genshi/layout.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/genshi/layout.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/genshi/layout.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/genshi/layout.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/jinja/helpers.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/jinja/helpers.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/jinja/helpers.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/jinja/helpers.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/jinja/index.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/jinja/index.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/jinja/index.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/jinja/index.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/jinja/layout.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/jinja/layout.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/jinja/layout.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/jinja/layout.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/mako/helpers.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/mako/helpers.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/mako/helpers.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/mako/helpers.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/mako/index.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/mako/index.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/mako/index.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/mako/index.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/mako/layout.html b/deps/v8_inspector/third_party/jinja2/examples/rwbench/mako/layout.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/mako/layout.html rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/mako/layout.html diff --git a/deps/v8_inspector/deps/jinja2/examples/rwbench/rwbench.py b/deps/v8_inspector/third_party/jinja2/examples/rwbench/rwbench.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/examples/rwbench/rwbench.py rename to deps/v8_inspector/third_party/jinja2/examples/rwbench/rwbench.py diff --git a/deps/v8_inspector/deps/jinja2/ext/Vim/jinja.vim b/deps/v8_inspector/third_party/jinja2/ext/Vim/jinja.vim similarity index 100% rename from deps/v8_inspector/deps/jinja2/ext/Vim/jinja.vim rename to deps/v8_inspector/third_party/jinja2/ext/Vim/jinja.vim diff --git a/deps/v8_inspector/deps/jinja2/ext/django2jinja/django2jinja.py b/deps/v8_inspector/third_party/jinja2/ext/django2jinja/django2jinja.py similarity index 99% rename from deps/v8_inspector/deps/jinja2/ext/django2jinja/django2jinja.py rename to deps/v8_inspector/third_party/jinja2/ext/django2jinja/django2jinja.py index 824d6a1c3679b5..ad9627ffbc3791 100644 --- a/deps/v8_inspector/deps/jinja2/ext/django2jinja/django2jinja.py +++ b/deps/v8_inspector/third_party/jinja2/ext/django2jinja/django2jinja.py @@ -33,13 +33,13 @@ def write_my_node(writer, node): writer = Writer() writer.node_handlers[MyNode] = write_my_node convert_templates('/path/to/output/folder', writer=writer) - + Here is an example hos to automatically translate your django variables to jinja2:: - + import re # List of tuple (Match pattern, Replace pattern, Exclusion pattern) - + var_re = ((re.compile(r"(u|user)\.is_authenticated"), r"\1.is_authenticated()", None), (re.compile(r"\.non_field_errors"), r".non_field_errors()", None), (re.compile(r"\.label_tag"), r".label_tag()", None), @@ -47,7 +47,7 @@ def write_my_node(writer, node): (re.compile(r"\.as_table"), r".as_table()", None), (re.compile(r"\.as_widget"), r".as_widget()", None), (re.compile(r"\.as_hidden"), r".as_hidden()", None), - + (re.compile(r"\.get_([0-9_\w]+)_url"), r".get_\1_url()", None), (re.compile(r"\.url"), r".url()", re.compile(r"(form|calendar).url")), (re.compile(r"\.get_([0-9_\w]+)_display"), r".get_\1_display()", None), @@ -55,14 +55,14 @@ def write_my_node(writer, node): (re.compile(r"loop\.revcounter"), r"loop.revindex", None), (re.compile(r"request\.GET\.([0-9_\w]+)"), r"request.GET.get('\1', '')", None), (re.compile(r"request\.get_host"), r"request.get_host()", None), - + (re.compile(r"\.all(?!_)"), r".all()", None), (re.compile(r"\.all\.0"), r".all()[0]", None), (re.compile(r"\.([0-9])($|\s+)"), r"[\1]\2", None), (re.compile(r"\.items"), r".items()", None), ) writer = Writer(var_re=var_re) - + For details about the writing process have a look at the module code. :copyright: (c) 2009 by the Jinja Team. @@ -314,7 +314,7 @@ def translate_variable_name(self, var): """Performs variable name translation.""" if self.in_loop and var == 'forloop' or var.startswith('forloop.'): var = var[3:] - + for reg, rep, unless in self.var_re: no_unless = unless and unless.search(var) or True if reg.search(var) and no_unless: @@ -425,7 +425,7 @@ def if_condition(writer, node): join_with = 'and' if node.link_type == core_tags.IfNode.LinkTypes.or_: join_with = 'or' - + for idx, (ifnot, expr) in enumerate(node.bool_exprs): if idx: writer.write(' %s ' % join_with) @@ -734,22 +734,22 @@ def simple_tag(writer, node): writer._filters_warned.add(name) writer.warn('Filter %s probably doesn\'t exist in Jinja' % name) - + if not node.vars_to_resolve: # No argument, pass the request writer.start_variable() writer.write('request|') writer.write(name) writer.end_variable() - return - + return + first_var = node.vars_to_resolve[0] args = node.vars_to_resolve[1:] writer.start_variable() - + # Copied from Writer.filters() writer.node(first_var) - + writer.write('|') writer.write(name) if args: @@ -762,7 +762,7 @@ def simple_tag(writer, node): else: writer.literal(var.literal) writer.write(')') - writer.end_variable() + writer.end_variable() # get rid of node now, it shouldn't be used normally del node diff --git a/deps/v8_inspector/deps/jinja2/ext/django2jinja/example.py b/deps/v8_inspector/third_party/jinja2/ext/django2jinja/example.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/ext/django2jinja/example.py rename to deps/v8_inspector/third_party/jinja2/ext/django2jinja/example.py diff --git a/deps/v8_inspector/deps/jinja2/ext/django2jinja/templates/index.html b/deps/v8_inspector/third_party/jinja2/ext/django2jinja/templates/index.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/ext/django2jinja/templates/index.html rename to deps/v8_inspector/third_party/jinja2/ext/django2jinja/templates/index.html diff --git a/deps/v8_inspector/deps/jinja2/ext/django2jinja/templates/layout.html b/deps/v8_inspector/third_party/jinja2/ext/django2jinja/templates/layout.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/ext/django2jinja/templates/layout.html rename to deps/v8_inspector/third_party/jinja2/ext/django2jinja/templates/layout.html diff --git a/deps/v8_inspector/deps/jinja2/ext/django2jinja/templates/subtemplate.html b/deps/v8_inspector/third_party/jinja2/ext/django2jinja/templates/subtemplate.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/ext/django2jinja/templates/subtemplate.html rename to deps/v8_inspector/third_party/jinja2/ext/django2jinja/templates/subtemplate.html diff --git a/deps/v8_inspector/deps/jinja2/ext/djangojinja2.py b/deps/v8_inspector/third_party/jinja2/ext/djangojinja2.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/ext/djangojinja2.py rename to deps/v8_inspector/third_party/jinja2/ext/djangojinja2.py diff --git a/deps/v8_inspector/deps/jinja2/ext/inlinegettext.py b/deps/v8_inspector/third_party/jinja2/ext/inlinegettext.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/ext/inlinegettext.py rename to deps/v8_inspector/third_party/jinja2/ext/inlinegettext.py diff --git a/deps/v8_inspector/deps/jinja2/ext/jinja.el b/deps/v8_inspector/third_party/jinja2/ext/jinja.el similarity index 100% rename from deps/v8_inspector/deps/jinja2/ext/jinja.el rename to deps/v8_inspector/third_party/jinja2/ext/jinja.el diff --git a/deps/v8_inspector/deps/jinja2/jinja2/__init__.py b/deps/v8_inspector/third_party/jinja2/jinja2/__init__.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/__init__.py rename to deps/v8_inspector/third_party/jinja2/jinja2/__init__.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/_compat.py b/deps/v8_inspector/third_party/jinja2/jinja2/_compat.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/_compat.py rename to deps/v8_inspector/third_party/jinja2/jinja2/_compat.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/_stringdefs.py b/deps/v8_inspector/third_party/jinja2/jinja2/_stringdefs.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/_stringdefs.py rename to deps/v8_inspector/third_party/jinja2/jinja2/_stringdefs.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/bccache.py b/deps/v8_inspector/third_party/jinja2/jinja2/bccache.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/bccache.py rename to deps/v8_inspector/third_party/jinja2/jinja2/bccache.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/compiler.py b/deps/v8_inspector/third_party/jinja2/jinja2/compiler.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/compiler.py rename to deps/v8_inspector/third_party/jinja2/jinja2/compiler.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/constants.py b/deps/v8_inspector/third_party/jinja2/jinja2/constants.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/constants.py rename to deps/v8_inspector/third_party/jinja2/jinja2/constants.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/debug.py b/deps/v8_inspector/third_party/jinja2/jinja2/debug.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/debug.py rename to deps/v8_inspector/third_party/jinja2/jinja2/debug.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/defaults.py b/deps/v8_inspector/third_party/jinja2/jinja2/defaults.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/defaults.py rename to deps/v8_inspector/third_party/jinja2/jinja2/defaults.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/environment.py b/deps/v8_inspector/third_party/jinja2/jinja2/environment.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/environment.py rename to deps/v8_inspector/third_party/jinja2/jinja2/environment.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/exceptions.py b/deps/v8_inspector/third_party/jinja2/jinja2/exceptions.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/exceptions.py rename to deps/v8_inspector/third_party/jinja2/jinja2/exceptions.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/ext.py b/deps/v8_inspector/third_party/jinja2/jinja2/ext.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/ext.py rename to deps/v8_inspector/third_party/jinja2/jinja2/ext.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/filters.py b/deps/v8_inspector/third_party/jinja2/jinja2/filters.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/filters.py rename to deps/v8_inspector/third_party/jinja2/jinja2/filters.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/lexer.py b/deps/v8_inspector/third_party/jinja2/jinja2/lexer.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/lexer.py rename to deps/v8_inspector/third_party/jinja2/jinja2/lexer.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/loaders.py b/deps/v8_inspector/third_party/jinja2/jinja2/loaders.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/loaders.py rename to deps/v8_inspector/third_party/jinja2/jinja2/loaders.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/meta.py b/deps/v8_inspector/third_party/jinja2/jinja2/meta.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/meta.py rename to deps/v8_inspector/third_party/jinja2/jinja2/meta.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/nodes.py b/deps/v8_inspector/third_party/jinja2/jinja2/nodes.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/nodes.py rename to deps/v8_inspector/third_party/jinja2/jinja2/nodes.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/optimizer.py b/deps/v8_inspector/third_party/jinja2/jinja2/optimizer.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/optimizer.py rename to deps/v8_inspector/third_party/jinja2/jinja2/optimizer.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/parser.py b/deps/v8_inspector/third_party/jinja2/jinja2/parser.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/parser.py rename to deps/v8_inspector/third_party/jinja2/jinja2/parser.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/runtime.py b/deps/v8_inspector/third_party/jinja2/jinja2/runtime.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/runtime.py rename to deps/v8_inspector/third_party/jinja2/jinja2/runtime.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/sandbox.py b/deps/v8_inspector/third_party/jinja2/jinja2/sandbox.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/sandbox.py rename to deps/v8_inspector/third_party/jinja2/jinja2/sandbox.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/tests.py b/deps/v8_inspector/third_party/jinja2/jinja2/tests.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/tests.py rename to deps/v8_inspector/third_party/jinja2/jinja2/tests.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/utils.py b/deps/v8_inspector/third_party/jinja2/jinja2/utils.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/utils.py rename to deps/v8_inspector/third_party/jinja2/jinja2/utils.py diff --git a/deps/v8_inspector/deps/jinja2/jinja2/visitor.py b/deps/v8_inspector/third_party/jinja2/jinja2/visitor.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/jinja2/visitor.py rename to deps/v8_inspector/third_party/jinja2/jinja2/visitor.py diff --git a/deps/v8_inspector/deps/jinja2/scripts/jinja2-debug.py b/deps/v8_inspector/third_party/jinja2/scripts/jinja2-debug.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/scripts/jinja2-debug.py rename to deps/v8_inspector/third_party/jinja2/scripts/jinja2-debug.py diff --git a/deps/v8_inspector/deps/jinja2/scripts/make-release.py b/deps/v8_inspector/third_party/jinja2/scripts/make-release.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/scripts/make-release.py rename to deps/v8_inspector/third_party/jinja2/scripts/make-release.py diff --git a/deps/v8_inspector/deps/jinja2/scripts/pylintrc b/deps/v8_inspector/third_party/jinja2/scripts/pylintrc similarity index 99% rename from deps/v8_inspector/deps/jinja2/scripts/pylintrc rename to deps/v8_inspector/third_party/jinja2/scripts/pylintrc index 6ebf385bcee24e..4f85b49066fe0b 100644 --- a/deps/v8_inspector/deps/jinja2/scripts/pylintrc +++ b/deps/v8_inspector/third_party/jinja2/scripts/pylintrc @@ -1,11 +1,11 @@ # lint Python modules using external checkers. -# +# # This is the main checker controling the other ones and the reports # generation. It is itself both a raw checker and an astng checker in order # to: # * handle message activation / deactivation at the module level # * handle some basic but necessary stats'data (number of classes, methods...) -# +# [MASTER] # Specify a configuration file. @@ -92,7 +92,7 @@ comment=no # * undefined variables # * redefinition of variable from builtins or from an outer scope # * use of variable before assigment -# +# [VARIABLES] # Tells wether we should check for unused import in __init__ files. @@ -107,7 +107,7 @@ additional-builtins= # try to find bugs in the code using type inference -# +# [TYPECHECK] # Tells wether missing members accessed in mixin class should be ignored. A @@ -132,7 +132,7 @@ acquired-members=REQUEST,acl_users,aq_parent # * dangerous default values as arguments # * redefinition of function / method / class # * uses of the global statement -# +# [BASIC] # Required attributes for module, separated by a comma @@ -183,7 +183,7 @@ bad-functions=apply,input # checks for sign of poor/misdesign: # * number of methods, attributes, local variables... # * size, complexity of functions, methods -# +# [DESIGN] # Maximum number of arguments for function / method @@ -219,7 +219,7 @@ max-public-methods=20 # * relative / wildcard imports # * cyclic imports # * uses of deprecated modules -# +# [IMPORTS] # Deprecated modules which should not be used, separated by a comma @@ -245,7 +245,7 @@ int-import-graph= # * attributes not defined in the __init__ method # * supported interfaces implementation # * unreachable code -# +# [CLASSES] # List of interface methods to ignore, separated by a comma. This is used for @@ -259,7 +259,7 @@ defining-attr-methods=__init__,__new__,setUp # checks for similarities and duplicated code. This computation may be # memory / CPU intensive, so you should disable it if you experiments some # problems. -# +# [SIMILARITIES] # Minimum lines number of a similarity. @@ -275,7 +275,7 @@ ignore-docstrings=yes # checks for: # * warning notes in the code like FIXME, XXX # * PEP 263: source code with non ascii character but no encoding declaration -# +# [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. @@ -287,7 +287,7 @@ notes=FIXME,XXX,TODO # * strict indentation # * line length # * use of <> instead of != -# +# [FORMAT] # Maximum number of characters on a single line. diff --git a/deps/v8_inspector/deps/jinja2/setup.cfg b/deps/v8_inspector/third_party/jinja2/setup.cfg similarity index 100% rename from deps/v8_inspector/deps/jinja2/setup.cfg rename to deps/v8_inspector/third_party/jinja2/setup.cfg diff --git a/deps/v8_inspector/deps/jinja2/setup.py b/deps/v8_inspector/third_party/jinja2/setup.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/setup.py rename to deps/v8_inspector/third_party/jinja2/setup.py diff --git a/deps/v8_inspector/deps/jinja2/tests/conftest.py b/deps/v8_inspector/third_party/jinja2/tests/conftest.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/conftest.py rename to deps/v8_inspector/third_party/jinja2/tests/conftest.py diff --git a/deps/v8_inspector/deps/jinja2/tests/res/__init__.py b/deps/v8_inspector/third_party/jinja2/tests/res/__init__.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/res/__init__.py rename to deps/v8_inspector/third_party/jinja2/tests/res/__init__.py diff --git a/deps/v8_inspector/deps/jinja2/tests/res/templates/broken.html b/deps/v8_inspector/third_party/jinja2/tests/res/templates/broken.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/res/templates/broken.html rename to deps/v8_inspector/third_party/jinja2/tests/res/templates/broken.html diff --git a/deps/v8_inspector/deps/jinja2/tests/res/templates/foo/test.html b/deps/v8_inspector/third_party/jinja2/tests/res/templates/foo/test.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/res/templates/foo/test.html rename to deps/v8_inspector/third_party/jinja2/tests/res/templates/foo/test.html diff --git a/deps/v8_inspector/deps/jinja2/tests/res/templates/syntaxerror.html b/deps/v8_inspector/third_party/jinja2/tests/res/templates/syntaxerror.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/res/templates/syntaxerror.html rename to deps/v8_inspector/third_party/jinja2/tests/res/templates/syntaxerror.html diff --git a/deps/v8_inspector/deps/jinja2/tests/res/templates/test.html b/deps/v8_inspector/third_party/jinja2/tests/res/templates/test.html similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/res/templates/test.html rename to deps/v8_inspector/third_party/jinja2/tests/res/templates/test.html diff --git a/deps/v8_inspector/deps/jinja2/tests/test_api.py b/deps/v8_inspector/third_party/jinja2/tests/test_api.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_api.py rename to deps/v8_inspector/third_party/jinja2/tests/test_api.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_bytecode_cache.py b/deps/v8_inspector/third_party/jinja2/tests/test_bytecode_cache.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_bytecode_cache.py rename to deps/v8_inspector/third_party/jinja2/tests/test_bytecode_cache.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_core_tags.py b/deps/v8_inspector/third_party/jinja2/tests/test_core_tags.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_core_tags.py rename to deps/v8_inspector/third_party/jinja2/tests/test_core_tags.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_debug.py b/deps/v8_inspector/third_party/jinja2/tests/test_debug.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_debug.py rename to deps/v8_inspector/third_party/jinja2/tests/test_debug.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_ext.py b/deps/v8_inspector/third_party/jinja2/tests/test_ext.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_ext.py rename to deps/v8_inspector/third_party/jinja2/tests/test_ext.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_filters.py b/deps/v8_inspector/third_party/jinja2/tests/test_filters.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_filters.py rename to deps/v8_inspector/third_party/jinja2/tests/test_filters.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_imports.py b/deps/v8_inspector/third_party/jinja2/tests/test_imports.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_imports.py rename to deps/v8_inspector/third_party/jinja2/tests/test_imports.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_inheritance.py b/deps/v8_inspector/third_party/jinja2/tests/test_inheritance.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_inheritance.py rename to deps/v8_inspector/third_party/jinja2/tests/test_inheritance.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_lexnparse.py b/deps/v8_inspector/third_party/jinja2/tests/test_lexnparse.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_lexnparse.py rename to deps/v8_inspector/third_party/jinja2/tests/test_lexnparse.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_loader.py b/deps/v8_inspector/third_party/jinja2/tests/test_loader.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_loader.py rename to deps/v8_inspector/third_party/jinja2/tests/test_loader.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_regression.py b/deps/v8_inspector/third_party/jinja2/tests/test_regression.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_regression.py rename to deps/v8_inspector/third_party/jinja2/tests/test_regression.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_security.py b/deps/v8_inspector/third_party/jinja2/tests/test_security.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_security.py rename to deps/v8_inspector/third_party/jinja2/tests/test_security.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_tests.py b/deps/v8_inspector/third_party/jinja2/tests/test_tests.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_tests.py rename to deps/v8_inspector/third_party/jinja2/tests/test_tests.py diff --git a/deps/v8_inspector/deps/jinja2/tests/test_utils.py b/deps/v8_inspector/third_party/jinja2/tests/test_utils.py similarity index 100% rename from deps/v8_inspector/deps/jinja2/tests/test_utils.py rename to deps/v8_inspector/third_party/jinja2/tests/test_utils.py diff --git a/deps/v8_inspector/deps/jinja2/tox.ini b/deps/v8_inspector/third_party/jinja2/tox.ini similarity index 100% rename from deps/v8_inspector/deps/jinja2/tox.ini rename to deps/v8_inspector/third_party/jinja2/tox.ini diff --git a/deps/v8_inspector/deps/markupsafe/.gitignore b/deps/v8_inspector/third_party/markupsafe/.gitignore similarity index 100% rename from deps/v8_inspector/deps/markupsafe/.gitignore rename to deps/v8_inspector/third_party/markupsafe/.gitignore diff --git a/deps/v8_inspector/deps/markupsafe/.travis.yml b/deps/v8_inspector/third_party/markupsafe/.travis.yml similarity index 100% rename from deps/v8_inspector/deps/markupsafe/.travis.yml rename to deps/v8_inspector/third_party/markupsafe/.travis.yml diff --git a/deps/v8_inspector/deps/markupsafe/AUTHORS b/deps/v8_inspector/third_party/markupsafe/AUTHORS similarity index 100% rename from deps/v8_inspector/deps/markupsafe/AUTHORS rename to deps/v8_inspector/third_party/markupsafe/AUTHORS diff --git a/deps/v8_inspector/deps/markupsafe/CHANGES b/deps/v8_inspector/third_party/markupsafe/CHANGES similarity index 100% rename from deps/v8_inspector/deps/markupsafe/CHANGES rename to deps/v8_inspector/third_party/markupsafe/CHANGES diff --git a/deps/v8_inspector/deps/markupsafe/LICENSE b/deps/v8_inspector/third_party/markupsafe/LICENSE similarity index 100% rename from deps/v8_inspector/deps/markupsafe/LICENSE rename to deps/v8_inspector/third_party/markupsafe/LICENSE diff --git a/deps/v8_inspector/deps/markupsafe/MANIFEST.in b/deps/v8_inspector/third_party/markupsafe/MANIFEST.in similarity index 100% rename from deps/v8_inspector/deps/markupsafe/MANIFEST.in rename to deps/v8_inspector/third_party/markupsafe/MANIFEST.in diff --git a/deps/v8_inspector/deps/markupsafe/Makefile b/deps/v8_inspector/third_party/markupsafe/Makefile similarity index 100% rename from deps/v8_inspector/deps/markupsafe/Makefile rename to deps/v8_inspector/third_party/markupsafe/Makefile diff --git a/deps/v8_inspector/deps/markupsafe/README.rst b/deps/v8_inspector/third_party/markupsafe/README.rst similarity index 100% rename from deps/v8_inspector/deps/markupsafe/README.rst rename to deps/v8_inspector/third_party/markupsafe/README.rst diff --git a/deps/v8_inspector/deps/markupsafe/bench/bench_basic.py b/deps/v8_inspector/third_party/markupsafe/bench/bench_basic.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/bench/bench_basic.py rename to deps/v8_inspector/third_party/markupsafe/bench/bench_basic.py diff --git a/deps/v8_inspector/deps/markupsafe/bench/bench_largestring.py b/deps/v8_inspector/third_party/markupsafe/bench/bench_largestring.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/bench/bench_largestring.py rename to deps/v8_inspector/third_party/markupsafe/bench/bench_largestring.py diff --git a/deps/v8_inspector/deps/markupsafe/bench/bench_long_empty_string.py b/deps/v8_inspector/third_party/markupsafe/bench/bench_long_empty_string.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/bench/bench_long_empty_string.py rename to deps/v8_inspector/third_party/markupsafe/bench/bench_long_empty_string.py diff --git a/deps/v8_inspector/deps/markupsafe/bench/bench_long_suffix.py b/deps/v8_inspector/third_party/markupsafe/bench/bench_long_suffix.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/bench/bench_long_suffix.py rename to deps/v8_inspector/third_party/markupsafe/bench/bench_long_suffix.py diff --git a/deps/v8_inspector/deps/markupsafe/bench/bench_short_empty_string.py b/deps/v8_inspector/third_party/markupsafe/bench/bench_short_empty_string.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/bench/bench_short_empty_string.py rename to deps/v8_inspector/third_party/markupsafe/bench/bench_short_empty_string.py diff --git a/deps/v8_inspector/deps/markupsafe/bench/runbench.py b/deps/v8_inspector/third_party/markupsafe/bench/runbench.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/bench/runbench.py rename to deps/v8_inspector/third_party/markupsafe/bench/runbench.py diff --git a/deps/v8_inspector/deps/markupsafe/markupsafe/__init__.py b/deps/v8_inspector/third_party/markupsafe/markupsafe/__init__.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/markupsafe/__init__.py rename to deps/v8_inspector/third_party/markupsafe/markupsafe/__init__.py diff --git a/deps/v8_inspector/deps/markupsafe/markupsafe/_compat.py b/deps/v8_inspector/third_party/markupsafe/markupsafe/_compat.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/markupsafe/_compat.py rename to deps/v8_inspector/third_party/markupsafe/markupsafe/_compat.py diff --git a/deps/v8_inspector/deps/markupsafe/markupsafe/_constants.py b/deps/v8_inspector/third_party/markupsafe/markupsafe/_constants.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/markupsafe/_constants.py rename to deps/v8_inspector/third_party/markupsafe/markupsafe/_constants.py diff --git a/deps/v8_inspector/deps/markupsafe/markupsafe/_native.py b/deps/v8_inspector/third_party/markupsafe/markupsafe/_native.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/markupsafe/_native.py rename to deps/v8_inspector/third_party/markupsafe/markupsafe/_native.py diff --git a/deps/v8_inspector/deps/markupsafe/markupsafe/_speedups.c b/deps/v8_inspector/third_party/markupsafe/markupsafe/_speedups.c similarity index 100% rename from deps/v8_inspector/deps/markupsafe/markupsafe/_speedups.c rename to deps/v8_inspector/third_party/markupsafe/markupsafe/_speedups.c diff --git a/deps/v8_inspector/deps/markupsafe/markupsafe/tests.py b/deps/v8_inspector/third_party/markupsafe/markupsafe/tests.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/markupsafe/tests.py rename to deps/v8_inspector/third_party/markupsafe/markupsafe/tests.py diff --git a/deps/v8_inspector/deps/markupsafe/setup.py b/deps/v8_inspector/third_party/markupsafe/setup.py similarity index 100% rename from deps/v8_inspector/deps/markupsafe/setup.py rename to deps/v8_inspector/third_party/markupsafe/setup.py diff --git a/deps/v8_inspector/deps/markupsafe/tox.ini b/deps/v8_inspector/third_party/markupsafe/tox.ini similarity index 100% rename from deps/v8_inspector/deps/markupsafe/tox.ini rename to deps/v8_inspector/third_party/markupsafe/tox.ini diff --git a/deps/v8_inspector/third_party/v8_inspector/LICENSE b/deps/v8_inspector/third_party/v8_inspector/LICENSE new file mode 100644 index 00000000000000..a32e00ce6be362 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/LICENSE @@ -0,0 +1,27 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/deps/v8_inspector/platform/inspector_protocol/Allocator.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Allocator.h similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/Allocator.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Allocator.h diff --git a/deps/v8_inspector/platform/inspector_protocol/Array.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Array.h similarity index 87% rename from deps/v8_inspector/platform/inspector_protocol/Array.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Array.h index b75f51742977c7..d92af3a5ed7d05 100644 --- a/deps/v8_inspector/platform/inspector_protocol/Array.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Array.h @@ -5,13 +5,14 @@ #ifndef Array_h #define Array_h -#include "platform/inspector_protocol/Collections.h" #include "platform/inspector_protocol/ErrorSupport.h" #include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" #include "platform/inspector_protocol/ValueConversions.h" #include "platform/inspector_protocol/Values.h" +#include + namespace blink { namespace protocol { @@ -33,9 +34,9 @@ class ArrayBase { errors->push(); std::unique_ptr> result(new Array()); for (size_t i = 0; i < array->size(); ++i) { - errors->setName(String16::number(i)); + errors->setName(String16::fromInteger(i)); T item = FromValue::parse(array->at(i), errors); - result->m_vector.append(item); + result->m_vector.push_back(item); } errors->pop(); if (errors->hasErrors()) @@ -45,7 +46,7 @@ class ArrayBase { void addItem(const T& value) { - m_vector.append(value); + m_vector.push_back(value); } size_t length() @@ -67,7 +68,7 @@ class ArrayBase { } private: - protocol::Vector m_vector; + std::vector m_vector; }; template<> class Array : public ArrayBase {}; @@ -94,9 +95,9 @@ class Array { std::unique_ptr> result(new Array()); errors->push(); for (size_t i = 0; i < array->size(); ++i) { - errors->setName(String16::number(i)); + errors->setName(String16::fromInteger(i)); std::unique_ptr item = FromValue::parse(array->at(i), errors); - result->m_vector.append(std::move(item)); + result->m_vector.push_back(std::move(item)); } errors->pop(); if (errors->hasErrors()) @@ -106,7 +107,7 @@ class Array { void addItem(std::unique_ptr value) { - m_vector.append(std::move(value)); + m_vector.push_back(std::move(value)); } size_t length() @@ -116,7 +117,7 @@ class Array { T* get(size_t index) { - return m_vector[index]; + return m_vector[index].get(); } std::unique_ptr serialize() @@ -128,7 +129,7 @@ class Array { } private: - protocol::Vector> m_vector; + std::vector> m_vector; }; } // namespace platform diff --git a/deps/v8_inspector/platform/inspector_protocol/BackendCallback.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/BackendCallback.h similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/BackendCallback.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/BackendCallback.h diff --git a/deps/v8_inspector/platform/inspector_protocol/CodeGenerator.py b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/CodeGenerator.py similarity index 98% rename from deps/v8_inspector/platform/inspector_protocol/CodeGenerator.py rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/CodeGenerator.py index 4c11161a3cad63..c785c79b528fd1 100644 --- a/deps/v8_inspector/platform/inspector_protocol/CodeGenerator.py +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/CodeGenerator.py @@ -25,13 +25,15 @@ # Insert at 1 so at front to override system libraries, and # after path[0] == invoking script dir third_party_dir = os.path.normpath(os.path.join( - module_path, os.pardir, os.pardir, os.pardir, os.pardir)) + module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, + "third_party")) if os.path.isdir(third_party_dir): sys.path.insert(1, third_party_dir) # In Node, it is in deps folder deps_dir = os.path.normpath(os.path.join( - module_path, os.pardir, os.pardir, "deps")) + module_path, os.pardir, os.pardir, os.pardir, os.pardir, "third_party")) + if os.path.isdir(deps_dir): sys.path.insert(1, os.path.join(deps_dir, "jinja2")) sys.path.insert(1, os.path.join(deps_dir, "markupsafe")) @@ -215,8 +217,8 @@ def create_primitive_type_definition(type): "boolean": "false" } jsontypes = { - "number": "TypeNumber", - "integer": "TypeNumber", + "number": "TypeDouble", + "integer": "TypeInteger", "boolean": "TypeBoolean", } return { diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Collections.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Collections.h new file mode 100644 index 00000000000000..a89bef413811e3 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Collections.h @@ -0,0 +1,46 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef Collections_h +#define Collections_h + +#include + +#if defined(__APPLE__) && !defined(_LIBCPP_VERSION) +#include +#include + +namespace blink { +namespace protocol { + +template using HashMap = std::map; +template using HashSet = std::set; + +} // namespace protocol +} // namespace blink + +#else +#include +#include + +namespace blink { +namespace protocol { + +template using HashMap = std::unordered_map; +template using HashSet = std::unordered_set; + +} // namespace protocol +} // namespace blink + +#endif // defined(__APPLE__) && !defined(_LIBCPP_VERSION) + +// Macro that returns a compile time constant with the length of an array, but gives an error if passed a non-array. +template char (&ArrayLengthHelperFunction(T (&)[Size]))[Size]; +// GCC needs some help to deduce a 0 length array. +#if defined(__GNUC__) +template char (&ArrayLengthHelperFunction(T (&)[0]))[0]; +#endif +#define PROTOCOL_ARRAY_LENGTH(array) sizeof(::ArrayLengthHelperFunction(array)) + +#endif // !defined(Collections_h) diff --git a/deps/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp similarity index 94% rename from deps/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp index 69798726515c11..49422eba09a9ca 100644 --- a/deps/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp @@ -18,7 +18,7 @@ DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(disp DispatcherBase::WeakPtr::~WeakPtr() { if (m_dispatcher) - m_dispatcher->m_weakPtrs.remove(this); + m_dispatcher->m_weakPtrs.erase(this); } DispatcherBase::Callback::Callback(std::unique_ptr backendImpl, int callId) @@ -73,7 +73,7 @@ void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError } std::unique_ptr responseMessage = DictionaryValue::create(); - responseMessage->setNumber("id", callId); + responseMessage->setInteger("id", callId); responseMessage->setObject("result", std::move(result)); if (m_frontendChannel) m_frontendChannel->sendProtocolResponse(callId, responseMessage->toJSONString()); @@ -92,14 +92,14 @@ void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError static void reportProtocolError(FrontendChannel* frontendChannel, int callId, DispatcherBase::CommonErrorCode code, const String16& errorMessage, ErrorSupport* errors) { std::unique_ptr error = DictionaryValue::create(); - error->setNumber("code", code); + error->setInteger("code", code); error->setString("message", errorMessage); DCHECK(error); if (errors && errors->hasErrors()) error->setString("data", errors->errors()); std::unique_ptr message = DictionaryValue::create(); message->setObject("error", std::move(error)); - message->setNumber("id", callId); + message->setInteger("id", callId); frontendChannel->sendProtocolResponse(callId, message->toJSONString()); } @@ -113,14 +113,14 @@ void DispatcherBase::clearFrontend() { m_frontendChannel = nullptr; for (auto& weak : m_weakPtrs) - weak.first->dispose(); + weak->dispose(); m_weakPtrs.clear(); } std::unique_ptr DispatcherBase::weakPtr() { std::unique_ptr weak(new DispatcherBase::WeakPtr(this)); - m_weakPtrs.add(weak.get()); + m_weakPtrs.insert(weak.get()); return weak; } @@ -129,7 +129,7 @@ UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel) void UberDispatcher::registerBackend(const String16& name, std::unique_ptr dispatcher) { - m_dispatchers.set(name, std::move(dispatcher)); + m_dispatchers[name] = std::move(dispatcher); } void UberDispatcher::dispatch(const String16& message) @@ -143,7 +143,7 @@ void UberDispatcher::dispatch(const String16& message) int callId = 0; protocol::Value* callIdValue = messageObject->get("id"); - bool success = callIdValue->asNumber(&callId); + bool success = callIdValue->asInteger(&callId); if (!success) return; diff --git a/deps/v8_inspector/platform/inspector_protocol/DispatcherBase.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/DispatcherBase.h similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/DispatcherBase.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/DispatcherBase.h diff --git a/deps/v8_inspector/platform/inspector_protocol/ErrorSupport.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ErrorSupport.cpp similarity index 91% rename from deps/v8_inspector/platform/inspector_protocol/ErrorSupport.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ErrorSupport.cpp index dc9e66373ee271..0ad89ade1c47d0 100644 --- a/deps/v8_inspector/platform/inspector_protocol/ErrorSupport.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ErrorSupport.cpp @@ -29,12 +29,12 @@ void ErrorSupport::setName(const String16& name) void ErrorSupport::push() { - m_path.append(String16()); + m_path.push_back(String16()); } void ErrorSupport::pop() { - m_path.removeLast(); + m_path.pop_back(); } void ErrorSupport::addError(const String16& error) @@ -42,12 +42,12 @@ void ErrorSupport::addError(const String16& error) String16Builder builder; for (size_t i = 0; i < m_path.size(); ++i) { if (i) - builder.append("."); + builder.append('.'); builder.append(m_path[i]); } builder.append(": "); builder.append(error); - m_errors.append(builder.toString()); + m_errors.push_back(builder.toString()); } bool ErrorSupport::hasErrors() diff --git a/deps/v8_inspector/platform/inspector_protocol/ErrorSupport.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ErrorSupport.h similarity index 86% rename from deps/v8_inspector/platform/inspector_protocol/ErrorSupport.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ErrorSupport.h index bb7e064934b01f..56ac442435262b 100644 --- a/deps/v8_inspector/platform/inspector_protocol/ErrorSupport.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ErrorSupport.h @@ -5,10 +5,11 @@ #ifndef ErrorSupport_h #define ErrorSupport_h -#include "platform/inspector_protocol/Collections.h" #include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" +#include + namespace blink { namespace protocol { @@ -28,8 +29,8 @@ class PLATFORM_EXPORT ErrorSupport { String16 errors(); private: - protocol::Vector m_path; - protocol::Vector m_errors; + std::vector m_path; + std::vector m_errors; String16* m_errorString; }; diff --git a/deps/v8_inspector/platform/inspector_protocol/FrontendChannel.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/FrontendChannel.h similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/FrontendChannel.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/FrontendChannel.h diff --git a/deps/v8_inspector/platform/inspector_protocol/Maybe.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Maybe.h similarity index 98% rename from deps/v8_inspector/platform/inspector_protocol/Maybe.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Maybe.h index 3fcd081d89f12a..cf372e0bbe2015 100644 --- a/deps/v8_inspector/platform/inspector_protocol/Maybe.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Maybe.h @@ -18,7 +18,7 @@ class String16; template class Maybe { public: - Maybe() { } + Maybe() : m_value() { } Maybe(std::unique_ptr value) : m_value(std::move(value)) { } void operator=(std::unique_ptr value) { m_value = std::move(value); } T* fromJust() const { DCHECK(m_value); return m_value.get(); } diff --git a/deps/v8_inspector/platform/inspector_protocol/OWNERS b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/OWNERS similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/OWNERS rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/OWNERS diff --git a/deps/v8_inspector/platform/inspector_protocol/Object.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Object.cpp similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/Object.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Object.cpp diff --git a/deps/v8_inspector/platform/inspector_protocol/Object.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Object.h similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/Object.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Object.h diff --git a/deps/v8_inspector/platform/inspector_protocol/Parser.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Parser.cpp similarity index 98% rename from deps/v8_inspector/platform/inspector_protocol/Parser.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Parser.cpp index 1c267f871a96b2..4193108b279162 100644 --- a/deps/v8_inspector/platform/inspector_protocol/Parser.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Parser.cpp @@ -382,7 +382,11 @@ std::unique_ptr buildValue(const UChar* start, const UChar* end, const UC double value = String16::charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok); if (!ok) return nullptr; - result = FundamentalValue::create(value); + int number = static_cast(value); + if (number == value) + result = FundamentalValue::create(number); + else + result = FundamentalValue::create(value); break; } case StringLiteral: { diff --git a/deps/v8_inspector/platform/inspector_protocol/Parser.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Parser.h similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/Parser.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Parser.h diff --git a/deps/v8_inspector/platform/inspector_protocol/ParserTest.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ParserTest.cpp similarity index 88% rename from deps/v8_inspector/platform/inspector_protocol/ParserTest.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ParserTest.cpp index 1dfeb4a4fbb983..1a8f44289f2a7b 100644 --- a/deps/v8_inspector/platform/inspector_protocol/ParserTest.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ParserTest.cpp @@ -41,13 +41,13 @@ TEST(ParserTest, Reading) EXPECT_EQ(Value::TypeNull, root->type()); root = parseJSON("40 /* comment */"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); - EXPECT_TRUE(root->asNumber(&intVal)); + EXPECT_EQ(Value::TypeInteger, root->type()); + EXPECT_TRUE(root->asInteger(&intVal)); EXPECT_EQ(40, intVal); root = parseJSON("/**/ 40 /* multi-line\n comment */ // more comment"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); - EXPECT_TRUE(root->asNumber(&intVal)); + EXPECT_EQ(Value::TypeInteger, root->type()); + EXPECT_TRUE(root->asInteger(&intVal)); EXPECT_EQ(40, intVal); root = parseJSON("true // comment"); ASSERT_TRUE(root.get()); @@ -63,11 +63,11 @@ TEST(ParserTest, Reading) EXPECT_EQ(2u, list->size()); tmpValue = list->at(0); ASSERT_TRUE(tmpValue); - EXPECT_TRUE(tmpValue->asNumber(&intVal)); + EXPECT_TRUE(tmpValue->asInteger(&intVal)); EXPECT_EQ(1, intVal); tmpValue = list->at(1); ASSERT_TRUE(tmpValue); - EXPECT_TRUE(tmpValue->asNumber(&intVal)); + EXPECT_TRUE(tmpValue->asInteger(&intVal)); EXPECT_EQ(3, intVal); root = parseJSON("[1, /*a*/2, 3]"); ASSERT_TRUE(root.get()); @@ -76,23 +76,23 @@ TEST(ParserTest, Reading) EXPECT_EQ(3u, list->size()); root = parseJSON("/* comment **/42"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); - EXPECT_TRUE(root->asNumber(&intVal)); + EXPECT_EQ(Value::TypeInteger, root->type()); + EXPECT_TRUE(root->asInteger(&intVal)); EXPECT_EQ(42, intVal); root = parseJSON( "/* comment **/\n" "// */ 43\n" "44"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); - EXPECT_TRUE(root->asNumber(&intVal)); + EXPECT_EQ(Value::TypeInteger, root->type()); + EXPECT_TRUE(root->asInteger(&intVal)); EXPECT_EQ(44, intVal); // Test number formats root = parseJSON("43"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); - EXPECT_TRUE(root->asNumber(&intVal)); + EXPECT_EQ(Value::TypeInteger, root->type()); + EXPECT_TRUE(root->asInteger(&intVal)); EXPECT_EQ(43, intVal); // According to RFC4627, oct, hex, and leading zeros are invalid JSON. @@ -107,9 +107,9 @@ TEST(ParserTest, Reading) // clause). root = parseJSON("0"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); + EXPECT_EQ(Value::TypeInteger, root->type()); intVal = 1; - EXPECT_TRUE(root->asNumber(&intVal)); + EXPECT_TRUE(root->asInteger(&intVal)); EXPECT_EQ(0, intVal); // Numbers that overflow ints should succeed, being internally promoted to @@ -117,58 +117,58 @@ TEST(ParserTest, Reading) root = parseJSON("2147483648"); ASSERT_TRUE(root.get()); double doubleVal; - EXPECT_EQ(Value::TypeNumber, root->type()); + EXPECT_EQ(Value::TypeDouble, root->type()); doubleVal = 0.0; - EXPECT_TRUE(root->asNumber(&doubleVal)); + EXPECT_TRUE(root->asDouble(&doubleVal)); EXPECT_DOUBLE_EQ(2147483648.0, doubleVal); root = parseJSON("-2147483649"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); + EXPECT_EQ(Value::TypeDouble, root->type()); doubleVal = 0.0; - EXPECT_TRUE(root->asNumber(&doubleVal)); + EXPECT_TRUE(root->asDouble(&doubleVal)); EXPECT_DOUBLE_EQ(-2147483649.0, doubleVal); // Parse a double root = parseJSON("43.1"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); + EXPECT_EQ(Value::TypeDouble, root->type()); doubleVal = 0.0; - EXPECT_TRUE(root->asNumber(&doubleVal)); + EXPECT_TRUE(root->asDouble(&doubleVal)); EXPECT_DOUBLE_EQ(43.1, doubleVal); root = parseJSON("4.3e-1"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); + EXPECT_EQ(Value::TypeDouble, root->type()); doubleVal = 0.0; - EXPECT_TRUE(root->asNumber(&doubleVal)); + EXPECT_TRUE(root->asDouble(&doubleVal)); EXPECT_DOUBLE_EQ(.43, doubleVal); root = parseJSON("2.1e0"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); + EXPECT_EQ(Value::TypeDouble, root->type()); doubleVal = 0.0; - EXPECT_TRUE(root->asNumber(&doubleVal)); + EXPECT_TRUE(root->asDouble(&doubleVal)); EXPECT_DOUBLE_EQ(2.1, doubleVal); root = parseJSON("2.1e+0001"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); + EXPECT_EQ(Value::TypeInteger, root->type()); doubleVal = 0.0; - EXPECT_TRUE(root->asNumber(&doubleVal)); + EXPECT_TRUE(root->asDouble(&doubleVal)); EXPECT_DOUBLE_EQ(21.0, doubleVal); root = parseJSON("0.01"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); + EXPECT_EQ(Value::TypeDouble, root->type()); doubleVal = 0.0; - EXPECT_TRUE(root->asNumber(&doubleVal)); + EXPECT_TRUE(root->asDouble(&doubleVal)); EXPECT_DOUBLE_EQ(0.01, doubleVal); root = parseJSON("1.00"); ASSERT_TRUE(root.get()); - EXPECT_EQ(Value::TypeNumber, root->type()); + EXPECT_EQ(Value::TypeInteger, root->type()); doubleVal = 0.0; - EXPECT_TRUE(root->asNumber(&doubleVal)); + EXPECT_TRUE(root->asDouble(&doubleVal)); EXPECT_DOUBLE_EQ(1.0, doubleVal); // Fractional parts must have a digit before and after the decimal point. @@ -312,7 +312,7 @@ TEST(ParserTest, Reading) protocol::DictionaryValue* objectVal = DictionaryValue::cast(root.get()); ASSERT_TRUE(objectVal); doubleVal = 0.0; - EXPECT_TRUE(objectVal->getNumber("number", &doubleVal)); + EXPECT_TRUE(objectVal->getDouble("number", &doubleVal)); EXPECT_DOUBLE_EQ(9.87654321, doubleVal); protocol::Value* nullVal = objectVal->get("null"); ASSERT_TRUE(nullVal); @@ -363,14 +363,14 @@ TEST(ParserTest, Reading) objectVal = DictionaryValue::cast(root.get()); ASSERT_TRUE(objectVal); int integerValue = 0; - EXPECT_TRUE(objectVal->getNumber("a.b", &integerValue)); + EXPECT_TRUE(objectVal->getInteger("a.b", &integerValue)); EXPECT_EQ(3, integerValue); - EXPECT_TRUE(objectVal->getNumber("c", &integerValue)); + EXPECT_TRUE(objectVal->getInteger("c", &integerValue)); EXPECT_EQ(2, integerValue); innerObject = objectVal->getObject("d.e.f"); ASSERT_TRUE(innerObject); EXPECT_EQ(1U, innerObject->size()); - EXPECT_TRUE(innerObject->getNumber("g.h.i.j", &integerValue)); + EXPECT_TRUE(innerObject->getInteger("g.h.i.j", &integerValue)); EXPECT_EQ(1, integerValue); root = parseJSON("{\"a\":{\"b\":2},\"a.b\":1}"); @@ -380,9 +380,9 @@ TEST(ParserTest, Reading) ASSERT_TRUE(objectVal); innerObject = objectVal->getObject("a"); ASSERT_TRUE(innerObject); - EXPECT_TRUE(innerObject->getNumber("b", &integerValue)); + EXPECT_TRUE(innerObject->getInteger("b", &integerValue)); EXPECT_EQ(2, integerValue); - EXPECT_TRUE(objectVal->getNumber("a.b", &integerValue)); + EXPECT_TRUE(objectVal->getInteger("a.b", &integerValue)); EXPECT_EQ(1, integerValue); // Invalid, no closing brace @@ -469,7 +469,7 @@ TEST(ParserTest, Reading) root = parseJSON("10"); ASSERT_TRUE(root.get()); - EXPECT_TRUE(root->asNumber(&integerValue)); + EXPECT_TRUE(root->asInteger(&integerValue)); EXPECT_EQ(10, integerValue); root = parseJSON("\"root\""); diff --git a/deps/v8_inspector/platform/inspector_protocol/Platform.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Platform.h similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/Platform.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Platform.h diff --git a/deps/v8_inspector/platform/inspector_protocol/PlatformSTL.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/PlatformSTL.h similarity index 90% rename from deps/v8_inspector/platform/inspector_protocol/PlatformSTL.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/PlatformSTL.h index 3e687b994c951e..33ca199b1f4e3b 100644 --- a/deps/v8_inspector/platform/inspector_protocol/PlatformSTL.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/PlatformSTL.h @@ -122,6 +122,7 @@ template class unique_ptr { unique_ptr() : m_ptr(nullptr) {} unique_ptr(std::nullptr_t) : m_ptr(nullptr) {} + unique_ptr(const unique_ptr&); unique_ptr(unique_ptr&&); template ::value>::type> unique_ptr(unique_ptr&&); @@ -134,7 +135,10 @@ template class unique_ptr { PtrType get() const { return m_ptr; } void reset(PtrType = nullptr); - PtrType release(); + PtrType release() + { + return this->internalRelease(); + } ValueType& operator*() const { DCHECK(m_ptr); return *m_ptr; } PtrType operator->() const { DCHECK(m_ptr); return m_ptr; } @@ -146,7 +150,7 @@ template class unique_ptr { unique_ptr& operator=(std::nullptr_t) { reset(); return *this; } - + unique_ptr& operator=(const unique_ptr&); unique_ptr& operator=(unique_ptr&&); template unique_ptr& operator=(unique_ptr&&); @@ -157,6 +161,12 @@ template class unique_ptr { explicit unique_ptr(PtrType ptr) : m_ptr(ptr) {} private: + PtrType internalRelease() const + { + PtrType ptr = m_ptr; + m_ptr = nullptr; + return ptr; + } // We should never have two unique_ptrs for the same underlying object // (otherwise we'll get double-destruction), so these equality operators @@ -172,7 +182,7 @@ template class unique_ptr { return false; } - PtrType m_ptr; + mutable PtrType m_ptr; }; @@ -180,16 +190,10 @@ template inline void unique_ptr::reset(PtrType ptr) { PtrType p = m_ptr; m_ptr = ptr; + DCHECK(!p || m_ptr != p); OwnedPtrDeleter::deletePtr(p); } -template inline typename unique_ptr::PtrType unique_ptr::release() -{ - PtrType ptr = m_ptr; - m_ptr = nullptr; - return ptr; -} - template inline typename unique_ptr::ValueType& unique_ptr::operator[](std::ptrdiff_t i) const { static_assert(is_array::value, "elements access is possible for arrays only"); @@ -198,8 +202,13 @@ template inline typename unique_ptr::ValueType& unique_ptr::o return m_ptr[i]; } +template inline unique_ptr::unique_ptr(const unique_ptr& o) + : m_ptr(o.internalRelease()) +{ +} + template inline unique_ptr::unique_ptr(unique_ptr&& o) - : m_ptr(o.release()) + : m_ptr(o.internalRelease()) { } @@ -210,13 +219,15 @@ template inline unique_ptr::unique_ptr(unique_ptr&& static_assert(!is_array::value, "pointers to array must never be converted"); } -template inline unique_ptr& unique_ptr::operator=(unique_ptr&& o) +template inline unique_ptr& unique_ptr::operator=(const unique_ptr& o) { - PtrType ptr = m_ptr; - m_ptr = o.release(); - DCHECK(!ptr || m_ptr != ptr); - OwnedPtrDeleter::deletePtr(ptr); + reset(o.internalRelease()); + return *this; +} +template inline unique_ptr& unique_ptr::operator=(unique_ptr&& o) +{ + reset(o.internalRelease()); return *this; } diff --git a/deps/v8_inspector/platform/inspector_protocol/PlatformWTF.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/PlatformWTF.h similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/PlatformWTF.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/PlatformWTF.h diff --git a/deps/v8_inspector/platform/inspector_protocol/String16.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16.h similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/String16.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16.h diff --git a/deps/v8_inspector/platform/inspector_protocol/String16STL.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.cpp similarity index 98% rename from deps/v8_inspector/platform/inspector_protocol/String16STL.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.cpp index 08c3e448c3b294..4883f4ceda46e1 100644 --- a/deps/v8_inspector/platform/inspector_protocol/String16STL.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.cpp @@ -562,20 +562,14 @@ std::string String16::utf8() const char* buffer = bufferVector.data(); const UChar* characters = m_impl.data(); - bool strict = false; - ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), strict); + ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), false); DCHECK(result != targetExhausted); // (length * 3) should be sufficient for any conversion // Only produced from strict conversion. - if (result == sourceIllegal) { - DCHECK(strict); - return std::string(); - } + DCHECK(result != sourceIllegal); // Check for an unconverted high surrogate. if (result == sourceExhausted) { - if (strict) - return std::string(); // This should be one unpaired high surrogate. Treat it the same // was as an unpaired high surrogate would have been handled in // the middle of a string with non-strict conversion - which is diff --git a/deps/v8_inspector/platform/inspector_protocol/String16STL.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.h similarity index 91% rename from deps/v8_inspector/platform/inspector_protocol/String16STL.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.h index e76e9775fb9ebc..703e5b0f025d94 100644 --- a/deps/v8_inspector/platform/inspector_protocol/String16STL.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.h @@ -42,7 +42,7 @@ class String16 { const UChar* characters16() const { return m_impl.c_str(); } std::string utf8() const; static String16 fromUTF8(const char* stringStart, size_t length); - static String16 number(int i) { return String16(String16::intToString(i).c_str()); } + static String16 fromInteger(int i) { return String16(String16::intToString(i).c_str()); } static String16 fromDouble(double d) { return String16(String16::doubleToString(d).c_str()); } static String16 fromDoubleFixedPrecision(double d, int len) { return String16(String16::doubleToString(d).c_str()); } @@ -136,7 +136,7 @@ class String16 { // presubmit: allow wstring wstring m_impl; mutable bool has_hash = false; - mutable std::size_t hash_code; + mutable std::size_t hash_code = 0; }; static inline bool isSpaceOrNewline(UChar c) @@ -170,7 +170,12 @@ class String16Builder { void appendNumber(int i) { - m_impl = m_impl + String16::number(i).impl(); + m_impl = m_impl + String16::fromInteger(i).impl(); + } + + void appendNumber(double d) + { + m_impl = m_impl + String16::fromDoubleFixedPrecision(d, 6).impl(); } void append(const UChar* c, size_t length) @@ -238,6 +243,20 @@ class String { }; } // namespace WTF +#if !defined(__APPLE__) || defined(_LIBCPP_VERSION) + +namespace std { +template<> struct hash { + std::size_t operator()(const String16& string) const + { + return string.hash(); + } +}; + +} // namespace std + +#endif // !defined(__APPLE__) || defined(_LIBCPP_VERSION) + using String = WTF::String; #endif // !defined(String16STL_h) diff --git a/deps/v8_inspector/platform/inspector_protocol/String16WTF.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16WTF.cpp similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/String16WTF.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16WTF.cpp diff --git a/deps/v8_inspector/platform/inspector_protocol/String16WTF.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16WTF.h similarity index 91% rename from deps/v8_inspector/platform/inspector_protocol/String16WTF.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16WTF.h index 57a91d82c6f68d..19c56256f0dec4 100644 --- a/deps/v8_inspector/platform/inspector_protocol/String16WTF.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16WTF.h @@ -11,6 +11,7 @@ #include "wtf/text/StringConcatenate.h" #include "wtf/text/StringHash.h" #include "wtf/text/StringToNumber.h" +#include "wtf/text/StringView.h" #include "wtf/text/WTFString.h" namespace blink { @@ -34,13 +35,14 @@ class PLATFORM_EXPORT String16 { String16(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { } bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); } operator WTF::String() const { return m_impl; } + operator WTF::StringView() const { return StringView(m_impl); } operator WebString() { return m_impl; } const WTF::String& impl() const { return m_impl; } String16 isolatedCopy() const { return String16(m_impl.isolatedCopy()); } ~String16() { } - static String16 number(int i) { return String::number(i); } + static String16 fromInteger(int i) { return String::number(i); } static String16 fromDouble(double number) { return Decimal::fromDouble(number).toString(); } static String16 fromDoubleFixedPrecision(double number, int precision) { return String::numberToStringFixedWidth(number, precision); } @@ -75,13 +77,14 @@ class PLATFORM_EXPORT String16 { class String16Builder { public: String16Builder() { } - void append(const String16& str) { m_impl.append(StringView(str)); }; + void append(const String16& str) { m_impl.append(str); }; void append(UChar c) { m_impl.append(c); }; void append(LChar c) { m_impl.append(c); }; void append(char c) { m_impl.append(c); }; void append(const UChar* c, size_t size) { m_impl.append(c, size); }; void append(const char* characters, unsigned length) { m_impl.append(characters, length); } void appendNumber(int number) { m_impl.appendNumber(number); } + void appendNumber(double number) { m_impl.appendNumber(number); } String16 toString() { return m_impl.toString(); } void reserveCapacity(unsigned newCapacity) { m_impl.reserveCapacity(newCapacity); } @@ -138,4 +141,14 @@ struct HashTraits : SimpleClassHashTraits { } // namespace WTF +namespace std { +template<> struct hash { + std::size_t operator()(const String16& string) const + { + return StringHash::hash(string.impl()); + } +}; + +} // namespace std + #endif // !defined(String16WTF_h) diff --git a/deps/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template similarity index 98% rename from deps/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template index 1aeef458f8d4ba..909fea4e71a7ff 100644 --- a/deps/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template @@ -140,7 +140,7 @@ public: {% for command in domain.commands %} {% if "redirect" in command %}{% continue %}{% endif %} {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{% continue %}{% endif %} - m_dispatchMap.set("{{domain.domain}}.{{command.name}}", &DispatcherImpl::{{command.name}}); + m_dispatchMap["{{domain.domain}}.{{command.name}}"] = &DispatcherImpl::{{command.name}}; {% endfor %} } ~DispatcherImpl() override { } @@ -169,7 +169,7 @@ void DispatcherImpl::dispatch(int callId, const String16& method, std::unique_pt } protocol::ErrorSupport errors; - ((*this).*(*it->second))(callId, std::move(messageObject), &errors); + (this->*(it->second))(callId, std::move(messageObject), &errors); } {% for command in domain.commands %} diff --git a/deps/v8_inspector/platform/inspector_protocol/TypeBuilder_h.template b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_h.template similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/TypeBuilder_h.template rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_h.template diff --git a/deps/v8_inspector/platform/inspector_protocol/ValueConversions.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.cpp similarity index 100% rename from deps/v8_inspector/platform/inspector_protocol/ValueConversions.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.cpp diff --git a/deps/v8_inspector/platform/inspector_protocol/ValueConversions.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.h similarity index 95% rename from deps/v8_inspector/platform/inspector_protocol/ValueConversions.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.h index b82f04f588f7f1..dd7b2e78641054 100644 --- a/deps/v8_inspector/platform/inspector_protocol/ValueConversions.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.h @@ -64,7 +64,7 @@ struct FromValue { static int parse(protocol::Value* value, ErrorSupport* errors) { int result = 0; - bool success = value ? value->asNumber(&result) : false; + bool success = value ? value->asInteger(&result) : false; if (!success) errors->addError("integer value expected"); return result; @@ -76,7 +76,7 @@ struct FromValue { static double parse(protocol::Value* value, ErrorSupport* errors) { double result = 0; - bool success = value ? value->asNumber(&result) : false; + bool success = value ? value->asDouble(&result) : false; if (!success) errors->addError("double value expected"); return result; @@ -112,8 +112,10 @@ struct FromValue { static std::unique_ptr parse(protocol::Value* value, ErrorSupport* errors) { bool success = !!value; - if (!success) + if (!success) { errors->addError("value expected"); + return nullptr; + } return value->clone(); } }; diff --git a/deps/v8_inspector/platform/inspector_protocol/Values.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.cpp similarity index 72% rename from deps/v8_inspector/platform/inspector_protocol/Values.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.cpp index 9cc1ca51bf484a..7d4ec242ae4c51 100644 --- a/deps/v8_inspector/platform/inspector_protocol/Values.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.cpp @@ -6,6 +6,8 @@ #include "platform/inspector_protocol/Parser.h" #include "platform/inspector_protocol/String16.h" + +#include #include namespace blink { @@ -75,12 +77,12 @@ bool Value::asBoolean(bool*) const return false; } -bool Value::asNumber(double*) const +bool Value::asDouble(double*) const { return false; } -bool Value::asNumber(int*) const +bool Value::asInteger(int*) const { return false; } @@ -117,42 +119,56 @@ bool FundamentalValue::asBoolean(bool* output) const return true; } -bool FundamentalValue::asNumber(double* output) const +bool FundamentalValue::asDouble(double* output) const { - if (type() != TypeNumber) - return false; - *output = m_doubleValue; - return true; + if (type() == TypeDouble) { + *output = m_doubleValue; + return true; + } + if (type() == TypeInteger) { + *output = m_integerValue; + return true; + } + return false; } -bool FundamentalValue::asNumber(int* output) const +bool FundamentalValue::asInteger(int* output) const { - if (type() != TypeNumber) + if (type() != TypeInteger) return false; - *output = static_cast(m_doubleValue); + *output = m_integerValue; return true; } void FundamentalValue::writeJSON(String16Builder* output) const { - DCHECK(type() == TypeBoolean || type() == TypeNumber); + DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble); if (type() == TypeBoolean) { if (m_boolValue) output->append(trueString, 4); else output->append(falseString, 5); - } else if (type() == TypeNumber) { + } else if (type() == TypeDouble) { if (!std::isfinite(m_doubleValue)) { output->append(nullString, 4); return; } output->append(String16::fromDouble(m_doubleValue)); + } else if (type() == TypeInteger) { + output->append(String16::fromInteger(m_integerValue)); } } std::unique_ptr FundamentalValue::clone() const { - return type() == TypeNumber ? FundamentalValue::create(m_doubleValue) : FundamentalValue::create(m_boolValue); + switch (type()) { + case TypeDouble: return FundamentalValue::create(m_doubleValue); + case TypeInteger: return FundamentalValue::create(m_integerValue); + case TypeBoolean: return FundamentalValue::create(m_boolValue); + default: + NOTREACHED(); + } + return nullptr; } bool StringValue::asString(String16* output) const @@ -181,7 +197,12 @@ void DictionaryValue::setBoolean(const String16& name, bool value) setValue(name, FundamentalValue::create(value)); } -void DictionaryValue::setNumber(const String16& name, double value) +void DictionaryValue::setInteger(const String16& name, int value) +{ + setValue(name, FundamentalValue::create(value)); +} + +void DictionaryValue::setDouble(const String16& name, double value) { setValue(name, FundamentalValue::create(value)); } @@ -193,23 +214,17 @@ void DictionaryValue::setString(const String16& name, const String16& value) void DictionaryValue::setValue(const String16& name, std::unique_ptr value) { - DCHECK(value); - if (m_data.set(name, std::move(value))) - m_order.append(name); + set(name, value); } void DictionaryValue::setObject(const String16& name, std::unique_ptr value) { - DCHECK(value); - if (m_data.set(name, std::move(value))) - m_order.append(name); + set(name, value); } void DictionaryValue::setArray(const String16& name, std::unique_ptr value) { - DCHECK(value); - if (m_data.set(name, std::move(value))) - m_order.append(name); + set(name, value); } bool DictionaryValue::getBoolean(const String16& name, bool* output) const @@ -220,6 +235,22 @@ bool DictionaryValue::getBoolean(const String16& name, bool* output) const return value->asBoolean(output); } +bool DictionaryValue::getInteger(const String16& name, int* output) const +{ + Value* value = get(name); + if (!value) + return false; + return value->asInteger(output); +} + +bool DictionaryValue::getDouble(const String16& name, double* output) const +{ + Value* value = get(name); + if (!value) + return false; + return value->asDouble(output); +} + bool DictionaryValue::getString(const String16& name, String16* output) const { protocol::Value* value = get(name); @@ -243,13 +274,13 @@ protocol::Value* DictionaryValue::get(const String16& name) const Dictionary::const_iterator it = m_data.find(name); if (it == m_data.end()) return nullptr; - return it->second; + return it->second.get(); } DictionaryValue::Entry DictionaryValue::at(size_t index) const { - String16 key = m_order[index]; - return std::make_pair(key, m_data.get(key)); + const String16 key = m_order[index]; + return std::make_pair(key, m_data.find(key)->second.get()); } bool DictionaryValue::booleanProperty(const String16& name, bool defaultValue) const @@ -259,22 +290,24 @@ bool DictionaryValue::booleanProperty(const String16& name, bool defaultValue) c return result; } -double DictionaryValue::numberProperty(const String16& name, double defaultValue) const +int DictionaryValue::integerProperty(const String16& name, int defaultValue) const +{ + int result = defaultValue; + getInteger(name, &result); + return result; +} + +double DictionaryValue::doubleProperty(const String16& name, double defaultValue) const { double result = defaultValue; - getNumber(name, &result); + getDouble(name, &result); return result; } void DictionaryValue::remove(const String16& name) { - m_data.remove(name); - for (size_t i = 0; i < m_order.size(); ++i) { - if (m_order[i] == name) { - m_order.remove(i); - break; - } - } + m_data.erase(name); + m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end()); } void DictionaryValue::writeJSON(String16Builder* output) const @@ -297,9 +330,9 @@ std::unique_ptr DictionaryValue::clone() const std::unique_ptr result = DictionaryValue::create(); for (size_t i = 0; i < m_order.size(); ++i) { String16 key = m_order[i]; - Value* value = m_data.get(key); - DCHECK(value); - result->setValue(key, value->clone()); + Dictionary::const_iterator value = m_data.find(key); + DCHECK(value != m_data.cend() && value->second); + result->setValue(key, value->second->clone()); } return std::move(result); } @@ -316,10 +349,12 @@ ListValue::~ListValue() void ListValue::writeJSON(String16Builder* output) const { output->append('['); - for (Vector>::const_iterator it = m_data.begin(); it != m_data.end(); ++it) { - if (it != m_data.begin()) + bool first = true; + for (const std::unique_ptr& value : m_data) { + if (!first) output->append(','); - (*it)->writeJSON(output); + value->writeJSON(output); + first = false; } output->append(']'); } @@ -327,8 +362,8 @@ void ListValue::writeJSON(String16Builder* output) const std::unique_ptr ListValue::clone() const { std::unique_ptr result = ListValue::create(); - for (Vector>::const_iterator it = m_data.begin(); it != m_data.end(); ++it) - result->pushValue((*it)->clone()); + for (const std::unique_ptr& value : m_data) + result->pushValue(value->clone()); return std::move(result); } @@ -340,13 +375,13 @@ ListValue::ListValue() void ListValue::pushValue(std::unique_ptr value) { DCHECK(value); - m_data.append(std::move(value)); + m_data.push_back(std::move(value)); } protocol::Value* ListValue::at(size_t index) { DCHECK_LT(index, m_data.size()); - return m_data[index]; + return m_data[index].get(); } } // namespace protocol diff --git a/deps/v8_inspector/platform/inspector_protocol/Values.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.h similarity index 82% rename from deps/v8_inspector/platform/inspector_protocol/Values.h rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.h index e4a719286fb67d..07a2cac9249f47 100644 --- a/deps/v8_inspector/platform/inspector_protocol/Values.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.h @@ -10,6 +10,8 @@ #include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" +#include + namespace blink { namespace protocol { @@ -32,7 +34,8 @@ class PLATFORM_EXPORT Value { enum ValueType { TypeNull = 0, TypeBoolean, - TypeNumber, + TypeInteger, + TypeDouble, TypeString, TypeObject, TypeArray @@ -43,8 +46,8 @@ class PLATFORM_EXPORT Value { bool isNull() const { return m_type == TypeNull; } virtual bool asBoolean(bool* output) const; - virtual bool asNumber(double* output) const; - virtual bool asNumber(int* output) const; + virtual bool asDouble(double* output) const; + virtual bool asInteger(int* output) const; virtual bool asString(String16* output) const; String16 toJSONString() const; @@ -80,19 +83,20 @@ class PLATFORM_EXPORT FundamentalValue : public Value { } bool asBoolean(bool* output) const override; - bool asNumber(double* output) const override; - bool asNumber(int* output) const override; + bool asDouble(double* output) const override; + bool asInteger(int* output) const override; void writeJSON(String16Builder* output) const override; std::unique_ptr clone() const override; private: explicit FundamentalValue(bool value) : Value(TypeBoolean), m_boolValue(value) { } - explicit FundamentalValue(int value) : Value(TypeNumber), m_doubleValue((double)value) { } - explicit FundamentalValue(double value) : Value(TypeNumber), m_doubleValue(value) { } + explicit FundamentalValue(int value) : Value(TypeInteger), m_integerValue(value) { } + explicit FundamentalValue(double value) : Value(TypeDouble), m_doubleValue(value) { } union { bool m_boolValue; double m_doubleValue; + int m_integerValue; }; }; @@ -145,20 +149,16 @@ class PLATFORM_EXPORT DictionaryValue : public Value { size_t size() const { return m_data.size(); } void setBoolean(const String16& name, bool); - void setNumber(const String16& name, double); + void setInteger(const String16& name, int); + void setDouble(const String16& name, double); void setString(const String16& name, const String16&); void setValue(const String16& name, std::unique_ptr); void setObject(const String16& name, std::unique_ptr); void setArray(const String16& name, std::unique_ptr); bool getBoolean(const String16& name, bool* output) const; - template bool getNumber(const String16& name, T* output) const - { - Value* value = get(name); - if (!value) - return false; - return value->asNumber(output); - } + bool getInteger(const String16& name, int* output) const; + bool getDouble(const String16& name, double* output) const; bool getString(const String16& name, String16* output) const; DictionaryValue* getObject(const String16& name) const; @@ -167,17 +167,27 @@ class PLATFORM_EXPORT DictionaryValue : public Value { Entry at(size_t index) const; bool booleanProperty(const String16& name, bool defaultValue) const; - double numberProperty(const String16& name, double defaultValue) const; + int integerProperty(const String16& name, int defaultValue) const; + double doubleProperty(const String16& name, double defaultValue) const; void remove(const String16& name); ~DictionaryValue() override; private: DictionaryValue(); + template + void set(const String16& key, std::unique_ptr& value) + { + DCHECK(value); + bool isNew = m_data.find(key) == m_data.end(); + m_data[key] = std::move(value); + if (isNew) + m_order.push_back(key); + } using Dictionary = protocol::HashMap>; Dictionary m_data; - protocol::Vector m_order; + std::vector m_order; }; class PLATFORM_EXPORT ListValue : public Value { @@ -211,7 +221,7 @@ class PLATFORM_EXPORT ListValue : public Value { private: ListValue(); - protocol::Vector> m_data; + std::vector> m_data; }; } // namespace protocol diff --git a/deps/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version similarity index 99% rename from deps/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version rename to deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version index 65738d6f38be9c..838a3ed2dd815a 100755 --- a/deps/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version @@ -4,7 +4,7 @@ # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: -# +# # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above @@ -14,7 +14,7 @@ # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. -# +# # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -28,7 +28,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Inspector protocol validator. -# +# # Tests that subsequent protocol changes are not breaking backwards compatibility. # Following violations are reported: # @@ -39,7 +39,7 @@ # - Event has been removed # - Required event parameter was removed or changed to optional # - Parameter type has changed. -# +# # For the parameters with composite types the above checks are also applied # recursively to every property of the type. # @@ -197,7 +197,7 @@ def extract_type(typed_object, types_map, errors): ref = typed_object["$ref"] if not ref in types_map: errors.append("Can not resolve type: %s" % ref) - types_map[ref] = { "id": "", "type": "object" } + types_map[ref] = { "id": "", "type": "object" } return types_map[ref] diff --git a/deps/v8_inspector/platform/v8_inspector/Atomics.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/Atomics.h similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/Atomics.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/Atomics.h diff --git a/deps/v8_inspector/platform/v8_inspector/DebuggerScript.js b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/DebuggerScript.js similarity index 98% rename from deps/v8_inspector/platform/v8_inspector/DebuggerScript.js rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/DebuggerScript.js index 85d214e06efad6..5b534f322160f3 100644 --- a/deps/v8_inspector/platform/v8_inspector/DebuggerScript.js +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/DebuggerScript.js @@ -92,9 +92,9 @@ DebuggerScript.getFunctionScopes = function(fun) /** * @param {Object} object - * @return {?GeneratorObjectDetails} + * @return {?RawLocation} */ -DebuggerScript.getGeneratorObjectDetails = function(object) +DebuggerScript.getGeneratorObjectLocation = function(object) { var mirror = MakeMirror(object, true /* transient */); if (!mirror.isGenerator()) @@ -103,21 +103,16 @@ DebuggerScript.getGeneratorObjectDetails = function(object) var funcMirror = generatorMirror.func(); if (!funcMirror.resolved()) return null; - var result = { - "function": funcMirror.value(), - "functionName": funcMirror.debugName(), - "status": generatorMirror.status() - }; - var script = funcMirror.script(); var location = generatorMirror.sourceLocation() || funcMirror.sourceLocation(); + var script = funcMirror.script(); if (script && location) { - result["location"] = { - "scriptId": String(script.id()), - "lineNumber": location.line, - "columnNumber": location.column + return { + scriptId: "" + script.id(), + lineNumber: location.line, + columnNumber: location.column }; } - return result; + return null; } /** diff --git a/deps/v8_inspector/platform/v8_inspector/InjectedScript.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.cpp similarity index 92% rename from deps/v8_inspector/platform/v8_inspector/InjectedScript.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.cpp index 868fdeabb4a10b..302b635ed47a1b 100644 --- a/deps/v8_inspector/platform/v8_inspector/InjectedScript.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.cpp @@ -47,13 +47,9 @@ #include "platform/v8_inspector/V8StringUtil.h" #include "platform/v8_inspector/public/V8Debugger.h" #include "platform/v8_inspector/public/V8DebuggerClient.h" -#include "platform/v8_inspector/public/V8ToProtocolValue.h" using blink::protocol::Array; using blink::protocol::Debugger::CallFrame; -using blink::protocol::Debugger::CollectionEntry; -using blink::protocol::Debugger::FunctionDetails; -using blink::protocol::Debugger::GeneratorObjectDetails; using blink::protocol::Runtime::PropertyDescriptor; using blink::protocol::Runtime::InternalPropertyDescriptor; using blink::protocol::Runtime::RemoteObject; @@ -149,7 +145,7 @@ void InjectedScript::releaseObject(const String16& objectId) if (!object) return; int boundId = 0; - if (!object->getNumber("id", &boundId)) + if (!object->getInteger("id", &boundId)) return; m_native->unbind(boundId); } @@ -187,7 +183,6 @@ bool InjectedScript::wrapPropertyInArray(ErrorString* errorString, v8::Localdebugger(), m_context->context(), v8Value(), "wrapObjectsInArray"); function.appendArgument(array); function.appendArgument(groupName); - function.appendArgument(canAccessInspectedWindow()); function.appendArgument(forceValueType); function.appendArgument(generatePreview); bool hadException = false; @@ -213,7 +207,6 @@ v8::MaybeLocal InjectedScript::wrapValue(ErrorString* errorString, v8 V8FunctionCall function(m_context->debugger(), m_context->context(), v8Value(), "wrapObject"); function.appendArgument(value); function.appendArgument(groupName); - function.appendArgument(canAccessInspectedWindow()); function.appendArgument(forceValueType); function.appendArgument(generatePreview); bool hadException = false; @@ -227,7 +220,6 @@ std::unique_ptr InjectedScript::wrapTable(v8::L { v8::HandleScope handles(m_context->isolate()); V8FunctionCall function(m_context->debugger(), m_context->context(), v8Value(), "wrapTable"); - function.appendArgument(canAccessInspectedWindow()); function.appendArgument(table); if (columns.IsEmpty()) function.appendArgument(false); @@ -271,14 +263,6 @@ void InjectedScript::setCustomObjectFormatterEnabled(bool enabled) DCHECK(!hadException); } -bool InjectedScript::canAccessInspectedWindow() const -{ - v8::Local callingContext = m_context->isolate()->GetCallingContext(); - if (callingContext.IsEmpty()) - return true; - return m_context->debugger()->client()->callingContextCanAccessContext(callingContext, m_context->context()); -} - v8::Local InjectedScript::v8Value() const { return m_value.Get(m_context->isolate()); @@ -322,20 +306,16 @@ v8::MaybeLocal InjectedScript::resolveCallArgument(ErrorString* error std::unique_ptr InjectedScript::createExceptionDetails(v8::Local message) { - std::unique_ptr exceptionDetailsObject = protocol::Runtime::ExceptionDetails::create().setText(toProtocolString(message->Get())).build(); - exceptionDetailsObject->setUrl(toProtocolStringWithTypeCheck(message->GetScriptResourceName())); - exceptionDetailsObject->setScriptId(String16::number(message->GetScriptOrigin().ScriptID()->Value())); - - v8::Maybe lineNumber = message->GetLineNumber(m_context->context()); - if (lineNumber.IsJust()) - exceptionDetailsObject->setLine(lineNumber.FromJust()); - v8::Maybe columnNumber = message->GetStartColumn(m_context->context()); - if (columnNumber.IsJust()) - exceptionDetailsObject->setColumn(columnNumber.FromJust()); + std::unique_ptr exceptionDetailsObject = protocol::Runtime::ExceptionDetails::create() + .setText(toProtocolString(message->Get())) + .setScriptId(String16::fromInteger(message->GetScriptOrigin().ScriptID()->Value())) + .setLineNumber(message->GetLineNumber(m_context->context()).FromMaybe(1) - 1) + .setColumnNumber(message->GetStartColumn(m_context->context()).FromMaybe(0)) + .build(); v8::Local stackTrace = message->GetStackTrace(); if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) - exceptionDetailsObject->setStack(m_context->debugger()->createStackTrace(stackTrace)->buildInspectorObject()); + exceptionDetailsObject->setStackTrace(m_context->debugger()->createStackTrace(stackTrace)->buildInspectorObject()); return exceptionDetailsObject; } @@ -414,7 +394,7 @@ void InjectedScript::Scope::ignoreExceptionsAndMuteConsole() { DCHECK(!m_ignoreExceptionsAndMuteConsole); m_ignoreExceptionsAndMuteConsole = true; - m_debugger->client()->muteConsole(); + m_debugger->client()->muteWarningsAndDeprecations(m_contextGroupId); m_previousPauseOnExceptionsState = setPauseOnExceptionsState(V8DebuggerImpl::DontPauseOnExceptions); } @@ -448,7 +428,7 @@ InjectedScript::Scope::~Scope() { if (m_ignoreExceptionsAndMuteConsole) { setPauseOnExceptionsState(m_previousPauseOnExceptionsState); - m_debugger->client()->unmuteConsole(); + m_debugger->client()->unmuteWarningsAndDeprecations(m_contextGroupId); } if (m_userGesture) m_debugger->client()->endUserGesture(); diff --git a/deps/v8_inspector/platform/v8_inspector/InjectedScript.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.h similarity index 99% rename from deps/v8_inspector/platform/v8_inspector/InjectedScript.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.h index 7dae28aba92cce..ab847ee0412906 100644 --- a/deps/v8_inspector/platform/v8_inspector/InjectedScript.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.h @@ -159,7 +159,6 @@ class InjectedScript final { private: InjectedScript(InspectedContext*, v8::Local, std::unique_ptr); - bool canAccessInspectedWindow() const; v8::Local v8Value() const; v8::MaybeLocal wrapValue(ErrorString*, v8::Local, const String16& groupName, bool forceValueType, bool generatePreview) const; v8::Local commandLineAPI(); diff --git a/deps/v8_inspector/platform/v8_inspector/InjectedScriptNative.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptNative.cpp similarity index 79% rename from deps/v8_inspector/platform/v8_inspector/InjectedScriptNative.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptNative.cpp index 89e48fcbf13cc4..4f0eff93c41aaa 100644 --- a/deps/v8_inspector/platform/v8_inspector/InjectedScriptNative.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptNative.cpp @@ -43,20 +43,21 @@ int InjectedScriptNative::bind(v8::Local value, const String16& group if (m_lastBoundObjectId <= 0) m_lastBoundObjectId = 1; int id = m_lastBoundObjectId++; - m_idToWrappedObject.set(id, wrapUnique(new v8::Global(m_isolate, value))); + m_idToWrappedObject[id] = wrapUnique(new v8::Global(m_isolate, value)); addObjectToGroup(id, groupName); return id; } void InjectedScriptNative::unbind(int id) { - m_idToWrappedObject.remove(id); - m_idToObjectGroupName.remove(id); + m_idToWrappedObject.erase(id); + m_idToObjectGroupName.erase(id); } v8::Local InjectedScriptNative::objectForId(int id) { - return m_idToWrappedObject.contains(id) ? m_idToWrappedObject.get(id)->Get(m_isolate) : v8::Local(); + auto iter = m_idToWrappedObject.find(id); + return iter != m_idToWrappedObject.end() ? iter->second->Get(m_isolate) : v8::Local(); } void InjectedScriptNative::addObjectToGroup(int objectId, const String16& groupName) @@ -65,13 +66,8 @@ void InjectedScriptNative::addObjectToGroup(int objectId, const String16& groupN return; if (objectId <= 0) return; - m_idToObjectGroupName.set(objectId, groupName); - auto it = m_nameToObjectGroup.find(groupName); - if (it == m_nameToObjectGroup.end()) { - m_nameToObjectGroup.set(groupName, protocol::Vector()); - it = m_nameToObjectGroup.find(groupName); - } - it->second->append(objectId); + m_idToObjectGroupName[objectId] = groupName; + m_nameToObjectGroup[groupName].push_back(objectId); // Creates an empty vector if key is not there } void InjectedScriptNative::releaseObjectGroup(const String16& groupName) @@ -81,16 +77,18 @@ void InjectedScriptNative::releaseObjectGroup(const String16& groupName) NameToObjectGroup::iterator groupIt = m_nameToObjectGroup.find(groupName); if (groupIt == m_nameToObjectGroup.end()) return; - for (int id : *groupIt->second) + for (int id : groupIt->second) unbind(id); - m_nameToObjectGroup.remove(groupName); + m_nameToObjectGroup.erase(groupIt); } String16 InjectedScriptNative::groupName(int objectId) const { if (objectId <= 0) return String16(); - return m_idToObjectGroupName.get(objectId); + IdToObjectGroupName::const_iterator iterator = m_idToObjectGroupName.find(objectId); + return iterator != m_idToObjectGroupName.end() ? iterator->second : String16(); } } // namespace blink + diff --git a/deps/v8_inspector/platform/v8_inspector/InjectedScriptNative.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptNative.h similarity index 93% rename from deps/v8_inspector/platform/v8_inspector/InjectedScriptNative.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptNative.h index 63d2a30f3c3165..c8082fe95edd61 100644 --- a/deps/v8_inspector/platform/v8_inspector/InjectedScriptNative.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptNative.h @@ -10,6 +10,8 @@ #include "platform/inspector_protocol/String16.h" #include +#include + namespace blink { class InjectedScriptNative final { @@ -35,7 +37,7 @@ class InjectedScriptNative final { protocol::HashMap>> m_idToWrappedObject; typedef protocol::HashMap IdToObjectGroupName; IdToObjectGroupName m_idToObjectGroupName; - typedef protocol::HashMap> NameToObjectGroup; + typedef protocol::HashMap> NameToObjectGroup; NameToObjectGroup m_nameToObjectGroup; }; diff --git a/deps/v8_inspector/platform/v8_inspector/InjectedScriptSource.js b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptSource.js similarity index 91% rename from deps/v8_inspector/platform/v8_inspector/InjectedScriptSource.js rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptSource.js index 0e0c4f8d28065b..d2b3b2725ee665 100644 --- a/deps/v8_inspector/platform/v8_inspector/InjectedScriptSource.js +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptSource.js @@ -199,6 +199,20 @@ InjectedScript.primitiveTypes = { __proto__: null } +/** + * @type {!Map} + * @const + */ +InjectedScript.closureTypes = new Map([ + ["local", "Local"], + ["closure", "Closure"], + ["catch", "Catch"], + ["block", "Block"], + ["script", "Script"], + ["with", "With Block"], + ["global", "Global"] +]); + InjectedScript.prototype = { /** * @param {*} object @@ -210,75 +224,61 @@ InjectedScript.prototype = { return InjectedScript.primitiveTypes[typeof object] && !this._isHTMLAllCollection(object); }, + /** + * @param {*} object + * @return {boolean} + */ + _shouldPassByValue: function(object) + { + return typeof object === "object" && InjectedScriptHost.subtype(object) === "internal#location"; + }, + /** * @param {*} object * @param {string} groupName - * @param {boolean} canAccessInspectedGlobalObject * @param {boolean} forceValueType * @param {boolean} generatePreview * @return {!RuntimeAgent.RemoteObject} */ - wrapObject: function(object, groupName, canAccessInspectedGlobalObject, forceValueType, generatePreview) + wrapObject: function(object, groupName, forceValueType, generatePreview) { - if (canAccessInspectedGlobalObject) - return this._wrapObject(object, groupName, forceValueType, generatePreview); - return this._fallbackWrapper(object); + return this._wrapObject(object, groupName, forceValueType, generatePreview); }, /** * @param {!Array} array * @param {string} property * @param {string} groupName - * @param {boolean} canAccessInspectedGlobalObject * @param {boolean} forceValueType * @param {boolean} generatePreview */ - wrapPropertyInArray: function(array, property, groupName, canAccessInspectedGlobalObject, forceValueType, generatePreview) + wrapPropertyInArray: function(array, property, groupName, forceValueType, generatePreview) { for (var i = 0; i < array.length; ++i) { if (typeof array[i] === "object" && property in array[i]) - array[i][property] = this.wrapObject(array[i][property], groupName, canAccessInspectedGlobalObject, forceValueType, generatePreview); + array[i][property] = this.wrapObject(array[i][property], groupName, forceValueType, generatePreview); } }, /** * @param {!Array<*>} array * @param {string} groupName - * @param {boolean} canAccessInspectedGlobalObject * @param {boolean} forceValueType * @param {boolean} generatePreview */ - wrapObjectsInArray: function(array, groupName, canAccessInspectedGlobalObject, forceValueType, generatePreview) + wrapObjectsInArray: function(array, groupName, forceValueType, generatePreview) { for (var i = 0; i < array.length; ++i) - array[i] = this.wrapObject(array[i], groupName, canAccessInspectedGlobalObject, forceValueType, generatePreview); - }, - - /** - * @param {*} object - * @return {!RuntimeAgent.RemoteObject} - */ - _fallbackWrapper: function(object) - { - var result = { __proto__: null }; - result.type = typeof object; - if (this.isPrimitiveValue(object)) - result.value = object; - else - result.description = toString(object); - return /** @type {!RuntimeAgent.RemoteObject} */ (result); + array[i] = this.wrapObject(array[i], groupName, forceValueType, generatePreview); }, /** - * @param {boolean} canAccessInspectedGlobalObject * @param {!Object} table * @param {!Array.|string|boolean} columns * @return {!RuntimeAgent.RemoteObject} */ - wrapTable: function(canAccessInspectedGlobalObject, table, columns) + wrapTable: function(table, columns) { - if (!canAccessInspectedGlobalObject) - return this._fallbackWrapper(table); var columnNames = null; if (typeof columns === "string") columns = [columns]; @@ -338,10 +338,20 @@ InjectedScript.prototype = { */ getProperties: function(object, objectGroupName, ownProperties, accessorPropertiesOnly, generatePreview) { + var subtype = this._subtype(object); + if (subtype === "internal#scope") { + // Internally, scope contains object with scope variables and additional information like type, + // we use additional information for preview and would like to report variables as scope + // properties. + object = object.object; + } + var descriptors = []; var iter = this._propertyDescriptors(object, ownProperties, accessorPropertiesOnly, undefined); // Go over properties, wrap object values. for (var descriptor of iter) { + if (subtype === "internal#scopeList" && descriptor.name === "length") + continue; if ("get" in descriptor) descriptor.get = this._wrapObject(descriptor.get, objectGroupName); if ("set" in descriptor) @@ -635,9 +645,34 @@ InjectedScript.prototype = { } } + if (subtype === "internal#entry") { + if ("key" in obj) + return "{" + this._describeIncludingPrimitives(obj.key) + " => " + this._describeIncludingPrimitives(obj.value) + "}"; + return this._describeIncludingPrimitives(obj.value); + } + + if (subtype === "internal#scopeList") + return "Scopes[" + obj.length + "]"; + + if (subtype === "internal#scope") + return (InjectedScript.closureTypes.get(obj.type) || "Unknown") + (obj.name ? " (" + obj.name + ")" : ""); + return className; }, + /** + * @param {*} value + * @return {string} + */ + _describeIncludingPrimitives: function(value) + { + if (typeof value === "string") + return "\"" + value.replace(/\n/g, "\u21B5") + "\""; + if (value === null) + return "" + value; + return this.isPrimitiveValue(value) ? toStringDescription(value) : (this._describe(value) || ""); + }, + /** * @param {boolean} enabled */ @@ -697,6 +732,13 @@ InjectedScript.RemoteObject = function(object, objectGroupName, doNotBind, force return; } + if (injectedScript._shouldPassByValue(object)) { + this.value = object; + this.subtype = injectedScript._subtype(object); + this.description = injectedScript._describeIncludingPrimitives(object); + return; + } + object = /** @type {!Object} */ (object); if (!doNotBind) @@ -827,7 +869,12 @@ InjectedScript.RemoteObject.prototype = { // Add internal properties to preview. var rawInternalProperties = InjectedScriptHost.getInternalProperties(object) || []; var internalProperties = []; + var entries = null; for (var i = 0; i < rawInternalProperties.length; i += 2) { + if (rawInternalProperties[i] === "[[Entries]]") { + entries = /** @type {!Array<*>} */(rawInternalProperties[i + 1]); + continue; + } push(internalProperties, { name: rawInternalProperties[i], value: rawInternalProperties[i + 1], @@ -839,7 +886,7 @@ InjectedScript.RemoteObject.prototype = { this._appendPropertyDescriptors(preview, internalProperties, propertiesThreshold, secondLevelKeys, isTable); if (this.subtype === "map" || this.subtype === "set" || this.subtype === "iterator") - this._appendEntriesPreview(object, preview, skipEntriesPreview); + this._appendEntriesPreview(entries, preview, skipEntriesPreview); } catch (e) {} @@ -947,13 +994,12 @@ InjectedScript.RemoteObject.prototype = { }, /** - * @param {!Object} object + * @param {?Array<*>} entries * @param {!RuntimeAgent.ObjectPreview} preview * @param {boolean=} skipEntriesPreview */ - _appendEntriesPreview: function(object, preview, skipEntriesPreview) + _appendEntriesPreview: function(entries, preview, skipEntriesPreview) { - var entries = InjectedScriptHost.collectionEntries(object); if (!entries) return; if (skipEntriesPreview) { diff --git a/deps/v8_inspector/platform/v8_inspector/InspectedContext.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.cpp similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/InspectedContext.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.cpp diff --git a/deps/v8_inspector/platform/v8_inspector/InspectedContext.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.h similarity index 97% rename from deps/v8_inspector/platform/v8_inspector/InspectedContext.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.h index 284679ddc0ca10..ecff5e4012f008 100644 --- a/deps/v8_inspector/platform/v8_inspector/InspectedContext.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.h @@ -6,7 +6,7 @@ #define InspectedContext_h #include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/Collections.h" +#include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" #include diff --git a/deps/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.cpp similarity index 92% rename from deps/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.cpp index c72cadcafe2612..8bcc475f401d72 100644 --- a/deps/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.cpp @@ -95,7 +95,7 @@ v8::Local JavaScriptCallFrame::details() const v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); v8::Local callFrame = v8::Local::New(m_isolate, m_callFrame); v8::Local func = v8::Local::Cast(callFrame->Get(toV8StringInternalized(m_isolate, "details"))); - return v8::Local::Cast(func->Call(m_isolate->GetCurrentContext(), callFrame, 0, nullptr).ToLocalChecked()); + return v8::Local::Cast(func->Call(m_debuggerContext.Get(m_isolate), callFrame, 0, nullptr).ToLocalChecked()); } v8::MaybeLocal JavaScriptCallFrame::evaluate(v8::Local expression) @@ -103,7 +103,7 @@ v8::MaybeLocal JavaScriptCallFrame::evaluate(v8::Local exp v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kRunMicrotasks); v8::Local callFrame = v8::Local::New(m_isolate, m_callFrame); v8::Local evalFunction = v8::Local::Cast(callFrame->Get(toV8StringInternalized(m_isolate, "evaluate"))); - return evalFunction->Call(m_isolate->GetCurrentContext(), callFrame, 1, &expression); + return evalFunction->Call(m_debuggerContext.Get(m_isolate), callFrame, 1, &expression); } v8::MaybeLocal JavaScriptCallFrame::restart() @@ -112,7 +112,7 @@ v8::MaybeLocal JavaScriptCallFrame::restart() v8::Local callFrame = v8::Local::New(m_isolate, m_callFrame); v8::Local restartFunction = v8::Local::Cast(callFrame->Get(toV8StringInternalized(m_isolate, "restart"))); v8::Debug::SetLiveEditEnabled(m_isolate, true); - v8::MaybeLocal result = restartFunction->Call(m_isolate->GetCurrentContext(), callFrame, 0, nullptr); + v8::MaybeLocal result = restartFunction->Call(m_debuggerContext.Get(m_isolate), callFrame, 0, nullptr); v8::Debug::SetLiveEditEnabled(m_isolate, false); return result; } @@ -127,7 +127,7 @@ v8::MaybeLocal JavaScriptCallFrame::setVariableValue(int scopeNumber, variableName, newValue }; - return setVariableValueFunction->Call(m_isolate->GetCurrentContext(), callFrame, PROTOCOL_ARRAY_LENGTH(argv), argv); + return setVariableValueFunction->Call(m_debuggerContext.Get(m_isolate), callFrame, PROTOCOL_ARRAY_LENGTH(argv), argv); } } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.h similarity index 96% rename from deps/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.h index 6f9693522eaba9..959f8172ee31da 100644 --- a/deps/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/JavaScriptCallFrame.h @@ -36,6 +36,8 @@ #include "platform/inspector_protocol/String16.h" #include +#include + namespace blink { class JavaScriptCallFrame { @@ -67,7 +69,7 @@ class JavaScriptCallFrame { v8::Global m_callFrame; }; -using JavaScriptCallFrames = protocol::Vector>; +using JavaScriptCallFrames = std::vector>; } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/OWNERS b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/OWNERS similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/OWNERS rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/OWNERS diff --git a/deps/v8_inspector/platform/v8_inspector/RemoteObjectId.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/RemoteObjectId.cpp similarity index 85% rename from deps/v8_inspector/platform/v8_inspector/RemoteObjectId.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/RemoteObjectId.cpp index 9a2a6c00886e96..e9aaf26d51e028 100644 --- a/deps/v8_inspector/platform/v8_inspector/RemoteObjectId.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/RemoteObjectId.cpp @@ -19,7 +19,7 @@ std::unique_ptr RemoteObjectIdBase::parseInjectedScri return nullptr; std::unique_ptr parsedObjectId(protocol::DictionaryValue::cast(parsedValue.release())); - bool success = parsedObjectId->getNumber("injectedScriptId", &m_injectedScriptId); + bool success = parsedObjectId->getInteger("injectedScriptId", &m_injectedScriptId); if (success) return parsedObjectId; return nullptr; @@ -36,7 +36,7 @@ std::unique_ptr RemoteObjectId::parse(ErrorString* errorString, return nullptr; } - bool success = parsedObjectId->getNumber("id", &result->m_id); + bool success = parsedObjectId->getInteger("id", &result->m_id); if (!success) { *errorString = "Invalid remote object id"; return nullptr; @@ -55,7 +55,7 @@ std::unique_ptr RemoteCallFrameId::parse(ErrorString* errorSt return nullptr; } - bool success = parsedObjectId->getNumber("ordinal", &result->m_frameOrdinal); + bool success = parsedObjectId->getInteger("ordinal", &result->m_frameOrdinal); if (!success) { *errorString = "Invalid call frame id"; return nullptr; @@ -66,7 +66,7 @@ std::unique_ptr RemoteCallFrameId::parse(ErrorString* errorSt String16 RemoteCallFrameId::serialize(int injectedScriptId, int frameOrdinal) { - return "{\"ordinal\":" + String16::number(frameOrdinal) + ",\"injectedScriptId\":" + String16::number(injectedScriptId) + "}"; + return "{\"ordinal\":" + String16::fromInteger(frameOrdinal) + ",\"injectedScriptId\":" + String16::fromInteger(injectedScriptId) + "}"; } } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/RemoteObjectId.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/RemoteObjectId.h similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/RemoteObjectId.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/RemoteObjectId.h diff --git a/deps/v8_inspector/platform/v8_inspector/ScriptBreakpoint.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/ScriptBreakpoint.h similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/ScriptBreakpoint.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/ScriptBreakpoint.h diff --git a/deps/v8_inspector/platform/v8_inspector/V8Compat.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Compat.h similarity index 97% rename from deps/v8_inspector/platform/v8_inspector/V8Compat.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Compat.h index 30492b3af7a8e9..0f5b12cbb6cb07 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8Compat.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Compat.h @@ -23,6 +23,6 @@ class V8_EXPORT MicrotasksScope { } // namespace v8 -#endif // V8_MAJOR_VERSION < 5 || (V8_MAJOR_VERSION == 5 && V8_MINOR_VERSION < 2) +#endif // V8_MAJOR_VERSION < 5 || (V8_MAJOR_VERSION == 5 && V8_MINOR_VERSION < 1) #endif // V8Compat_h diff --git a/deps/v8_inspector/platform/v8_inspector/V8Console.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Console.cpp similarity index 87% rename from deps/v8_inspector/platform/v8_inspector/V8Console.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Console.cpp index d10b326d151f67..f7e142deeadbf3 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8Console.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Console.cpp @@ -9,6 +9,7 @@ #include "platform/v8_inspector/InjectedScript.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/V8Compat.h" +#include "platform/v8_inspector/V8ConsoleMessage.h" #include "platform/v8_inspector/V8DebuggerAgentImpl.h" #include "platform/v8_inspector/V8DebuggerImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" @@ -16,8 +17,6 @@ #include "platform/v8_inspector/V8RuntimeAgentImpl.h" #include "platform/v8_inspector/V8StackTraceImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/ConsoleAPITypes.h" -#include "platform/v8_inspector/public/ConsoleTypes.h" #include "platform/v8_inspector/public/V8DebuggerClient.h" namespace blink { @@ -77,26 +76,48 @@ class ConsoleHelper { return m_debuggerClient; } - void addMessage(MessageType type, MessageLevel level, String16 emptyText, int skipArgumentCount) + void reportCall(ConsoleAPIType type) { - if (emptyText.isEmpty() && !m_info.Length()) + if (!m_info.Length()) return; - if (V8DebuggerClient* debuggerClient = ensureDebuggerClient()) - debuggerClient->reportMessageToConsole(m_context, type, level, m_info.Length() <= skipArgumentCount ? emptyText : String16(), &m_info, skipArgumentCount); + std::vector> arguments; + for (int i = 0; i < m_info.Length(); ++i) + arguments.push_back(m_info[i]); + reportCall(type, arguments); } - void addMessage(MessageType type, MessageLevel level, const String16& message) + void reportCallWithDefaultArgument(ConsoleAPIType type, const String16& message) { - if (V8DebuggerClient* debuggerClient = ensureDebuggerClient()) - debuggerClient->reportMessageToConsole(m_context, type, level, message, nullptr, 0 /* skipArgumentsCount */); + std::vector> arguments; + for (int i = 0; i < m_info.Length(); ++i) + arguments.push_back(m_info[i]); + if (!m_info.Length()) + arguments.push_back(toV8String(m_isolate, message)); + reportCall(type, arguments); } - void addDeprecationMessage(const char* id, const String16& message) + void reportCallWithArgument(ConsoleAPIType type, const String16& message) + { + std::vector> arguments(1, toV8String(m_isolate, message)); + reportCall(type, arguments); + } + + void reportCall(ConsoleAPIType type, const std::vector>& arguments) + { + InspectedContext* inspectedContext = ensureInspectedContext(); + if (!inspectedContext) + return; + V8DebuggerImpl* debugger = inspectedContext->debugger(); + std::unique_ptr message = V8ConsoleMessage::createForConsoleAPI(debugger->client()->currentTimeMS(), type, arguments, debugger->captureStackTrace(false), inspectedContext); + debugger->ensureConsoleMessageStorage(inspectedContext->contextGroupId())->addMessage(std::move(message)); + } + + void reportDeprecatedCall(const char* id, const String16& message) { if (checkAndSetPrivateFlagOnConsole(id, false)) return; - if (V8DebuggerClient* debuggerClient = ensureDebuggerClient()) - debuggerClient->reportMessageToConsole(m_context, LogMessageType, WarningMessageLevel, message, nullptr, 0 /* skipArgumentsCount */); + std::vector> arguments(1, toV8String(m_isolate, message)); + reportCall(ConsoleAPIType::kWarning, arguments); } bool firstArgToBoolean(bool defaultValue) @@ -250,13 +271,13 @@ void createBoundFunctionProperty(v8::Local context, v8::Local funcName = toV8StringInternalized(context->GetIsolate(), name); v8::Local func; - if (!v8::Function::New(context, callback, console).ToLocal(&func)) + if (!v8::Function::New(context, callback, console, 0, v8::ConstructorBehavior::kThrow).ToLocal(&func)) return; func->SetName(funcName); if (description) { v8::Local returnValue = toV8String(context->GetIsolate(), description); v8::Local toStringFunction; - if (v8::Function::New(context, returnDataCallback, returnValue).ToLocal(&toStringFunction)) + if (v8::Function::New(context, returnDataCallback, returnValue, 0, v8::ConstructorBehavior::kThrow).ToLocal(&toStringFunction)) func->Set(toV8StringInternalized(context->GetIsolate(), "toString"), toStringFunction); } if (!console->Set(context, funcName, func).FromMaybe(false)) @@ -267,67 +288,67 @@ void createBoundFunctionProperty(v8::Local context, v8::Local& info) { - ConsoleHelper(info).addMessage(LogMessageType, DebugMessageLevel, String16(), 0); + ConsoleHelper(info).reportCall(ConsoleAPIType::kDebug); } void V8Console::errorCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(LogMessageType, ErrorMessageLevel, String16(), 0); + ConsoleHelper(info).reportCall(ConsoleAPIType::kError); } void V8Console::infoCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(LogMessageType, InfoMessageLevel, String16(), 0); + ConsoleHelper(info).reportCall(ConsoleAPIType::kInfo); } void V8Console::logCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(LogMessageType, LogMessageLevel, String16(), 0); + ConsoleHelper(info).reportCall(ConsoleAPIType::kLog); } void V8Console::warnCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(LogMessageType, WarningMessageLevel, String16(), 0); + ConsoleHelper(info).reportCall(ConsoleAPIType::kWarning); } void V8Console::dirCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(DirMessageType, LogMessageLevel, String16(), 0); + ConsoleHelper(info).reportCall(ConsoleAPIType::kDir); } void V8Console::dirxmlCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(DirXMLMessageType, LogMessageLevel, String16(), 0); + ConsoleHelper(info).reportCall(ConsoleAPIType::kDirXML); } void V8Console::tableCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(TableMessageType, LogMessageLevel, String16(), 0); + ConsoleHelper(info).reportCall(ConsoleAPIType::kTable); } void V8Console::traceCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(TraceMessageType, LogMessageLevel, String16("console.trace"), 0); + ConsoleHelper(info).reportCallWithDefaultArgument(ConsoleAPIType::kTrace, String16("console.trace")); } void V8Console::groupCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(StartGroupMessageType, LogMessageLevel, String16("console.group"), 0); + ConsoleHelper(info).reportCallWithDefaultArgument(ConsoleAPIType::kStartGroup, String16("console.group")); } void V8Console::groupCollapsedCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(StartGroupCollapsedMessageType, LogMessageLevel, String16("console.groupCollapsed"), 0); + ConsoleHelper(info).reportCallWithDefaultArgument(ConsoleAPIType::kStartGroupCollapsed, String16("console.groupCollapsed")); } void V8Console::groupEndCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(EndGroupMessageType, LogMessageLevel, String16("console.groupEnd"), 0); + ConsoleHelper(info).reportCallWithDefaultArgument(ConsoleAPIType::kEndGroup, String16("console.groupEnd")); } void V8Console::clearCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addMessage(ClearMessageType, LogMessageLevel, String16("console.clear"), 0); + ConsoleHelper(info).reportCallWithDefaultArgument(ConsoleAPIType::kClear, String16("console.clear")); } void V8Console::countCallback(const v8::FunctionCallbackInfo& info) @@ -337,9 +358,9 @@ void V8Console::countCallback(const v8::FunctionCallbackInfo& info) String16 title = helper.firstArgToString(String16()); String16 identifier; if (title.isEmpty()) { - std::unique_ptr stackTrace = V8StackTraceImpl::capture(nullptr, 1); + std::unique_ptr stackTrace = V8StackTraceImpl::capture(nullptr, 0, 1); if (stackTrace) - identifier = stackTrace->topSourceURL() + ":" + String16::number(stackTrace->topLineNumber()); + identifier = stackTrace->topSourceURL() + ":" + String16::fromInteger(stackTrace->topLineNumber()); } else { identifier = title + "@"; } @@ -349,7 +370,7 @@ void V8Console::countCallback(const v8::FunctionCallbackInfo& info) return; int64_t count = helper.getIntFromMap(countMap, identifier, 0) + 1; helper.setIntOnMap(countMap, identifier, count); - helper.addMessage(CountMessageType, DebugMessageLevel, title + ": " + String16::number(count)); + helper.reportCallWithArgument(ConsoleAPIType::kCount, title + ": " + String16::fromInteger(count)); } void V8Console::assertCallback(const v8::FunctionCallbackInfo& info) @@ -357,14 +378,21 @@ void V8Console::assertCallback(const v8::FunctionCallbackInfo& info) ConsoleHelper helper(info); if (helper.firstArgToBoolean(false)) return; - helper.addMessage(AssertMessageType, ErrorMessageLevel, String16("console.assert"), 1); + + std::vector> arguments; + for (int i = 1; i < info.Length(); ++i) + arguments.push_back(info[i]); + if (info.Length() < 2) + arguments.push_back(toV8String(info.GetIsolate(), String16("console.assert"))); + helper.reportCall(ConsoleAPIType::kAssert, arguments); + if (V8DebuggerAgentImpl* debuggerAgent = helper.debuggerAgent()) debuggerAgent->breakProgramOnException(protocol::Debugger::Paused::ReasonEnum::Assert, nullptr); } void V8Console::markTimelineCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addDeprecationMessage("V8Console#markTimelineDeprecated", "'console.markTimeline' is deprecated. Please use 'console.timeStamp' instead."); + ConsoleHelper(info).reportDeprecatedCall("V8Console#markTimelineDeprecated", "'console.markTimeline' is deprecated. Please use 'console.timeStamp' instead."); timeStampCallback(info); } @@ -412,19 +440,19 @@ static void timeEndFunction(const v8::FunctionCallbackInfo& info, boo return; double elapsed = client->currentTimeMS() - helper.getDoubleFromMap(timeMap, protocolTitle, 0.0); String16 message = protocolTitle + ": " + String16::fromDoubleFixedPrecision(elapsed, 3) + "ms"; - helper.addMessage(TimeEndMessageType, DebugMessageLevel, message); + helper.reportCallWithArgument(ConsoleAPIType::kTimeEnd, message); } } void V8Console::timelineCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addDeprecationMessage("V8Console#timeline", "'console.timeline' is deprecated. Please use 'console.time' instead."); + ConsoleHelper(info).reportDeprecatedCall("V8Console#timeline", "'console.timeline' is deprecated. Please use 'console.time' instead."); timeFunction(info, true); } void V8Console::timelineEndCallback(const v8::FunctionCallbackInfo& info) { - ConsoleHelper(info).addDeprecationMessage("V8Console#timelineEnd", "'console.timelineEnd' is deprecated. Please use 'console.timeEnd' instead."); + ConsoleHelper(info).reportDeprecatedCall("V8Console#timelineEnd", "'console.timelineEnd' is deprecated. Please use 'console.timeEnd' instead."); timeEndFunction(info, true); } @@ -507,7 +535,7 @@ static void setFunctionBreakpoint(ConsoleHelper& helper, v8::Local V8DebuggerAgentImpl* debuggerAgent = helper.debuggerAgent(); if (!debuggerAgent) return; - String16 scriptId = String16::number(function->ScriptId()); + String16 scriptId = String16::fromInteger(function->ScriptId()); int lineNumber = function->GetScriptLineNumber(); int columnNumber = function->GetScriptColumnNumber(); if (lineNumber == v8::Function::kLineOffsetNotFound || columnNumber == v8::Function::kLineOffsetNotFound) @@ -661,7 +689,7 @@ v8::Local V8Console::createConsole(InspectedContext* inspectedContex DCHECK(success); if (hasMemoryAttribute) - console->SetAccessorProperty(toV8StringInternalized(isolate, "memory"), v8::Function::New(isolate, V8Console::memoryGetterCallback, console), v8::Function::New(isolate, V8Console::memorySetterCallback), static_cast(v8::None), v8::DEFAULT); + console->SetAccessorProperty(toV8StringInternalized(isolate, "memory"), v8::Function::New(context, V8Console::memoryGetterCallback, console, 0, v8::ConstructorBehavior::kThrow).ToLocalChecked(), v8::Function::New(context, V8Console::memorySetterCallback, v8::Local(), 0, v8::ConstructorBehavior::kThrow).ToLocalChecked(), static_cast(v8::None), v8::DEFAULT); console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::External::New(isolate, inspectedContext)); return console; diff --git a/deps/v8_inspector/platform/v8_inspector/V8Console.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Console.h similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/V8Console.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Console.h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.cpp new file mode 100644 index 00000000000000..ab4017532f4bd8 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.cpp @@ -0,0 +1,88 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/v8_inspector/V8ConsoleAgentImpl.h" + +#include "platform/v8_inspector/V8ConsoleMessage.h" +#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InspectorSessionImpl.h" +#include "platform/v8_inspector/V8StackTraceImpl.h" + +namespace blink { + +namespace ConsoleAgentState { +static const char consoleEnabled[] = "consoleEnabled"; +} + +V8ConsoleAgentImpl::V8ConsoleAgentImpl(V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel, protocol::DictionaryValue* state) + : m_session(session) + , m_state(state) + , m_frontend(frontendChannel) + , m_enabled(false) +{ +} + +V8ConsoleAgentImpl::~V8ConsoleAgentImpl() +{ +} + +void V8ConsoleAgentImpl::enable(ErrorString* errorString) +{ + if (m_enabled) + return; + m_state->setBoolean(ConsoleAgentState::consoleEnabled, true); + m_enabled = true; + m_session->debugger()->enableStackCapturingIfNeeded(); + reportAllMessages(); +} + +void V8ConsoleAgentImpl::disable(ErrorString* errorString) +{ + if (!m_enabled) + return; + m_session->debugger()->disableStackCapturingIfNeeded(); + m_state->setBoolean(ConsoleAgentState::consoleEnabled, false); + m_enabled = false; +} + +void V8ConsoleAgentImpl::clearMessages(ErrorString* errorString) +{ +} + +void V8ConsoleAgentImpl::restore() +{ + if (!m_state->booleanProperty(ConsoleAgentState::consoleEnabled, false)) + return; + ErrorString ignored; + enable(&ignored); +} + +void V8ConsoleAgentImpl::messageAdded(V8ConsoleMessage* message) +{ + if (m_enabled) + reportMessage(message, true); +} + +bool V8ConsoleAgentImpl::enabled() +{ + return m_enabled; +} + +void V8ConsoleAgentImpl::reportAllMessages() +{ + V8ConsoleMessageStorage* storage = m_session->debugger()->ensureConsoleMessageStorage(m_session->contextGroupId()); + for (const auto& message : storage->messages()) { + if (message->origin() == V8MessageOrigin::kConsole) + reportMessage(message.get(), false); + } +} + +void V8ConsoleAgentImpl::reportMessage(V8ConsoleMessage* message, bool generatePreview) +{ + DCHECK(message->origin() == V8MessageOrigin::kConsole); + message->reportToFrontend(&m_frontend); + m_frontend.flush(); +} + +} // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.h new file mode 100644 index 00000000000000..bc897ac352e289 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.h @@ -0,0 +1,45 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8ConsoleAgentImpl_h +#define V8ConsoleAgentImpl_h + +#include "platform/inspector_protocol/Allocator.h" +#include "platform/inspector_protocol/String16.h" +#include "platform/v8_inspector/protocol/Console.h" + +namespace blink { + +class V8ConsoleMessage; +class V8InspectorSessionImpl; + +class V8ConsoleAgentImpl : public protocol::Console::Backend { + PROTOCOL_DISALLOW_COPY(V8ConsoleAgentImpl); +public: + V8ConsoleAgentImpl(V8InspectorSessionImpl*, protocol::FrontendChannel*, protocol::DictionaryValue* state); + ~V8ConsoleAgentImpl() override; + + void enable(ErrorString*) override; + void disable(ErrorString*) override; + void clearMessages(ErrorString*) override; + + void restore(); + void messageAdded(V8ConsoleMessage*); + void reset(); + bool enabled(); + +private: + void reportAllMessages(); + void reportMessage(V8ConsoleMessage*, bool generatePreview); + + V8InspectorSessionImpl* m_session; + protocol::DictionaryValue* m_state; + protocol::Console::Frontend m_frontend; + bool m_enabled; +}; + +} // namespace blink + + +#endif // !defined(V8ConsoleAgentImpl_h) diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.cpp new file mode 100644 index 00000000000000..42fe95bdfcd890 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.cpp @@ -0,0 +1,440 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/v8_inspector/V8ConsoleMessage.h" + +#include "platform/v8_inspector/InspectedContext.h" +#include "platform/v8_inspector/V8ConsoleAgentImpl.h" +#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InspectorSessionImpl.h" +#include "platform/v8_inspector/V8RuntimeAgentImpl.h" +#include "platform/v8_inspector/V8StackTraceImpl.h" +#include "platform/v8_inspector/V8StringUtil.h" +#include "platform/v8_inspector/public/V8DebuggerClient.h" + +namespace blink { + +namespace { + +String16 consoleAPITypeValue(ConsoleAPIType type) +{ + switch (type) { + case ConsoleAPIType::kLog: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Log; + case ConsoleAPIType::kDebug: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Debug; + case ConsoleAPIType::kInfo: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Info; + case ConsoleAPIType::kError: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Error; + case ConsoleAPIType::kWarning: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Warning; + case ConsoleAPIType::kClear: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Clear; + case ConsoleAPIType::kDir: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Dir; + case ConsoleAPIType::kDirXML: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Dirxml; + case ConsoleAPIType::kTable: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Table; + case ConsoleAPIType::kTrace: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Trace; + case ConsoleAPIType::kStartGroup: return protocol::Runtime::ConsoleAPICalled::TypeEnum::StartGroup; + case ConsoleAPIType::kStartGroupCollapsed: return protocol::Runtime::ConsoleAPICalled::TypeEnum::StartGroupCollapsed; + case ConsoleAPIType::kEndGroup: return protocol::Runtime::ConsoleAPICalled::TypeEnum::EndGroup; + case ConsoleAPIType::kAssert: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Assert; + case ConsoleAPIType::kTimeEnd: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Debug; + case ConsoleAPIType::kCount: return protocol::Runtime::ConsoleAPICalled::TypeEnum::Debug; + } + return protocol::Runtime::ConsoleAPICalled::TypeEnum::Log; +} + +const unsigned maxConsoleMessageCount = 1000; +const unsigned maxArrayItemsLimit = 10000; +const unsigned maxStackDepthLimit = 32; + +class V8ValueStringBuilder { +public: + static String16 toString(v8::Local value, v8::Isolate* isolate) + { + V8ValueStringBuilder builder(isolate); + if (!builder.append(value)) + return String16(); + return builder.toString(); + } + +private: + enum { + IgnoreNull = 1 << 0, + IgnoreUndefined = 1 << 1, + }; + + V8ValueStringBuilder(v8::Isolate* isolate) + : m_arrayLimit(maxArrayItemsLimit) + , m_isolate(isolate) + , m_tryCatch(isolate) + { + } + + bool append(v8::Local value, unsigned ignoreOptions = 0) + { + if (value.IsEmpty()) + return true; + if ((ignoreOptions & IgnoreNull) && value->IsNull()) + return true; + if ((ignoreOptions & IgnoreUndefined) && value->IsUndefined()) + return true; + if (value->IsString()) + return append(v8::Local::Cast(value)); + if (value->IsStringObject()) + return append(v8::Local::Cast(value)->ValueOf()); + if (value->IsSymbol()) + return append(v8::Local::Cast(value)); + if (value->IsSymbolObject()) + return append(v8::Local::Cast(value)->ValueOf()); + if (value->IsNumberObject()) { + m_builder.appendNumber(v8::Local::Cast(value)->ValueOf()); + return true; + } + if (value->IsBooleanObject()) { + m_builder.append(v8::Local::Cast(value)->ValueOf() ? "true" : "false"); + return true; + } + if (value->IsArray()) + return append(v8::Local::Cast(value)); + if (value->IsProxy()) { + m_builder.append("[object Proxy]"); + return true; + } + if (value->IsObject() + && !value->IsDate() + && !value->IsFunction() + && !value->IsNativeError() + && !value->IsRegExp()) { + v8::Local object = v8::Local::Cast(value); + v8::Local stringValue; + if (object->ObjectProtoToString(m_isolate->GetCurrentContext()).ToLocal(&stringValue)) + return append(stringValue); + } + v8::Local stringValue; + if (!value->ToString(m_isolate->GetCurrentContext()).ToLocal(&stringValue)) + return false; + return append(stringValue); + } + + bool append(v8::Local array) + { + for (const auto& it : m_visitedArrays) { + if (it == array) + return true; + } + uint32_t length = array->Length(); + if (length > m_arrayLimit) + return false; + if (m_visitedArrays.size() > maxStackDepthLimit) + return false; + + bool result = true; + m_arrayLimit -= length; + m_visitedArrays.push_back(array); + for (uint32_t i = 0; i < length; ++i) { + if (i) + m_builder.append(','); + if (!append(array->Get(i), IgnoreNull | IgnoreUndefined)) { + result = false; + break; + } + } + m_visitedArrays.pop_back(); + return result; + } + + bool append(v8::Local symbol) + { + m_builder.append("Symbol("); + bool result = append(symbol->Name(), IgnoreUndefined); + m_builder.append(')'); + return result; + } + + bool append(v8::Local string) + { + if (m_tryCatch.HasCaught()) + return false; + if (!string.IsEmpty()) + m_builder.append(toProtocolString(string)); + return true; + } + + String16 toString() + { + if (m_tryCatch.HasCaught()) + return String16(); + return m_builder.toString(); + } + + uint32_t m_arrayLimit; + v8::Isolate* m_isolate; + String16Builder m_builder; + std::vector> m_visitedArrays; + v8::TryCatch m_tryCatch; +}; + +} // namespace + +V8ConsoleMessage::V8ConsoleMessage(V8MessageOrigin origin, double timestamp, const String16& message) + : m_origin(origin) + , m_timestamp(timestamp) + , m_message(message) + , m_lineNumber(0) + , m_columnNumber(0) + , m_scriptId(0) + , m_contextId(0) + , m_type(ConsoleAPIType::kLog) + , m_exceptionId(0) + , m_revokedExceptionId(0) +{ +} + +V8ConsoleMessage::~V8ConsoleMessage() +{ +} + +void V8ConsoleMessage::setLocation(const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId) +{ + m_url = url; + m_lineNumber = lineNumber; + m_columnNumber = columnNumber; + m_stackTrace = std::move(stackTrace); + m_scriptId = scriptId; +} + +void V8ConsoleMessage::reportToFrontend(protocol::Console::Frontend* frontend) const +{ + DCHECK(m_origin == V8MessageOrigin::kConsole); + std::unique_ptr result = + protocol::Console::ConsoleMessage::create() + .setSource(protocol::Console::ConsoleMessage::SourceEnum::ConsoleApi) + .setLevel(protocol::Console::ConsoleMessage::LevelEnum::Log) + .setText(m_message) + .build(); + result->setLine(static_cast(m_lineNumber)); + result->setColumn(static_cast(m_columnNumber)); + result->setUrl(m_url); + frontend->messageAdded(std::move(result)); +} + +std::unique_ptr> V8ConsoleMessage::wrapArguments(V8InspectorSessionImpl* session, bool generatePreview) const +{ + if (!m_arguments.size() || !m_contextId) + return nullptr; + InspectedContext* inspectedContext = session->debugger()->getContext(session->contextGroupId(), m_contextId); + if (!inspectedContext) + return nullptr; + + v8::Isolate* isolate = inspectedContext->isolate(); + v8::HandleScope handles(isolate); + v8::Local context = inspectedContext->context(); + + std::unique_ptr> args = protocol::Array::create(); + if (m_type == ConsoleAPIType::kTable && generatePreview) { + v8::Local table = m_arguments[0]->Get(isolate); + v8::Local columns = m_arguments.size() > 1 ? m_arguments[1]->Get(isolate) : v8::Local(); + std::unique_ptr wrapped = session->wrapTable(context, table, columns); + if (wrapped) + args->addItem(std::move(wrapped)); + else + args = nullptr; + } else { + for (size_t i = 0; i < m_arguments.size(); ++i) { + std::unique_ptr wrapped = session->wrapObject(context, m_arguments[i]->Get(isolate), "console", generatePreview); + if (!wrapped) { + args = nullptr; + break; + } + args->addItem(std::move(wrapped)); + } + } + return args; +} + +void V8ConsoleMessage::reportToFrontend(protocol::Runtime::Frontend* frontend, V8InspectorSessionImpl* session, bool generatePreview) const +{ + if (m_origin == V8MessageOrigin::kException) { + // TODO(dgozman): unify with InjectedScript::createExceptionDetails. + std::unique_ptr details = protocol::Runtime::ExceptionDetails::create() + .setText(m_message) + .setLineNumber(m_lineNumber ? m_lineNumber - 1 : 0) + .setColumnNumber(m_columnNumber ? m_columnNumber - 1 : 0) + .setScriptId(m_scriptId ? String16::fromInteger(m_scriptId) : String16()) + .build(); + if (!m_url.isEmpty()) + details->setUrl(m_url); + if (m_stackTrace) + details->setStackTrace(m_stackTrace->buildInspectorObject()); + + std::unique_ptr exception = wrapException(session, generatePreview); + + if (exception) + frontend->exceptionThrown(m_exceptionId, m_timestamp, std::move(details), std::move(exception), m_contextId); + else + frontend->exceptionThrown(m_exceptionId, m_timestamp, std::move(details)); + return; + } + if (m_origin == V8MessageOrigin::kRevokedException) { + frontend->exceptionRevoked(m_message, m_revokedExceptionId); + return; + } + if (m_origin == V8MessageOrigin::kConsole) { + std::unique_ptr> arguments = wrapArguments(session, generatePreview); + if (!arguments) { + arguments = protocol::Array::create(); + if (!m_message.isEmpty()) { + std::unique_ptr messageArg = protocol::Runtime::RemoteObject::create().setType(protocol::Runtime::RemoteObject::TypeEnum::String).build(); + messageArg->setValue(protocol::StringValue::create(m_message)); + arguments->addItem(std::move(messageArg)); + } + } + frontend->consoleAPICalled(consoleAPITypeValue(m_type), std::move(arguments), m_contextId, m_timestamp, m_stackTrace ? m_stackTrace->buildInspectorObject() : nullptr); + return; + } + NOTREACHED(); +} + +std::unique_ptr V8ConsoleMessage::wrapException(V8InspectorSessionImpl* session, bool generatePreview) const +{ + if (!m_arguments.size() || !m_contextId) + return nullptr; + DCHECK_EQ(1u, m_arguments.size()); + InspectedContext* inspectedContext = session->debugger()->getContext(session->contextGroupId(), m_contextId); + if (!inspectedContext) + return nullptr; + + v8::Isolate* isolate = inspectedContext->isolate(); + v8::HandleScope handles(isolate); + // TODO(dgozman): should we use different object group? + return session->wrapObject(inspectedContext->context(), m_arguments[0]->Get(isolate), "console", generatePreview); +} + +V8MessageOrigin V8ConsoleMessage::origin() const +{ + return m_origin; +} + +ConsoleAPIType V8ConsoleMessage::type() const +{ + return m_type; +} + +// static +std::unique_ptr V8ConsoleMessage::createForConsoleAPI(double timestamp, ConsoleAPIType type, const std::vector>& arguments, std::unique_ptr stackTrace, InspectedContext* context) +{ + std::unique_ptr message = wrapUnique(new V8ConsoleMessage(V8MessageOrigin::kConsole, timestamp, String16())); + if (stackTrace && !stackTrace->isEmpty()) { + message->m_url = stackTrace->topSourceURL(); + message->m_lineNumber = stackTrace->topLineNumber(); + message->m_columnNumber = stackTrace->topColumnNumber(); + } + message->m_stackTrace = std::move(stackTrace); + message->m_type = type; + message->m_contextId = context->contextId(); + for (size_t i = 0; i < arguments.size(); ++i) + message->m_arguments.push_back(wrapUnique(new v8::Global(context->isolate(), arguments.at(i)))); + if (arguments.size()) + message->m_message = V8ValueStringBuilder::toString(arguments[0], context->isolate()); + + MessageLevel level = LogMessageLevel; + if (type == ConsoleAPIType::kDebug || type == ConsoleAPIType::kCount || type == ConsoleAPIType::kTimeEnd) + level = DebugMessageLevel; + if (type == ConsoleAPIType::kError || type == ConsoleAPIType::kAssert) + level = ErrorMessageLevel; + if (type == ConsoleAPIType::kWarning) + level = WarningMessageLevel; + if (type == ConsoleAPIType::kInfo) + level = InfoMessageLevel; + context->debugger()->client()->consoleAPIMessage(context->contextGroupId(), level, message->m_message, message->m_url, message->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get()); + + return message; +} + +// static +std::unique_ptr V8ConsoleMessage::createForException(double timestamp, const String16& messageText, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId, v8::Isolate* isolate, int contextId, v8::Local exception, unsigned exceptionId) +{ + std::unique_ptr message = wrapUnique(new V8ConsoleMessage(V8MessageOrigin::kException, timestamp, messageText)); + message->setLocation(url, lineNumber, columnNumber, std::move(stackTrace), scriptId); + message->m_exceptionId = exceptionId; + if (contextId && !exception.IsEmpty()) { + message->m_contextId = contextId; + message->m_arguments.push_back(wrapUnique(new v8::Global(isolate, exception))); + } + return message; +} + +// static +std::unique_ptr V8ConsoleMessage::createForRevokedException(double timestamp, const String16& messageText, unsigned revokedExceptionId) +{ + std::unique_ptr message = wrapUnique(new V8ConsoleMessage(V8MessageOrigin::kRevokedException, timestamp, messageText)); + message->m_revokedExceptionId = revokedExceptionId; + return message; +} + +void V8ConsoleMessage::contextDestroyed(int contextId) +{ + if (contextId != m_contextId) + return; + m_contextId = 0; + if (m_message.isEmpty()) + m_message = ""; + Arguments empty; + m_arguments.swap(empty); +} + +// ------------------------ V8ConsoleMessageStorage ---------------------------- + +V8ConsoleMessageStorage::V8ConsoleMessageStorage(V8DebuggerImpl* debugger, int contextGroupId) + : m_debugger(debugger) + , m_contextGroupId(contextGroupId) + , m_expiredCount(0) +{ +} + +V8ConsoleMessageStorage::~V8ConsoleMessageStorage() +{ + clear(); + notifyClear(); +} + +void V8ConsoleMessageStorage::addMessage(std::unique_ptr message) +{ + if (message->type() == ConsoleAPIType::kClear) { + clear(); + notifyClear(); + } + + V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_contextGroupId); + if (session) { + if (message->origin() == V8MessageOrigin::kConsole) + session->consoleAgent()->messageAdded(message.get()); + session->runtimeAgent()->messageAdded(message.get()); + } + + DCHECK(m_messages.size() <= maxConsoleMessageCount); + if (m_messages.size() == maxConsoleMessageCount) { + ++m_expiredCount; + m_messages.pop_front(); + } + m_messages.push_back(std::move(message)); +} + +void V8ConsoleMessageStorage::clear() +{ + m_messages.clear(); + m_expiredCount = 0; + if (V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_contextGroupId)) + session->releaseObjectGroup("console"); +} + +void V8ConsoleMessageStorage::contextDestroyed(int contextId) +{ + for (size_t i = 0; i < m_messages.size(); ++i) + m_messages[i]->contextDestroyed(contextId); +} + +void V8ConsoleMessageStorage::notifyClear() +{ + if (V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_contextGroupId)) + session->client()->consoleCleared(); +} + +} // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.h new file mode 100644 index 00000000000000..923a84e9269080 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.h @@ -0,0 +1,110 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8ConsoleMessage_h +#define V8ConsoleMessage_h + +#include "platform/inspector_protocol/Collections.h" +#include "platform/inspector_protocol/String16.h" +#include "platform/v8_inspector/protocol/Console.h" +#include "platform/v8_inspector/protocol/Runtime.h" +#include "platform/v8_inspector/public/V8ConsoleTypes.h" +#include "platform/v8_inspector/public/V8StackTrace.h" +#include +#include + +namespace blink { + +class InspectedContext; +class V8DebuggerImpl; +class V8InspectorSessionImpl; +class V8StackTrace; + +enum class V8MessageOrigin { kConsole, kException, kRevokedException }; + +enum class ConsoleAPIType { kLog, kDebug, kInfo, kError, kWarning, kDir, kDirXML, kTable, kTrace, kStartGroup, kStartGroupCollapsed, kEndGroup, kClear, kAssert, kTimeEnd, kCount }; + +class V8ConsoleMessage { +public: + ~V8ConsoleMessage(); + + static std::unique_ptr createForConsoleAPI( + double timestamp, + ConsoleAPIType, + const std::vector>& arguments, + std::unique_ptr, + InspectedContext*); + + static std::unique_ptr createForException( + double timestamp, + const String16& message, + const String16& url, + unsigned lineNumber, + unsigned columnNumber, + std::unique_ptr, + int scriptId, + v8::Isolate*, + int contextId, + v8::Local exception, + unsigned exceptionId); + + static std::unique_ptr createForRevokedException( + double timestamp, + const String16& message, + unsigned revokedExceptionId); + + V8MessageOrigin origin() const; + void reportToFrontend(protocol::Console::Frontend*) const; + void reportToFrontend(protocol::Runtime::Frontend*, V8InspectorSessionImpl*, bool generatePreview) const; + ConsoleAPIType type() const; + void contextDestroyed(int contextId); + +private: + V8ConsoleMessage(V8MessageOrigin, double timestamp, const String16& message); + + using Arguments = std::vector>>; + std::unique_ptr> wrapArguments(V8InspectorSessionImpl*, bool generatePreview) const; + std::unique_ptr wrapException(V8InspectorSessionImpl*, bool generatePreview) const; + void setLocation(const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId); + + V8MessageOrigin m_origin; + double m_timestamp; + String16 m_message; + String16 m_url; + unsigned m_lineNumber; + unsigned m_columnNumber; + std::unique_ptr m_stackTrace; + int m_scriptId; + int m_contextId; + ConsoleAPIType m_type; + unsigned m_exceptionId; + unsigned m_revokedExceptionId; + Arguments m_arguments; +}; + +class V8ConsoleMessageStorage { +public: + V8ConsoleMessageStorage(V8DebuggerImpl*, int contextGroupId); + ~V8ConsoleMessageStorage(); + + int contextGroupId() { return m_contextGroupId; } + int expiredCount() { return m_expiredCount; } + const std::deque>& messages() const { return m_messages; } + + void addMessage(std::unique_ptr); + void contextDestroyed(int contextId); + void clear(); + +private: + void notifyClear(); + + V8DebuggerImpl* m_debugger; + int m_contextGroupId; + int m_expiredCount; + std::deque> m_messages; +}; + +} // namespace blink + +#endif // V8ConsoleMessage_h diff --git a/deps/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp similarity index 66% rename from deps/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp index e95d4af0f57210..2b232efc2e714b 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp @@ -19,26 +19,18 @@ #include "platform/v8_inspector/public/V8ContentSearchUtil.h" #include "platform/v8_inspector/public/V8Debugger.h" #include "platform/v8_inspector/public/V8DebuggerClient.h" -#include "platform/v8_inspector/public/V8ToProtocolValue.h" + +#include using blink::protocol::Array; using blink::protocol::Maybe; using blink::protocol::Debugger::BreakpointId; using blink::protocol::Debugger::CallFrame; -using blink::protocol::Debugger::CollectionEntry; using blink::protocol::Runtime::ExceptionDetails; -using blink::protocol::Debugger::FunctionDetails; -using blink::protocol::Debugger::GeneratorObjectDetails; using blink::protocol::Runtime::ScriptId; using blink::protocol::Runtime::StackTrace; using blink::protocol::Runtime::RemoteObject; -namespace { -static const char v8AsyncTaskEventEnqueue[] = "enqueue"; -static const char v8AsyncTaskEventWillHandle[] = "willHandle"; -static const char v8AsyncTaskEventDidHandle[] = "didHandle"; -} - namespace blink { namespace DebuggerAgentState { @@ -75,7 +67,7 @@ static String16 breakpointIdSuffix(V8DebuggerAgentImpl::BreakpointSource source) static String16 generateBreakpointId(const String16& scriptId, int lineNumber, int columnNumber, V8DebuggerAgentImpl::BreakpointSource source) { - return scriptId + ":" + String16::number(lineNumber) + ":" + String16::number(columnNumber) + breakpointIdSuffix(source); + return scriptId + ":" + String16::fromInteger(lineNumber) + ":" + String16::fromInteger(columnNumber) + breakpointIdSuffix(source); } static bool positionComparator(const std::pair& a, const std::pair& b) @@ -85,61 +77,6 @@ static bool positionComparator(const std::pair& a, const std::pairappend(hexDigits[number & 0xF]); - number >>= 4; - } -} - -// Hash algorithm for substrings is described in "Über die Komplexität der Multiplikation in -// eingeschränkten Branchingprogrammmodellen" by Woelfe. -// http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000 -static String16 calculateHash(const String16& str) -{ - static uint64_t prime[] = { 0x3FB75161, 0xAB1F4E4F, 0x82675BC5, 0xCD924D35, 0x81ABE279 }; - static uint64_t random[] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; - static uint32_t randomOdd[] = { 0xB4663807, 0xCC322BF5, 0xD4F91BBD, 0xA7BEA11D, 0x8F462907 }; - - uint64_t hashes[] = { 0, 0, 0, 0, 0 }; - uint64_t zi[] = { 1, 1, 1, 1, 1 }; - - const size_t hashesSize = PROTOCOL_ARRAY_LENGTH(hashes); - - size_t current = 0; - const uint32_t* data = nullptr; - data = reinterpret_cast(str.characters16()); - for (size_t i = 0; i < str.sizeInBytes() / 4; i += 4) { - uint32_t v = data[i]; - uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF; - hashes[current] = (hashes[current] + zi[current] * xi) % prime[current]; - zi[current] = (zi[current] * random[current]) % prime[current]; - current = current == hashesSize - 1 ? 0 : current + 1; - } - if (str.sizeInBytes() % 4) { - uint32_t v = 0; - for (size_t i = str.sizeInBytes() - str.sizeInBytes() % 4; i < str.sizeInBytes(); ++i) { - v <<= 8; - v |= reinterpret_cast(data)[i]; - } - uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF; - hashes[current] = (hashes[current] + zi[current] * xi) % prime[current]; - zi[current] = (zi[current] * random[current]) % prime[current]; - current = current == hashesSize - 1 ? 0 : current + 1; - } - - for (size_t i = 0; i < hashesSize; ++i) - hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i]; - - String16Builder hash; - for (size_t i = 0; i < hashesSize; ++i) - appendUnsignedAsHex(hashes[i], &hash); - return hash.toString(); -} - static bool hasInternalError(ErrorString* errorString, bool hasError) { if (hasError) @@ -172,7 +109,6 @@ V8DebuggerAgentImpl::V8DebuggerAgentImpl(V8InspectorSessionImpl* session, protoc , m_recursionLevelForStepOut(0) , m_recursionLevelForStepFrame(0) , m_skipAllPauses(false) - , m_maxAsyncCallStackDepth(0) { clearBreakDetails(); } @@ -197,14 +133,13 @@ void V8DebuggerAgentImpl::enable() m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true); debugger().debuggerAgentEnabled(); - protocol::Vector compiledScripts; + std::vector> compiledScripts; debugger().getCompiledScripts(m_session->contextGroupId(), compiledScripts); for (size_t i = 0; i < compiledScripts.size(); i++) - didParseSource(compiledScripts[i]); + didParseSource(std::move(compiledScripts[i]), true); // FIXME(WK44513): breakpoints activated flag should be synchronized between all front-ends debugger().setBreakpointsActivated(true); - m_session->changeInstrumentationCounter(+1); } bool V8DebuggerAgentImpl::enabled() @@ -229,11 +164,10 @@ void V8DebuggerAgentImpl::disable(ErrorString*) { if (!enabled()) return; - m_session->changeInstrumentationCounter(-1); m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, protocol::DictionaryValue::create()); - m_state->setNumber(DebuggerAgentState::pauseOnExceptionsState, V8DebuggerImpl::DontPauseOnExceptions); - m_state->setNumber(DebuggerAgentState::asyncCallStackDepth, 0); + m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, V8DebuggerImpl::DontPauseOnExceptions); + m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0); if (!m_pausedContext.IsEmpty()) debugger().continueProgram(); @@ -244,7 +178,7 @@ void V8DebuggerAgentImpl::disable(ErrorString*) m_scripts.clear(); m_blackboxedPositions.clear(); m_breakpointIdToDebuggerBreakpointIds.clear(); - internalSetAsyncCallStackDepth(0); + m_debugger->setAsyncCallStackDepth(this, 0); m_continueToLocationBreakpointId = String16(); clearBreakDetails(); m_scheduledDebuggerStep = NoStep; @@ -261,16 +195,6 @@ void V8DebuggerAgentImpl::disable(ErrorString*) m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false); } -void V8DebuggerAgentImpl::internalSetAsyncCallStackDepth(int depth) -{ - if (depth <= 0) { - m_maxAsyncCallStackDepth = 0; - allAsyncTasksCanceled(); - } else { - m_maxAsyncCallStackDepth = depth; - } -} - void V8DebuggerAgentImpl::restore() { DCHECK(!m_enabled); @@ -283,15 +207,15 @@ void V8DebuggerAgentImpl::restore() ErrorString error; int pauseState = V8DebuggerImpl::DontPauseOnExceptions; - m_state->getNumber(DebuggerAgentState::pauseOnExceptionsState, &pauseState); + m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState); setPauseOnExceptionsImpl(&error, pauseState); DCHECK(error.isEmpty()); m_skipAllPauses = m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false); int asyncCallStackDepth = 0; - m_state->getNumber(DebuggerAgentState::asyncCallStackDepth, &asyncCallStackDepth); - internalSetAsyncCallStackDepth(asyncCallStackDepth); + m_state->getInteger(DebuggerAgentState::asyncCallStackDepth, &asyncCallStackDepth); + m_debugger->setAsyncCallStackDepth(this, asyncCallStackDepth); String16 blackboxPattern; if (m_state->getString(DebuggerAgentState::blackboxPattern, &blackboxPattern)) { @@ -317,8 +241,8 @@ static std::unique_ptr buildObjectForBreakpointCookie { std::unique_ptr breakpointObject = protocol::DictionaryValue::create(); breakpointObject->setString(DebuggerAgentState::url, url); - breakpointObject->setNumber(DebuggerAgentState::lineNumber, lineNumber); - breakpointObject->setNumber(DebuggerAgentState::columnNumber, columnNumber); + breakpointObject->setInteger(DebuggerAgentState::lineNumber, lineNumber); + breakpointObject->setInteger(DebuggerAgentState::columnNumber, columnNumber); breakpointObject->setString(DebuggerAgentState::condition, condition); breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex); return breakpointObject; @@ -360,7 +284,7 @@ void V8DebuggerAgentImpl::setBreakpointByUrl(ErrorString* errorString, String16 condition = optionalCondition.fromMaybe(""); bool isRegex = optionalURLRegex.isJust(); - String16 breakpointId = (isRegex ? "/" + url + "/" : url) + ":" + String16::number(lineNumber) + ":" + String16::number(columnNumber); + String16 breakpointId = (isRegex ? "/" + url + "/" : url) + ":" + String16::fromInteger(lineNumber) + ":" + String16::fromInteger(columnNumber); protocol::DictionaryValue* breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); if (!breakpointsCookie) { std::unique_ptr newValue = protocol::DictionaryValue::create(); @@ -375,7 +299,7 @@ void V8DebuggerAgentImpl::setBreakpointByUrl(ErrorString* errorString, breakpointsCookie->setObject(breakpointId, buildObjectForBreakpointCookie(url, lineNumber, columnNumber, condition, isRegex)); ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); - for (auto& script : m_scripts) { + for (const auto& script : m_scripts) { if (!matches(m_debugger, script.second->sourceURL(), url, isRegex)) continue; std::unique_ptr location = resolveBreakpoint(breakpointId, script.first, breakpoint, UserBreakpointSource); @@ -410,7 +334,7 @@ void V8DebuggerAgentImpl::setBreakpoint(ErrorString* errorString, String16 condition = optionalCondition.fromMaybe(""); String16 breakpointId = generateBreakpointId(scriptId, lineNumber, columnNumber, UserBreakpointSource); - if (m_breakpointIdToDebuggerBreakpointIds.contains(breakpointId)) { + if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != m_breakpointIdToDebuggerBreakpointIds.end()) { *errorString = "Breakpoint at specified location already exists."; return; } @@ -438,14 +362,14 @@ void V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) BreakpointIdToDebuggerBreakpointIdsMap::iterator debuggerBreakpointIdsIterator = m_breakpointIdToDebuggerBreakpointIds.find(breakpointId); if (debuggerBreakpointIdsIterator == m_breakpointIdToDebuggerBreakpointIds.end()) return; - protocol::Vector* ids = debuggerBreakpointIdsIterator->second; - for (size_t i = 0; i < ids->size(); ++i) { - const String16& debuggerBreakpointId = ids->at(i); + const std::vector& ids = debuggerBreakpointIdsIterator->second; + for (size_t i = 0; i < ids.size(); ++i) { + const String16& debuggerBreakpointId = ids[i]; debugger().removeBreakpoint(debuggerBreakpointId); - m_serverBreakpoints.remove(debuggerBreakpointId); + m_serverBreakpoints.erase(debuggerBreakpointId); } - m_breakpointIdToDebuggerBreakpointIds.remove(breakpointId); + m_breakpointIdToDebuggerBreakpointIds.erase(breakpointId); } void V8DebuggerAgentImpl::continueToLocation(ErrorString* errorString, @@ -475,7 +399,8 @@ void V8DebuggerAgentImpl::getBacktrace(ErrorString* errorString, std::unique_ptr { if (!assertPaused(errorString)) return; - m_pausedCallFrames.swap(debugger().currentCallFrames()); + JavaScriptCallFrames frames = debugger().currentCallFrames(); + m_pausedCallFrames.swap(frames); *callFrames = currentCallFrames(errorString); if (!*callFrames) return; @@ -487,7 +412,7 @@ bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() DCHECK(enabled()); JavaScriptCallFrames callFrames = debugger().currentCallFrames(); for (size_t index = 0; index < callFrames.size(); ++index) { - if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index])) + if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index].get())) return false; } return true; @@ -496,32 +421,34 @@ bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() bool V8DebuggerAgentImpl::isTopPausedCallFrameBlackboxed() { DCHECK(enabled()); - return isCallFrameWithUnknownScriptOrBlackboxed(m_pausedCallFrames.size() ? m_pausedCallFrames[0] : nullptr); + JavaScriptCallFrame* frame = m_pausedCallFrames.size() ? m_pausedCallFrames[0].get() : nullptr; + return isCallFrameWithUnknownScriptOrBlackboxed(frame); } bool V8DebuggerAgentImpl::isCallFrameWithUnknownScriptOrBlackboxed(JavaScriptCallFrame* frame) { if (!frame) return true; - ScriptsMap::iterator it = m_scripts.find(String16::number(frame->sourceID())); + ScriptsMap::iterator it = m_scripts.find(String16::fromInteger(frame->sourceID())); if (it == m_scripts.end()) { // Unknown scripts are blackboxed. return true; } if (m_blackboxPattern) { - String16 scriptSourceURL = it->second->sourceURL(); + const String16& scriptSourceURL = it->second->sourceURL(); if (!scriptSourceURL.isEmpty() && m_blackboxPattern->match(scriptSourceURL) != -1) return true; } - auto itBlackboxedPositions = m_blackboxedPositions.find(String16::number(frame->sourceID())); + auto itBlackboxedPositions = m_blackboxedPositions.find(String16::fromInteger(frame->sourceID())); if (itBlackboxedPositions == m_blackboxedPositions.end()) return false; - protocol::Vector>* ranges = itBlackboxedPositions->second; - auto itRange = std::lower_bound(ranges->begin(), ranges->end(), std::make_pair(frame->line(), frame->column()), positionComparator); + const std::vector>& ranges = itBlackboxedPositions->second; + auto itRange = std::lower_bound(ranges.begin(), ranges.end(), + std::make_pair(frame->line(), frame->column()), positionComparator); // Ranges array contains positions in script where blackbox state is changed. // [(0,0) ... ranges[0]) isn't blackboxed, [ranges[0] ... ranges[1]) is blackboxed... - return std::distance(ranges->begin(), itRange) % 2; + return std::distance(ranges.begin(), itRange) % 2; } V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::shouldSkipExceptionPause(JavaScriptCallFrame* topCallFrame) @@ -566,8 +493,7 @@ std::unique_ptr V8DebuggerAgentImpl::resolveBreakp ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId); if (scriptIterator == m_scripts.end()) return nullptr; - V8DebuggerScript* script = scriptIterator->second; - if (breakpoint.lineNumber < script->startLine() || script->endLine() < breakpoint.lineNumber) + if (breakpoint.lineNumber < scriptIterator->second->startLine() || scriptIterator->second->endLine() < breakpoint.lineNumber) return nullptr; int actualLineNumber; @@ -576,14 +502,10 @@ std::unique_ptr V8DebuggerAgentImpl::resolveBreakp if (debuggerBreakpointId.isEmpty()) return nullptr; - m_serverBreakpoints.set(debuggerBreakpointId, std::make_pair(breakpointId, source)); + m_serverBreakpoints[debuggerBreakpointId] = std::make_pair(breakpointId, source); CHECK(!breakpointId.isEmpty()); - if (!m_breakpointIdToDebuggerBreakpointIds.contains(breakpointId)) - m_breakpointIdToDebuggerBreakpointIds.set(breakpointId, protocol::Vector()); - - BreakpointIdToDebuggerBreakpointIdsMap::iterator debuggerBreakpointIdsIterator = m_breakpointIdToDebuggerBreakpointIds.find(breakpointId); - debuggerBreakpointIdsIterator->second->append(debuggerBreakpointId); + m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back(debuggerBreakpointId); return buildProtocolLocation(scriptId, actualLineNumber, actualColumnNumber); } @@ -592,9 +514,10 @@ void V8DebuggerAgentImpl::searchInContent(ErrorString* error, const String16& sc const Maybe& optionalIsRegex, std::unique_ptr>* results) { + v8::HandleScope handles(m_isolate); ScriptsMap::iterator it = m_scripts.find(scriptId); if (it != m_scripts.end()) - *results = V8ContentSearchUtil::searchInTextByLines(m_session, it->second->source(), query, optionalCaseSensitive.fromMaybe(false), optionalIsRegex.fromMaybe(false)); + *results = V8ContentSearchUtil::searchInTextByLines(m_session, toProtocolString(it->second->source(m_isolate)), query, optionalCaseSensitive.fromMaybe(false), optionalIsRegex.fromMaybe(false)); else *error = String16("No script for id: " + scriptId); } @@ -606,23 +529,25 @@ void V8DebuggerAgentImpl::setScriptSource(ErrorString* errorString, Maybe>* newCallFrames, Maybe* stackChanged, Maybe* asyncStackTrace, - Maybe* optOutCompileError) + Maybe* optOutCompileError) { if (!checkEnabled(errorString)) return; - if (!debugger().setScriptSource(scriptId, newContent, preview.fromMaybe(false), errorString, optOutCompileError, &m_pausedCallFrames, stackChanged)) + + v8::HandleScope handles(m_isolate); + v8::Local newSource = toV8String(m_isolate, newContent); + if (!debugger().setScriptSource(scriptId, newSource, preview.fromMaybe(false), errorString, optOutCompileError, &m_pausedCallFrames, stackChanged)) return; + ScriptsMap::iterator it = m_scripts.find(scriptId); + if (it != m_scripts.end()) + it->second->setSource(m_isolate, newSource); + std::unique_ptr> callFrames = currentCallFrames(errorString); if (!callFrames) return; *newCallFrames = std::move(callFrames); *asyncStackTrace = currentAsyncStackTrace(); - - ScriptsMap::iterator it = m_scripts.find(scriptId); - if (it == m_scripts.end()) - return; - it->second->setSource(newContent); } void V8DebuggerAgentImpl::restartFrame(ErrorString* errorString, @@ -646,7 +571,8 @@ void V8DebuggerAgentImpl::restartFrame(ErrorString* errorString, *errorString = "Internal error"; return; } - m_pausedCallFrames.swap(debugger().currentCallFrames()); + JavaScriptCallFrames frames = debugger().currentCallFrames(); + m_pausedCallFrames.swap(frames); *newCallFrames = currentCallFrames(errorString); if (!*newCallFrames) @@ -663,106 +589,8 @@ void V8DebuggerAgentImpl::getScriptSource(ErrorString* error, const String16& sc *error = "No script for id: " + scriptId; return; } - *scriptSource = it->second->source(); -} - -void V8DebuggerAgentImpl::getFunctionDetails(ErrorString* errorString, const String16& functionId, std::unique_ptr* details) -{ - if (!checkEnabled(errorString)) - return; - InjectedScript::ObjectScope scope(errorString, m_debugger, m_session->contextGroupId(), functionId); - if (!scope.initialize()) - return; - if (!scope.object()->IsFunction()) { - *errorString = "Value with given id is not a function"; - return; - } - v8::Local function = scope.object().As(); - - v8::Local scopesValue; - v8::Local scopes; - if (m_debugger->functionScopes(function).ToLocal(&scopesValue) && scopesValue->IsArray()) { - scopes = scopesValue.As(); - if (!scope.injectedScript()->wrapPropertyInArray(errorString, scopes, toV8StringInternalized(m_isolate, "object"), scope.objectGroupName())) - return; - } - - std::unique_ptr functionDetails = FunctionDetails::create() - .setLocation(buildProtocolLocation(String16::number(function->ScriptId()), function->GetScriptLineNumber(), function->GetScriptColumnNumber())) - .setFunctionName(toProtocolStringWithTypeCheck(function->GetDebugName())) - .setIsGenerator(function->IsGeneratorFunction()).build(); - - if (!scopes.IsEmpty()) { - protocol::ErrorSupport errorSupport; - std::unique_ptr> scopeChain = protocol::Array::parse(toProtocolValue(scope.context(), scopes).get(), &errorSupport); - if (hasInternalError(errorString, errorSupport.hasErrors())) - return; - functionDetails->setScopeChain(std::move(scopeChain)); - } - - *details = std::move(functionDetails); -} - -void V8DebuggerAgentImpl::getGeneratorObjectDetails(ErrorString* errorString, const String16& objectId, std::unique_ptr* outDetails) -{ - if (!checkEnabled(errorString)) - return; - InjectedScript::ObjectScope scope(errorString, m_debugger, m_session->contextGroupId(), objectId); - if (!scope.initialize()) - return; - if (!scope.object()->IsObject()) { - *errorString = "Value with given id is not an Object"; - return; - } - v8::Local object = scope.object().As(); - - v8::Local detailsObject; - v8::Local detailsValue = debugger().generatorObjectDetails(object); - if (hasInternalError(errorString, !detailsValue->IsObject() || !detailsValue->ToObject(scope.context()).ToLocal(&detailsObject))) - return; - - if (!scope.injectedScript()->wrapObjectProperty(errorString, detailsObject, toV8StringInternalized(m_isolate, "function"), scope.objectGroupName())) - return; - - protocol::ErrorSupport errors; - std::unique_ptr protocolDetails = GeneratorObjectDetails::parse(toProtocolValue(scope.context(), detailsObject).get(), &errors); - if (hasInternalError(errorString, !protocolDetails)) - return; - *outDetails = std::move(protocolDetails); -} - -void V8DebuggerAgentImpl::getCollectionEntries(ErrorString* errorString, const String16& objectId, std::unique_ptr>* outEntries) -{ - if (!checkEnabled(errorString)) - return; - InjectedScript::ObjectScope scope(errorString, m_debugger, m_session->contextGroupId(), objectId); - if (!scope.initialize()) - return; - if (!scope.object()->IsObject()) { - *errorString = "Object with given id is not a collection"; - return; - } - v8::Local object = scope.object().As(); - - v8::Local entriesValue = m_debugger->collectionEntries(object); - if (hasInternalError(errorString, entriesValue.IsEmpty())) - return; - if (entriesValue->IsUndefined()) { - *errorString = "Object with given id is not a collection"; - return; - } - if (hasInternalError(errorString, !entriesValue->IsArray())) - return; - v8::Local entriesArray = entriesValue.As(); - if (!scope.injectedScript()->wrapPropertyInArray(errorString, entriesArray, toV8StringInternalized(m_isolate, "key"), scope.objectGroupName())) - return; - if (!scope.injectedScript()->wrapPropertyInArray(errorString, entriesArray, toV8StringInternalized(m_isolate, "value"), scope.objectGroupName())) - return; - protocol::ErrorSupport errors; - std::unique_ptr> entries = protocol::Array::parse(toProtocolValue(scope.context(), entriesArray).get(), &errors); - if (hasInternalError(errorString, !entries)) - return; - *outEntries = std::move(entries); + v8::HandleScope handles(m_isolate); + *scriptSource = toProtocolString(it->second->source(m_isolate)); } void V8DebuggerAgentImpl::schedulePauseOnNextStatement(const String16& breakReason, std::unique_ptr data) @@ -797,26 +625,6 @@ void V8DebuggerAgentImpl::cancelPauseOnNextStatement() debugger().setPauseOnNextStatement(false); } -bool V8DebuggerAgentImpl::v8AsyncTaskEventsEnabled() const -{ - return m_maxAsyncCallStackDepth; -} - -void V8DebuggerAgentImpl::didReceiveV8AsyncTaskEvent(v8::Local context, const String16& eventType, const String16& eventName, int id) -{ - DCHECK(m_maxAsyncCallStackDepth); - // The scopes for the ids are defined by the eventName namespaces. There are currently two namespaces: "Object." and "Promise.". - void* ptr = reinterpret_cast(id * 4 + (eventName[0] == 'P' ? 2 : 0) + 1); - if (eventType == v8AsyncTaskEventEnqueue) - asyncTaskScheduled(eventName, ptr, false); - else if (eventType == v8AsyncTaskEventWillHandle) - asyncTaskStarted(ptr); - else if (eventType == v8AsyncTaskEventDidHandle) - asyncTaskFinished(ptr); - else - NOTREACHED(); -} - void V8DebuggerAgentImpl::pause(ErrorString* errorString) { if (!checkEnabled(errorString)) @@ -846,7 +654,7 @@ void V8DebuggerAgentImpl::stepOver(ErrorString* errorString) if (!assertPaused(errorString)) return; // StepOver at function return point should fallback to StepInto. - JavaScriptCallFrame* frame = m_pausedCallFrames.size() ? m_pausedCallFrames[0] : nullptr; + JavaScriptCallFrame* frame = !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr; if (frame && frame->isAtReturn()) { stepInto(errorString); return; @@ -903,7 +711,7 @@ void V8DebuggerAgentImpl::setPauseOnExceptionsImpl(ErrorString* errorString, int if (debugger().getPauseOnExceptionsState() != pauseState) *errorString = "Internal error. Could not change pause on exceptions state"; else - m_state->setNumber(DebuggerAgentState::pauseOnExceptionsState, pauseState); + m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState); } void V8DebuggerAgentImpl::evaluateOnCallFrame(ErrorString* errorString, @@ -982,71 +790,8 @@ void V8DebuggerAgentImpl::setAsyncCallStackDepth(ErrorString* errorString, int d { if (!checkEnabled(errorString)) return; - m_state->setNumber(DebuggerAgentState::asyncCallStackDepth, depth); - internalSetAsyncCallStackDepth(depth); -} - -void V8DebuggerAgentImpl::asyncTaskScheduled(const String16& taskName, void* task, bool recurring) -{ - if (!m_maxAsyncCallStackDepth) - return; - v8::HandleScope scope(m_isolate); - std::unique_ptr chain = V8StackTraceImpl::capture(this, V8StackTrace::maxCallStackSizeToCapture, taskName); - if (chain) { - m_asyncTaskStacks.set(task, std::move(chain)); - if (recurring) - m_recurringTasks.add(task); - } -} - -void V8DebuggerAgentImpl::asyncTaskCanceled(void* task) -{ - if (!m_maxAsyncCallStackDepth) - return; - m_asyncTaskStacks.remove(task); - m_recurringTasks.remove(task); -} - -void V8DebuggerAgentImpl::asyncTaskStarted(void* task) -{ - // Not enabled, return. - if (!m_maxAsyncCallStackDepth) - return; - - m_currentTasks.append(task); - V8StackTraceImpl* stack = m_asyncTaskStacks.get(task); - // Needs to support following order of events: - // - asyncTaskScheduled - // <-- attached here --> - // - asyncTaskStarted - // - asyncTaskCanceled <-- canceled before finished - // <-- async stack requested here --> - // - asyncTaskFinished - m_currentStacks.append(stack ? stack->cloneImpl() : nullptr); -} - -void V8DebuggerAgentImpl::asyncTaskFinished(void* task) -{ - if (!m_maxAsyncCallStackDepth) - return; - // We could start instrumenting half way and the stack is empty. - if (!m_currentStacks.size()) - return; - - DCHECK(m_currentTasks.last() == task); - m_currentTasks.removeLast(); - - m_currentStacks.removeLast(); - if (!m_recurringTasks.contains(task)) - m_asyncTaskStacks.remove(task); -} - -void V8DebuggerAgentImpl::allAsyncTasksCanceled() -{ - m_asyncTaskStacks.clear(); - m_recurringTasks.clear(); - m_currentStacks.clear(); - m_currentTasks.clear(); + m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, depth); + m_debugger->setAsyncCallStackDepth(this, depth); } void V8DebuggerAgentImpl::setBlackboxPatterns(ErrorString* errorString, std::unique_ptr> patterns) @@ -1058,10 +803,13 @@ void V8DebuggerAgentImpl::setBlackboxPatterns(ErrorString* errorString, std::uni } String16Builder patternBuilder; - patternBuilder.append("("); - for (size_t i = 0; i < patterns->length() - 1; ++i) - patternBuilder.append(patterns->get(i) + "|"); - patternBuilder.append(patterns->get(patterns->length() - 1) + ")"); + patternBuilder.append('('); + for (size_t i = 0; i < patterns->length() - 1; ++i) { + patternBuilder.append(patterns->get(i)); + patternBuilder.append("|"); + } + patternBuilder.append(patterns->get(patterns->length() - 1)); + patternBuilder.append(')'); String16 pattern = patternBuilder.toString(); if (!setBlackboxPattern(errorString, pattern)) return; @@ -1079,30 +827,32 @@ bool V8DebuggerAgentImpl::setBlackboxPattern(ErrorString* errorString, const Str return true; } -void V8DebuggerAgentImpl::setBlackboxedRanges(ErrorString* error, const String16& scriptId, std::unique_ptr> inPositions) +void V8DebuggerAgentImpl::setBlackboxedRanges(ErrorString* error, const String16& scriptId, + std::unique_ptr> inPositions) { - if (!m_scripts.contains(scriptId)) { + if (m_scripts.find(scriptId) == m_scripts.end()) { *error = "No script with passed id."; return; } if (!inPositions->length()) { - m_blackboxedPositions.remove(scriptId); + m_blackboxedPositions.erase(scriptId); return; } - protocol::Vector> positions(inPositions->length()); - for (size_t i = 0; i < positions.size(); ++i) { + std::vector> positions; + positions.reserve(inPositions->length()); + for (size_t i = 0; i < inPositions->length(); ++i) { protocol::Debugger::ScriptPosition* position = inPositions->get(i); - if (position->getLine() < 0) { + if (position->getLineNumber() < 0) { *error = "Position missing 'line' or 'line' < 0."; return; } - if (position->getColumn() < 0) { + if (position->getColumnNumber() < 0) { *error = "Position missing 'column' or 'column' < 0."; return; } - positions[i] = std::make_pair(position->getLine(), position->getColumn()); + positions.push_back(std::make_pair(position->getLineNumber(), position->getColumnNumber())); } for (size_t i = 1; i < positions.size(); ++i) { @@ -1114,7 +864,7 @@ void V8DebuggerAgentImpl::setBlackboxedRanges(ErrorString* error, const String16 return; } - m_blackboxedPositions.set(scriptId, positions); + m_blackboxedPositions[scriptId] = positions; } void V8DebuggerAgentImpl::willExecuteScript(int scriptId) @@ -1124,7 +874,7 @@ void V8DebuggerAgentImpl::willExecuteScript(int scriptId) if (m_scheduledDebuggerStep != StepInto) return; // Skip unknown scripts (e.g. InjectedScript). - if (!m_scripts.contains(String16::number(scriptId))) + if (m_scripts.find(String16::fromInteger(scriptId)) == m_scripts.end()) return; schedulePauseOnNextStatementIfSteppingInto(); } @@ -1172,19 +922,14 @@ std::unique_ptr> V8DebuggerAgentImpl::currentCallFrames(ErrorSt if (m_pausedContext.IsEmpty() || !m_pausedCallFrames.size()) return Array::create(); ErrorString ignored; - InjectedScript* topFrameInjectedScript = m_session->findInjectedScript(&ignored, V8Debugger::contextId(m_pausedContext.Get(m_isolate))); - if (!topFrameInjectedScript) { - // Context has been reported as removed while on pause. - return Array::create(); - } - v8::HandleScope handles(m_isolate); - v8::Local context = topFrameInjectedScript->context()->context(); - v8::Context::Scope contextScope(context); + v8::Local debuggerContext = v8::Debug::GetDebugContext(m_isolate); + v8::Context::Scope contextScope(debuggerContext); v8::Local objects = v8::Array::New(m_isolate); + for (size_t frameOrdinal = 0; frameOrdinal < m_pausedCallFrames.size(); ++frameOrdinal) { - JavaScriptCallFrame* currentCallFrame = m_pausedCallFrames[frameOrdinal]; + const std::unique_ptr& currentCallFrame = m_pausedCallFrames[frameOrdinal]; v8::Local details = currentCallFrame->details(); if (hasInternalError(errorString, details.IsEmpty())) @@ -1192,34 +937,42 @@ std::unique_ptr> V8DebuggerAgentImpl::currentCallFrames(ErrorSt int contextId = currentCallFrame->contextId(); InjectedScript* injectedScript = contextId ? m_session->findInjectedScript(&ignored, contextId) : nullptr; - if (!injectedScript) - injectedScript = topFrameInjectedScript; - String16 callFrameId = RemoteCallFrameId::serialize(injectedScript->context()->contextId(), frameOrdinal); - if (hasInternalError(errorString, !details->Set(context, toV8StringInternalized(m_isolate, "callFrameId"), toV8String(m_isolate, callFrameId)).FromMaybe(false))) + String16 callFrameId = RemoteCallFrameId::serialize(contextId, frameOrdinal); + if (hasInternalError(errorString, !details->Set(debuggerContext, toV8StringInternalized(m_isolate, "callFrameId"), toV8String(m_isolate, callFrameId)).FromMaybe(false))) return Array::create(); - v8::Local scopeChain; - if (hasInternalError(errorString, !details->Get(context, toV8StringInternalized(m_isolate, "scopeChain")).ToLocal(&scopeChain) || !scopeChain->IsArray())) - return Array::create(); - v8::Local scopeChainArray = scopeChain.As(); - if (!injectedScript->wrapPropertyInArray(errorString, scopeChainArray, toV8StringInternalized(m_isolate, "object"), V8InspectorSession::backtraceObjectGroup)) - return Array::create(); - - if (!injectedScript->wrapObjectProperty(errorString, details, toV8StringInternalized(m_isolate, "this"), V8InspectorSession::backtraceObjectGroup)) - return Array::create(); - - if (details->Has(context, toV8StringInternalized(m_isolate, "returnValue")).FromMaybe(false)) { - if (!injectedScript->wrapObjectProperty(errorString, details, toV8StringInternalized(m_isolate, "returnValue"), V8InspectorSession::backtraceObjectGroup)) + if (injectedScript) { + v8::Local scopeChain; + if (hasInternalError(errorString, !details->Get(debuggerContext, toV8StringInternalized(m_isolate, "scopeChain")).ToLocal(&scopeChain) || !scopeChain->IsArray())) + return Array::create(); + v8::Local scopeChainArray = scopeChain.As(); + if (!injectedScript->wrapPropertyInArray(errorString, scopeChainArray, toV8StringInternalized(m_isolate, "object"), V8InspectorSession::backtraceObjectGroup)) + return Array::create(); + if (!injectedScript->wrapObjectProperty(errorString, details, toV8StringInternalized(m_isolate, "this"), V8InspectorSession::backtraceObjectGroup)) + return Array::create(); + if (details->Has(debuggerContext, toV8StringInternalized(m_isolate, "returnValue")).FromMaybe(false)) { + if (!injectedScript->wrapObjectProperty(errorString, details, toV8StringInternalized(m_isolate, "returnValue"), V8InspectorSession::backtraceObjectGroup)) + return Array::create(); + } + } else { + if (hasInternalError(errorString, !details->Set(debuggerContext, toV8StringInternalized(m_isolate, "scopeChain"), v8::Array::New(m_isolate, 0)).FromMaybe(false))) + return Array::create(); + v8::Local remoteObject = v8::Object::New(m_isolate); + if (hasInternalError(errorString, !remoteObject->Set(debuggerContext, toV8StringInternalized(m_isolate, "type"), toV8StringInternalized(m_isolate, "undefined")).FromMaybe(false))) + return Array::create(); + if (hasInternalError(errorString, !details->Set(debuggerContext, toV8StringInternalized(m_isolate, "this"), remoteObject).FromMaybe(false))) + return Array::create(); + if (hasInternalError(errorString, !details->Delete(debuggerContext, toV8StringInternalized(m_isolate, "returnValue")).FromMaybe(false))) return Array::create(); } - if (hasInternalError(errorString, !objects->Set(context, frameOrdinal, details).FromMaybe(false))) + if (hasInternalError(errorString, !objects->Set(debuggerContext, frameOrdinal, details).FromMaybe(false))) return Array::create(); } protocol::ErrorSupport errorSupport; - std::unique_ptr> callFrames = Array::parse(toProtocolValue(context, objects).get(), &errorSupport); + std::unique_ptr> callFrames = Array::parse(toProtocolValue(debuggerContext, objects).get(), &errorSupport); if (hasInternalError(errorString, !callFrames)) return Array::create(); return callFrames; @@ -1227,60 +980,50 @@ std::unique_ptr> V8DebuggerAgentImpl::currentCallFrames(ErrorSt std::unique_ptr V8DebuggerAgentImpl::currentAsyncStackTrace() { - if (m_pausedContext.IsEmpty() || !m_maxAsyncCallStackDepth || !m_currentStacks.size() || !m_currentStacks.last()) - return nullptr; - - return m_currentStacks.last()->buildInspectorObjectForTail(this); -} - -V8StackTraceImpl* V8DebuggerAgentImpl::currentAsyncCallChain() -{ - if (!m_currentStacks.size()) + if (m_pausedContext.IsEmpty()) return nullptr; - return m_currentStacks.last(); + V8StackTraceImpl* stackTrace = m_debugger->currentAsyncCallChain(); + return stackTrace ? stackTrace->buildInspectorObjectForTail(m_debugger) : nullptr; } -void V8DebuggerAgentImpl::didParseSource(const V8DebuggerParsedScript& parsedScript) +void V8DebuggerAgentImpl::didParseSource(std::unique_ptr script, bool success) { - V8DebuggerScript script = parsedScript.script; - + v8::HandleScope handles(m_isolate); + String16 scriptSource = toProtocolString(script->source(m_isolate)); bool isDeprecatedSourceURL = false; - if (!parsedScript.success) - script.setSourceURL(V8ContentSearchUtil::findSourceURL(script.source(), false, &isDeprecatedSourceURL)); - else if (script.hasSourceURL()) - V8ContentSearchUtil::findSourceURL(script.source(), false, &isDeprecatedSourceURL); + if (!success) + script->setSourceURL(V8ContentSearchUtil::findSourceURL(scriptSource, false, &isDeprecatedSourceURL)); + else if (script->hasSourceURL()) + V8ContentSearchUtil::findSourceURL(scriptSource, false, &isDeprecatedSourceURL); bool isDeprecatedSourceMappingURL = false; - if (!parsedScript.success) - script.setSourceMappingURL(V8ContentSearchUtil::findSourceMapURL(script.source(), false, &isDeprecatedSourceMappingURL)); - else if (!script.sourceMappingURL().isEmpty()) - V8ContentSearchUtil::findSourceMapURL(script.source(), false, &isDeprecatedSourceMappingURL); - - script.setHash(calculateHash(script.source())); - - int executionContextId = script.executionContextId(); - bool isContentScript = script.isContentScript(); - bool isInternalScript = script.isInternalScript(); - bool isLiveEdit = script.isLiveEdit(); - bool hasSourceURL = script.hasSourceURL(); - String16 scriptURL = script.sourceURL(); - String16 sourceMapURL = script.sourceMappingURL(); + if (!success) + script->setSourceMappingURL(V8ContentSearchUtil::findSourceMapURL(scriptSource, false, &isDeprecatedSourceMappingURL)); + else if (!script->sourceMappingURL().isEmpty()) + V8ContentSearchUtil::findSourceMapURL(scriptSource, false, &isDeprecatedSourceMappingURL); + + bool isContentScript = script->isContentScript(); + bool isInternalScript = script->isInternalScript(); + bool isLiveEdit = script->isLiveEdit(); + bool hasSourceURL = script->hasSourceURL(); + String16 scriptId = script->scriptId(); + String16 scriptURL = script->sourceURL(); bool deprecatedCommentWasUsed = isDeprecatedSourceURL || isDeprecatedSourceMappingURL; - const Maybe& sourceMapURLParam = sourceMapURL; + const Maybe& sourceMapURLParam = script->sourceMappingURL(); const bool* isContentScriptParam = isContentScript ? &isContentScript : nullptr; const bool* isInternalScriptParam = isInternalScript ? &isInternalScript : nullptr; const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; const bool* deprecatedCommentWasUsedParam = deprecatedCommentWasUsed ? &deprecatedCommentWasUsed : nullptr; - if (parsedScript.success) - m_frontend.scriptParsed(parsedScript.scriptId, scriptURL, script.startLine(), script.startColumn(), script.endLine(), script.endColumn(), executionContextId, script.hash(), isContentScriptParam, isInternalScriptParam, isLiveEditParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); + if (success) + m_frontend.scriptParsed(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), isContentScriptParam, isInternalScriptParam, isLiveEditParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); else - m_frontend.scriptFailedToParse(parsedScript.scriptId, scriptURL, script.startLine(), script.startColumn(), script.endLine(), script.endColumn(), executionContextId, script.hash(), isContentScriptParam, isInternalScriptParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); + m_frontend.scriptFailedToParse(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), isContentScriptParam, isInternalScriptParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); - m_scripts.set(parsedScript.scriptId, script); + m_scripts[scriptId] = std::move(script); - if (scriptURL.isEmpty() || !parsedScript.success) + if (scriptURL.isEmpty() || !success) return; protocol::DictionaryValue* breakpointsCookie = m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); @@ -1297,24 +1040,24 @@ void V8DebuggerAgentImpl::didParseSource(const V8DebuggerParsedScript& parsedScr if (!matches(m_debugger, scriptURL, url, isRegex)) continue; ScriptBreakpoint breakpoint; - breakpointObject->getNumber(DebuggerAgentState::lineNumber, &breakpoint.lineNumber); - breakpointObject->getNumber(DebuggerAgentState::columnNumber, &breakpoint.columnNumber); + breakpointObject->getInteger(DebuggerAgentState::lineNumber, &breakpoint.lineNumber); + breakpointObject->getInteger(DebuggerAgentState::columnNumber, &breakpoint.columnNumber); breakpointObject->getString(DebuggerAgentState::condition, &breakpoint.condition); - std::unique_ptr location = resolveBreakpoint(cookie.first, parsedScript.scriptId, breakpoint, UserBreakpointSource); + std::unique_ptr location = resolveBreakpoint(cookie.first, scriptId, breakpoint, UserBreakpointSource); if (location) m_frontend.breakpointResolved(cookie.first, std::move(location)); } } -V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(v8::Local context, v8::Local exception, const protocol::Vector& hitBreakpoints, bool isPromiseRejection) +V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(v8::Local context, v8::Local exception, const std::vector& hitBreakpoints, bool isPromiseRejection) { JavaScriptCallFrames callFrames = debugger().currentCallFrames(1); - JavaScriptCallFrame* topCallFrame = callFrames.size() > 0 ? callFrames[0] : nullptr; + JavaScriptCallFrame* topCallFrame = !callFrames.empty() ? callFrames.begin()->get() : nullptr; V8DebuggerAgentImpl::SkipPauseRequest result; if (m_skipAllPauses) result = RequestContinue; - else if (!hitBreakpoints.isEmpty()) + else if (!hitBreakpoints.empty()) result = RequestNoSkip; // Don't skip explicit breakpoints even if set in frameworks. else if (!exception.IsEmpty()) result = shouldSkipExceptionPause(topCallFrame); @@ -1331,13 +1074,14 @@ V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(v8::LocalfindInjectedScript(&ignored, V8Debugger::contextId(context)); + InjectedScript* injectedScript = m_session->findInjectedScript(&ignored, V8DebuggerImpl::contextId(context)); if (injectedScript) { m_breakReason = isPromiseRejection ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection : protocol::Debugger::Paused::ReasonEnum::Exception; ErrorString errorString; @@ -1352,10 +1096,10 @@ V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(v8::Localsecond->first; + const String16& localId = breakpointIterator->second.first; hitBreakpointIds->addItem(localId); - BreakpointSource source = breakpointIterator->second->second; + BreakpointSource source = breakpointIterator->second.second; if (m_breakReason == protocol::Debugger::Paused::ReasonEnum::Other && source == DebugCommandBreakpointSource) m_breakReason = protocol::Debugger::Paused::ReasonEnum::DebugCommand; } @@ -1440,7 +1184,6 @@ void V8DebuggerAgentImpl::reset() m_scripts.clear(); m_blackboxedPositions.clear(); m_breakpointIdToDebuggerBreakpointIds.clear(); - allAsyncTasksCanceled(); } } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h similarity index 82% rename from deps/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h index ab04bb50a43a11..b6aea619e10318 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h @@ -10,6 +10,8 @@ #include "platform/v8_inspector/V8DebuggerImpl.h" #include "platform/v8_inspector/protocol/Debugger.h" +#include + namespace blink { class JavaScriptCallFrame; @@ -84,21 +86,12 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { Maybe>* optOutCallFrames, Maybe* optOutStackChanged, Maybe* optOutAsyncStackTrace, - Maybe* optOutCompileError) override; + Maybe* optOutCompileError) override; void restartFrame(ErrorString*, const String16& callFrameId, std::unique_ptr>* newCallFrames, Maybe* asyncStackTrace) override; void getScriptSource(ErrorString*, const String16& scriptId, String16* scriptSource) override; - void getFunctionDetails(ErrorString*, - const String16& functionId, - std::unique_ptr*) override; - void getGeneratorObjectDetails(ErrorString*, - const String16& objectId, - std::unique_ptr*) override; - void getCollectionEntries(ErrorString*, - const String16& objectId, - std::unique_ptr>*) override; void pause(ErrorString*) override; void resume(ErrorString*) override; void stepOver(ErrorString*) override; @@ -138,27 +131,16 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { void breakProgram(const String16& breakReason, std::unique_ptr data); void breakProgramOnException(const String16& breakReason, std::unique_ptr data); - // Async call stacks implementation. - void asyncTaskScheduled(const String16& taskName, void* task, bool recurring); - void asyncTaskCanceled(void* task); - void asyncTaskStarted(void* task); - void asyncTaskFinished(void* task); - void allAsyncTasksCanceled(); - void reset(); // Interface for V8DebuggerImpl - SkipPauseRequest didPause(v8::Local, v8::Local exception, const protocol::Vector& hitBreakpoints, bool isPromiseRejection); + SkipPauseRequest didPause(v8::Local, v8::Local exception, const std::vector& hitBreakpoints, bool isPromiseRejection); void didContinue(); - void didParseSource(const V8DebuggerParsedScript&); - bool v8AsyncTaskEventsEnabled() const; - void didReceiveV8AsyncTaskEvent(v8::Local, const String16& eventType, const String16& eventName, int id); + void didParseSource(std::unique_ptr, bool success); void willExecuteScript(int scriptId); void didExecuteScript(); v8::Isolate* isolate() { return m_isolate; } - int maxAsyncCallChainDepth() { return m_maxAsyncCallStackDepth; } - V8StackTraceImpl* currentAsyncCallChain(); private: bool checkEnabled(ErrorString*); @@ -190,8 +172,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { bool setBlackboxPattern(ErrorString*, const String16& pattern); - using ScriptsMap = protocol::HashMap; - using BreakpointIdToDebuggerBreakpointIdsMap = protocol::HashMap>; + using ScriptsMap = protocol::HashMap>; + using BreakpointIdToDebuggerBreakpointIdsMap = protocol::HashMap>; using DebugServerBreakpointToBreakpointIdAndSourceMap = protocol::HashMap>; using MuteBreakpoins = protocol::HashMap>; @@ -227,14 +209,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { int m_recursionLevelForStepFrame; bool m_skipAllPauses; - using AsyncTaskToStackTrace = protocol::HashMap>; - AsyncTaskToStackTrace m_asyncTaskStacks; - protocol::HashSet m_recurringTasks; - int m_maxAsyncCallStackDepth; - protocol::Vector m_currentTasks; - protocol::Vector> m_currentStacks; std::unique_ptr m_blackboxPattern; - protocol::HashMap>> m_blackboxedPositions; + protocol::HashMap>> m_blackboxedPositions; }; } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/V8DebuggerImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.cpp similarity index 59% rename from deps/v8_inspector/platform/v8_inspector/V8DebuggerImpl.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.cpp index 387bc4b86693a1..4d84b32cece21b 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8DebuggerImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.cpp @@ -36,8 +36,12 @@ #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/ScriptBreakpoint.h" #include "platform/v8_inspector/V8Compat.h" +#include "platform/v8_inspector/V8ConsoleAgentImpl.h" +#include "platform/v8_inspector/V8ConsoleMessage.h" #include "platform/v8_inspector/V8DebuggerAgentImpl.h" +#include "platform/v8_inspector/V8InjectedScriptHost.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" +#include "platform/v8_inspector/V8InternalValueType.h" #include "platform/v8_inspector/V8RuntimeAgentImpl.h" #include "platform/v8_inspector/V8StackTraceImpl.h" #include "platform/v8_inspector/V8StringUtil.h" @@ -50,6 +54,9 @@ namespace { const char stepIntoV8MethodName[] = "stepIntoStatement"; const char stepOutV8MethodName[] = "stepOutOfFunction"; volatile int s_lastContextId = 0; +static const char v8AsyncTaskEventEnqueue[] = "enqueue"; +static const char v8AsyncTaskEventWillHandle[] = "willHandle"; +static const char v8AsyncTaskEventDidHandle[] = "didHandle"; inline v8::Local v8Boolean(bool value, v8::Isolate* isolate) { @@ -77,9 +84,12 @@ std::unique_ptr V8Debugger::create(v8::Isolate* isolate, V8DebuggerC V8DebuggerImpl::V8DebuggerImpl(v8::Isolate* isolate, V8DebuggerClient* client) : m_isolate(isolate) , m_client(client) + , m_capturingStackTracesCount(0) + , m_lastExceptionId(0) , m_enabledAgentsCount(0) , m_breakpointsActivated(true) , m_runningNestedMessageLoop(false) + , m_maxAsyncCallStackDepth(0) { } @@ -102,6 +112,7 @@ void V8DebuggerImpl::disable() clearBreakpoints(); m_debuggerScript.Reset(); m_debuggerContext.Reset(); + allAsyncTasksCanceled(); v8::Debug::SetDebugEventListener(m_isolate, nullptr); } @@ -110,7 +121,8 @@ bool V8DebuggerImpl::enabled() const return !m_debuggerScript.IsEmpty(); } -int V8Debugger::contextId(v8::Local context) +// static +int V8DebuggerImpl::contextId(v8::Local context) { v8::Local data = context->GetEmbedderData(static_cast(v8::Context::kDebugIdIndex)); if (data.IsEmpty() || !data->IsString()) @@ -127,7 +139,8 @@ int V8Debugger::contextId(v8::Local context) return dataString.substring(commaPos + 1, commaPos2 - commaPos - 1).toInt(); } -static int getGroupId(v8::Local context) +// static +int V8DebuggerImpl::getGroupId(v8::Local context) { v8::Local data = context->GetEmbedderData(static_cast(v8::Context::kDebugIdIndex)); if (data.IsEmpty() || !data->IsString()) @@ -157,10 +170,13 @@ V8DebuggerAgentImpl* V8DebuggerImpl::findEnabledDebuggerAgent(int contextGroupId { if (!contextGroupId) return nullptr; - V8InspectorSessionImpl* session = m_sessions.get(contextGroupId); - if (session && session->debuggerAgent()->enabled()) - return session->debuggerAgent(); - return nullptr; + SessionMap::iterator it = m_sessions.find(contextGroupId); + if (it == m_sessions.end()) + return nullptr; + V8DebuggerAgentImpl* agent = it->second->debuggerAgent(); + if (!agent->enabled()) + return nullptr; + return agent; } V8DebuggerAgentImpl* V8DebuggerImpl::findEnabledDebuggerAgent(v8::Local context) @@ -168,7 +184,7 @@ V8DebuggerAgentImpl* V8DebuggerImpl::findEnabledDebuggerAgent(v8::Local& result) +void V8DebuggerImpl::getCompiledScripts(int contextGroupId, std::vector>& result) { v8::HandleScope scope(m_isolate); v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); @@ -181,9 +197,11 @@ void V8DebuggerImpl::getCompiledScripts(int contextGroupId, protocol::VectorIsArray()); v8::Local scriptsArray = v8::Local::Cast(value); - result.resize(scriptsArray->Length()); - for (unsigned i = 0; i < scriptsArray->Length(); ++i) - result[i] = createParsedScript(v8::Local::Cast(scriptsArray->Get(v8::Integer::New(m_isolate, i))), true); + result.reserve(scriptsArray->Length()); + for (unsigned i = 0; i < scriptsArray->Length(); ++i) { + v8::Local scriptObject = v8::Local::Cast(scriptsArray->Get(v8::Integer::New(m_isolate, i))); + result.push_back(wrapUnique(new V8DebuggerScript(m_isolate, scriptObject, inLiveEditScope))); + } } String16 V8DebuggerImpl::setBreakpoint(const String16& sourceID, const ScriptBreakpoint& scriptBreakpoint, int* actualLineNumber, int* actualColumnNumber, bool interstatementLocation) @@ -298,7 +316,7 @@ void V8DebuggerImpl::breakProgram() v8::HandleScope scope(m_isolate); v8::Local breakFunction; - if (!v8::Function::New(m_isolate->GetCurrentContext(), &V8DebuggerImpl::breakProgramCallback, v8::External::New(m_isolate, this)).ToLocal(&breakFunction)) + if (!v8::Function::New(m_isolate->GetCurrentContext(), &V8DebuggerImpl::breakProgramCallback, v8::External::New(m_isolate, this), 0, v8::ConstructorBehavior::kThrow).ToLocal(&breakFunction)) return; v8::Debug::Call(debuggerContext(), breakFunction).ToLocalChecked(); } @@ -351,7 +369,7 @@ void V8DebuggerImpl::clearStepping() callDebuggerMethod("clearStepping", 0, argv); } -bool V8DebuggerImpl::setScriptSource(const String16& sourceID, const String16& newContent, bool preview, ErrorString* error, Maybe* errorData, JavaScriptCallFrames* newCallFrames, Maybe* stackChanged) +bool V8DebuggerImpl::setScriptSource(const String16& sourceID, v8::Local newSource, bool preview, ErrorString* error, Maybe* exceptionDetails, JavaScriptCallFrames* newCallFrames, Maybe* stackChanged) { class EnableLiveEditScope { public: @@ -376,7 +394,7 @@ bool V8DebuggerImpl::setScriptSource(const String16& sourceID, const String16& n if (!isPaused()) contextScope = wrapUnique(new v8::Context::Scope(debuggerContext())); - v8::Local argv[] = { toV8String(m_isolate, sourceID), toV8String(m_isolate, newContent), v8Boolean(preview, m_isolate) }; + v8::Local argv[] = { toV8String(m_isolate, sourceID), newSource, v8Boolean(preview, m_isolate) }; v8::Local v8result; { @@ -402,17 +420,20 @@ bool V8DebuggerImpl::setScriptSource(const String16& sourceID, const String16& n { *stackChanged = resultTuple->Get(1)->BooleanValue(); // Call stack may have changed after if the edited function was on the stack. - if (!preview && isPaused()) - newCallFrames->swap(currentCallFrames()); + if (!preview && isPaused()) { + JavaScriptCallFrames frames = currentCallFrames(); + newCallFrames->swap(frames); + } return true; } // Compile error. case 1: { - *errorData = protocol::Debugger::SetScriptSourceError::create() - .setMessage(toProtocolStringWithTypeCheck(resultTuple->Get(2))) - .setLineNumber(resultTuple->Get(3)->ToInteger(m_isolate)->Value()) - .setColumnNumber(resultTuple->Get(4)->ToInteger(m_isolate)->Value()).build(); + *exceptionDetails = protocol::Runtime::ExceptionDetails::create() + .setText(toProtocolStringWithTypeCheck(resultTuple->Get(2))) + .setScriptId(String16("0")) + .setLineNumber(resultTuple->Get(3)->ToInteger(m_isolate)->Value() - 1) + .setColumnNumber(resultTuple->Get(4)->ToInteger(m_isolate)->Value() - 1).build(); return false; } } @@ -444,7 +465,7 @@ JavaScriptCallFrames V8DebuggerImpl::currentCallFrames(int limit) if (!callFrameValue->IsObject()) return JavaScriptCallFrames(); v8::Local callFrameObject = callFrameValue.As(); - callFrames.append(JavaScriptCallFrame::create(debuggerContext(), v8::Local::Cast(callFrameObject))); + callFrames.push_back(JavaScriptCallFrame::create(debuggerContext(), v8::Local::Cast(callFrameObject))); } return callFrames; } @@ -475,13 +496,13 @@ void V8DebuggerImpl::handleProgramBreak(v8::Local pausedContext, v8 if (!agent) return; - protocol::Vector breakpointIds; + std::vector breakpointIds; if (!hitBreakpointNumbers.IsEmpty()) { - breakpointIds.resize(hitBreakpointNumbers->Length()); + breakpointIds.reserve(hitBreakpointNumbers->Length()); for (size_t i = 0; i < hitBreakpointNumbers->Length(); i++) { v8::Local hitBreakpointNumber = hitBreakpointNumbers->Get(i); DCHECK(!hitBreakpointNumber.IsEmpty() && hitBreakpointNumber->IsInt32()); - breakpointIds[i] = String16::number(hitBreakpointNumber->Int32Value()); + breakpointIds.push_back(String16::fromInteger(hitBreakpointNumber->Int32Value())); } } @@ -539,6 +560,12 @@ void V8DebuggerImpl::handleV8DebugEvent(const v8::Debug::EventDetails& eventDeta v8::Local eventContext = eventDetails.GetEventContext(); DCHECK(!eventContext.IsEmpty()); + if (event == v8::AsyncTaskEvent) { + v8::HandleScope scope(m_isolate); + handleV8AsyncTaskEvent(eventContext, eventDetails.GetExecutionState(), eventDetails.GetEventData()); + return; + } + V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(eventContext); if (agent) { v8::HandleScope scope(m_isolate); @@ -547,8 +574,8 @@ void V8DebuggerImpl::handleV8DebugEvent(const v8::Debug::EventDetails& eventDeta v8::Local argv[] = { eventDetails.GetEventData() }; v8::Local value = callDebuggerMethod("getAfterCompileScript", 1, argv).ToLocalChecked(); DCHECK(value->IsObject()); - v8::Local object = v8::Local::Cast(value); - agent->didParseSource(createParsedScript(object, event == v8::AfterCompile)); + v8::Local scriptObject = v8::Local::Cast(value); + agent->didParseSource(wrapUnique(new V8DebuggerScript(m_isolate, scriptObject, inLiveEditScope)), event == v8::AfterCompile); } else if (event == v8::Exception) { v8::Local eventData = eventDetails.GetEventData(); v8::Local exception = callInternalGetterFunction(eventData, "exception"); @@ -560,42 +587,35 @@ void V8DebuggerImpl::handleV8DebugEvent(const v8::Debug::EventDetails& eventDeta v8::Local hitBreakpoints = callDebuggerMethod("getBreakpointNumbers", 1, argv).ToLocalChecked(); DCHECK(hitBreakpoints->IsArray()); handleProgramBreak(eventContext, eventDetails.GetExecutionState(), v8::Local(), hitBreakpoints.As()); - } else if (event == v8::AsyncTaskEvent) { - if (agent->v8AsyncTaskEventsEnabled()) - handleV8AsyncTaskEvent(agent, eventContext, eventDetails.GetExecutionState(), eventDetails.GetEventData()); } } } -void V8DebuggerImpl::handleV8AsyncTaskEvent(V8DebuggerAgentImpl* agent, v8::Local context, v8::Local executionState, v8::Local eventData) +void V8DebuggerImpl::handleV8AsyncTaskEvent(v8::Local context, v8::Local executionState, v8::Local eventData) { + if (!m_maxAsyncCallStackDepth) + return; + String16 type = toProtocolStringWithTypeCheck(callInternalGetterFunction(eventData, "type")); String16 name = toProtocolStringWithTypeCheck(callInternalGetterFunction(eventData, "name")); int id = callInternalGetterFunction(eventData, "id")->ToInteger(m_isolate)->Value(); - agent->didReceiveV8AsyncTaskEvent(context, type, name, id); + // The scopes for the ids are defined by the eventData.name namespaces. There are currently two namespaces: "Object." and "Promise.". + void* ptr = reinterpret_cast(id * 4 + (name[0] == 'P' ? 2 : 0) + 1); + if (type == v8AsyncTaskEventEnqueue) + asyncTaskScheduled(name, ptr, false); + else if (type == v8AsyncTaskEventWillHandle) + asyncTaskStarted(ptr); + else if (type == v8AsyncTaskEventDidHandle) + asyncTaskFinished(ptr); + else + NOTREACHED(); } -V8DebuggerParsedScript V8DebuggerImpl::createParsedScript(v8::Local object, bool success) +V8StackTraceImpl* V8DebuggerImpl::currentAsyncCallChain() { - v8::Local id = object->Get(v8InternalizedString("id")); - DCHECK(!id.IsEmpty() && id->IsInt32()); - - V8DebuggerParsedScript parsedScript; - parsedScript.scriptId = String16::number(id->Int32Value()); - parsedScript.script.setURL(toProtocolStringWithTypeCheck(object->Get(v8InternalizedString("name")))) - .setSourceURL(toProtocolStringWithTypeCheck(object->Get(v8InternalizedString("sourceURL")))) - .setSourceMappingURL(toProtocolStringWithTypeCheck(object->Get(v8InternalizedString("sourceMappingURL")))) - .setSource(toProtocolStringWithTypeCheck(object->Get(v8InternalizedString("source")))) - .setStartLine(object->Get(v8InternalizedString("startLine"))->ToInteger(m_isolate)->Value()) - .setStartColumn(object->Get(v8InternalizedString("startColumn"))->ToInteger(m_isolate)->Value()) - .setEndLine(object->Get(v8InternalizedString("endLine"))->ToInteger(m_isolate)->Value()) - .setEndColumn(object->Get(v8InternalizedString("endColumn"))->ToInteger(m_isolate)->Value()) - .setIsContentScript(object->Get(v8InternalizedString("isContentScript"))->ToBoolean(m_isolate)->Value()) - .setIsInternalScript(object->Get(v8InternalizedString("isInternalScript"))->ToBoolean(m_isolate)->Value()) - .setExecutionContextId(object->Get(v8InternalizedString("executionContextId"))->ToInteger(m_isolate)->Value()) - .setIsLiveEdit(inLiveEditScope); - parsedScript.success = success; - return parsedScript; + if (!m_currentStacks.size()) + return nullptr; + return m_currentStacks.back().get(); } void V8DebuggerImpl::compileDebuggerScript() @@ -634,27 +654,118 @@ v8::MaybeLocal V8DebuggerImpl::functionScopes(v8::Local return v8::Local::New(m_isolate, v8::Undefined(m_isolate)); } v8::Local argv[] = { function }; - return callDebuggerMethod("getFunctionScopes", 1, argv); + v8::Local scopesValue; + if (!callDebuggerMethod("getFunctionScopes", 1, argv).ToLocal(&scopesValue) || !scopesValue->IsArray()) + return v8::MaybeLocal(); + v8::Local scopes = scopesValue.As(); + v8::Local context = m_debuggerContext.Get(m_isolate); + if (!markAsInternal(context, scopes, V8InternalValueType::kScopeList)) + return v8::MaybeLocal(); + if (!markArrayEntriesAsInternal(context, scopes, V8InternalValueType::kScope)) + return v8::MaybeLocal(); + if (!scopes->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) + return v8::Undefined(m_isolate); + return scopes; +} + +v8::MaybeLocal V8DebuggerImpl::internalProperties(v8::Local context, v8::Local value) +{ + v8::Local properties; + if (!v8::Debug::GetInternalProperties(m_isolate, value).ToLocal(&properties)) + return v8::MaybeLocal(); + if (value->IsFunction()) { + v8::Local function = value.As(); + v8::Local location = functionLocation(context, function); + if (location->IsObject()) { + properties->Set(properties->Length(), v8InternalizedString("[[FunctionLocation]]")); + properties->Set(properties->Length(), location); + } + if (function->IsGeneratorFunction()) { + properties->Set(properties->Length(), v8InternalizedString("[[IsGenerator]]")); + properties->Set(properties->Length(), v8::True(m_isolate)); + } + } + if (!enabled()) + return properties; + if (value->IsMap() || value->IsWeakMap() || value->IsSet() || value->IsWeakSet() || value->IsSetIterator() || value->IsMapIterator()) { + v8::Local entries = collectionEntries(context, v8::Local::Cast(value)); + if (entries->IsArray()) { + properties->Set(properties->Length(), v8InternalizedString("[[Entries]]")); + properties->Set(properties->Length(), entries); + } + } + if (value->IsGeneratorObject()) { + v8::Local location = generatorObjectLocation(v8::Local::Cast(value)); + if (location->IsObject()) { + properties->Set(properties->Length(), v8InternalizedString("[[GeneratorLocation]]")); + properties->Set(properties->Length(), location); + } + } + if (value->IsFunction()) { + v8::Local function = value.As(); + v8::Local boundFunction = function->GetBoundFunction(); + v8::Local scopes; + if (boundFunction->IsUndefined() && functionScopes(function).ToLocal(&scopes)) { + properties->Set(properties->Length(), v8InternalizedString("[[Scopes]]")); + properties->Set(properties->Length(), scopes); + } + } + return properties; } -v8::Local V8DebuggerImpl::generatorObjectDetails(v8::Local& object) +v8::Local V8DebuggerImpl::collectionEntries(v8::Local context, v8::Local object) { if (!enabled()) { NOTREACHED(); - return v8::Local::New(m_isolate, v8::Undefined(m_isolate)); + return v8::Undefined(m_isolate); } v8::Local argv[] = { object }; - return callDebuggerMethod("getGeneratorObjectDetails", 1, argv).ToLocalChecked(); + v8::Local entriesValue = callDebuggerMethod("getCollectionEntries", 1, argv).ToLocalChecked(); + if (!entriesValue->IsArray()) + return v8::Undefined(m_isolate); + v8::Local entries = entriesValue.As(); + if (!markArrayEntriesAsInternal(context, entries, V8InternalValueType::kEntry)) + return v8::Undefined(m_isolate); + if (!entries->SetPrototype(context, v8::Null(m_isolate)).FromMaybe(false)) + return v8::Undefined(m_isolate); + return entries; } -v8::Local V8DebuggerImpl::collectionEntries(v8::Local& object) +v8::Local V8DebuggerImpl::generatorObjectLocation(v8::Local object) { if (!enabled()) { NOTREACHED(); - return v8::Local::New(m_isolate, v8::Undefined(m_isolate)); + return v8::Null(m_isolate); } v8::Local argv[] = { object }; - return callDebuggerMethod("getCollectionEntries", 1, argv).ToLocalChecked(); + v8::Local location = callDebuggerMethod("getGeneratorObjectLocation", 1, argv).ToLocalChecked(); + if (!location->IsObject()) + return v8::Null(m_isolate); + v8::Local context = m_debuggerContext.Get(m_isolate); + if (!markAsInternal(context, v8::Local::Cast(location), V8InternalValueType::kLocation)) + return v8::Null(m_isolate); + return location; +} + +v8::Local V8DebuggerImpl::functionLocation(v8::Local context, v8::Local function) +{ + int scriptId = function->ScriptId(); + if (scriptId == v8::UnboundScript::kNoScriptId) + return v8::Null(m_isolate); + int lineNumber = function->GetScriptLineNumber(); + int columnNumber = function->GetScriptColumnNumber(); + if (lineNumber == v8::Function::kLineOffsetNotFound || columnNumber == v8::Function::kLineOffsetNotFound) + return v8::Null(m_isolate); + v8::Local location = v8::Object::New(m_isolate); + if (!location->Set(context, v8InternalizedString("scriptId"), toV8String(m_isolate, String16::fromInteger(scriptId))).FromMaybe(false)) + return v8::Null(m_isolate); + if (!location->Set(context, v8InternalizedString("lineNumber"), v8::Integer::New(m_isolate, lineNumber)).FromMaybe(false)) + return v8::Null(m_isolate); + if (!location->Set(context, v8InternalizedString("columnNumber"), v8::Integer::New(m_isolate, columnNumber)).FromMaybe(false)) + return v8::Null(m_isolate); + if (!markAsInternal(context, location, V8InternalValueType::kLocation)) + return v8::Null(m_isolate); + return location; } bool V8DebuggerImpl::isPaused() @@ -725,24 +836,59 @@ v8::Local V8DebuggerImpl::compileInternalScript(v8::Localsecond.get(); +} + std::unique_ptr V8DebuggerImpl::createStackTrace(v8::Local stackTrace) { - V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(m_isolate->GetCurrentContext()); - return V8StackTraceImpl::create(agent, stackTrace, V8StackTrace::maxCallStackSizeToCapture); + int contextGroupId = m_isolate->InContext() ? getGroupId(m_isolate->GetCurrentContext()) : 0; + return V8StackTraceImpl::create(this, contextGroupId, stackTrace, V8StackTraceImpl::maxCallStackSizeToCapture); } std::unique_ptr V8DebuggerImpl::connect(int contextGroupId, protocol::FrontendChannel* channel, V8InspectorSessionClient* client, const String16* state) { - DCHECK(!m_sessions.contains(contextGroupId)); - std::unique_ptr session = V8InspectorSessionImpl::create(this, contextGroupId, channel, client, state); - m_sessions.set(contextGroupId, session.get()); + DCHECK(m_sessions.find(contextGroupId) == m_sessions.cend()); + std::unique_ptr session = + V8InspectorSessionImpl::create(this, contextGroupId, channel, client, state); + m_sessions[contextGroupId] = session.get(); return std::move(session); } void V8DebuggerImpl::disconnect(V8InspectorSessionImpl* session) { - DCHECK(m_sessions.contains(session->contextGroupId())); - m_sessions.remove(session->contextGroupId()); + DCHECK(m_sessions.find(session->contextGroupId()) != m_sessions.end()); + m_sessions.erase(session->contextGroupId()); +} + +InspectedContext* V8DebuggerImpl::getContext(int groupId, int contextId) const +{ + ContextsByGroupMap::const_iterator contextGroupIt = m_contexts.find(groupId); + if (contextGroupIt == m_contexts.end()) + return nullptr; + + ContextByIdMap::iterator contextIt = contextGroupIt->second->find(contextId); + if (contextIt == contextGroupIt->second->end()) + return nullptr; + + return contextIt->second.get(); } void V8DebuggerImpl::contextCreated(const V8ContextInfo& info) @@ -750,44 +896,144 @@ void V8DebuggerImpl::contextCreated(const V8ContextInfo& info) DCHECK(info.context->GetIsolate() == m_isolate); // TODO(dgozman): make s_lastContextId non-static. int contextId = atomicIncrement(&s_lastContextId); - String16 debugData = String16::number(info.contextGroupId) + "," + String16::number(contextId) + "," + (info.isDefault ? "default" : "nondefault"); + String16 debugData = String16::fromInteger(info.contextGroupId) + "," + String16::fromInteger(contextId) + "," + (info.isDefault ? "default" : "nondefault"); v8::HandleScope scope(m_isolate); v8::Context::Scope contextScope(info.context); info.context->SetEmbedderData(static_cast(v8::Context::kDebugIdIndex), toV8String(m_isolate, debugData)); - if (!m_contexts.contains(info.contextGroupId)) - m_contexts.set(info.contextGroupId, wrapUnique(new ContextByIdMap())); - DCHECK(!m_contexts.get(info.contextGroupId)->contains(contextId)); + ContextsByGroupMap::iterator contextIt = m_contexts.find(info.contextGroupId); + if (contextIt == m_contexts.end()) + contextIt = m_contexts.insert(std::make_pair(info.contextGroupId, wrapUnique(new ContextByIdMap()))).first; - std::unique_ptr contextOwner(new InspectedContext(this, info, contextId)); - InspectedContext* inspectedContext = contextOwner.get(); - m_contexts.get(info.contextGroupId)->set(contextId, std::move(contextOwner)); + const auto& contextById = contextIt->second; - if (V8InspectorSessionImpl* session = m_sessions.get(info.contextGroupId)) - session->runtimeAgent()->reportExecutionContextCreated(inspectedContext); + DCHECK(contextById->find(contextId) == contextById->cend()); + InspectedContext* context = new InspectedContext(this, info, contextId); + (*contextById)[contextId] = wrapUnique(context); + SessionMap::iterator sessionIt = m_sessions.find(info.contextGroupId); + if (sessionIt != m_sessions.end()) + sessionIt->second->runtimeAgent()->reportExecutionContextCreated(context); } void V8DebuggerImpl::contextDestroyed(v8::Local context) { - int contextId = V8Debugger::contextId(context); + int contextId = V8DebuggerImpl::contextId(context); int contextGroupId = getGroupId(context); - if (!m_contexts.contains(contextGroupId) || !m_contexts.get(contextGroupId)->contains(contextId)) - return; - InspectedContext* inspectedContext = m_contexts.get(contextGroupId)->get(contextId); - if (V8InspectorSessionImpl* session = m_sessions.get(contextGroupId)) - session->runtimeAgent()->reportExecutionContextDestroyed(inspectedContext); + ConsoleStorageMap::iterator storageIt = m_consoleStorageMap.find(contextGroupId); + if (storageIt != m_consoleStorageMap.end()) + storageIt->second->contextDestroyed(contextId); + + InspectedContext* inspectedContext = getContext(contextGroupId, contextId); + if (!inspectedContext) + return; - m_contexts.get(contextGroupId)->remove(contextId); - if (m_contexts.get(contextGroupId)->isEmpty()) - m_contexts.remove(contextGroupId); + SessionMap::iterator iter = m_sessions.find(contextGroupId); + if (iter != m_sessions.end()) + iter->second->runtimeAgent()->reportExecutionContextDestroyed(inspectedContext); + discardInspectedContext(contextGroupId, contextId); } void V8DebuggerImpl::resetContextGroup(int contextGroupId) { - if (V8InspectorSessionImpl* session = m_sessions.get(contextGroupId)) - session->reset(); - m_contexts.remove(contextGroupId); + m_consoleStorageMap.erase(contextGroupId); + SessionMap::iterator session = m_sessions.find(contextGroupId); + if (session != m_sessions.end()) + session->second->reset(); + m_contexts.erase(contextGroupId); +} + +void V8DebuggerImpl::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) +{ + if (depth <= 0) + m_maxAsyncCallStackDepthMap.erase(agent); + else + m_maxAsyncCallStackDepthMap[agent] = depth; + + int maxAsyncCallStackDepth = 0; + for (const auto& pair : m_maxAsyncCallStackDepthMap) { + if (pair.second > maxAsyncCallStackDepth) + maxAsyncCallStackDepth = pair.second; + } + + if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) + return; + + if (maxAsyncCallStackDepth && !m_maxAsyncCallStackDepth) + m_client->enableAsyncInstrumentation(); + else if (!maxAsyncCallStackDepth && m_maxAsyncCallStackDepth) + m_client->disableAsyncInstrumentation(); + + m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; + if (!maxAsyncCallStackDepth) + allAsyncTasksCanceled(); +} + +void V8DebuggerImpl::asyncTaskScheduled(const String16& taskName, void* task, bool recurring) +{ + if (!m_maxAsyncCallStackDepth) + return; + v8::HandleScope scope(m_isolate); + int contextGroupId = m_isolate->InContext() ? getGroupId(m_isolate->GetCurrentContext()) : 0; + std::unique_ptr chain = V8StackTraceImpl::capture(this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, taskName); + if (chain) { + m_asyncTaskStacks[task] = std::move(chain); + if (recurring) + m_recurringTasks.insert(task); + } +} + +void V8DebuggerImpl::asyncTaskCanceled(void* task) +{ + if (!m_maxAsyncCallStackDepth) + return; + m_asyncTaskStacks.erase(task); + m_recurringTasks.erase(task); +} + +void V8DebuggerImpl::asyncTaskStarted(void* task) +{ + // Not enabled, return. + if (!m_maxAsyncCallStackDepth) + return; + + m_currentTasks.push_back(task); + AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(task); + // Needs to support following order of events: + // - asyncTaskScheduled + // <-- attached here --> + // - asyncTaskStarted + // - asyncTaskCanceled <-- canceled before finished + // <-- async stack requested here --> + // - asyncTaskFinished + std::unique_ptr stack; + if (stackIt != m_asyncTaskStacks.end() && stackIt->second) + stack = stackIt->second->cloneImpl(); + m_currentStacks.push_back(std::move(stack)); +} + +void V8DebuggerImpl::asyncTaskFinished(void* task) +{ + if (!m_maxAsyncCallStackDepth) + return; + // We could start instrumenting half way and the stack is empty. + if (!m_currentStacks.size()) + return; + + DCHECK(m_currentTasks.back() == task); + m_currentTasks.pop_back(); + + m_currentStacks.pop_back(); + if (m_recurringTasks.find(task) == m_recurringTasks.end()) + m_asyncTaskStacks.erase(task); +} + +void V8DebuggerImpl::allAsyncTasksCanceled() +{ + m_asyncTaskStacks.clear(); + m_recurringTasks.clear(); + m_currentStacks.clear(); + m_currentTasks.clear(); } void V8DebuggerImpl::willExecuteScript(v8::Local context, int scriptId) @@ -812,10 +1058,64 @@ void V8DebuggerImpl::idleFinished() m_isolate->GetCpuProfiler()->SetIdle(false); } -std::unique_ptr V8DebuggerImpl::captureStackTrace(size_t maxStackSize) +void V8DebuggerImpl::logToConsole(v8::Local context, v8::Local arg1, v8::Local arg2) +{ + int contextGroupId = getGroupId(context); + InspectedContext* inspectedContext = getContext(contextGroupId, contextId(context)); + if (!inspectedContext) + return; + std::vector> arguments; + if (!arg1.IsEmpty()) + arguments.push_back(arg1); + if (!arg2.IsEmpty()) + arguments.push_back(arg2); + ensureConsoleMessageStorage(contextGroupId)->addMessage(V8ConsoleMessage::createForConsoleAPI(m_client->currentTimeMS(), ConsoleAPIType::kLog, arguments, captureStackTrace(false), inspectedContext)); +} + +void V8DebuggerImpl::exceptionThrown(int contextGroupId, const String16& errorMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId) +{ + unsigned exceptionId = ++m_lastExceptionId; + std::unique_ptr consoleMessage = V8ConsoleMessage::createForException(m_client->currentTimeMS(), errorMessage, url, lineNumber, columnNumber, std::move(stackTrace), scriptId, m_isolate, 0, v8::Local(), exceptionId); + ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage)); +} + +unsigned V8DebuggerImpl::promiseRejected(v8::Local context, const String16& errorMessage, v8::Local exception, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId) +{ + int contextGroupId = getGroupId(context); + if (!contextGroupId) + return 0; + unsigned exceptionId = ++m_lastExceptionId; + std::unique_ptr consoleMessage = V8ConsoleMessage::createForException(m_client->currentTimeMS(), errorMessage, url, lineNumber, columnNumber, std::move(stackTrace), scriptId, m_isolate, contextId(context), exception, exceptionId); + ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage)); + return exceptionId; +} + +void V8DebuggerImpl::promiseRejectionRevoked(v8::Local context, unsigned promiseRejectionId) +{ + int contextGroupId = getGroupId(context); + if (!contextGroupId) + return; + + std::unique_ptr consoleMessage = V8ConsoleMessage::createForRevokedException(m_client->currentTimeMS(), "Handler added to rejected promise", promiseRejectionId); + ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage)); +} + +std::unique_ptr V8DebuggerImpl::captureStackTrace(bool fullStack) { - V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(m_isolate->GetCurrentContext()); - return V8StackTraceImpl::capture(agent, maxStackSize); + if (!m_isolate->InContext()) + return nullptr; + + v8::HandleScope handles(m_isolate); + int contextGroupId = getGroupId(m_isolate->GetCurrentContext()); + if (!contextGroupId) + return nullptr; + + size_t stackSize = fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; + SessionMap::iterator sessionIt = m_sessions.find(contextGroupId); + if (sessionIt != m_sessions.end() && sessionIt->second->runtimeAgent()->enabled()) + stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; + + return V8StackTraceImpl::capture(this, contextGroupId, stackSize); } v8::Local V8DebuggerImpl::regexContext() @@ -827,23 +1127,25 @@ v8::Local V8DebuggerImpl::regexContext() void V8DebuggerImpl::discardInspectedContext(int contextGroupId, int contextId) { - if (!m_contexts.contains(contextGroupId) || !m_contexts.get(contextGroupId)->contains(contextId)) + if (!getContext(contextGroupId, contextId)) return; - m_contexts.get(contextGroupId)->remove(contextId); - if (m_contexts.get(contextGroupId)->isEmpty()) - m_contexts.remove(contextGroupId); + m_contexts[contextGroupId]->erase(contextId); + if (m_contexts[contextGroupId]->empty()) + m_contexts.erase(contextGroupId); } const V8DebuggerImpl::ContextByIdMap* V8DebuggerImpl::contextGroup(int contextGroupId) { - if (!m_contexts.contains(contextGroupId)) - return nullptr; - return m_contexts.get(contextGroupId); + ContextsByGroupMap::iterator iter = m_contexts.find(contextGroupId); + return iter == m_contexts.end() ? nullptr : iter->second.get(); } V8InspectorSessionImpl* V8DebuggerImpl::sessionForContextGroup(int contextGroupId) { - return contextGroupId ? m_sessions.get(contextGroupId) : nullptr; + if (!contextGroupId) + return nullptr; + SessionMap::iterator iter = m_sessions.find(contextGroupId); + return iter == m_sessions.end() ? nullptr : iter->second; } } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h similarity index 69% rename from deps/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h index b62a2a003a5661..0be86bfb28ae52 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h @@ -31,6 +31,7 @@ #ifndef V8DebuggerImpl_h #define V8DebuggerImpl_h +#include "platform/inspector_protocol/Collections.h" #include "platform/inspector_protocol/Maybe.h" #include "platform/inspector_protocol/Platform.h" #include "platform/v8_inspector/JavaScriptCallFrame.h" @@ -40,6 +41,9 @@ #include #include +#include + +#include namespace blink { @@ -47,9 +51,11 @@ using protocol::Maybe; struct ScriptBreakpoint; class InspectedContext; +class V8ConsoleMessageStorage; class V8DebuggerAgentImpl; class V8InspectorSessionImpl; class V8RuntimeAgentImpl; +class V8StackTraceImpl; class V8DebuggerImpl : public V8Debugger { PROTOCOL_DISALLOW_COPY(V8DebuggerImpl); @@ -57,6 +63,9 @@ class V8DebuggerImpl : public V8Debugger { V8DebuggerImpl(v8::Isolate*, V8DebuggerClient*); ~V8DebuggerImpl() override; + static int contextId(v8::Local); + static int getGroupId(v8::Local); + bool enabled() const; String16 setBreakpoint(const String16& sourceID, const ScriptBreakpoint&, int* actualLineNumber, int* actualColumnNumber, bool interstatementLocation); @@ -80,22 +89,24 @@ class V8DebuggerImpl : public V8Debugger { void stepOutOfFunction(); void clearStepping(); - bool setScriptSource(const String16& sourceID, const String16& newContent, bool preview, ErrorString*, Maybe*, JavaScriptCallFrames* newCallFrames, Maybe* stackChanged); + bool setScriptSource(const String16& sourceID, v8::Local newSource, bool preview, ErrorString*, Maybe*, JavaScriptCallFrames* newCallFrames, Maybe* stackChanged); JavaScriptCallFrames currentCallFrames(int limit = 0); // Each script inherits debug data from v8::Context where it has been compiled. // Only scripts whose debug data matches |contextGroupId| will be reported. // Passing 0 will result in reporting all scripts. - void getCompiledScripts(int contextGroupId, protocol::Vector&); + void getCompiledScripts(int contextGroupId, std::vector>&); void debuggerAgentEnabled(); void debuggerAgentDisabled(); - bool isPaused() override; + bool isPaused(); v8::Local pausedContext() { return m_pausedContext; } + int maxAsyncCallChainDepth() { return m_maxAsyncCallStackDepth; } + V8StackTraceImpl* currentAsyncCallChain(); + void setAsyncCallStackDepth(V8DebuggerAgentImpl*, int); v8::MaybeLocal functionScopes(v8::Local); - v8::Local generatorObjectDetails(v8::Local&); - v8::Local collectionEntries(v8::Local&); + v8::MaybeLocal internalProperties(v8::Local, v8::Local); v8::Isolate* isolate() const { return m_isolate; } V8DebuggerClient* client() { return m_client; } @@ -106,6 +117,10 @@ class V8DebuggerImpl : public V8Debugger { v8::Local compileInternalScript(v8::Local, v8::Local, const String16& fileName); v8::Local regexContext(); + void enableStackCapturingIfNeeded(); + void disableStackCapturingIfNeeded(); + V8ConsoleMessageStorage* ensureConsoleMessageStorage(int contextGroupId); + // V8Debugger implementation std::unique_ptr connect(int contextGroupId, protocol::FrontendChannel*, V8InspectorSessionClient*, const String16* state) override; void contextCreated(const V8ContextInfo&) override; @@ -115,14 +130,24 @@ class V8DebuggerImpl : public V8Debugger { void didExecuteScript(v8::Local) override; void idleStarted() override; void idleFinished() override; + void logToConsole(v8::Local, v8::Local arg1, v8::Local arg2) override; + void exceptionThrown(int contextGroupId, const String16& errorMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) override; + unsigned promiseRejected(v8::Local, const String16& errorMessage, v8::Local exception, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) override; + void promiseRejectionRevoked(v8::Local, unsigned promiseRejectionId) override; std::unique_ptr createStackTrace(v8::Local) override; - std::unique_ptr captureStackTrace(size_t maxStackSize) override; + std::unique_ptr captureStackTrace(bool fullStack) override; + void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) override; + void asyncTaskCanceled(void* task) override; + void asyncTaskStarted(void* task) override; + void asyncTaskFinished(void* task) override; + void allAsyncTasksCanceled() override; using ContextByIdMap = protocol::HashMap>; void discardInspectedContext(int contextGroupId, int contextId); const ContextByIdMap* contextGroup(int contextGroupId); void disconnect(V8InspectorSessionImpl*); V8InspectorSessionImpl* sessionForContextGroup(int contextGroupId); + InspectedContext* getContext(int groupId, int contextId) const; private: void enable(); @@ -135,8 +160,6 @@ class V8DebuggerImpl : public V8Debugger { v8::Local debuggerContext() const; void clearBreakpoints(); - V8DebuggerParsedScript createParsedScript(v8::Local sourceObject, bool success); - static void breakProgramCallback(const v8::FunctionCallbackInfo&); void handleProgramBreak(v8::Local pausedContext, v8::Local executionState, v8::Local exception, v8::Local hitBreakpoints, bool isPromiseRejection = false); static void v8DebugEventCallback(const v8::Debug::EventDetails&); @@ -145,14 +168,23 @@ class V8DebuggerImpl : public V8Debugger { v8::Local v8InternalizedString(const char*) const; - void handleV8AsyncTaskEvent(V8DebuggerAgentImpl*, v8::Local, v8::Local executionState, v8::Local eventData); + void handleV8AsyncTaskEvent(v8::Local, v8::Local executionState, v8::Local eventData); + + using ContextsByGroupMap = protocol::HashMap>; + + v8::Local collectionEntries(v8::Local, v8::Local); + v8::Local generatorObjectLocation(v8::Local); + v8::Local functionLocation(v8::Local, v8::Local); v8::Isolate* m_isolate; V8DebuggerClient* m_client; - using ContextsByGroupMap = protocol::HashMap>; ContextsByGroupMap m_contexts; using SessionMap = protocol::HashMap; SessionMap m_sessions; + using ConsoleStorageMap = protocol::HashMap>; + ConsoleStorageMap m_consoleStorageMap; + int m_capturingStackTracesCount; + unsigned m_lastExceptionId; int m_enabledAgentsCount; bool m_breakpointsActivated; v8::Global m_debuggerScript; @@ -161,6 +193,14 @@ class V8DebuggerImpl : public V8Debugger { v8::Local m_pausedContext; bool m_runningNestedMessageLoop; v8::Global m_regexContext; + + using AsyncTaskToStackTrace = protocol::HashMap>; + AsyncTaskToStackTrace m_asyncTaskStacks; + protocol::HashSet m_recurringTasks; + int m_maxAsyncCallStackDepth; + std::vector m_currentTasks; + std::vector> m_currentStacks; + protocol::HashMap m_maxAsyncCallStackDepthMap; }; } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp new file mode 100644 index 00000000000000..91a060b954e023 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp @@ -0,0 +1,121 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/v8_inspector/V8DebuggerScript.h" + +#include "platform/inspector_protocol/Collections.h" +#include "platform/inspector_protocol/Platform.h" +#include "platform/v8_inspector/V8StringUtil.h" + +namespace blink { + +static const LChar hexDigits[17] = "0123456789ABCDEF"; + +static void appendUnsignedAsHex(unsigned number, String16Builder* destination) +{ + for (size_t i = 0; i < 8; ++i) { + destination->append(hexDigits[number & 0xF]); + number >>= 4; + } +} + +// Hash algorithm for substrings is described in "Über die Komplexität der Multiplikation in +// eingeschränkten Branchingprogrammmodellen" by Woelfe. +// http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000 +static String16 calculateHash(const String16& str) +{ + static uint64_t prime[] = { 0x3FB75161, 0xAB1F4E4F, 0x82675BC5, 0xCD924D35, 0x81ABE279 }; + static uint64_t random[] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; + static uint32_t randomOdd[] = { 0xB4663807, 0xCC322BF5, 0xD4F91BBD, 0xA7BEA11D, 0x8F462907 }; + + uint64_t hashes[] = { 0, 0, 0, 0, 0 }; + uint64_t zi[] = { 1, 1, 1, 1, 1 }; + + const size_t hashesSize = PROTOCOL_ARRAY_LENGTH(hashes); + + size_t current = 0; + const uint32_t* data = nullptr; + data = reinterpret_cast(str.characters16()); + for (size_t i = 0; i < str.sizeInBytes() / 4; i += 4) { + uint32_t v = data[i]; + uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF; + hashes[current] = (hashes[current] + zi[current] * xi) % prime[current]; + zi[current] = (zi[current] * random[current]) % prime[current]; + current = current == hashesSize - 1 ? 0 : current + 1; + } + if (str.sizeInBytes() % 4) { + uint32_t v = 0; + for (size_t i = str.sizeInBytes() - str.sizeInBytes() % 4; i < str.sizeInBytes(); ++i) { + v <<= 8; + v |= reinterpret_cast(data)[i]; + } + uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF; + hashes[current] = (hashes[current] + zi[current] * xi) % prime[current]; + zi[current] = (zi[current] * random[current]) % prime[current]; + current = current == hashesSize - 1 ? 0 : current + 1; + } + + for (size_t i = 0; i < hashesSize; ++i) + hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i]; + + String16Builder hash; + for (size_t i = 0; i < hashesSize; ++i) + appendUnsignedAsHex(hashes[i], &hash); + return hash.toString(); +} + +V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, v8::Local object, bool isLiveEdit) +{ + v8::Local idValue = object->Get(toV8StringInternalized(isolate, "id")); + DCHECK(!idValue.IsEmpty() && idValue->IsInt32()); + m_id = String16::fromInteger(idValue->Int32Value()); + + m_url = toProtocolStringWithTypeCheck(object->Get(toV8StringInternalized(isolate, "name"))); + m_sourceURL = toProtocolStringWithTypeCheck(object->Get(toV8StringInternalized(isolate, "sourceURL"))); + m_sourceMappingURL = toProtocolStringWithTypeCheck(object->Get(toV8StringInternalized(isolate, "sourceMappingURL"))); + m_startLine = object->Get(toV8StringInternalized(isolate, "startLine"))->ToInteger(isolate)->Value(); + m_startColumn = object->Get(toV8StringInternalized(isolate, "startColumn"))->ToInteger(isolate)->Value(); + m_endLine = object->Get(toV8StringInternalized(isolate, "endLine"))->ToInteger(isolate)->Value(); + m_endColumn = object->Get(toV8StringInternalized(isolate, "endColumn"))->ToInteger(isolate)->Value(); + m_isContentScript = object->Get(toV8StringInternalized(isolate, "isContentScript"))->ToBoolean(isolate)->Value(); + m_isInternalScript = object->Get(toV8StringInternalized(isolate, "isInternalScript"))->ToBoolean(isolate)->Value(); + m_executionContextId = object->Get(toV8StringInternalized(isolate, "executionContextId"))->ToInteger(isolate)->Value(); + m_isLiveEdit = isLiveEdit; + + v8::Local sourceValue = object->Get(toV8StringInternalized(isolate, "source")); + if (!sourceValue.IsEmpty() && sourceValue->IsString()) + setSource(isolate, sourceValue.As()); +} + +V8DebuggerScript::~V8DebuggerScript() +{ +} + +String16 V8DebuggerScript::sourceURL() const +{ + return m_sourceURL.isEmpty() ? m_url : m_sourceURL; +} + +v8::Local V8DebuggerScript::source(v8::Isolate* isolate) const +{ + return m_source.Get(isolate); +} + +void V8DebuggerScript::setSourceURL(const String16& sourceURL) +{ + m_sourceURL = sourceURL; +} + +void V8DebuggerScript::setSourceMappingURL(const String16& sourceMappingURL) +{ + m_sourceMappingURL = sourceMappingURL; +} + +void V8DebuggerScript::setSource(v8::Isolate* isolate, v8::Local source) +{ + m_source.Reset(isolate, source); + m_hash = calculateHash(toProtocolString(source)); +} + +} // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/V8DebuggerScript.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.h similarity index 77% rename from deps/v8_inspector/platform/v8_inspector/V8DebuggerScript.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.h index 55080be0dacea7..60d93d81986493 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8DebuggerScript.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.h @@ -37,15 +37,17 @@ namespace blink { class V8DebuggerScript { - PROTOCOL_DISALLOW_NEW(); + PROTOCOL_DISALLOW_COPY(V8DebuggerScript); public: - V8DebuggerScript(); + V8DebuggerScript(v8::Isolate*, v8::Local, bool isLiveEdit); + ~V8DebuggerScript(); + String16 scriptId() const { return m_id; } String16 url() const { return m_url; } bool hasSourceURL() const { return !m_sourceURL.isEmpty(); } String16 sourceURL() const; String16 sourceMappingURL() const { return m_sourceMappingURL; } - String16 source() const { return m_source; } + v8::Local source(v8::Isolate*) const; String16 hash() const { return m_hash; } int startLine() const { return m_startLine; } int startColumn() const { return m_startColumn; } @@ -56,25 +58,16 @@ class V8DebuggerScript { bool isInternalScript() const { return m_isInternalScript; } bool isLiveEdit() const { return m_isLiveEdit; } - V8DebuggerScript& setURL(const String16&); - V8DebuggerScript& setSourceURL(const String16&); - V8DebuggerScript& setSourceMappingURL(const String16&); - V8DebuggerScript& setSource(const String16&); - V8DebuggerScript& setHash(const String16&); - V8DebuggerScript& setStartLine(int); - V8DebuggerScript& setStartColumn(int); - V8DebuggerScript& setEndLine(int); - V8DebuggerScript& setEndColumn(int); - V8DebuggerScript& setExecutionContextId(int); - V8DebuggerScript& setIsContentScript(bool); - V8DebuggerScript& setIsInternalScript(bool); - V8DebuggerScript& setIsLiveEdit(bool); + void setSourceURL(const String16&); + void setSourceMappingURL(const String16&); + void setSource(v8::Isolate*, v8::Local); private: + String16 m_id; String16 m_url; String16 m_sourceURL; String16 m_sourceMappingURL; - String16 m_source; + v8::Global m_source; String16 m_hash; int m_startLine; int m_startColumn; @@ -86,12 +79,6 @@ class V8DebuggerScript { bool m_isLiveEdit; }; -struct V8DebuggerParsedScript { - String16 scriptId; - V8DebuggerScript script; - bool success; -}; - } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp similarity index 92% rename from deps/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp index 83e24d79be63fc..73edc7260f0719 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp @@ -50,27 +50,27 @@ V8FunctionCall::V8FunctionCall(V8DebuggerImpl* debugger, v8::Local void V8FunctionCall::appendArgument(v8::Local value) { - m_arguments.append(value); + m_arguments.push_back(value); } void V8FunctionCall::appendArgument(const String16& argument) { - m_arguments.append(toV8String(m_context->GetIsolate(), argument)); + m_arguments.push_back(toV8String(m_context->GetIsolate(), argument)); } void V8FunctionCall::appendArgument(int argument) { - m_arguments.append(v8::Number::New(m_context->GetIsolate(), argument)); + m_arguments.push_back(v8::Number::New(m_context->GetIsolate(), argument)); } void V8FunctionCall::appendArgument(bool argument) { - m_arguments.append(argument ? v8::True(m_context->GetIsolate()) : v8::False(m_context->GetIsolate())); + m_arguments.push_back(argument ? v8::True(m_context->GetIsolate()) : v8::False(m_context->GetIsolate())); } void V8FunctionCall::appendUndefinedArgument() { - m_arguments.append(v8::Undefined(m_context->GetIsolate())); + m_arguments.push_back(v8::Undefined(m_context->GetIsolate())); } v8::Local V8FunctionCall::call(bool& hadException, bool reportExceptions) diff --git a/deps/v8_inspector/platform/v8_inspector/V8FunctionCall.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.h similarity index 95% rename from deps/v8_inspector/platform/v8_inspector/V8FunctionCall.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.h index 1c94d240aa91de..0b9d4e2a5096f1 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8FunctionCall.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.h @@ -31,7 +31,6 @@ #ifndef V8FunctionCall_h #define V8FunctionCall_h -#include "platform/inspector_protocol/Collections.h" #include "platform/inspector_protocol/String16.h" #include @@ -58,7 +57,7 @@ class V8FunctionCall { protected: V8DebuggerImpl* m_debugger; v8::Local m_context; - protocol::Vector> m_arguments; + std::vector> m_arguments; v8::Local m_name; v8::Local m_value; }; diff --git a/deps/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp similarity index 95% rename from deps/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp index 3281d1ba1dab48..240dc3d27492e9 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp @@ -45,14 +45,12 @@ class HeapSnapshotProgress final : public v8::ActivityControl { class GlobalObjectNameResolver final : public v8::HeapProfiler::ObjectNameResolver { public: - explicit GlobalObjectNameResolver(V8InspectorSessionImpl* session) : m_offset(0), m_session(session) - { - m_strings.resize(10000); - } + explicit GlobalObjectNameResolver(V8InspectorSessionImpl* session) + : m_offset(0), m_strings(10000), m_session(session) {} const char* GetName(v8::Local object) override { - int contextId = V8Debugger::contextId(object->CreationContext()); + int contextId = V8DebuggerImpl::contextId(object->CreationContext()); if (!contextId) return ""; ErrorString errorString; @@ -75,7 +73,7 @@ class GlobalObjectNameResolver final : public v8::HeapProfiler::ObjectNameResolv private: size_t m_offset; - protocol::Vector m_strings; + std::vector m_strings; V8InspectorSessionImpl* m_session; }; @@ -171,7 +169,7 @@ void V8HeapProfilerAgentImpl::restore() #if V8_MAJOR_VERSION >= 5 if (m_state->booleanProperty(HeapProfilerAgentState::samplingHeapProfilerEnabled, false)) { ErrorString error; - double samplingInterval = m_state->numberProperty(HeapProfilerAgentState::samplingHeapProfilerInterval, -1); + double samplingInterval = m_state->doubleProperty(HeapProfilerAgentState::samplingHeapProfilerInterval, -1); DCHECK_GE(samplingInterval, 0); startSampling(&error, Maybe(samplingInterval)); } @@ -260,7 +258,7 @@ void V8HeapProfilerAgentImpl::getObjectByHeapObjectId(ErrorString* error, const return; } - *result = m_session->wrapObject(heapObject->CreationContext(), heapObject, objectGroup.fromMaybe("")); + *result = m_session->wrapObject(heapObject->CreationContext(), heapObject, objectGroup.fromMaybe(""), false); if (!result) *error = "Object is not available"; } @@ -297,7 +295,7 @@ void V8HeapProfilerAgentImpl::getHeapObjectId(ErrorString* errorString, const St return; v8::SnapshotObjectId id = m_isolate->GetHeapProfiler()->GetObjectId(value); - *heapSnapshotObjectId = String16::number(id); + *heapSnapshotObjectId = String16::fromInteger(id); } void V8HeapProfilerAgentImpl::requestHeapStatsUpdate() @@ -343,7 +341,7 @@ void V8HeapProfilerAgentImpl::startSampling(ErrorString* errorString, const Mayb } const unsigned defaultSamplingInterval = 1 << 15; double samplingIntervalValue = samplingInterval.fromMaybe(defaultSamplingInterval); - m_state->setNumber(HeapProfilerAgentState::samplingHeapProfilerInterval, samplingIntervalValue); + m_state->setDouble(HeapProfilerAgentState::samplingHeapProfilerInterval, samplingIntervalValue); m_state->setBoolean(HeapProfilerAgentState::samplingHeapProfilerEnabled, true); #if V8_MAJOR_VERSION * 1000 + V8_MINOR_VERSION >= 5002 profiler->StartSamplingHeapProfiler(static_cast(samplingIntervalValue), 128, v8::HeapProfiler::kSamplingForceGC); @@ -363,12 +361,15 @@ std::unique_ptr buildSampingHea size_t selfSize = 0; for (const auto& allocation : node->allocations) selfSize += allocation.size * allocation.count; - std::unique_ptr result = protocol::HeapProfiler::SamplingHeapProfileNode::create() + std::unique_ptr callFrame = protocol::Runtime::CallFrame::create() .setFunctionName(toProtocolString(node->name)) - .setScriptId(String16::number(node->script_id)) + .setScriptId(String16::fromInteger(node->script_id)) .setUrl(toProtocolString(node->script_name)) - .setLineNumber(node->line_number) - .setColumnNumber(node->column_number) + .setLineNumber(node->line_number - 1) + .setColumnNumber(node->column_number - 1) + .build(); + std::unique_ptr result = protocol::HeapProfiler::SamplingHeapProfileNode::create() + .setCallFrame(std::move(callFrame)) .setSelfSize(selfSize) .setChildren(std::move(children)).build(); return result; diff --git a/deps/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.h similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.h diff --git a/deps/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp similarity index 90% rename from deps/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp index e7f9bed382349b..afa5138f6ec245 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp @@ -8,6 +8,7 @@ #include "platform/v8_inspector/InjectedScriptNative.h" #include "platform/v8_inspector/V8Compat.h" #include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InternalValueType.h" #include "platform/v8_inspector/V8StringUtil.h" #include "platform/v8_inspector/public/V8DebuggerClient.h" @@ -19,7 +20,7 @@ void setFunctionProperty(v8::Local context, v8::Local o { v8::Local funcName = toV8StringInternalized(context->GetIsolate(), name); v8::Local func; - if (!v8::Function::New(context, callback, external).ToLocal(&func)) + if (!v8::Function::New(context, callback, external, 0, v8::ConstructorBehavior::kThrow).ToLocal(&func)) return; func->SetName(funcName); if (!obj->Set(context, funcName, func).FromMaybe(false)) @@ -46,7 +47,6 @@ v8::Local V8InjectedScriptHost::create(v8::Local contex setFunctionProperty(context, injectedScriptHost, "formatAccessorsAsProperties", V8InjectedScriptHost::formatAccessorsAsProperties, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "isTypedArray", V8InjectedScriptHost::isTypedArrayCallback, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "subtype", V8InjectedScriptHost::subtypeCallback, debuggerExternal); - setFunctionProperty(context, injectedScriptHost, "collectionEntries", V8InjectedScriptHost::collectionEntriesCallback, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "getInternalProperties", V8InjectedScriptHost::getInternalPropertiesCallback, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "suppressWarningsAndCallFunction", V8InjectedScriptHost::suppressWarningsAndCallFunctionCallback, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "bind", V8InjectedScriptHost::bindCallback, debuggerExternal); @@ -91,6 +91,13 @@ void V8InjectedScriptHost::subtypeCallback(const v8::FunctionCallbackInfo value = info[0]; + if (value->IsObject()) { + v8::Local internalType = v8InternalValueTypeFrom(isolate->GetCurrentContext(), v8::Local::Cast(value)); + if (internalType->IsString()) { + info.GetReturnValue().Set(internalType); + return; + } + } if (value->IsArray() || value->IsTypedArray() || value->IsArgumentsObject()) { info.GetReturnValue().Set(toV8StringInternalized(isolate, "array")); return; @@ -134,23 +141,12 @@ void V8InjectedScriptHost::subtypeCallback(const v8::FunctionCallbackInfo& info) -{ - if (info.Length() < 1 || !info[0]->IsObject()) - return; - - v8::Local object = info[0].As(); - info.GetReturnValue().Set(unwrapDebugger(info)->collectionEntries(object)); -} - void V8InjectedScriptHost::getInternalPropertiesCallback(const v8::FunctionCallbackInfo& info) { - if (info.Length() < 1 || !info[0]->IsObject()) + if (info.Length() < 1) return; - - v8::Local object = info[0].As(); v8::Local properties; - if (v8::Debug::GetInternalProperties(info.GetIsolate(), object).ToLocal(&properties)) + if (unwrapDebugger(info)->internalProperties(info.GetIsolate()->GetCurrentContext(), info[0]).ToLocal(&properties)) info.GetReturnValue().Set(properties); } @@ -183,15 +179,18 @@ void V8InjectedScriptHost::suppressWarningsAndCallFunctionCallback(const v8::Fun } } - V8DebuggerClient* client = unwrapDebugger(info)->client(); - client->muteWarningsAndDeprecations(); + V8DebuggerImpl* debugger = unwrapDebugger(info); + int contextGroupId = V8DebuggerImpl::getGroupId(context); + if (contextGroupId) + debugger->client()->muteWarningsAndDeprecations(contextGroupId); v8::MicrotasksScope microtasks(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); v8::Local result; if (function->Call(context, receiver, argc, argv.get()).ToLocal(&result)) info.GetReturnValue().Set(result); - client->unmuteWarningsAndDeprecations(); + if (contextGroupId) + debugger->client()->unmuteWarningsAndDeprecations(contextGroupId); } void V8InjectedScriptHost::bindCallback(const v8::FunctionCallbackInfo& info) diff --git a/deps/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h similarity index 95% rename from deps/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h index d21bbdd33e3d28..bf49fa71f40cea 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h @@ -21,13 +21,11 @@ class V8InjectedScriptHost { // We expect that debugger outlives any JS context and thus V8InjectedScriptHost (owned by JS) // is destroyed before debugger. static v8::Local create(v8::Local, V8DebuggerImpl*); - private: static void internalConstructorNameCallback(const v8::FunctionCallbackInfo&); static void formatAccessorsAsProperties(const v8::FunctionCallbackInfo&); static void isTypedArrayCallback(const v8::FunctionCallbackInfo&); static void subtypeCallback(const v8::FunctionCallbackInfo&); - static void collectionEntriesCallback(const v8::FunctionCallbackInfo&); static void getInternalPropertiesCallback(const v8::FunctionCallbackInfo&); static void suppressWarningsAndCallFunctionCallback(const v8::FunctionCallbackInfo&); static void bindCallback(const v8::FunctionCallbackInfo&); diff --git a/deps/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp similarity index 81% rename from deps/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp index 1c584e713e07b3..88aac8c894d41a 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp @@ -8,6 +8,7 @@ #include "platform/v8_inspector/InjectedScript.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/RemoteObjectId.h" +#include "platform/v8_inspector/V8ConsoleAgentImpl.h" #include "platform/v8_inspector/V8DebuggerAgentImpl.h" #include "platform/v8_inspector/V8DebuggerImpl.h" #include "platform/v8_inspector/V8HeapProfilerAgentImpl.h" @@ -23,7 +24,7 @@ const char V8InspectorSession::backtraceObjectGroup[] = "backtrace"; // static bool V8InspectorSession::isV8ProtocolMethod(const String16& method) { - return method.startWith("Debugger.") || method.startWith("HeapProfiler.") || method.startWith("Profiler.") || method.startWith("Runtime."); + return method.startWith("Debugger.") || method.startWith("HeapProfiler.") || method.startWith("Profiler.") || method.startWith("Runtime.") || method.startWith("Console."); } std::unique_ptr V8InspectorSessionImpl::create(V8DebuggerImpl* debugger, int contextGroupId, protocol::FrontendChannel* channel, V8InspectorSessionClient* client, const String16* state) @@ -36,13 +37,13 @@ V8InspectorSessionImpl::V8InspectorSessionImpl(V8DebuggerImpl* debugger, int con , m_debugger(debugger) , m_client(client) , m_customObjectFormatterEnabled(false) - , m_instrumentationCounter(0) , m_dispatcher(channel) , m_state(nullptr) , m_runtimeAgent(nullptr) , m_debuggerAgent(nullptr) , m_heapProfilerAgent(nullptr) , m_profilerAgent(nullptr) + , m_consoleAgent(nullptr) { if (savedState) { std::unique_ptr state = protocol::parseJSON(*savedState); @@ -66,17 +67,22 @@ V8InspectorSessionImpl::V8InspectorSessionImpl(V8DebuggerImpl* debugger, int con m_heapProfilerAgent = wrapUnique(new V8HeapProfilerAgentImpl(this, channel, agentState(protocol::HeapProfiler::Metainfo::domainName))); protocol::HeapProfiler::Dispatcher::wire(&m_dispatcher, m_heapProfilerAgent.get()); + m_consoleAgent = wrapUnique(new V8ConsoleAgentImpl(this, channel, agentState(protocol::Console::Metainfo::domainName))); + protocol::Console::Dispatcher::wire(&m_dispatcher, m_consoleAgent.get()); + if (savedState) { m_runtimeAgent->restore(); m_debuggerAgent->restore(); m_heapProfilerAgent->restore(); m_profilerAgent->restore(); + m_consoleAgent->restore(); } } V8InspectorSessionImpl::~V8InspectorSessionImpl() { ErrorString errorString; + m_consoleAgent->disable(&errorString); m_profilerAgent->disable(&errorString); m_heapProfilerAgent->disable(&errorString); m_debuggerAgent->disable(&errorString); @@ -111,13 +117,17 @@ void V8InspectorSessionImpl::discardInjectedScripts() if (!contexts) return; - protocol::Vector keys; + std::vector keys; + keys.reserve(contexts->size()); for (auto& idContext : *contexts) - keys.append(idContext.first); + keys.push_back(idContext.first); for (auto& key : keys) { contexts = m_debugger->contextGroup(m_contextGroupId); - if (contexts && contexts->contains(key)) - contexts->get(key)->discardInjectedScript(); // This may destroy some contexts. + if (!contexts) + continue; + auto contextIt = contexts->find(key); + if (contextIt != contexts->end()) + contextIt->second->discardInjectedScript(); // This may destroy some contexts. } } @@ -129,12 +139,13 @@ InjectedScript* V8InspectorSessionImpl::findInjectedScript(ErrorString* errorStr } const V8DebuggerImpl::ContextByIdMap* contexts = m_debugger->contextGroup(m_contextGroupId); - if (!contexts || !contexts->contains(contextId)) { + auto contextsIt = contexts ? contexts->find(contextId) : contexts->end(); + if (contextsIt == contexts->end()) { *errorString = "Cannot find context with specified id"; return nullptr; } - InspectedContext* context = contexts->get(contextId); + const std::unique_ptr& context = contextsIt->second; if (!context->getInjectedScript()) { context->createInjectedScript(); if (!context->getInjectedScript()) { @@ -158,16 +169,19 @@ void V8InspectorSessionImpl::releaseObjectGroup(const String16& objectGroup) if (!contexts) return; - protocol::Vector keys; + std::vector keys; for (auto& idContext : *contexts) - keys.append(idContext.first); + keys.push_back(idContext.first); for (auto& key : keys) { contexts = m_debugger->contextGroup(m_contextGroupId); - if (contexts && contexts->contains(key)) { - InjectedScript* injectedScript = contexts->get(key)->getInjectedScript(); - if (injectedScript) - injectedScript->releaseObjectGroup(objectGroup); // This may destroy some contexts. - } + if (!contexts) + continue; + auto contextsIt = contexts->find(key); + if (contextsIt == contexts->end()) + continue; + InjectedScript* injectedScript = contextsIt->second->getInjectedScript(); + if (injectedScript) + injectedScript->releaseObjectGroup(objectGroup); // This may destroy some contexts. } } @@ -193,7 +207,7 @@ v8::Local V8InspectorSessionImpl::findObject(ErrorString* errorString std::unique_ptr V8InspectorSessionImpl::wrapObject(v8::Local context, v8::Local value, const String16& groupName, bool generatePreview) { ErrorString errorString; - InjectedScript* injectedScript = findInjectedScript(&errorString, V8Debugger::contextId(context)); + InjectedScript* injectedScript = findInjectedScript(&errorString, V8DebuggerImpl::contextId(context)); if (!injectedScript) return nullptr; return injectedScript->wrapObject(&errorString, value, groupName, false, generatePreview); @@ -202,7 +216,7 @@ std::unique_ptr V8InspectorSessionImpl::wrapObj std::unique_ptr V8InspectorSessionImpl::wrapTable(v8::Local context, v8::Local table, v8::Local columns) { ErrorString errorString; - InjectedScript* injectedScript = findInjectedScript(&errorString, V8Debugger::contextId(context)); + InjectedScript* injectedScript = findInjectedScript(&errorString, V8DebuggerImpl::contextId(context)); if (!injectedScript) return nullptr; return injectedScript->wrapTable(table, columns); @@ -227,17 +241,7 @@ void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) if (!contexts) return; for (auto& idContext : *contexts) - agent->reportExecutionContextCreated(idContext.second); -} - -void V8InspectorSessionImpl::changeInstrumentationCounter(int delta) -{ - DCHECK_GE(m_instrumentationCounter + delta, 0); - if (!m_instrumentationCounter) - m_client->startInstrumenting(); - m_instrumentationCounter += delta; - if (!m_instrumentationCounter) - m_client->stopInstrumenting(); + agent->reportExecutionContextCreated(idContext.second.get()); } void V8InspectorSessionImpl::dispatchProtocolMessage(const String16& message) @@ -252,16 +256,16 @@ String16 V8InspectorSessionImpl::stateJSON() void V8InspectorSessionImpl::addInspectedObject(std::unique_ptr inspectable) { - m_inspectedObjects.prepend(std::move(inspectable)); - while (m_inspectedObjects.size() > kInspectedObjectBufferSize) - m_inspectedObjects.removeLast(); + m_inspectedObjects.insert(m_inspectedObjects.begin(), std::move(inspectable)); + if (m_inspectedObjects.size() > kInspectedObjectBufferSize) + m_inspectedObjects.resize(kInspectedObjectBufferSize); } V8InspectorSession::Inspectable* V8InspectorSessionImpl::inspectedObject(unsigned num) { if (num >= m_inspectedObjects.size()) return nullptr; - return m_inspectedObjects[num]; + return m_inspectedObjects[num].get(); } void V8InspectorSessionImpl::schedulePauseOnNextStatement(const String16& breakReason, std::unique_ptr data) @@ -279,11 +283,6 @@ void V8InspectorSessionImpl::breakProgram(const String16& breakReason, std::uniq m_debuggerAgent->breakProgram(breakReason, std::move(data)); } -void V8InspectorSessionImpl::breakProgramOnException(const String16& breakReason, std::unique_ptr data) -{ - m_debuggerAgent->breakProgramOnException(breakReason, std::move(data)); -} - void V8InspectorSessionImpl::setSkipAllPauses(bool skip) { ErrorString errorString; @@ -302,29 +301,4 @@ void V8InspectorSessionImpl::stepOver() m_debuggerAgent->stepOver(&errorString); } -void V8InspectorSessionImpl::asyncTaskScheduled(const String16& taskName, void* task, bool recurring) -{ - m_debuggerAgent->asyncTaskScheduled(taskName, task, recurring); -} - -void V8InspectorSessionImpl::asyncTaskCanceled(void* task) -{ - m_debuggerAgent->asyncTaskCanceled(task); -} - -void V8InspectorSessionImpl::asyncTaskStarted(void* task) -{ - m_debuggerAgent->asyncTaskStarted(task); -} - -void V8InspectorSessionImpl::asyncTaskFinished(void* task) -{ - m_debuggerAgent->asyncTaskFinished(task); -} - -void V8InspectorSessionImpl::allAsyncTasksCanceled() -{ - m_debuggerAgent->allAsyncTasksCanceled(); -} - } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h similarity index 84% rename from deps/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h index bf90eb241dafaf..21753dac21b98a 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h @@ -6,7 +6,6 @@ #define V8InspectorSessionImpl_h #include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/Collections.h" #include "platform/inspector_protocol/DispatcherBase.h" #include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" @@ -16,10 +15,13 @@ #include +#include + namespace blink { class InjectedScript; class RemoteObjectIdBase; +class V8ConsoleAgentImpl; class V8DebuggerAgentImpl; class V8DebuggerImpl; class V8HeapProfilerAgentImpl; @@ -34,6 +36,7 @@ class V8InspectorSessionImpl : public V8InspectorSession { V8DebuggerImpl* debugger() const { return m_debugger; } V8InspectorSessionClient* client() const { return m_client; } + V8ConsoleAgentImpl* consoleAgent() { return m_consoleAgent.get(); } V8DebuggerAgentImpl* debuggerAgent() { return m_debuggerAgent.get(); } V8ProfilerAgentImpl* profilerAgent() { return m_profilerAgent.get(); } V8RuntimeAgentImpl* runtimeAgent() { return m_runtimeAgent.get(); } @@ -45,7 +48,6 @@ class V8InspectorSessionImpl : public V8InspectorSession { void discardInjectedScripts(); void reportAllContexts(V8RuntimeAgentImpl*); void setCustomObjectFormatterEnabled(bool); - void changeInstrumentationCounter(int delta); // V8InspectorSession implementation. void dispatchProtocolMessage(const String16& message) override; @@ -54,19 +56,13 @@ class V8InspectorSessionImpl : public V8InspectorSession { void schedulePauseOnNextStatement(const String16& breakReason, std::unique_ptr data) override; void cancelPauseOnNextStatement() override; void breakProgram(const String16& breakReason, std::unique_ptr data) override; - void breakProgramOnException(const String16& breakReason, std::unique_ptr data) override; void setSkipAllPauses(bool) override; void resume() override; void stepOver() override; - void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) override; - void asyncTaskCanceled(void* task) override; - void asyncTaskStarted(void* task) override; - void asyncTaskFinished(void* task) override; - void allAsyncTasksCanceled() override; void releaseObjectGroup(const String16& objectGroup) override; v8::Local findObject(ErrorString*, const String16& objectId, v8::Local* = nullptr, String16* groupName = nullptr) override; - std::unique_ptr wrapObject(v8::Local, v8::Local, const String16& groupName, bool generatePreview = false) override; - std::unique_ptr wrapTable(v8::Local, v8::Local table, v8::Local columns) override; + std::unique_ptr wrapObject(v8::Local, v8::Local, const String16& groupName, bool generatePreview) override; + std::unique_ptr wrapTable(v8::Local, v8::Local table, v8::Local columns); V8InspectorSession::Inspectable* inspectedObject(unsigned num); static const unsigned kInspectedObjectBufferSize = 5; @@ -79,7 +75,6 @@ class V8InspectorSessionImpl : public V8InspectorSession { V8DebuggerImpl* m_debugger; V8InspectorSessionClient* m_client; bool m_customObjectFormatterEnabled; - int m_instrumentationCounter; protocol::UberDispatcher m_dispatcher; std::unique_ptr m_state; @@ -88,7 +83,8 @@ class V8InspectorSessionImpl : public V8InspectorSession { std::unique_ptr m_debuggerAgent; std::unique_ptr m_heapProfilerAgent; std::unique_ptr m_profilerAgent; - protocol::Vector> m_inspectedObjects; + std::unique_ptr m_consoleAgent; + std::vector> m_inspectedObjects; }; } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InternalValueType.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InternalValueType.cpp new file mode 100644 index 00000000000000..52e7677fd709e2 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InternalValueType.cpp @@ -0,0 +1,72 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/v8_inspector/V8InternalValueType.h" + +#include "platform/inspector_protocol/Platform.h" +#include "platform/v8_inspector/V8StringUtil.h" + +namespace blink { + +namespace { + +v8::Local internalSubtypePrivate(v8::Isolate* isolate) +{ + return v8::Private::ForApi(isolate, toV8StringInternalized(isolate, "V8InternalType#internalSubtype")); +} + +v8::Local subtypeForInternalType(v8::Isolate* isolate, V8InternalValueType type) +{ + switch (type) { + case V8InternalValueType::kEntry: + return toV8StringInternalized(isolate, "internal#entry"); + case V8InternalValueType::kLocation: + return toV8StringInternalized(isolate, "internal#location"); + case V8InternalValueType::kScope: + return toV8StringInternalized(isolate, "internal#scope"); + case V8InternalValueType::kScopeList: + return toV8StringInternalized(isolate, "internal#scopeList"); + } + NOTREACHED(); + return v8::Local(); +} + +} // namespace + +bool markAsInternal(v8::Local context, v8::Local object, V8InternalValueType type) +{ + v8::Isolate* isolate = context->GetIsolate(); + v8::Local privateValue = internalSubtypePrivate(isolate); + v8::Local subtype = subtypeForInternalType(isolate, type); + return object->SetPrivate(context, privateValue, subtype).FromMaybe(false); +} + +bool markArrayEntriesAsInternal(v8::Local context, v8::Local array, V8InternalValueType type) +{ + v8::Isolate* isolate = context->GetIsolate(); + v8::Local privateValue = internalSubtypePrivate(isolate); + v8::Local subtype = subtypeForInternalType(isolate, type); + for (size_t i = 0; i < array->Length(); ++i) { + v8::Local entry; + if (!array->Get(context, i).ToLocal(&entry) || !entry->IsObject()) + return false; + if (!entry.As()->SetPrivate(context, privateValue, subtype).FromMaybe(false)) + return false; + } + return true; +} + +v8::Local v8InternalValueTypeFrom(v8::Local context, v8::Local object) +{ + v8::Isolate* isolate = context->GetIsolate(); + v8::Local privateValue = internalSubtypePrivate(isolate); + if (!object->HasPrivate(context, privateValue).FromMaybe(false)) + return v8::Null(isolate); + v8::Local subtypeValue; + if (!object->GetPrivate(context, privateValue).ToLocal(&subtypeValue) || !subtypeValue->IsString()) + return v8::Null(isolate); + return subtypeValue; +} + +} // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InternalValueType.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InternalValueType.h new file mode 100644 index 00000000000000..4bb71720f055c4 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InternalValueType.h @@ -0,0 +1,21 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8InternalValueType_h +#define V8InternalValueType_h + +#include + +namespace blink { + +enum class V8InternalValueType { kEntry, kLocation, kScope, kScopeList }; + +bool markAsInternal(v8::Local, v8::Local, V8InternalValueType); +bool markArrayEntriesAsInternal(v8::Local, v8::Local, V8InternalValueType); +v8::Local v8InternalValueTypeFrom(v8::Local, v8::Local); + + +} // namespace blink + +#endif // V8InternalValueType_h diff --git a/deps/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp similarity index 90% rename from deps/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp index 92762f73dc8e9d..0761f87e0d7a26 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp @@ -11,6 +11,8 @@ #include "platform/v8_inspector/V8StringUtil.h" #include +#include + namespace blink { namespace ProfilerAgentState { @@ -28,7 +30,7 @@ std::unique_ptr> buildInsp if (!lineCount) return array; - protocol::Vector entries(lineCount); + std::vector entries(lineCount); if (node->GetLineTicks(&entries[0], lineCount)) { for (unsigned i = 0; i < lineCount; i++) { std::unique_ptr line = protocol::Profiler::PositionTickInfo::create() @@ -54,14 +56,16 @@ std::unique_ptr buildInspectorObjectFor(v8:: std::unique_ptr> positionTicks = buildInspectorObjectForPositionTicks(node); - std::unique_ptr result = protocol::Profiler::CPUProfileNode::create() + std::unique_ptr callFrame = protocol::Runtime::CallFrame::create() .setFunctionName(toProtocolString(node->GetFunctionName())) - .setScriptId(String16::number(node->GetScriptId())) + .setScriptId(String16::fromInteger(node->GetScriptId())) .setUrl(toProtocolString(node->GetScriptResourceName())) - .setLineNumber(node->GetLineNumber()) - .setColumnNumber(node->GetColumnNumber()) + .setLineNumber(node->GetLineNumber() - 1) + .setColumnNumber(node->GetColumnNumber() - 1) + .build(); + std::unique_ptr result = protocol::Profiler::CPUProfileNode::create() + .setCallFrame(std::move(callFrame)) .setHitCount(node->GetHitCount()) - .setCallUID(node->GetCallUid()) .setChildren(std::move(children)) .setPositionTicks(std::move(positionTicks)) .setDeoptReason(node->GetBailoutReason()) @@ -140,7 +144,7 @@ void V8ProfilerAgentImpl::consoleProfile(const String16& title) if (!m_enabled) return; String16 id = nextProfileId(); - m_startedProfiles.append(ProfileDescriptor(id, title)); + m_startedProfiles.push_back(ProfileDescriptor(id, title)); startProfiling(id); m_frontend.consoleProfileStarted(id, currentDebugLocation(m_session->debugger()), title); } @@ -153,17 +157,17 @@ void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) String16 resolvedTitle; // Take last started profile if no title was passed. if (title.isEmpty()) { - if (m_startedProfiles.isEmpty()) + if (m_startedProfiles.empty()) return; - id = m_startedProfiles.last().m_id; - resolvedTitle = m_startedProfiles.last().m_title; - m_startedProfiles.removeLast(); + id = m_startedProfiles.back().m_id; + resolvedTitle = m_startedProfiles.back().m_title; + m_startedProfiles.pop_back(); } else { for (size_t i = 0; i < m_startedProfiles.size(); i++) { if (m_startedProfiles[i].m_title == title) { resolvedTitle = title; id = m_startedProfiles[i].m_id; - m_startedProfiles.remove(i); + m_startedProfiles.erase(m_startedProfiles.begin() + i); break; } } @@ -183,14 +187,12 @@ void V8ProfilerAgentImpl::enable(ErrorString*) return; m_enabled = true; m_state->setBoolean(ProfilerAgentState::profilerEnabled, true); - m_session->changeInstrumentationCounter(+1); } void V8ProfilerAgentImpl::disable(ErrorString* errorString) { if (!m_enabled) return; - m_session->changeInstrumentationCounter(-1); for (size_t i = m_startedProfiles.size(); i > 0; --i) stopProfiling(m_startedProfiles[i - 1].m_id, false); m_startedProfiles.clear(); @@ -205,7 +207,7 @@ void V8ProfilerAgentImpl::setSamplingInterval(ErrorString* error, int interval) *error = "Cannot change sampling interval when profiling."; return; } - m_state->setNumber(ProfilerAgentState::samplingInterval, interval); + m_state->setInteger(ProfilerAgentState::samplingInterval, interval); m_isolate->GetCpuProfiler()->SetSamplingInterval(interval); } @@ -215,9 +217,8 @@ void V8ProfilerAgentImpl::restore() if (!m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false)) return; m_enabled = true; - m_session->changeInstrumentationCounter(+1); int interval = 0; - m_state->getNumber(ProfilerAgentState::samplingInterval, &interval); + m_state->getInteger(ProfilerAgentState::samplingInterval, &interval); if (interval) m_isolate->GetCpuProfiler()->SetSamplingInterval(interval); if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling, false)) { @@ -262,7 +263,7 @@ void V8ProfilerAgentImpl::stop(ErrorString* errorString, std::unique_ptr V8ProfilerAgentImpl::stopProfili bool V8ProfilerAgentImpl::isRecording() const { - return m_recordingCPUProfile || !m_startedProfiles.isEmpty(); + return m_recordingCPUProfile || !m_startedProfiles.empty(); } } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h similarity index 95% rename from deps/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h index 7fa5f49b4684e1..03b8f703ae1215 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h @@ -9,6 +9,8 @@ #include "platform/inspector_protocol/String16.h" #include "platform/v8_inspector/protocol/Profiler.h" +#include + namespace v8 { class Isolate; } @@ -50,7 +52,7 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend { bool m_enabled; bool m_recordingCPUProfile; class ProfileDescriptor; - protocol::Vector m_startedProfiles; + std::vector m_startedProfiles; String16 m_frontendInitiatedProfileId; }; diff --git a/deps/v8_inspector/platform/v8_inspector/V8Regex.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.cpp similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/V8Regex.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.cpp diff --git a/deps/v8_inspector/platform/v8_inspector/V8Regex.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.h similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/V8Regex.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.h diff --git a/deps/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp similarity index 89% rename from deps/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp index dc45b11875ec86..c9a235ae29e5fd 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp @@ -34,6 +34,7 @@ #include "platform/v8_inspector/InjectedScript.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/RemoteObjectId.h" +#include "platform/v8_inspector/V8ConsoleMessage.h" #include "platform/v8_inspector/V8DebuggerImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8StringUtil.h" @@ -87,11 +88,13 @@ void V8RuntimeAgentImpl::evaluate( if (executionContextId.isJust()) { contextId = executionContextId.fromJust(); } else { - contextId = m_debugger->client()->ensureDefaultContextInGroup(m_session->contextGroupId()); - if (!contextId) { + v8::HandleScope handles(m_debugger->isolate()); + v8::Local defaultContext = m_debugger->client()->ensureDefaultContextInGroup(m_session->contextGroupId()); + if (defaultContext.IsEmpty()) { *errorString = "Cannot find default execution context"; return; } + contextId = V8DebuggerImpl::contextId(defaultContext); } InjectedScript::ContextScope scope(errorString, m_debugger, m_session->contextGroupId(), contextId); @@ -218,7 +221,7 @@ void V8RuntimeAgentImpl::getProperties( if (!errorString->isEmpty() || exceptionDetails->isJust() || accessorPropertiesOnly.fromMaybe(false)) return; v8::Local propertiesArray; - if (hasInternalError(errorString, !v8::Debug::GetInternalProperties(m_debugger->isolate(), scope.object()).ToLocal(&propertiesArray))) + if (hasInternalError(errorString, !m_debugger->internalProperties(scope.context(), scope.object()).ToLocal(&propertiesArray))) return; std::unique_ptr> propertiesProtocolArray = protocol::Array::create(); for (uint32_t i = 0; i < propertiesArray->Length(); i += 2) { @@ -264,6 +267,12 @@ void V8RuntimeAgentImpl::setCustomObjectFormatterEnabled(ErrorString*, bool enab m_session->setCustomObjectFormatterEnabled(enabled); } +void V8RuntimeAgentImpl::discardConsoleEntries(ErrorString*) +{ + V8ConsoleMessageStorage* storage = m_session->debugger()->ensureConsoleMessageStorage(m_session->contextGroupId()); + storage->clear(); +} + void V8RuntimeAgentImpl::compileScript(ErrorString* errorString, const String16& expression, const String16& sourceURL, @@ -293,9 +302,9 @@ void V8RuntimeAgentImpl::compileScript(ErrorString* errorString, if (!persistScript) return; - String16 scriptValueId = String16::number(script->GetUnboundScript()->GetId()); + String16 scriptValueId = String16::fromInteger(script->GetUnboundScript()->GetId()); std::unique_ptr> global(new v8::Global(m_debugger->isolate(), script)); - m_compiledScripts.set(scriptValueId, std::move(global)); + m_compiledScripts[scriptValueId] = std::move(global); *scriptId = scriptValueId; } @@ -313,7 +322,8 @@ void V8RuntimeAgentImpl::runScript(ErrorString* errorString, return; } - if (!m_compiledScripts.contains(scriptId)) { + auto it = m_compiledScripts.find(scriptId); + if (it == m_compiledScripts.end()) { *errorString = "Script execution failed"; return; } @@ -325,7 +335,8 @@ void V8RuntimeAgentImpl::runScript(ErrorString* errorString, if (doNotPauseOnExceptionsAndMuteConsole.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole(); - std::unique_ptr> scriptWrapper = m_compiledScripts.take(scriptId); + std::unique_ptr> scriptWrapper = std::move(it->second); + m_compiledScripts.erase(it); v8::Local script = scriptWrapper->Get(m_debugger->isolate()); if (script.IsEmpty()) { *errorString = "Script execution failed"; @@ -358,11 +369,14 @@ void V8RuntimeAgentImpl::enable(ErrorString* errorString) { if (m_enabled) return; - m_session->changeInstrumentationCounter(+1); + m_session->client()->runtimeEnabled(); m_enabled = true; m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, true); - v8::HandleScope handles(m_debugger->isolate()); + m_session->debugger()->enableStackCapturingIfNeeded(); m_session->reportAllContexts(this); + V8ConsoleMessageStorage* storage = m_session->debugger()->ensureConsoleMessageStorage(m_session->contextGroupId()); + for (const auto& message : storage->messages()) + reportMessage(message.get(), false); } void V8RuntimeAgentImpl::disable(ErrorString* errorString) @@ -371,9 +385,10 @@ void V8RuntimeAgentImpl::disable(ErrorString* errorString) return; m_enabled = false; m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, false); + m_session->debugger()->disableStackCapturingIfNeeded(); m_session->discardInjectedScripts(); reset(); - m_session->changeInstrumentationCounter(-1); + m_session->client()->runtimeDisabled(); } void V8RuntimeAgentImpl::reset() @@ -416,4 +431,16 @@ void V8RuntimeAgentImpl::inspect(std::unique_ptrreportToFrontend(&m_frontend, m_session, generatePreview); + m_frontend.flush(); +} + } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h similarity index 95% rename from deps/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h index 7eb2b135450c4c..7b33379a0c29c0 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h @@ -42,6 +42,7 @@ namespace blink { class InjectedScript; class InspectedContext; class RemoteObjectIdBase; +class V8ConsoleMessage; class V8DebuggerImpl; class V8InspectorSessionImpl; @@ -95,6 +96,7 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { void releaseObjectGroup(ErrorString*, const String16& objectGroup) override; void run(ErrorString*) override; void setCustomObjectFormatterEnabled(ErrorString*, bool) override; + void discardConsoleEntries(ErrorString*) override; void compileScript(ErrorString*, const String16& expression, const String16& sourceURL, @@ -115,8 +117,12 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { void reportExecutionContextCreated(InspectedContext*); void reportExecutionContextDestroyed(InspectedContext*); void inspect(std::unique_ptr objectToInspect, std::unique_ptr hints); + void messageAdded(V8ConsoleMessage*); + bool enabled() const { return m_enabled; } private: + void reportMessage(V8ConsoleMessage*, bool generatePreview); + V8InspectorSessionImpl* m_session; protocol::DictionaryValue* m_state; protocol::Runtime::Frontend m_frontend; diff --git a/deps/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp similarity index 70% rename from deps/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp index 650c71eb957f20..343234c02278cc 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp @@ -6,7 +6,6 @@ #include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" -#include "platform/v8_inspector/V8DebuggerAgentImpl.h" #include "platform/v8_inspector/V8DebuggerImpl.h" #include "platform/v8_inspector/V8StringUtil.h" @@ -18,9 +17,16 @@ namespace blink { namespace { +static const v8::StackTrace::StackTraceOptions stackTraceOptions = static_cast( + v8::StackTrace::kLineNumber | + v8::StackTrace::kColumnOffset | + v8::StackTrace::kScriptId | + v8::StackTrace::kScriptNameOrSourceURL | + v8::StackTrace::kFunctionName); + V8StackTraceImpl::Frame toFrame(v8::Local frame) { - String16 scriptId = String16::number(frame->GetScriptId()); + String16 scriptId = String16::fromInteger(frame->GetScriptId()); String16 sourceName; v8::Local sourceNameValue(frame->GetScriptNameOrSourceURL()); if (!sourceNameValue.IsEmpty()) @@ -36,7 +42,7 @@ V8StackTraceImpl::Frame toFrame(v8::Local frame) return V8StackTraceImpl::Frame(functionName, scriptId, sourceName, sourceLineNumber, sourceColumn); } -void toFramesVector(v8::Local stackTrace, protocol::Vector& frames, size_t maxStackSize, v8::Isolate* isolate) +void toFramesVector(v8::Local stackTrace, std::vector& frames, size_t maxStackSize, v8::Isolate* isolate) { DCHECK(isolate->InContext()); int frameCount = stackTrace->GetFrameCount(); @@ -44,7 +50,7 @@ void toFramesVector(v8::Local stackTrace, protocol::Vector stackFrame = stackTrace->GetFrame(i); - frames.append(toFrame(stackFrame)); + frames.push_back(toFrame(stackFrame)); } } @@ -66,6 +72,8 @@ V8StackTraceImpl::Frame::Frame(const String16& functionName, const String16& scr , m_lineNumber(lineNumber) , m_columnNumber(column) { + DCHECK(m_lineNumber != v8::Message::kNoLineNumberInfo); + DCHECK(m_columnNumber != v8::Message::kNoColumnInfo); } V8StackTraceImpl::Frame::~Frame() @@ -80,8 +88,8 @@ std::unique_ptr V8StackTraceImpl::Frame::buildInsp .setFunctionName(m_functionName) .setScriptId(m_scriptId) .setUrl(m_scriptName) - .setLineNumber(m_lineNumber) - .setColumnNumber(m_columnNumber) + .setLineNumber(m_lineNumber - 1) + .setColumnNumber(m_columnNumber - 1) .build(); } @@ -90,19 +98,32 @@ V8StackTraceImpl::Frame V8StackTraceImpl::Frame::isolatedCopy() const return Frame(m_functionName.isolatedCopy(), m_scriptId.isolatedCopy(), m_scriptName.isolatedCopy(), m_lineNumber, m_columnNumber); } -std::unique_ptr V8StackTraceImpl::create(V8DebuggerAgentImpl* agent, v8::Local stackTrace, size_t maxStackSize, const String16& description) +// static +void V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(v8::Isolate* isolate, bool capture) +{ + isolate->SetCaptureStackTraceForUncaughtExceptions(capture, V8StackTraceImpl::maxCallStackSizeToCapture, stackTraceOptions); +} + +// static +std::unique_ptr V8StackTraceImpl::create(V8DebuggerImpl* debugger, int contextGroupId, v8::Local stackTrace, size_t maxStackSize, const String16& description) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::HandleScope scope(isolate); - protocol::Vector frames; + std::vector frames; if (!stackTrace.IsEmpty()) toFramesVector(stackTrace, frames, maxStackSize, isolate); int maxAsyncCallChainDepth = 1; V8StackTraceImpl* asyncCallChain = nullptr; - if (agent && maxStackSize > 1) { - asyncCallChain = agent->currentAsyncCallChain(); - maxAsyncCallChainDepth = agent->maxAsyncCallChainDepth(); + if (debugger && maxStackSize > 1) { + asyncCallChain = debugger->currentAsyncCallChain(); + maxAsyncCallChainDepth = debugger->maxAsyncCallChainDepth(); + } + // Do not accidentally append async call chain from another group. This should not + // happen if we have proper instrumentation, but let's double-check to be safe. + if (contextGroupId && asyncCallChain && asyncCallChain->m_contextGroupId && asyncCallChain->m_contextGroupId != contextGroupId) { + asyncCallChain = nullptr; + maxAsyncCallChainDepth = 1; } // Only the top stack in the chain may be empty, so ensure that second stack is non-empty (it's the top of appended chain). @@ -112,7 +133,7 @@ std::unique_ptr V8StackTraceImpl::create(V8DebuggerAgentImpl* if (stackTrace.IsEmpty() && !asyncCallChain) return nullptr; - std::unique_ptr result(new V8StackTraceImpl(description, frames, asyncCallChain ? asyncCallChain->cloneImpl() : nullptr)); + std::unique_ptr result(new V8StackTraceImpl(contextGroupId, description, frames, asyncCallChain ? asyncCallChain->cloneImpl() : nullptr)); // Crop to not exceed maxAsyncCallChainDepth. V8StackTraceImpl* deepest = result.get(); @@ -126,7 +147,7 @@ std::unique_ptr V8StackTraceImpl::create(V8DebuggerAgentImpl* return result; } -std::unique_ptr V8StackTraceImpl::capture(V8DebuggerAgentImpl* agent, size_t maxStackSize, const String16& description) +std::unique_ptr V8StackTraceImpl::capture(V8DebuggerImpl* debugger, int contextGroupId, size_t maxStackSize, const String16& description) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::HandleScope handleScope(isolate); @@ -137,7 +158,7 @@ std::unique_ptr V8StackTraceImpl::capture(V8DebuggerAgentImpl* #endif stackTrace = v8::StackTrace::CurrentStackTrace(isolate, maxStackSize, stackTraceOptions); } - return V8StackTraceImpl::create(agent, stackTrace, maxStackSize, description); + return V8StackTraceImpl::create(debugger, contextGroupId, stackTrace, maxStackSize, description); } std::unique_ptr V8StackTraceImpl::clone() @@ -147,8 +168,8 @@ std::unique_ptr V8StackTraceImpl::clone() std::unique_ptr V8StackTraceImpl::cloneImpl() { - protocol::Vector framesCopy(m_frames); - return wrapUnique(new V8StackTraceImpl(m_description, framesCopy, m_parent ? m_parent->cloneImpl() : nullptr)); + std::vector framesCopy(m_frames); + return wrapUnique(new V8StackTraceImpl(m_contextGroupId, m_description, framesCopy, m_parent ? m_parent->cloneImpl() : nullptr)); } std::unique_ptr V8StackTraceImpl::isolatedCopy() @@ -158,14 +179,15 @@ std::unique_ptr V8StackTraceImpl::isolatedCopy() std::unique_ptr V8StackTraceImpl::isolatedCopyImpl() { - protocol::Vector frames; + std::vector frames; for (size_t i = 0; i < m_frames.size(); i++) - frames.append(m_frames.at(i).isolatedCopy()); - return wrapUnique(new V8StackTraceImpl(m_description.isolatedCopy(), frames, m_parent ? m_parent->isolatedCopyImpl() : nullptr)); + frames.push_back(m_frames.at(i).isolatedCopy()); + return wrapUnique(new V8StackTraceImpl(m_contextGroupId, m_description.isolatedCopy(), frames, m_parent ? m_parent->isolatedCopyImpl() : nullptr)); } -V8StackTraceImpl::V8StackTraceImpl(const String16& description, protocol::Vector& frames, std::unique_ptr parent) - : m_description(description) +V8StackTraceImpl::V8StackTraceImpl(int contextGroupId, const String16& description, std::vector& frames, std::unique_ptr parent) + : m_contextGroupId(contextGroupId) + , m_description(description) , m_parent(std::move(parent)) { m_frames.swap(frames); @@ -220,11 +242,11 @@ std::unique_ptr V8StackTraceImpl::buildInspectorO return stackTrace; } -std::unique_ptr V8StackTraceImpl::buildInspectorObjectForTail(V8DebuggerAgentImpl* agent) const +std::unique_ptr V8StackTraceImpl::buildInspectorObjectForTail(V8DebuggerImpl* debugger) const { v8::HandleScope handleScope(v8::Isolate::GetCurrent()); // Next call collapses possible empty stack and ensures maxAsyncCallChainDepth. - std::unique_ptr fullChain = V8StackTraceImpl::create(agent, v8::Local(), V8StackTrace::maxCallStackSizeToCapture); + std::unique_ptr fullChain = V8StackTraceImpl::create(debugger, m_contextGroupId, v8::Local(), V8StackTraceImpl::maxCallStackSizeToCapture); if (!fullChain || !fullChain->m_parent) return nullptr; return fullChain->m_parent->buildInspectorObject(); diff --git a/deps/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h similarity index 76% rename from deps/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h index 721789319bb297..63b59e8d9009b3 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h @@ -5,14 +5,15 @@ #ifndef V8StackTraceImpl_h #define V8StackTraceImpl_h -#include "platform/inspector_protocol/Collections.h" #include "platform/inspector_protocol/Platform.h" #include "platform/v8_inspector/public/V8StackTrace.h" +#include + namespace blink { class TracedValue; -class V8DebuggerAgentImpl; +class V8DebuggerImpl; // Note: async stack trace may have empty top stack with non-empty tail to indicate // that current native-only state had some async story. @@ -20,6 +21,8 @@ class V8DebuggerAgentImpl; class V8StackTraceImpl final : public V8StackTrace { PROTOCOL_DISALLOW_COPY(V8StackTraceImpl); public: + static const size_t maxCallStackSizeToCapture = 200; + class Frame { public: Frame(); @@ -45,14 +48,15 @@ class V8StackTraceImpl final : public V8StackTrace { int m_columnNumber; }; - static std::unique_ptr create(V8DebuggerAgentImpl*, v8::Local, size_t maxStackSize, const String16& description = String16()); - static std::unique_ptr capture(V8DebuggerAgentImpl*, size_t maxStackSize, const String16& description = String16()); + static void setCaptureStackTraceForUncaughtExceptions(v8::Isolate*, bool capture); + static std::unique_ptr create(V8DebuggerImpl*, int contextGroupId, v8::Local, size_t maxStackSize, const String16& description = String16()); + static std::unique_ptr capture(V8DebuggerImpl*, int contextGroupId, size_t maxStackSize, const String16& description = String16()); std::unique_ptr clone() override; std::unique_ptr cloneImpl(); std::unique_ptr isolatedCopy() override; std::unique_ptr isolatedCopyImpl(); - std::unique_ptr buildInspectorObjectForTail(V8DebuggerAgentImpl*) const; + std::unique_ptr buildInspectorObjectForTail(V8DebuggerImpl*) const; ~V8StackTraceImpl() override; // V8StackTrace implementation. @@ -66,10 +70,11 @@ class V8StackTraceImpl final : public V8StackTrace { String16 toString() const override; private: - V8StackTraceImpl(const String16& description, protocol::Vector& frames, std::unique_ptr parent); + V8StackTraceImpl(int contextGroupId, const String16& description, std::vector& frames, std::unique_ptr parent); + int m_contextGroupId; String16 m_description; - protocol::Vector m_frames; + std::vector m_frames; std::unique_ptr m_parent; }; diff --git a/deps/v8_inspector/platform/v8_inspector/V8StringUtil.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.cpp similarity index 90% rename from deps/v8_inspector/platform/v8_inspector/V8StringUtil.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.cpp index e47981e72ccc97..4ba7898bc58162 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8StringUtil.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.cpp @@ -9,7 +9,6 @@ #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8Regex.h" #include "platform/v8_inspector/public/V8ContentSearchUtil.h" -#include "platform/v8_inspector/public/V8ToProtocolValue.h" namespace blink { @@ -95,9 +94,9 @@ String16 createSearchRegexSource(const String16& text) return result.toString(); } -std::unique_ptr> lineEndings(const String16& text) +std::unique_ptr> lineEndings(const String16& text) { - std::unique_ptr> result(new protocol::Vector()); + std::unique_ptr> result(new std::vector()); unsigned start = 0; while (start < text.length()) { @@ -105,21 +104,21 @@ std::unique_ptr> lineEndings(const String16& text) if (lineEnd == kNotFound) break; - result->append(static_cast(lineEnd)); + result->push_back(static_cast(lineEnd)); start = lineEnd + 1; } - result->append(text.length()); + result->push_back(text.length()); return result; } -protocol::Vector> scriptRegexpMatchesByLines(const V8Regex& regex, const String16& text) +std::vector> scriptRegexpMatchesByLines(const V8Regex& regex, const String16& text) { - protocol::Vector> result; + std::vector> result; if (text.isEmpty()) return result; - std::unique_ptr> endings(lineEndings(text)); + std::unique_ptr> endings(lineEndings(text)); unsigned size = endings->size(); unsigned start = 0; for (unsigned lineNumber = 0; lineNumber < size; ++lineNumber) { @@ -130,7 +129,7 @@ protocol::Vector> scriptRegexpMatchesByLines(const V8Re int matchLength; if (regex.match(line, 0, &matchLength) != -1) - result.append(std::pair(lineNumber, line)); + result.push_back(std::pair(lineNumber, line)); start = lineEnd + 1; } @@ -199,7 +198,7 @@ std::unique_ptr> searchInTextBy { std::unique_ptr> result = protocol::Array::create(); std::unique_ptr regex = createSearchRegex(static_cast(session)->debugger(), query, caseSensitive, isRegex); - protocol::Vector> matches = scriptRegexpMatchesByLines(*regex.get(), text); + std::vector> matches = scriptRegexpMatchesByLines(*regex.get(), text); for (const auto& match : matches) result->addItem(buildObjectForSearchMatch(match.first, match.second)); @@ -224,8 +223,13 @@ std::unique_ptr toProtocolValue(v8::Local context, return protocol::Value::null(); if (value->IsBoolean()) return protocol::FundamentalValue::create(value.As()->Value()); - if (value->IsNumber()) - return protocol::FundamentalValue::create(value.As()->Value()); + if (value->IsNumber()) { + double doubleValue = value.As()->Value(); + int intValue = static_cast(doubleValue); + if (intValue == doubleValue) + return protocol::FundamentalValue::create(intValue); + return protocol::FundamentalValue::create(doubleValue); + } if (value->IsString()) return protocol::StringValue::create(toProtocolString(value.As())); if (value->IsArray()) { diff --git a/deps/v8_inspector/platform/v8_inspector/V8StringUtil.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.h similarity index 76% rename from deps/v8_inspector/platform/v8_inspector/V8StringUtil.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.h index c1c506baae8140..2d42613d41614d 100644 --- a/deps/v8_inspector/platform/v8_inspector/V8StringUtil.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.h @@ -6,10 +6,13 @@ #define V8StringUtil_h #include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/Values.h" #include namespace blink { +std::unique_ptr toProtocolValue(v8::Local, v8::Local, int maxDepth = protocol::Value::maxDepth); + v8::Local toV8String(v8::Isolate*, const String16&); v8::Local toV8StringInternalized(v8::Isolate*, const String16&); diff --git a/deps/v8_inspector/platform/v8_inspector/build/rjsmin.py b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/build/rjsmin.py similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/build/rjsmin.py rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/build/rjsmin.py diff --git a/deps/v8_inspector/platform/v8_inspector/build/xxd.py b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/build/xxd.py similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/build/xxd.py rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/build/xxd.py diff --git a/deps/v8_inspector/platform/v8_inspector/debugger_script_externs.js b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/debugger_script_externs.js similarity index 98% rename from deps/v8_inspector/platform/v8_inspector/debugger_script_externs.js rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/debugger_script_externs.js index 25d07542792e92..cf2a0457c4c1b3 100644 --- a/deps/v8_inspector/platform/v8_inspector/debugger_script_externs.js +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/debugger_script_externs.js @@ -18,14 +18,6 @@ var Scope; }} */ var RawLocation; -/** @typedef {{ - function: function(), - functionName: string, - status: string, - location: (!RawLocation|undefined) - }} */ -var GeneratorObjectDetails; - /** @typedef {{ id: number, name: string, diff --git a/deps/v8_inspector/platform/v8_inspector/injected_script_externs.js b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/injected_script_externs.js similarity index 92% rename from deps/v8_inspector/platform/v8_inspector/injected_script_externs.js rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/injected_script_externs.js index 218010938c10e3..5fba025caab2b8 100644 --- a/deps/v8_inspector/platform/v8_inspector/injected_script_externs.js +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/injected_script_externs.js @@ -32,12 +32,6 @@ InjectedScriptHostClass.prototype.subtype = function(obj) {} */ InjectedScriptHostClass.prototype.isTypedArray = function(obj) {} -/** - * @param {!Object} obj - * @return {?Array.<*>} - */ -InjectedScriptHostClass.prototype.collectionEntries = function(obj) {} - /** * @param {*} obj * @return {!Array.<*>} diff --git a/deps/v8_inspector/platform/v8_inspector/js_protocol-1.1.json b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/js_protocol-1.1.json similarity index 100% rename from deps/v8_inspector/platform/v8_inspector/js_protocol-1.1.json rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/js_protocol-1.1.json diff --git a/deps/v8_inspector/platform/v8_inspector/js_protocol.json b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/js_protocol.json similarity index 90% rename from deps/v8_inspector/platform/v8_inspector/js_protocol.json rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/js_protocol.json index 9ae7e60cb025ac..78548bc8402aeb 100644 --- a/deps/v8_inspector/platform/v8_inspector/js_protocol.json +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/js_protocol.json @@ -133,16 +133,23 @@ { "id": "ExceptionDetails", "type": "object", - "description": "Detailed information on exception (or error) that was thrown during script compilation or execution.", + "hidden": true, + "description": "Detailed information about exception (or error) that was thrown during script compilation or execution.", "properties": [ { "name": "text", "type": "string", "description": "Exception text." }, - { "name": "url", "type": "string", "optional": true, "description": "URL of the message origin." }, - { "name": "scriptId", "type": "string", "optional": true, "description": "Script ID of the message origin." }, - { "name": "line", "type": "integer", "optional": true, "description": "Line number in the resource that generated this message." }, - { "name": "column", "type": "integer", "optional": true, "description": "Column number in the resource that generated this message." }, - { "name": "stack", "$ref": "StackTrace", "optional": true, "description": "JavaScript stack trace for assertions and error messages." } + { "name": "scriptId", "$ref": "ScriptId", "description": "Script ID of the exception location." }, + { "name": "lineNumber", "type": "integer", "description": "Line number of the exception location (0-based)." }, + { "name": "columnNumber", "type": "integer", "description": "Column number of the exception location (0-based)." }, + { "name": "url", "type": "string", "optional": true, "description": "URL of the exception location, to be used when the script was not reported." }, + { "name": "stackTrace", "$ref": "StackTrace", "optional": true, "description": "JavaScript stack trace if available." } ] }, + { + "id": "Timestamp", + "type": "number", + "description": "Number of milliseconds since epoch.", + "hidden": true + }, { "id": "CallFrame", "type": "object", @@ -151,8 +158,8 @@ { "name": "functionName", "type": "string", "description": "JavaScript function name." }, { "name": "scriptId", "$ref": "ScriptId", "description": "JavaScript script id." }, { "name": "url", "type": "string", "description": "JavaScript script name or url." }, - { "name": "lineNumber", "type": "integer", "description": "JavaScript script line number." }, - { "name": "columnNumber", "type": "integer", "description": "JavaScript script column number." } + { "name": "lineNumber", "type": "integer", "description": "JavaScript script line number (0-based)." }, + { "name": "columnNumber", "type": "integer", "description": "JavaScript script column number (0-based)." } ] }, { @@ -162,7 +169,7 @@ "properties": [ { "name": "description", "type": "string", "optional": true, "description": "String label of this stack trace. For async traces this may be a name of the function that initiated the async call." }, { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "JavaScript function name." }, - { "name": "parent", "$ref": "StackTrace", "optional": true, "hidden": true, "hidden": true, "description": "Asynchronous JavaScript stack trace that preceded this stack, if available." } + { "name": "parent", "$ref": "StackTrace", "optional": true, "hidden": true, "description": "Asynchronous JavaScript stack trace that preceded this stack, if available." } ] } ], @@ -246,6 +253,11 @@ "hidden": true, "description": "Disables reporting of execution contexts creation." }, + { + "name": "discardConsoleEntries", + "hidden": true, + "description": "Discards collected exceptions and console API calls." + }, { "name": "setCustomObjectFormatterEnabled", "parameters": [ @@ -307,6 +319,39 @@ "name": "executionContextsCleared", "description": "Issued when all executionContexts were cleared in browser" }, + { + "name": "exceptionThrown", + "description": "Issued when exception was thrown and unhandled.", + "parameters": [ + { "name": "exceptionId", "type": "integer", "description": "Exception id." }, + { "name": "timestamp", "$ref": "Timestamp", "description": "Timestamp of the exception." }, + { "name": "details", "$ref": "ExceptionDetails" }, + { "name": "exception", "$ref": "RemoteObject", "optional": true, "description": "Exception object." }, + { "name": "executionContextId", "$ref": "ExecutionContextId", "optional": true, "description": "Identifier of the context where exception happened." } + ], + "hidden": true + }, + { + "name": "exceptionRevoked", + "description": "Issued when unhandled exception was revoked.", + "parameters": [ + { "name": "message", "type": "string", "description": "Message describing why exception was revoked." }, + { "name": "exceptionId", "type": "integer", "description": "The id of revoked exception, as reported in exceptionUnhandled." } + ], + "hidden": true + }, + { + "name": "consoleAPICalled", + "description": "Issued when console API was called.", + "parameters": [ + { "name": "type", "type": "string", "enum": ["log", "debug", "info", "error", "warning", "dir", "dirxml", "table", "trace", "clear", "startGroup", "startGroupCollapsed", "endGroup", "assert", "profile", "profileEnd"], "description": "Type of the call." }, + { "name": "args", "type": "array", "items": { "$ref": "RemoteObject" }, "description": "Call arguments." }, + { "name": "executionContextId", "$ref": "ExecutionContextId", "description": "Identifier of the context where the call was made." }, + { "name": "timestamp", "$ref": "Timestamp", "description": "Call timestamp." }, + { "name": "stackTrace", "$ref": "StackTrace", "optional": true, "description": "Stack trace captured when the call was made." } + ], + "hidden": true + }, { "name": "inspectRequested", "parameters": [ @@ -347,45 +392,11 @@ "hidden": true, "type": "object", "properties": [ - { "name": "line", "type": "integer" }, - { "name": "column", "type": "integer" } + { "name": "lineNumber", "type": "integer" }, + { "name": "columnNumber", "type": "integer" } ], "description": "Location in the source code." }, - { - "id": "FunctionDetails", - "hidden": true, - "type": "object", - "properties": [ - { "name": "location", "$ref": "Location", "optional": true, "description": "Location of the function, none for native functions." }, - { "name": "functionName", "type": "string", "description": "Name of the function." }, - { "name": "isGenerator", "type": "boolean", "description": "Whether this is a generator function." }, - { "name": "scopeChain", "type": "array", "optional": true, "items": { "$ref": "Scope" }, "description": "Scope chain for this closure." } - ], - "description": "Information about the function." - }, - { - "id": "GeneratorObjectDetails", - "hidden": true, - "type": "object", - "properties": [ - { "name": "function", "$ref": "Runtime.RemoteObject", "description": "Generator function." }, - { "name": "functionName", "type": "string", "description": "Name of the generator function." }, - { "name": "status", "type": "string", "enum": ["running", "suspended", "closed"], "description": "Current generator object status." }, - { "name": "location", "$ref": "Location", "optional": true, "description": "If suspended, location where generator function was suspended (e.g. location of the last 'yield'). Otherwise, location of the generator function." } - ], - "description": "Information about the generator object." - }, - { - "id": "CollectionEntry", - "hidden": true, - "type": "object", - "properties": [ - { "name": "key", "$ref": "Runtime.RemoteObject", "optional": true, "description": "Entry key of a map-like collection, otherwise not provided." }, - { "name": "value", "$ref": "Runtime.RemoteObject", "description": "Entry value." } - ], - "description": "Collection entry." - }, { "id": "CallFrame", "type": "object", @@ -412,17 +423,6 @@ ], "description": "Scope description." }, - { - "id": "SetScriptSourceError", - "type": "object", - "properties": [ - { "name": "message", "type": "string", "description": "Compiler error message" }, - { "name": "lineNumber", "type": "integer", "description": "Compile error line number (1-based)" }, - { "name": "columnNumber", "type": "integer", "description": "Compile error column number (1-based)" } - ], - "description": "Error data for setScriptSource command. Contains uncompilable script source error.", - "hidden": true - }, { "id": "SearchMatch", "type": "object", @@ -551,7 +551,7 @@ { "name": "callFrames", "type": "array", "optional": true, "items": { "$ref": "CallFrame" }, "description": "New stack trace in case editing has happened while VM was stopped." }, { "name": "stackChanged", "type": "boolean", "optional": true, "description": "Whether current call stack was modified after applying the changes.", "hidden": true }, { "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any.", "hidden": true }, - { "name": "compileError", "optional": true, "$ref": "SetScriptSourceError", "description": "Error data if any." } + { "name": "compileError", "optional": true, "$ref": "Runtime.ExceptionDetails", "description": "Error data if any." } ], "description": "Edits JavaScript source live." }, @@ -577,39 +577,6 @@ ], "description": "Returns source for the script with given id." }, - { - "name": "getFunctionDetails", - "hidden": true, - "parameters": [ - { "name": "functionId", "$ref": "Runtime.RemoteObjectId", "description": "Id of the function to get details for." } - ], - "returns": [ - { "name": "details", "$ref": "FunctionDetails", "description": "Information about the function." } - ], - "description": "Returns detailed information on given function." - }, - { - "name": "getGeneratorObjectDetails", - "hidden": true, - "parameters": [ - { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Id of the generator object to get details for." } - ], - "returns": [ - { "name": "details", "$ref": "GeneratorObjectDetails", "description": "Information about the generator object." } - ], - "description": "Returns detailed information on given generator object." - }, - { - "name": "getCollectionEntries", - "hidden": true, - "parameters": [ - { "name": "objectId", "$ref": "Runtime.RemoteObjectId", "description": "Id of the collection to get entries for." } - ], - "returns": [ - { "name": "entries", "type": "array", "items": { "$ref": "CollectionEntry" }, "description": "Array of collection entries." } - ], - "description": "Returns entries of given collection." - }, { "name": "setPauseOnExceptions", "parameters": [ @@ -733,7 +700,7 @@ "name": "paused", "parameters": [ { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." }, - { "name": "reason", "type": "string", "enum": [ "XHR", "DOM", "EventListener", "exception", "assert", "CSPViolation", "debugCommand", "promiseRejection", "other" ], "description": "Pause reason." }, + { "name": "reason", "type": "string", "enum": [ "XHR", "DOM", "EventListener", "exception", "assert", "debugCommand", "promiseRejection", "other" ], "description": "Pause reason." }, { "name": "data", "type": "object", "optional": true, "description": "Object containing break-specific auxiliary properties." }, { "name": "hitBreakpoints", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Hit breakpoints IDs", "hidden": true }, { "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any.", "hidden": true } @@ -746,6 +713,64 @@ } ] }, + { + "domain": "Console", + "description": "This domain is deprecated - use Runtime or Log instead.", + "dependencies": ["Runtime"], + "deprecated": true, + "types": [ + { + "id": "ConsoleMessage", + "type": "object", + "description": "Console message.", + "properties": [ + { "name": "source", "type": "string", "enum": ["xml", "javascript", "network", "console-api", "storage", "appcache", "rendering", "security", "other", "deprecation", "worker"], "description": "Message source." }, + { "name": "level", "type": "string", "enum": ["log", "warning", "error", "debug", "info"], "description": "Message severity." }, + { "name": "text", "type": "string", "description": "Message text." }, + { "name": "url", "type": "string", "optional": true, "description": "URL of the message origin." }, + { "name": "line", "type": "integer", "optional": true, "description": "Line number in the resource that generated this message (1-based)." }, + { "name": "column", "type": "integer", "optional": true, "description": "Column number in the resource that generated this message (1-based)." } + ] + } + ], + "commands": [ + { + "name": "enable", + "description": "Enables console domain, sends the messages collected so far to the client by means of the messageAdded notification." + }, + { + "name": "disable", + "description": "Disables console domain, prevents further console messages from being reported to the client." + }, + { + "name": "clearMessages", + "description": "Does nothing." + } + ], + "events": [ + { + "name": "messageAdded", + "parameters": [ + { "name": "message", "$ref": "ConsoleMessage", "description": "Console message that has been added." } + ], + "description": "Issued when new console message is added." + }, + { + "name": "messageRepeatCountUpdated", + "parameters": [ + { "name": "count", "type": "integer", "description": "New repeat count value." }, + { "name": "timestamp", "$ref": "Runtime.Timestamp", "description": "Timestamp of most recent message in batch.", "hidden": true } + ], + "description": "Not issued.", + "deprecated": true + }, + { + "name": "messagesCleared", + "description": "Not issued.", + "deprecated": true + } + ] + }, { "domain": "Profiler", "dependencies": ["Runtime", "Debugger"], @@ -756,13 +781,8 @@ "type": "object", "description": "CPU Profile node. Holds callsite information, execution statistics and child nodes.", "properties": [ - { "name": "functionName", "type": "string", "description": "Function name." }, - { "name": "scriptId", "$ref": "Runtime.ScriptId", "description": "Script identifier." }, - { "name": "url", "type": "string", "description": "URL." }, - { "name": "lineNumber", "type": "integer", "description": "1-based line number of the function start position." }, - { "name": "columnNumber", "type": "integer", "description": "1-based column number of the function start position." }, + { "name": "callFrame", "$ref": "Runtime.CallFrame", "description": "Function location." }, { "name": "hitCount", "type": "integer", "description": "Number of samples where this node was on top of the call stack." }, - { "name": "callUID", "type": "number", "description": "Call UID." }, { "name": "children", "type": "array", "items": { "$ref": "CPUProfileNode" }, "description": "Child nodes." }, { "name": "deoptReason", "type": "string", "description": "The reason of being not optimized. The function may be deoptimized or marked as don't optimize."}, { "name": "id", "type": "integer", "description": "Unique id of the node." }, @@ -822,7 +842,6 @@ { "name": "id", "type": "string" }, { "name": "location", "$ref": "Debugger.Location", "description": "Location of console.profile()." }, { "name": "title", "type": "string", "optional": true, "description": "Profile title passed as argument to console.profile()." } - ], "description": "Sent when new profile recodring is started using console.profile() call." }, @@ -852,11 +871,7 @@ "type": "object", "description": "Sampling Heap Profile node. Holds callsite information, allocation statistics and child nodes.", "properties": [ - { "name": "functionName", "type": "string", "description": "Function name." }, - { "name": "scriptId", "$ref": "Runtime.ScriptId", "description": "Script identifier." }, - { "name": "url", "type": "string", "description": "URL." }, - { "name": "lineNumber", "type": "integer", "description": "1-based line number of the function start position." }, - { "name": "columnNumber", "type": "integer", "description": "1-based column number of the function start position." }, + { "name": "callFrame", "$ref": "Runtime.CallFrame", "description": "Function location." }, { "name": "selfSize", "type": "number", "description": "Allocations size in bytes for the node excluding children." }, { "name": "children", "type": "array", "items": { "$ref": "SamplingHeapProfileNode" }, "description": "Child nodes." } ] @@ -888,7 +903,6 @@ "parameters": [ { "name": "reportProgress", "type": "boolean", "optional": true, "description": "If true 'reportHeapSnapshotProgress' events will be generated while snapshot is being taken when the tracking is stopped." } ] - }, { "name": "takeHeapSnapshot", diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ConsoleTypes.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ConsoleTypes.h new file mode 100644 index 00000000000000..73c1878e9e3d84 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ConsoleTypes.h @@ -0,0 +1,20 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8ConsoleTypes_h +#define V8ConsoleTypes_h + +namespace blink { + +enum MessageLevel { + DebugMessageLevel = 4, + LogMessageLevel = 1, + InfoMessageLevel = 5, + WarningMessageLevel = 2, + ErrorMessageLevel = 3 +}; + +} + +#endif // !defined(V8ConsoleTypes_h) diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h similarity index 94% rename from deps/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h index 35cf12331f88c9..a932b7a4664c92 100644 --- a/deps/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h @@ -7,6 +7,7 @@ #include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" +#include "platform/v8_inspector/protocol/Debugger.h" namespace blink { diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h similarity index 95% rename from deps/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h index 43ce46f9f6a35f..0dc1de29da75e5 100644 --- a/deps/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h @@ -5,7 +5,6 @@ #ifndef V8ContextInfo_h #define V8ContextInfo_h -#include "platform/inspector_protocol/Collections.h" #include "platform/inspector_protocol/String16.h" #include @@ -33,6 +32,7 @@ class V8ContextInfo { bool isDefault; const String16 origin; const String16 humanReadableName; + // TODO(dgozman): aux data? const String16 frameId; bool hasMemoryOnConsole; }; diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8Debugger.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Debugger.h similarity index 50% rename from deps/v8_inspector/platform/v8_inspector/public/V8Debugger.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Debugger.h index b605d8a15e9fa4..da3dcacf555b15 100644 --- a/deps/v8_inspector/platform/v8_inspector/public/V8Debugger.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Debugger.h @@ -7,6 +7,7 @@ #include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" +#include "platform/v8_inspector/public/V8ConsoleTypes.h" #include @@ -19,7 +20,6 @@ class V8InspectorSessionClient; class V8StackTrace; namespace protocol { -class DictionaryValue; class FrontendChannel; } @@ -28,23 +28,37 @@ class PLATFORM_EXPORT V8Debugger { static std::unique_ptr create(v8::Isolate*, V8DebuggerClient*); virtual ~V8Debugger() { } - // TODO(dgozman): make this non-static? - static int contextId(v8::Local); - + // Contexts instrumentation. virtual void contextCreated(const V8ContextInfo&) = 0; virtual void contextDestroyed(v8::Local) = 0; - // TODO(dgozman): remove this one. virtual void resetContextGroup(int contextGroupId) = 0; + + // Various instrumentation. virtual void willExecuteScript(v8::Local, int scriptId) = 0; virtual void didExecuteScript(v8::Local) = 0; virtual void idleStarted() = 0; virtual void idleFinished() = 0; - virtual std::unique_ptr connect(int contextGroupId, protocol::FrontendChannel*, V8InspectorSessionClient*, const String16* state) = 0; - virtual bool isPaused() = 0; + // Async call stacks instrumentation. + virtual void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) = 0; + virtual void asyncTaskCanceled(void* task) = 0; + virtual void asyncTaskStarted(void* task) = 0; + virtual void asyncTaskFinished(void* task) = 0; + virtual void allAsyncTasksCanceled() = 0; + // Runtime instrumentation. + // TODO(dgozman): can we pass exception object? + virtual void exceptionThrown(int contextGroupId, const String16& errorMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) = 0; + virtual unsigned promiseRejected(v8::Local, const String16& errorMessage, v8::Local exception, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) = 0; + virtual void promiseRejectionRevoked(v8::Local, unsigned promiseRejectionId) = 0; + + // TODO(dgozman): can we remove this method? + virtual void logToConsole(v8::Local, v8::Local arg1, v8::Local arg2) = 0; + + // API methods. + virtual std::unique_ptr connect(int contextGroupId, protocol::FrontendChannel*, V8InspectorSessionClient*, const String16* state) = 0; virtual std::unique_ptr createStackTrace(v8::Local) = 0; - virtual std::unique_ptr captureStackTrace(size_t maxStackSize) = 0; + virtual std::unique_ptr captureStackTrace(bool fullStack) = 0; }; } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h similarity index 73% rename from deps/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h index e927d4cc664c81..3747f66707d051 100644 --- a/deps/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h @@ -6,23 +6,22 @@ #define V8DebuggerClient_h #include "platform/inspector_protocol/Platform.h" -#include "platform/v8_inspector/public/ConsoleAPITypes.h" -#include "platform/v8_inspector/public/ConsoleTypes.h" +#include "platform/v8_inspector/public/V8ConsoleTypes.h" #include "platform/v8_inspector/public/V8ContextInfo.h" #include namespace blink { +class V8StackTrace; + class PLATFORM_EXPORT V8DebuggerClient { public: virtual ~V8DebuggerClient() { } virtual void runMessageLoopOnPause(int contextGroupId) = 0; virtual void quitMessageLoopOnPause() = 0; - virtual void muteWarningsAndDeprecations() = 0; - virtual void unmuteWarningsAndDeprecations() = 0; - virtual void muteConsole() = 0; - virtual void unmuteConsole() = 0; + virtual void muteWarningsAndDeprecations(int contextGroupId) = 0; + virtual void unmuteWarningsAndDeprecations(int contextGroupId) = 0; virtual void beginUserGesture() = 0; virtual void endUserGesture() = 0; virtual bool callingContextCanAccessContext(v8::Local calling, v8::Local target) = 0; @@ -30,15 +29,17 @@ class PLATFORM_EXPORT V8DebuggerClient { virtual bool formatAccessorsAsProperties(v8::Local) = 0; virtual bool isExecutionAllowed() = 0; virtual double currentTimeMS() = 0; - virtual int ensureDefaultContextInGroup(int contextGroupId) = 0; + virtual v8::Local ensureDefaultContextInGroup(int contextGroupId) = 0; virtual bool isInspectableHeapObject(v8::Local) = 0; + virtual void enableAsyncInstrumentation() = 0; + virtual void disableAsyncInstrumentation() = 0; virtual void installAdditionalCommandLineAPI(v8::Local, v8::Local) = 0; - virtual void reportMessageToConsole(v8::Local, MessageType, MessageLevel, const String16& message, const v8::FunctionCallbackInfo* arguments, unsigned skipArgumentCount) = 0; virtual void consoleTime(const String16& title) = 0; virtual void consoleTimeEnd(const String16& title) = 0; virtual void consoleTimeStamp(const String16& title) = 0; + virtual void consoleAPIMessage(int contextGroupId, MessageLevel, const String16& message, const String16& url, unsigned lineNumber, unsigned columnNumber, V8StackTrace*) = 0; virtual v8::MaybeLocal memoryInfo(v8::Isolate*, v8::Local) = 0; diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp similarity index 89% rename from deps/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp index fadab16d7ebd1e..f118dcacf3ce5a 100644 --- a/deps/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp @@ -13,6 +13,7 @@ namespace blink { V8Inspector::V8Inspector(v8::Isolate* isolate, v8::Local context) + : m_context(context) { m_debugger = V8Debugger::create(isolate, this); m_debugger->contextCreated(V8ContextInfo(context, 1, true, "", @@ -55,21 +56,17 @@ void V8Inspector::dispatchMessageFromFrontend(const String16& message) m_session->dispatchProtocolMessage(message); } -int V8Inspector::ensureDefaultContextInGroup(int contextGroupId) +v8::Local V8Inspector::ensureDefaultContextInGroup(int) { - return 1; + return m_context; } -void V8Inspector::muteConsole() -{ -} - -void V8Inspector::unmuteConsole() +bool V8Inspector::isExecutionAllowed() { - + return true; } -bool V8Inspector::isExecutionAllowed() +bool V8Inspector::canExecuteScripts() { return true; } diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8Inspector.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.h similarity index 73% rename from deps/v8_inspector/platform/v8_inspector/public/V8Inspector.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.h index 38bbc88774cf9c..4dbb797d50935f 100644 --- a/deps/v8_inspector/platform/v8_inspector/public/V8Inspector.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.h @@ -38,40 +38,42 @@ class V8Inspector : public V8DebuggerClient, V8InspectorSessionClient { bool callingContextCanAccessContext(v8::Local calling, v8::Local target) override; String16 valueSubtype(v8::Local) override; bool formatAccessorsAsProperties(v8::Local) override; - void muteWarningsAndDeprecations() override { } - void unmuteWarningsAndDeprecations() override { } + void muteWarningsAndDeprecations(int) override { } + void unmuteWarningsAndDeprecations(int) override { } double currentTimeMS() override { return 0; }; - void muteConsole() override; - void unmuteConsole() override; bool isExecutionAllowed() override; - int ensureDefaultContextInGroup(int contextGroupId) override; + v8::Local ensureDefaultContextInGroup(int contextGroupId) override; void beginUserGesture() override { } void endUserGesture() override { } bool isInspectableHeapObject(v8::Local) override { return true; } void consoleTime(const String16& title) override { } void consoleTimeEnd(const String16& title) override { } void consoleTimeStamp(const String16& title) override { } + void consoleAPIMessage(int contextGroupId, MessageLevel, const String16& message, const String16& url, unsigned lineNumber, unsigned columnNumber, V8StackTrace*) override { } v8::MaybeLocal memoryInfo(v8::Isolate*, v8::Local) override { return v8::MaybeLocal(); } - void reportMessageToConsole(v8::Local, MessageType, MessageLevel, const String16& message, const v8::FunctionCallbackInfo* arguments, unsigned skipArgumentCount) override { } void installAdditionalCommandLineAPI(v8::Local, v8::Local) override { } - - // V8InspectorSessionClient - void startInstrumenting() override { } - void stopInstrumenting() override { } - void resumeStartup() override { } - bool canExecuteScripts() override { return true; } - void profilingStarted() override { } - void profilingStopped() override { } + void enableAsyncInstrumentation() override { } + void disableAsyncInstrumentation() override { } void startRepeatingTimer(double, TimerCallback, void* data) override { } void cancelTimer(void* data) override { } + // V8InspectorSessionClient + void runtimeEnabled() override { }; + void runtimeDisabled() override { }; + void resumeStartup() override { }; + bool canExecuteScripts() override; + void profilingStarted() override { }; + void profilingStopped() override { }; + void consoleCleared() override { }; + std::unique_ptr m_debugger; std::unique_ptr m_session; String16 m_state; + v8::Local m_context; }; } diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h similarity index 64% rename from deps/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h index e9ad175afc830b..2103467e44087b 100644 --- a/deps/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h @@ -12,15 +12,9 @@ namespace blink { -class V8DebuggerAgent; -class V8HeapProfilerAgent; -class V8InspectorSessionClient; -class V8ProfilerAgent; -class V8RuntimeAgent; - class PLATFORM_EXPORT V8InspectorSession { public: - static const char backtraceObjectGroup[]; + virtual ~V8InspectorSession() { } // Cross-context inspectable values (DOM nodes in different worlds, etc.). class Inspectable { @@ -28,34 +22,25 @@ class PLATFORM_EXPORT V8InspectorSession { virtual v8::Local get(v8::Local) = 0; virtual ~Inspectable() { } }; + virtual void addInspectedObject(std::unique_ptr) = 0; - virtual ~V8InspectorSession() { } - + // Dispatching protocol messages. + // TODO(dgozman): generate this one. static bool isV8ProtocolMethod(const String16& method); virtual void dispatchProtocolMessage(const String16& message) = 0; virtual String16 stateJSON() = 0; - virtual void addInspectedObject(std::unique_ptr) = 0; - // API for the embedder to report native activities. + // Debugger actions. virtual void schedulePauseOnNextStatement(const String16& breakReason, std::unique_ptr data) = 0; virtual void cancelPauseOnNextStatement() = 0; virtual void breakProgram(const String16& breakReason, std::unique_ptr data) = 0; - virtual void breakProgramOnException(const String16& breakReason, std::unique_ptr data) = 0; virtual void setSkipAllPauses(bool) = 0; virtual void resume() = 0; virtual void stepOver() = 0; - // API to report async call stacks. - virtual void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) = 0; - virtual void asyncTaskCanceled(void* task) = 0; - virtual void asyncTaskStarted(void* task) = 0; - virtual void asyncTaskFinished(void* task) = 0; - virtual void allAsyncTasksCanceled() = 0; - - // API to work with remote objects. - virtual std::unique_ptr wrapObject(v8::Local, v8::Local, const String16& groupName, bool generatePreview = false) = 0; - // FIXME: remove when InspectorConsoleAgent moves into V8 inspector. - virtual std::unique_ptr wrapTable(v8::Local, v8::Local table, v8::Local columns) = 0; + // Remote objects. + static const char backtraceObjectGroup[]; + virtual std::unique_ptr wrapObject(v8::Local, v8::Local, const String16& groupName, bool generatePreview) = 0; virtual v8::Local findObject(ErrorString*, const String16& objectId, v8::Local* = nullptr, String16* objectGroup = nullptr) = 0; virtual void releaseObjectGroup(const String16&) = 0; }; diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h similarity index 68% rename from deps/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h index 87772b3cca241e..e9e7c33ea83fd2 100644 --- a/deps/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h @@ -5,23 +5,23 @@ #ifndef V8InspectorSessionClient_h #define V8InspectorSessionClient_h -#include "platform/inspector_protocol/FrontendChannel.h" #include "platform/inspector_protocol/Platform.h" #include namespace blink { -class PLATFORM_EXPORT V8InspectorSessionClient -{ +class PLATFORM_EXPORT V8InspectorSessionClient { public: virtual ~V8InspectorSessionClient() { } - virtual void startInstrumenting() = 0; - virtual void stopInstrumenting() = 0; + virtual void runtimeEnabled() = 0; + virtual void runtimeDisabled() = 0; virtual void resumeStartup() = 0; + // TODO(dgozman): this was added to support service worker shadow page. We should not connect at all. virtual bool canExecuteScripts() = 0; virtual void profilingStarted() = 0; virtual void profilingStopped() = 0; + virtual void consoleCleared() = 0; }; } // namespace blink diff --git a/deps/v8_inspector/platform/v8_inspector/public/V8StackTrace.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8StackTrace.h similarity index 74% rename from deps/v8_inspector/platform/v8_inspector/public/V8StackTrace.h rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8StackTrace.h index 6d5c4804c4be35..beee1155f6e87f 100644 --- a/deps/v8_inspector/platform/v8_inspector/public/V8StackTrace.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8StackTrace.h @@ -13,19 +13,9 @@ namespace blink { -class TracedValue; - -const v8::StackTrace::StackTraceOptions stackTraceOptions = static_cast( - v8::StackTrace::kLineNumber | - v8::StackTrace::kColumnOffset | - v8::StackTrace::kScriptId | - v8::StackTrace::kScriptNameOrSourceURL | - v8::StackTrace::kFunctionName); - +// TODO(dgozman): migrate to V8SourceLocation. class V8StackTrace { public: - static const size_t maxCallStackSizeToCapture = 200; - virtual bool isEmpty() const = 0; virtual String16 topSourceURL() const = 0; virtual int topLineNumber() const = 0; diff --git a/deps/v8_inspector/platform/v8_inspector/v8_inspector.gyp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/v8_inspector.gyp similarity index 90% rename from deps/v8_inspector/platform/v8_inspector/v8_inspector.gyp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/v8_inspector.gyp index a9b31dc1d4a4af..6de6017c6931af 100644 --- a/deps/v8_inspector/platform/v8_inspector/v8_inspector.gyp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/v8_inspector.gyp @@ -57,8 +57,8 @@ ['debug_devtools=="node"', { # Node build 'jinja_module_files': [ - '../../deps/jinja2/jinja2/__init__.py', - '../../deps/markupsafe/markupsafe/__init__.py', # jinja2 dep + '../../../jinja2/jinja2/__init__.py', + '../../../markupsafe/markupsafe/__init__.py', # jinja2 dep ], }, { 'jinja_module_files': [ @@ -83,6 +83,8 @@ 'js_protocol.json', ], 'outputs': [ + '<(blink_platform_output_dir)/v8_inspector/protocol/Console.cpp', + '<(blink_platform_output_dir)/v8_inspector/protocol/Console.h', '<(blink_platform_output_dir)/v8_inspector/protocol/Debugger.cpp', '<(blink_platform_output_dir)/v8_inspector/protocol/Debugger.h', '<(blink_platform_output_dir)/v8_inspector/protocol/HeapProfiler.cpp', @@ -143,11 +145,13 @@ ], 'include_dirs': [ '../..', - '../../../v8/include', - '../../../v8', + '../../../../../v8/include', + '../../../../../v8', '<(SHARED_INTERMEDIATE_DIR)/blink', ], 'sources': [ + '<(blink_platform_output_dir)/v8_inspector/protocol/Console.cpp', + '<(blink_platform_output_dir)/v8_inspector/protocol/Console.h', '<(blink_platform_output_dir)/v8_inspector/protocol/Debugger.cpp', '<(blink_platform_output_dir)/v8_inspector/protocol/Debugger.h', '<(blink_platform_output_dir)/v8_inspector/protocol/HeapProfiler.cpp', @@ -160,7 +164,6 @@ '../inspector_protocol/Allocator.h', '../inspector_protocol/Array.h', '../inspector_protocol/Collections.h', - '../inspector_protocol/CollectionsSTL.h', '../inspector_protocol/DispatcherBase.cpp', '../inspector_protocol/DispatcherBase.h', '../inspector_protocol/ErrorSupport.cpp', @@ -193,6 +196,10 @@ 'RemoteObjectId.h', 'V8Console.cpp', 'V8Console.h', + 'V8ConsoleAgentImpl.cpp', + 'V8ConsoleAgentImpl.h', + 'V8ConsoleMessage.cpp', + 'V8ConsoleMessage.h', 'V8DebuggerAgentImpl.cpp', 'V8DebuggerAgentImpl.h', 'V8DebuggerImpl.cpp', @@ -207,6 +214,8 @@ 'V8InjectedScriptHost.h', 'V8InspectorSessionImpl.cpp', 'V8InspectorSessionImpl.h', + 'V8InternalValueType.cpp', + 'V8InternalValueType.h', 'V8ProfilerAgentImpl.cpp', 'V8ProfilerAgentImpl.h', 'V8Regex.cpp', @@ -227,10 +236,9 @@ 'public/V8Inspector.h', 'public/V8InspectorSession.h', 'public/V8StackTrace.h', - 'public/V8ToProtocolValue.h', - '<(blink_platform_output_dir/v8_inspector/DebuggerScript.h', - '<(blink_platform_output_dir/v8_inspector/InjectedScriptSource.h', + '<(blink_platform_output_dir)/v8_inspector/DebuggerScript.h', + '<(blink_platform_output_dir)/v8_inspector/InjectedScriptSource.h', ], }, ], # targets diff --git a/node.gyp b/node.gyp index cbf957a8c7c1f6..634ba972b57d97 100644 --- a/node.gyp +++ b/node.gyp @@ -314,6 +314,7 @@ 'defines': [ 'HAVE_INSPECTOR=1', 'V8_INSPECTOR_USE_STL=1', + 'V8_INSPECTOR_USE_OLD_STL=1', ], 'sources': [ 'src/inspector_agent.cc', @@ -322,11 +323,11 @@ 'src/inspector_agent.h', ], 'dependencies': [ - 'deps/v8_inspector/platform/v8_inspector/v8_inspector.gyp:v8_inspector_stl', + 'deps/v8_inspector/third_party/v8_inspector/platform/' + 'v8_inspector/v8_inspector.gyp:v8_inspector_stl', ], 'include_dirs': [ - 'deps/v8_inspector', - 'deps/v8_inspector/deps/wtf', # temporary + 'deps/v8_inspector/third_party/v8_inspector', '<(SHARED_INTERMEDIATE_DIR)/blink', # for inspector ], }, { diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index 2f8b75886d9899..5a870aa91ca0f4 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -36,7 +36,7 @@ const char TAG_CONNECT[] = "#connect"; const char TAG_DISCONNECT[] = "#disconnect"; const char DEVTOOLS_PATH[] = "/node"; -const char DEVTOOLS_HASH[] = "521e5b7e2b7cc66b4006a8a54cb9c4e57494a5ef"; +const char DEVTOOLS_HASH[] = "851972d6da7463c353d712d2cb6c1ec23fa6c4fe"; void PrintDebuggerReadyMessage(int port) { fprintf(stderr, "Debugger listening on port %d.\n" From 57312fc0c55c8b850acdcbed3a87bd23ddc4e59b Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Tue, 19 Jul 2016 13:12:53 -0700 Subject: [PATCH 127/144] deps: remove jinja.el from deps/v8_inspector jinja.el is not shipped as part of the distribution, and neither is it used in the build. While not strictly necessary, removing it simplifies life from a licensing point of view. PR-URL: https://github.com/nodejs/node/pull/7796 Reviewed-By: bnoordhuis - Ben Noordhuis Reviewed-By: jasnell - James M Snell --- .../third_party/jinja2/ext/jinja.el | 128 ------------------ 1 file changed, 128 deletions(-) delete mode 100644 deps/v8_inspector/third_party/jinja2/ext/jinja.el diff --git a/deps/v8_inspector/third_party/jinja2/ext/jinja.el b/deps/v8_inspector/third_party/jinja2/ext/jinja.el deleted file mode 100644 index 4cf0c72e29af1d..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/ext/jinja.el +++ /dev/null @@ -1,128 +0,0 @@ -;;; jinja.el --- Jinja mode highlighting -;; -;; Author: Georg Brandl -;; Copyright: (c) 2009 by the Jinja Team -;; Last modified: 2008-05-22 23:04 by gbr -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Commentary: -;; -;; Mostly ripped off django-mode by Lennart Borgman. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; This program is free software; you can redistribute it and/or -;; modify it under the terms of the GNU General Public License as -;; published by the Free Software Foundation; either version 2, or -;; (at your option) any later version. -;; -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with this program; see the file COPYING. If not, write to -;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth -;; Floor, Boston, MA 02110-1301, USA. -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;;; Code: - -(defconst jinja-font-lock-keywords - (list -; (cons (rx "{% comment %}" (submatch (0+ anything)) -; "{% endcomment %}") (list 1 font-lock-comment-face)) - '("{# ?\\(.*?\\) ?#}" . (1 font-lock-comment-face)) - '("{%-?\\|-?%}\\|{{\\|}}" . font-lock-preprocessor-face) - '("{#\\|#}" . font-lock-comment-delimiter-face) - ;; first word in a block is a command - '("{%-?[ \t\n]*\\([a-zA-Z_]+\\)" . (1 font-lock-keyword-face)) - ;; variables - '("\\({{ ?\\)\\([^|]*?\\)\\(|.*?\\)? ?}}" . (1 font-lock-variable-name-face)) - ;; keywords and builtins - (cons (rx word-start - (or "in" "as" "recursive" "not" "and" "or" "if" "else" - "import" "with" "without" "context") - word-end) - font-lock-keyword-face) - (cons (rx word-start - (or "true" "false" "none" "loop" "self" "super") - word-end) - font-lock-builtin-face) - ;; tests - '("\\(is\\)[ \t]*\\(not\\)[ \t]*\\([a-zA-Z_]+\\)" - (1 font-lock-keyword-face) (2 font-lock-keyword-face) - (3 font-lock-function-name-face)) - ;; builtin filters - (cons (rx - "|" (* space) - (submatch - (or "abs" "batch" "capitalize" "capture" "center" "count" "default" - "dformat" "dictsort" "e" "escape" "filesizeformat" "first" - "float" "format" "getattribute" "getitem" "groupby" "indent" - "int" "join" "jsonencode" "last" "length" "lower" "markdown" - "pprint" "random" "replace" "reverse" "round" "rst" "slice" - "sort" "string" "striptags" "sum" "textile" "title" "trim" - "truncate" "upper" "urlencode" "urlize" "wordcount" "wordwrap" - "xmlattr"))) - (list 1 font-lock-builtin-face)) - ) - "Minimal highlighting expressions for Jinja mode") - -(define-derived-mode jinja-mode nil "Jinja" - "Simple Jinja mode for use with `mumamo-mode'. -This mode only provides syntax highlighting." - ;;(set (make-local-variable 'comment-start) "{#") - ;;(set (make-local-variable 'comment-end) "#}") - (setq font-lock-defaults '(jinja-font-lock-keywords))) - -;; mumamo stuff -(when (require 'mumamo nil t) - - (defun mumamo-chunk-jinja3 (pos max) - "Find {# ... #}" - (mumamo-quick-chunk-forward pos max "{#" "#}" 'borders 'jinja-mode)) - - (defun mumamo-chunk-jinja2 (pos max) - "Find {{ ... }}" - (mumamo-quick-chunk-forward pos max "{{" "}}" 'borders 'jinja-mode)) - - (defun mumamo-chunk-jinja (pos max) - "Find {% ... %}" - (mumamo-quick-chunk-forward pos max "{%" "%}" 'borders 'jinja-mode)) - -;;;###autoload - (define-mumamo-multi-major-mode jinja-html-mumamo - "Turn on multiple major modes for Jinja with main mode `html-mode'. -This also covers inlined style and javascript." - ("Jinja HTML Family" html-mode - (mumamo-chunk-jinja - mumamo-chunk-jinja2 - mumamo-chunk-jinja3 - mumamo-chunk-inlined-style - mumamo-chunk-inlined-script - mumamo-chunk-style= - mumamo-chunk-onjs= - ))) - -;;;###autoload - (define-mumamo-multi-major-mode jinja-nxhtml-mumamo - "Turn on multiple major modes for Jinja with main mode `nxhtml-mode'. -This also covers inlined style and javascript." - ("Jinja nXhtml Family" nxhtml-mode - (mumamo-chunk-jinja - mumamo-chunk-jinja2 - mumamo-chunk-jinja3 - mumamo-chunk-inlined-style - mumamo-chunk-inlined-script - mumamo-chunk-style= - mumamo-chunk-onjs= - ))) - ) - -(provide 'jinja) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; jinja.el ends here From 583a2515dab66895e6fc2341aba56cc315ba9ffe Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Wed, 20 Jul 2016 15:39:48 -0700 Subject: [PATCH 128/144] tools: update license-builder.sh for v8_inspector Start including the license from v8_inspector and its build time dependencies: jinja2 and markupsafe. PR-URL: https://github.com/nodejs/node/pull/7796 Reviewed-By: bnoordhuis - Ben Noordhuis Reviewed-By: jasnell - James M Snell --- tools/license-builder.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/license-builder.sh b/tools/license-builder.sh index eb3980e7d027cd..94da24ebeb3d74 100755 --- a/tools/license-builder.sh +++ b/tools/license-builder.sh @@ -82,5 +82,15 @@ addlicense "gtest" "deps/gtest" "$(cat ${rootdir}/deps/gtest/LICENSE)" addlicense "node-weak" "test/gc/node_modules/weak" \ "$(cat ${rootdir}/test/gc/node_modules/weak/LICENSE)" +# v8_inspector +addlicense "v8_inspector" "deps/v8_inspector/third_party/v8_inspector" \ + "$(cat ${rootdir}/deps/v8_inspector/third_party/v8_inspector/LICENSE)" +# Build tooling for v8_inspector +addlicense "jinja2" "deps/v8_inspector/third_party/jinja2" \ + "$(cat ${rootdir}/deps/v8_inspector/third_party/jinja2/LICENSE)" +addlicense "markupsafe" "deps/v8_inspector/third_party/markupsafe" \ + "$(cat ${rootdir}/deps/v8_inspector/third_party/markupsafe/LICENSE)" + + mv $tmplicense $licensefile From 3fe122f57eb76acbec1d6f340f203c235d416f5e Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Wed, 20 Jul 2016 15:42:42 -0700 Subject: [PATCH 129/144] doc: update licenses Created using `tools/license-builder.sh`. PR-URL: https://github.com/nodejs/node/pull/7796 Reviewed-By: bnoordhuis - Ben Noordhuis Reviewed-By: jasnell - James M Snell --- LICENSE | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index afe38dd748c7b7..254d5484323b93 100644 --- a/LICENSE +++ b/LICENSE @@ -96,7 +96,7 @@ The externally maintained libraries used by Node.js are: IN THE SOFTWARE. """ -- ICU, located at deps/icu, is licensed as follows: +- ICU, located at deps/icu-small, is licensed as follows: """ ICU License - ICU 1.8.1 and later @@ -1094,3 +1094,106 @@ The externally maintained libraries used by Node.js are: ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ + +- v8_inspector, located at deps/v8_inspector/third_party/v8_inspector, is licensed as follows: + """ + // Copyright 2015 The Chromium Authors. All rights reserved. + // + // Redistribution and use in source and binary forms, with or without + // modification, are permitted provided that the following conditions are + // met: + // + // * Redistributions of source code must retain the above copyright + // notice, this list of conditions and the following disclaimer. + // * Redistributions in binary form must reproduce the above + // copyright notice, this list of conditions and the following disclaimer + // in the documentation and/or other materials provided with the + // distribution. + // * Neither the name of Google Inc. nor the names of its + // contributors may be used to endorse or promote products derived from + // this software without specific prior written permission. + // + // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + """ + +- jinja2, located at deps/v8_inspector/third_party/jinja2, is licensed as follows: + """ + Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. + + Some rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + """ + +- markupsafe, located at deps/v8_inspector/third_party/markupsafe, is licensed as follows: + """ + Copyright (c) 2010 by Armin Ronacher and contributors. See AUTHORS + for more details. + + Some rights reserved. + + Redistribution and use in source and binary forms of the software as well + as documentation, with or without modification, are permitted provided + that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. + """ From 4d81362b992287ad07f71339142800343e51f080 Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Mon, 25 Jul 2016 11:41:11 -0700 Subject: [PATCH 130/144] deps: v8_inspector: remove jinja2 tests PR-URL: https://github.com/nodejs/node/pull/7796 Reviewed-By: bnoordhuis - Ben Noordhuis Reviewed-By: jasnell - James M Snell --- .../third_party/jinja2/tests/conftest.py | 74 --- .../third_party/jinja2/tests/res/__init__.py | 0 .../jinja2/tests/res/templates/broken.html | 3 - .../jinja2/tests/res/templates/foo/test.html | 1 - .../tests/res/templates/syntaxerror.html | 4 - .../jinja2/tests/res/templates/test.html | 1 - .../third_party/jinja2/tests/test_api.py | 327 ---------- .../jinja2/tests/test_bytecode_cache.py | 32 - .../jinja2/tests/test_core_tags.py | 337 ---------- .../third_party/jinja2/tests/test_debug.py | 73 --- .../third_party/jinja2/tests/test_ext.py | 467 -------------- .../third_party/jinja2/tests/test_filters.py | 558 ---------------- .../third_party/jinja2/tests/test_imports.py | 148 ----- .../jinja2/tests/test_inheritance.py | 248 ------- .../jinja2/tests/test_lexnparse.py | 609 ------------------ .../third_party/jinja2/tests/test_loader.py | 220 ------- .../jinja2/tests/test_regression.py | 278 -------- .../third_party/jinja2/tests/test_security.py | 161 ----- .../third_party/jinja2/tests/test_tests.py | 104 --- .../third_party/jinja2/tests/test_utils.py | 76 --- 20 files changed, 3721 deletions(-) delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/conftest.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/res/__init__.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/res/templates/broken.html delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/res/templates/foo/test.html delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/res/templates/syntaxerror.html delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/res/templates/test.html delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_api.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_bytecode_cache.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_core_tags.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_debug.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_ext.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_filters.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_imports.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_inheritance.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_lexnparse.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_loader.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_regression.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_security.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_tests.py delete mode 100644 deps/v8_inspector/third_party/jinja2/tests/test_utils.py diff --git a/deps/v8_inspector/third_party/jinja2/tests/conftest.py b/deps/v8_inspector/third_party/jinja2/tests/conftest.py deleted file mode 100644 index b5582323d7ee46..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/conftest.py +++ /dev/null @@ -1,74 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.conftest - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - Configuration and Fixtures for the tests - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest -import os -import re -import sys - -from traceback import format_exception -from jinja2 import loaders -from jinja2._compat import PY2 -from jinja2 import Environment - - -@pytest.fixture -def env(): - '''returns a new environment. - ''' - return Environment() - - -@pytest.fixture -def dict_loader(): - '''returns DictLoader - ''' - return loaders.DictLoader({ - 'justdict.html': 'FOO' - }) - - -@pytest.fixture -def package_loader(): - '''returns PackageLoader initialized from templates - ''' - return loaders.PackageLoader('res', 'templates') - - -@pytest.fixture -def filesystem_loader(): - '''returns FileSystemLoader initialized to res/templates directory - ''' - here = os.path.dirname(os.path.abspath(__file__)) - return loaders.FileSystemLoader(here + '/res/templates') - - -@pytest.fixture -def function_loader(): - '''returns a FunctionLoader - ''' - return loaders.FunctionLoader({'justfunction.html': 'FOO'}.get) - - -@pytest.fixture -def choice_loader(dict_loader, package_loader): - '''returns a ChoiceLoader - ''' - return loaders.ChoiceLoader([dict_loader, package_loader]) - - -@pytest.fixture -def prefix_loader(filesystem_loader, dict_loader): - '''returns a PrefixLoader - ''' - return loaders.PrefixLoader({ - 'a': filesystem_loader, - 'b': dict_loader - }) diff --git a/deps/v8_inspector/third_party/jinja2/tests/res/__init__.py b/deps/v8_inspector/third_party/jinja2/tests/res/__init__.py deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/deps/v8_inspector/third_party/jinja2/tests/res/templates/broken.html b/deps/v8_inspector/third_party/jinja2/tests/res/templates/broken.html deleted file mode 100644 index 77669fae57cdc2..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/res/templates/broken.html +++ /dev/null @@ -1,3 +0,0 @@ -Before -{{ fail() }} -After diff --git a/deps/v8_inspector/third_party/jinja2/tests/res/templates/foo/test.html b/deps/v8_inspector/third_party/jinja2/tests/res/templates/foo/test.html deleted file mode 100644 index b7d6715e2df11b..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/res/templates/foo/test.html +++ /dev/null @@ -1 +0,0 @@ -FOO diff --git a/deps/v8_inspector/third_party/jinja2/tests/res/templates/syntaxerror.html b/deps/v8_inspector/third_party/jinja2/tests/res/templates/syntaxerror.html deleted file mode 100644 index f21b817939831b..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/res/templates/syntaxerror.html +++ /dev/null @@ -1,4 +0,0 @@ -Foo -{% for item in broken %} - ... -{% endif %} diff --git a/deps/v8_inspector/third_party/jinja2/tests/res/templates/test.html b/deps/v8_inspector/third_party/jinja2/tests/res/templates/test.html deleted file mode 100644 index ba578e48b18366..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/res/templates/test.html +++ /dev/null @@ -1 +0,0 @@ -BAR diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_api.py b/deps/v8_inspector/third_party/jinja2/tests/test_api.py deleted file mode 100644 index 99d8dc1e13ea99..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_api.py +++ /dev/null @@ -1,327 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.api - ~~~~~~~~~~~~~~~~~~~~ - - Tests the public API and related stuff. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import os -import tempfile -import shutil - -import pytest -from jinja2 import Environment, Undefined, DebugUndefined, \ - StrictUndefined, UndefinedError, meta, \ - is_undefined, Template, DictLoader, make_logging_undefined -from jinja2.compiler import CodeGenerator -from jinja2.runtime import Context -from jinja2.utils import Cycler - - -@pytest.mark.api -@pytest.mark.extended -class TestExtendedAPI(): - - def test_item_and_attribute(self, env): - from jinja2.sandbox import SandboxedEnvironment - - for env in Environment(), SandboxedEnvironment(): - # the |list is necessary for python3 - tmpl = env.from_string('{{ foo.items()|list }}') - assert tmpl.render(foo={'items': 42}) == "[('items', 42)]" - tmpl = env.from_string('{{ foo|attr("items")()|list }}') - assert tmpl.render(foo={'items': 42}) == "[('items', 42)]" - tmpl = env.from_string('{{ foo["items"] }}') - assert tmpl.render(foo={'items': 42}) == '42' - - def test_finalizer(self, env): - def finalize_none_empty(value): - if value is None: - value = u'' - return value - env = Environment(finalize=finalize_none_empty) - tmpl = env.from_string('{% for item in seq %}|{{ item }}{% endfor %}') - assert tmpl.render(seq=(None, 1, "foo")) == '||1|foo' - tmpl = env.from_string('<{{ none }}>') - assert tmpl.render() == '<>' - - def test_cycler(self, env): - items = 1, 2, 3 - c = Cycler(*items) - for item in items + items: - assert c.current == item - assert next(c) == item - next(c) - assert c.current == 2 - c.reset() - assert c.current == 1 - - def test_expressions(self, env): - expr = env.compile_expression("foo") - assert expr() is None - assert expr(foo=42) == 42 - expr2 = env.compile_expression("foo", undefined_to_none=False) - assert is_undefined(expr2()) - - expr = env.compile_expression("42 + foo") - assert expr(foo=42) == 84 - - def test_template_passthrough(self, env): - t = Template('Content') - assert env.get_template(t) is t - assert env.select_template([t]) is t - assert env.get_or_select_template([t]) is t - assert env.get_or_select_template(t) is t - - def test_autoescape_autoselect(self, env): - def select_autoescape(name): - if name is None or '.' not in name: - return False - return name.endswith('.html') - env = Environment(autoescape=select_autoescape, - loader=DictLoader({ - 'test.txt': '{{ foo }}', - 'test.html': '{{ foo }}' - })) - t = env.get_template('test.txt') - assert t.render(foo='') == '' - t = env.get_template('test.html') - assert t.render(foo='') == '<foo>' - t = env.from_string('{{ foo }}') - assert t.render(foo='') == '' - - -@pytest.mark.api -@pytest.mark.meta -class TestMeta(): - - def test_find_undeclared_variables(self, env): - ast = env.parse('{% set foo = 42 %}{{ bar + foo }}') - x = meta.find_undeclared_variables(ast) - assert x == set(['bar']) - - ast = env.parse('{% set foo = 42 %}{{ bar + foo }}' - '{% macro meh(x) %}{{ x }}{% endmacro %}' - '{% for item in seq %}{{ muh(item) + meh(seq) }}' - '{% endfor %}') - x = meta.find_undeclared_variables(ast) - assert x == set(['bar', 'seq', 'muh']) - - def test_find_refererenced_templates(self, env): - ast = env.parse('{% extends "layout.html" %}{% include helper %}') - i = meta.find_referenced_templates(ast) - assert next(i) == 'layout.html' - assert next(i) is None - assert list(i) == [] - - ast = env.parse('{% extends "layout.html" %}' - '{% from "test.html" import a, b as c %}' - '{% import "meh.html" as meh %}' - '{% include "muh.html" %}') - i = meta.find_referenced_templates(ast) - assert list(i) == ['layout.html', 'test.html', 'meh.html', 'muh.html'] - - def test_find_included_templates(self, env): - ast = env.parse('{% include ["foo.html", "bar.html"] %}') - i = meta.find_referenced_templates(ast) - assert list(i) == ['foo.html', 'bar.html'] - - ast = env.parse('{% include ("foo.html", "bar.html") %}') - i = meta.find_referenced_templates(ast) - assert list(i) == ['foo.html', 'bar.html'] - - ast = env.parse('{% include ["foo.html", "bar.html", foo] %}') - i = meta.find_referenced_templates(ast) - assert list(i) == ['foo.html', 'bar.html', None] - - ast = env.parse('{% include ("foo.html", "bar.html", foo) %}') - i = meta.find_referenced_templates(ast) - assert list(i) == ['foo.html', 'bar.html', None] - - -@pytest.mark.api -@pytest.mark.streaming -class TestStreaming(): - - def test_basic_streaming(self, env): - tmpl = env.from_string("
    {% for item in seq %}
  • {{ loop.index " - "}} - {{ item }}
  • {%- endfor %}
") - stream = tmpl.stream(seq=list(range(4))) - assert next(stream) == '
    ' - assert next(stream) == '
  • 1 - 0
  • ' - assert next(stream) == '
  • 2 - 1
  • ' - assert next(stream) == '
  • 3 - 2
  • ' - assert next(stream) == '
  • 4 - 3
  • ' - assert next(stream) == '
' - - def test_buffered_streaming(self, env): - tmpl = env.from_string("
    {% for item in seq %}
  • {{ loop.index " - "}} - {{ item }}
  • {%- endfor %}
") - stream = tmpl.stream(seq=list(range(4))) - stream.enable_buffering(size=3) - assert next(stream) == u'
  • 1 - 0
  • 2 - 1
  • ' - assert next(stream) == u'
  • 3 - 2
  • 4 - 3
' - - def test_streaming_behavior(self, env): - tmpl = env.from_string("") - stream = tmpl.stream() - assert not stream.buffered - stream.enable_buffering(20) - assert stream.buffered - stream.disable_buffering() - assert not stream.buffered - - def test_dump_stream(self, env): - tmp = tempfile.mkdtemp() - try: - tmpl = env.from_string(u"\u2713") - stream = tmpl.stream() - stream.dump(os.path.join(tmp, 'dump.txt'), 'utf-8') - with open(os.path.join(tmp, 'dump.txt'), 'rb') as f: - assert f.read() == b'\xe2\x9c\x93' - finally: - shutil.rmtree(tmp) - - -@pytest.mark.api -@pytest.mark.undefined -class TestUndefined(): - - def test_stopiteration_is_undefined(self): - def test(): - raise StopIteration() - t = Template('A{{ test() }}B') - assert t.render(test=test) == 'AB' - t = Template('A{{ test().missingattribute }}B') - pytest.raises(UndefinedError, t.render, test=test) - - def test_undefined_and_special_attributes(self): - try: - Undefined('Foo').__dict__ - except AttributeError: - pass - else: - assert False, "Expected actual attribute error" - - def test_logging_undefined(self): - _messages = [] - - class DebugLogger(object): - def warning(self, msg, *args): - _messages.append('W:' + msg % args) - - def error(self, msg, *args): - _messages.append('E:' + msg % args) - - logging_undefined = make_logging_undefined(DebugLogger()) - env = Environment(undefined=logging_undefined) - assert env.from_string('{{ missing }}').render() == u'' - pytest.raises(UndefinedError, - env.from_string('{{ missing.attribute }}').render) - assert env.from_string('{{ missing|list }}').render() == '[]' - assert env.from_string('{{ missing is not defined }}').render() \ - == 'True' - assert env.from_string('{{ foo.missing }}').render(foo=42) == '' - assert env.from_string('{{ not missing }}').render() == 'True' - assert _messages == [ - 'W:Template variable warning: missing is undefined', - "E:Template variable error: 'missing' is undefined", - 'W:Template variable warning: missing is undefined', - 'W:Template variable warning: int object has no attribute missing', - 'W:Template variable warning: missing is undefined', - ] - - def test_default_undefined(self): - env = Environment(undefined=Undefined) - assert env.from_string('{{ missing }}').render() == u'' - pytest.raises(UndefinedError, - env.from_string('{{ missing.attribute }}').render) - assert env.from_string('{{ missing|list }}').render() == '[]' - assert env.from_string('{{ missing is not defined }}').render() \ - == 'True' - assert env.from_string('{{ foo.missing }}').render(foo=42) == '' - assert env.from_string('{{ not missing }}').render() == 'True' - - def test_debug_undefined(self): - env = Environment(undefined=DebugUndefined) - assert env.from_string('{{ missing }}').render() == '{{ missing }}' - pytest.raises(UndefinedError, - env.from_string('{{ missing.attribute }}').render) - assert env.from_string('{{ missing|list }}').render() == '[]' - assert env.from_string('{{ missing is not defined }}').render() \ - == 'True' - assert env.from_string('{{ foo.missing }}').render(foo=42) \ - == u"{{ no such element: int object['missing'] }}" - assert env.from_string('{{ not missing }}').render() == 'True' - - def test_strict_undefined(self): - env = Environment(undefined=StrictUndefined) - pytest.raises(UndefinedError, env.from_string('{{ missing }}').render) - pytest.raises(UndefinedError, - env.from_string('{{ missing.attribute }}').render) - pytest.raises(UndefinedError, - env.from_string('{{ missing|list }}').render) - assert env.from_string('{{ missing is not defined }}').render() \ - == 'True' - pytest.raises(UndefinedError, - env.from_string('{{ foo.missing }}').render, foo=42) - pytest.raises(UndefinedError, - env.from_string('{{ not missing }}').render) - assert env.from_string('{{ missing|default("default", true) }}')\ - .render() == 'default' - - def test_indexing_gives_undefined(self): - t = Template("{{ var[42].foo }}") - pytest.raises(UndefinedError, t.render, var=0) - - def test_none_gives_proper_error(self): - try: - Environment().getattr(None, 'split')() - except UndefinedError as e: - assert e.message == "'None' has no attribute 'split'" - else: - assert False, 'expected exception' - - def test_object_repr(self): - try: - Undefined(obj=42, name='upper')() - except UndefinedError as e: - assert e.message == "'int object' has no attribute 'upper'" - else: - assert False, 'expected exception' - - -@pytest.mark.api -@pytest.mark.lowlevel -class TestLowLevel(): - - def test_custom_code_generator(self): - class CustomCodeGenerator(CodeGenerator): - def visit_Const(self, node, frame=None): - # This method is pure nonsense, but works fine for testing... - if node.value == 'foo': - self.write(repr('bar')) - else: - super(CustomCodeGenerator, self).visit_Const(node, frame) - - class CustomEnvironment(Environment): - code_generator_class = CustomCodeGenerator - - env = CustomEnvironment() - tmpl = env.from_string('{% set foo = "foo" %}{{ foo }}') - assert tmpl.render() == 'bar' - - def test_custom_context(self): - class CustomContext(Context): - def resolve(self, key): - return 'resolve-' + key - - class CustomEnvironment(Environment): - context_class = CustomContext - - env = CustomEnvironment() - tmpl = env.from_string('{{ foo }}') - assert tmpl.render() == 'resolve-foo' diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_bytecode_cache.py b/deps/v8_inspector/third_party/jinja2/tests/test_bytecode_cache.py deleted file mode 100644 index 2ffe4c60379bc4..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_bytecode_cache.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.bytecode_cache - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Test bytecode caching - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest -from jinja2 import Environment -from jinja2.bccache import FileSystemBytecodeCache -from jinja2.exceptions import TemplateNotFound - - -@pytest.fixture -def env(package_loader): - bytecode_cache = FileSystemBytecodeCache() - return Environment( - loader=package_loader, - bytecode_cache=bytecode_cache, - ) - - -@pytest.mark.byte_code_cache -class TestByteCodeCache(): - - def test_simple(self, env): - tmpl = env.get_template('test.html') - assert tmpl.render().strip() == 'BAR' - pytest.raises(TemplateNotFound, env.get_template, 'missing.html') diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_core_tags.py b/deps/v8_inspector/third_party/jinja2/tests/test_core_tags.py deleted file mode 100644 index 2ea7757e4862aa..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_core_tags.py +++ /dev/null @@ -1,337 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.core_tags - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Test the core tags like for and if. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest -from jinja2 import Environment, TemplateSyntaxError, UndefinedError, \ - DictLoader - - -@pytest.fixture -def env_trim(): - return Environment(trim_blocks=True) - - -@pytest.mark.core_tags -@pytest.mark.for_loop -class TestForLoop(): - - def test_simple(self, env): - tmpl = env.from_string('{% for item in seq %}{{ item }}{% endfor %}') - assert tmpl.render(seq=list(range(10))) == '0123456789' - - def test_else(self, env): - tmpl = env.from_string( - '{% for item in seq %}XXX{% else %}...{% endfor %}') - assert tmpl.render() == '...' - - def test_empty_blocks(self, env): - tmpl = env.from_string('<{% for item in seq %}{% else %}{% endfor %}>') - assert tmpl.render() == '<>' - - def test_context_vars(self, env): - slist = [42, 24] - for seq in [slist, iter(slist), reversed(slist), (_ for _ in slist)]: - tmpl = env.from_string('''{% for item in seq -%} - {{ loop.index }}|{{ loop.index0 }}|{{ loop.revindex }}|{{ - loop.revindex0 }}|{{ loop.first }}|{{ loop.last }}|{{ - loop.length }}###{% endfor %}''') - one, two, _ = tmpl.render(seq=seq).split('###') - (one_index, one_index0, one_revindex, one_revindex0, one_first, - one_last, one_length) = one.split('|') - (two_index, two_index0, two_revindex, two_revindex0, two_first, - two_last, two_length) = two.split('|') - - assert int(one_index) == 1 and int(two_index) == 2 - assert int(one_index0) == 0 and int(two_index0) == 1 - assert int(one_revindex) == 2 and int(two_revindex) == 1 - assert int(one_revindex0) == 1 and int(two_revindex0) == 0 - assert one_first == 'True' and two_first == 'False' - assert one_last == 'False' and two_last == 'True' - assert one_length == two_length == '2' - - def test_cycling(self, env): - tmpl = env.from_string('''{% for item in seq %}{{ - loop.cycle('<1>', '<2>') }}{% endfor %}{% - for item in seq %}{{ loop.cycle(*through) }}{% endfor %}''') - output = tmpl.render(seq=list(range(4)), through=('<1>', '<2>')) - assert output == '<1><2>' * 4 - - def test_scope(self, env): - tmpl = env.from_string('{% for item in seq %}{% endfor %}{{ item }}') - output = tmpl.render(seq=list(range(10))) - assert not output - - def test_varlen(self, env): - def inner(): - for item in range(5): - yield item - tmpl = env.from_string('{% for item in iter %}{{ item }}{% endfor %}') - output = tmpl.render(iter=inner()) - assert output == '01234' - - def test_noniter(self, env): - tmpl = env.from_string('{% for item in none %}...{% endfor %}') - pytest.raises(TypeError, tmpl.render) - - def test_recursive(self, env): - tmpl = env.from_string('''{% for item in seq recursive -%} - [{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}] - {%- endfor %}''') - assert tmpl.render(seq=[ - dict(a=1, b=[dict(a=1), dict(a=2)]), - dict(a=2, b=[dict(a=1), dict(a=2)]), - dict(a=3, b=[dict(a='a')]) - ]) == '[1<[1][2]>][2<[1][2]>][3<[a]>]' - - def test_recursive_depth0(self, env): - tmpl = env.from_string('''{% for item in seq recursive -%} - [{{ loop.depth0 }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}] - {%- endfor %}''') - assert tmpl.render(seq=[ - dict(a=1, b=[dict(a=1), dict(a=2)]), - dict(a=2, b=[dict(a=1), dict(a=2)]), - dict(a=3, b=[dict(a='a')]) - ]) == '[0:1<[1:1][1:2]>][0:2<[1:1][1:2]>][0:3<[1:a]>]' - - def test_recursive_depth(self, env): - tmpl = env.from_string('''{% for item in seq recursive -%} - [{{ loop.depth }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}] - {%- endfor %}''') - assert tmpl.render(seq=[ - dict(a=1, b=[dict(a=1), dict(a=2)]), - dict(a=2, b=[dict(a=1), dict(a=2)]), - dict(a=3, b=[dict(a='a')]) - ]) == '[1:1<[2:1][2:2]>][1:2<[2:1][2:2]>][1:3<[2:a]>]' - - def test_looploop(self, env): - tmpl = env.from_string('''{% for row in table %} - {%- set rowloop = loop -%} - {% for cell in row -%} - [{{ rowloop.index }}|{{ loop.index }}] - {%- endfor %} - {%- endfor %}''') - assert tmpl.render(table=['ab', 'cd']) == '[1|1][1|2][2|1][2|2]' - - def test_reversed_bug(self, env): - tmpl = env.from_string('{% for i in items %}{{ i }}' - '{% if not loop.last %}' - ',{% endif %}{% endfor %}') - assert tmpl.render(items=reversed([3, 2, 1])) == '1,2,3' - - def test_loop_errors(self, env): - tmpl = env.from_string('''{% for item in [1] if loop.index - == 0 %}...{% endfor %}''') - pytest.raises(UndefinedError, tmpl.render) - tmpl = env.from_string('''{% for item in [] %}...{% else - %}{{ loop }}{% endfor %}''') - assert tmpl.render() == '' - - def test_loop_filter(self, env): - tmpl = env.from_string('{% for item in range(10) if item ' - 'is even %}[{{ item }}]{% endfor %}') - assert tmpl.render() == '[0][2][4][6][8]' - tmpl = env.from_string(''' - {%- for item in range(10) if item is even %}[{{ - loop.index }}:{{ item }}]{% endfor %}''') - assert tmpl.render() == '[1:0][2:2][3:4][4:6][5:8]' - - def test_loop_unassignable(self, env): - pytest.raises(TemplateSyntaxError, env.from_string, - '{% for loop in seq %}...{% endfor %}') - - def test_scoped_special_var(self, env): - t = env.from_string( - '{% for s in seq %}[{{ loop.first }}{% for c in s %}' - '|{{ loop.first }}{% endfor %}]{% endfor %}') - assert t.render(seq=('ab', 'cd')) \ - == '[True|True|False][False|True|False]' - - def test_scoped_loop_var(self, env): - t = env.from_string('{% for x in seq %}{{ loop.first }}' - '{% for y in seq %}{% endfor %}{% endfor %}') - assert t.render(seq='ab') == 'TrueFalse' - t = env.from_string('{% for x in seq %}{% for y in seq %}' - '{{ loop.first }}{% endfor %}{% endfor %}') - assert t.render(seq='ab') == 'TrueFalseTrueFalse' - - def test_recursive_empty_loop_iter(self, env): - t = env.from_string(''' - {%- for item in foo recursive -%}{%- endfor -%} - ''') - assert t.render(dict(foo=[])) == '' - - def test_call_in_loop(self, env): - t = env.from_string(''' - {%- macro do_something() -%} - [{{ caller() }}] - {%- endmacro %} - - {%- for i in [1, 2, 3] %} - {%- call do_something() -%} - {{ i }} - {%- endcall %} - {%- endfor -%} - ''') - assert t.render() == '[1][2][3]' - - def test_scoping_bug(self, env): - t = env.from_string(''' - {%- for item in foo %}...{{ item }}...{% endfor %} - {%- macro item(a) %}...{{ a }}...{% endmacro %} - {{- item(2) -}} - ''') - assert t.render(foo=(1,)) == '...1......2...' - - def test_unpacking(self, env): - tmpl = env.from_string('{% for a, b, c in [[1, 2, 3]] %}' - '{{ a }}|{{ b }}|{{ c }}{% endfor %}') - assert tmpl.render() == '1|2|3' - - -@pytest.mark.core_tags -@pytest.mark.if_condition -class TestIfCondition(): - - def test_simple(self, env): - tmpl = env.from_string('''{% if true %}...{% endif %}''') - assert tmpl.render() == '...' - - def test_elif(self, env): - tmpl = env.from_string('''{% if false %}XXX{% elif true - %}...{% else %}XXX{% endif %}''') - assert tmpl.render() == '...' - - def test_else(self, env): - tmpl = env.from_string('{% if false %}XXX{% else %}...{% endif %}') - assert tmpl.render() == '...' - - def test_empty(self, env): - tmpl = env.from_string('[{% if true %}{% else %}{% endif %}]') - assert tmpl.render() == '[]' - - def test_complete(self, env): - tmpl = env.from_string('{% if a %}A{% elif b %}B{% elif c == d %}' - 'C{% else %}D{% endif %}') - assert tmpl.render(a=0, b=False, c=42, d=42.0) == 'C' - - def test_no_scope(self, env): - tmpl = env.from_string( - '{% if a %}{% set foo = 1 %}{% endif %}{{ foo }}') - assert tmpl.render(a=True) == '1' - tmpl = env.from_string( - '{% if true %}{% set foo = 1 %}{% endif %}{{ foo }}') - assert tmpl.render() == '1' - - -@pytest.mark.core_tags -@pytest.mark.macros -class TestMacros(): - def test_simple(self, env_trim): - tmpl = env_trim.from_string('''\ -{% macro say_hello(name) %}Hello {{ name }}!{% endmacro %} -{{ say_hello('Peter') }}''') - assert tmpl.render() == 'Hello Peter!' - - def test_scoping(self, env_trim): - tmpl = env_trim.from_string('''\ -{% macro level1(data1) %} -{% macro level2(data2) %}{{ data1 }}|{{ data2 }}{% endmacro %} -{{ level2('bar') }}{% endmacro %} -{{ level1('foo') }}''') - assert tmpl.render() == 'foo|bar' - - def test_arguments(self, env_trim): - tmpl = env_trim.from_string('''\ -{% macro m(a, b, c='c', d='d') %}{{ a }}|{{ b }}|{{ c }}|{{ d }}{% endmacro %} -{{ m() }}|{{ m('a') }}|{{ m('a', 'b') }}|{{ m(1, 2, 3) }}''') - assert tmpl.render() == '||c|d|a||c|d|a|b|c|d|1|2|3|d' - - def test_arguments_defaults_nonsense(self, env_trim): - pytest.raises(TemplateSyntaxError, env_trim.from_string, '''\ -{% macro m(a, b=1, c) %}a={{ a }}, b={{ b }}, c={{ c }}{% endmacro %}''') - - def test_caller_defaults_nonsense(self, env_trim): - pytest.raises(TemplateSyntaxError, env_trim.from_string, '''\ -{% macro a() %}{{ caller() }}{% endmacro %} -{% call(x, y=1, z) a() %}{% endcall %}''') - - def test_varargs(self, env_trim): - tmpl = env_trim.from_string('''\ -{% macro test() %}{{ varargs|join('|') }}{% endmacro %}\ -{{ test(1, 2, 3) }}''') - assert tmpl.render() == '1|2|3' - - def test_simple_call(self, env_trim): - tmpl = env_trim.from_string('''\ -{% macro test() %}[[{{ caller() }}]]{% endmacro %}\ -{% call test() %}data{% endcall %}''') - assert tmpl.render() == '[[data]]' - - def test_complex_call(self, env_trim): - tmpl = env_trim.from_string('''\ -{% macro test() %}[[{{ caller('data') }}]]{% endmacro %}\ -{% call(data) test() %}{{ data }}{% endcall %}''') - assert tmpl.render() == '[[data]]' - - def test_caller_undefined(self, env_trim): - tmpl = env_trim.from_string('''\ -{% set caller = 42 %}\ -{% macro test() %}{{ caller is not defined }}{% endmacro %}\ -{{ test() }}''') - assert tmpl.render() == 'True' - - def test_include(self, env_trim): - env_trim = Environment( - loader=DictLoader({ - 'include': '{% macro test(foo) %}[{{ foo }}]{% endmacro %}' - }) - ) - tmpl = env_trim.from_string( - '{% from "include" import test %}{{ test("foo") }}') - assert tmpl.render() == '[foo]' - - def test_macro_api(self, env_trim): - tmpl = env_trim.from_string( - '{% macro foo(a, b) %}{% endmacro %}' - '{% macro bar() %}{{ varargs }}{{ kwargs }}{% endmacro %}' - '{% macro baz() %}{{ caller() }}{% endmacro %}') - assert tmpl.module.foo.arguments == ('a', 'b') - assert tmpl.module.foo.defaults == () - assert tmpl.module.foo.name == 'foo' - assert not tmpl.module.foo.caller - assert not tmpl.module.foo.catch_kwargs - assert not tmpl.module.foo.catch_varargs - assert tmpl.module.bar.arguments == () - assert tmpl.module.bar.defaults == () - assert not tmpl.module.bar.caller - assert tmpl.module.bar.catch_kwargs - assert tmpl.module.bar.catch_varargs - assert tmpl.module.baz.caller - - def test_callself(self, env_trim): - tmpl = env_trim.from_string('{% macro foo(x) %}{{ x }}{% if x > 1 %}|' - '{{ foo(x - 1) }}{% endif %}{% endmacro %}' - '{{ foo(5) }}') - assert tmpl.render() == '5|4|3|2|1' - - -@pytest.mark.core_tags -@pytest.mark.set -class TestSet(): - - def test_normal(self, env_trim): - tmpl = env_trim.from_string('{% set foo = 1 %}{{ foo }}') - assert tmpl.render() == '1' - assert tmpl.module.foo == 1 - - def test_block(self, env_trim): - tmpl = env_trim.from_string('{% set foo %}42{% endset %}{{ foo }}') - assert tmpl.render() == '42' - assert tmpl.module.foo == u'42' diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_debug.py b/deps/v8_inspector/third_party/jinja2/tests/test_debug.py deleted file mode 100644 index d8617ae08e1176..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_debug.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.debug - ~~~~~~~~~~~~~~~~~~~~~~ - - Tests the debug system. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest - -import re - -import sys -from traceback import format_exception - -from jinja2 import Environment, TemplateSyntaxError -from traceback import format_exception - - -@pytest.fixture -def fs_env(filesystem_loader): - '''returns a new environment. - ''' - return Environment(loader=filesystem_loader) - - -@pytest.mark.debug -class TestDebug(): - - def assert_traceback_matches(self, callback, expected_tb): - try: - callback() - except Exception as e: - tb = format_exception(*sys.exc_info()) - if re.search(expected_tb.strip(), ''.join(tb)) is None: - assert False, ('Traceback did not match:\n\n%s\nexpected:\n%s' % - (''.join(tb), expected_tb)) - else: - assert False, 'Expected exception' - - def test_runtime_error(self, fs_env): - def test(): - tmpl.render(fail=lambda: 1 / 0) - tmpl = fs_env.get_template('broken.html') - self.assert_traceback_matches(test, r''' - File ".*?broken.html", line 2, in (top-level template code|) - \{\{ fail\(\) \}\} - File ".*debug?.pyc?", line \d+, in - tmpl\.render\(fail=lambda: 1 / 0\) -ZeroDivisionError: (int(eger)? )?division (or modulo )?by zero -''') - - def test_syntax_error(self, fs_env): - # XXX: the .*? is necessary for python3 which does not hide - # some of the stack frames we don't want to show. Not sure - # what's up with that, but that is not that critical. Should - # be fixed though. - self.assert_traceback_matches(lambda: fs_env.get_template('syntaxerror.html'), r'''(?sm) - File ".*?syntaxerror.html", line 4, in (template|) - \{% endif %\}.*? -(jinja2\.exceptions\.)?TemplateSyntaxError: Encountered unknown tag 'endif'. Jinja was looking for the following tags: 'endfor' or 'else'. The innermost block that needs to be closed is 'for'. - ''') - - def test_regular_syntax_error(self, fs_env): - def test(): - raise TemplateSyntaxError('wtf', 42) - self.assert_traceback_matches(test, r''' - File ".*debug.pyc?", line \d+, in test - raise TemplateSyntaxError\('wtf', 42\) -(jinja2\.exceptions\.)?TemplateSyntaxError: wtf - line 42''') diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_ext.py b/deps/v8_inspector/third_party/jinja2/tests/test_ext.py deleted file mode 100644 index 8985416c9cb356..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_ext.py +++ /dev/null @@ -1,467 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.ext - ~~~~~~~~~~~~~~~~~~~~ - - Tests for the extensions. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import re -import pytest - -from jinja2 import Environment, DictLoader, contextfunction, nodes -from jinja2.exceptions import TemplateAssertionError -from jinja2.ext import Extension -from jinja2.lexer import Token, count_newlines -from jinja2._compat import BytesIO, itervalues, text_type - -importable_object = 23 - -_gettext_re = re.compile(r'_\((.*?)\)(?s)') - - -i18n_templates = { - 'master.html': '{{ page_title|default(_("missing")) }}' - '{% block body %}{% endblock %}', - 'child.html': '{% extends "master.html" %}{% block body %}' - '{% trans %}watch out{% endtrans %}{% endblock %}', - 'plural.html': '{% trans user_count %}One user online{% pluralize %}' - '{{ user_count }} users online{% endtrans %}', - 'plural2.html': '{% trans user_count=get_user_count() %}{{ user_count }}s' - '{% pluralize %}{{ user_count }}p{% endtrans %}', - 'stringformat.html': '{{ _("User: %(num)s")|format(num=user_count) }}' -} - -newstyle_i18n_templates = { - 'master.html': '{{ page_title|default(_("missing")) }}' - '{% block body %}{% endblock %}', - 'child.html': '{% extends "master.html" %}{% block body %}' - '{% trans %}watch out{% endtrans %}{% endblock %}', - 'plural.html': '{% trans user_count %}One user online{% pluralize %}' - '{{ user_count }} users online{% endtrans %}', - 'stringformat.html': '{{ _("User: %(num)s", num=user_count) }}', - 'ngettext.html': '{{ ngettext("%(num)s apple", "%(num)s apples", apples) }}', - 'ngettext_long.html': '{% trans num=apples %}{{ num }} apple{% pluralize %}' - '{{ num }} apples{% endtrans %}', - 'transvars1.html': '{% trans %}User: {{ num }}{% endtrans %}', - 'transvars2.html': '{% trans num=count %}User: {{ num }}{% endtrans %}', - 'transvars3.html': '{% trans count=num %}User: {{ count }}{% endtrans %}', - 'novars.html': '{% trans %}%(hello)s{% endtrans %}', - 'vars.html': '{% trans %}{{ foo }}%(foo)s{% endtrans %}', - 'explicitvars.html': '{% trans foo="42" %}%(foo)s{% endtrans %}' -} - - -languages = { - 'de': { - 'missing': u'fehlend', - 'watch out': u'pass auf', - 'One user online': u'Ein Benutzer online', - '%(user_count)s users online': u'%(user_count)s Benutzer online', - 'User: %(num)s': u'Benutzer: %(num)s', - 'User: %(count)s': u'Benutzer: %(count)s', - '%(num)s apple': u'%(num)s Apfel', - '%(num)s apples': u'%(num)s Äpfel' - } -} - - -@contextfunction -def gettext(context, string): - language = context.get('LANGUAGE', 'en') - return languages.get(language, {}).get(string, string) - - -@contextfunction -def ngettext(context, s, p, n): - language = context.get('LANGUAGE', 'en') - if n != 1: - return languages.get(language, {}).get(p, p) - return languages.get(language, {}).get(s, s) - - -i18n_env = Environment( - loader=DictLoader(i18n_templates), - extensions=['jinja2.ext.i18n'] -) -i18n_env.globals.update({ - '_': gettext, - 'gettext': gettext, - 'ngettext': ngettext -}) - -newstyle_i18n_env = Environment( - loader=DictLoader(newstyle_i18n_templates), - extensions=['jinja2.ext.i18n'] -) -newstyle_i18n_env.install_gettext_callables(gettext, ngettext, newstyle=True) - - -class TestExtension(Extension): - tags = set(['test']) - ext_attr = 42 - - def parse(self, parser): - return nodes.Output([self.call_method('_dump', [ - nodes.EnvironmentAttribute('sandboxed'), - self.attr('ext_attr'), - nodes.ImportedName(__name__ + '.importable_object'), - nodes.ContextReference() - ])]).set_lineno(next(parser.stream).lineno) - - def _dump(self, sandboxed, ext_attr, imported_object, context): - return '%s|%s|%s|%s' % ( - sandboxed, - ext_attr, - imported_object, - context.blocks - ) - - -class PreprocessorExtension(Extension): - - def preprocess(self, source, name, filename=None): - return source.replace('[[TEST]]', '({{ foo }})') - - -class StreamFilterExtension(Extension): - - def filter_stream(self, stream): - for token in stream: - if token.type == 'data': - for t in self.interpolate(token): - yield t - else: - yield token - - def interpolate(self, token): - pos = 0 - end = len(token.value) - lineno = token.lineno - while 1: - match = _gettext_re.search(token.value, pos) - if match is None: - break - value = token.value[pos:match.start()] - if value: - yield Token(lineno, 'data', value) - lineno += count_newlines(token.value) - yield Token(lineno, 'variable_begin', None) - yield Token(lineno, 'name', 'gettext') - yield Token(lineno, 'lparen', None) - yield Token(lineno, 'string', match.group(1)) - yield Token(lineno, 'rparen', None) - yield Token(lineno, 'variable_end', None) - pos = match.end() - if pos < end: - yield Token(lineno, 'data', token.value[pos:]) - - -@pytest.mark.ext -class TestExtensions(): - - def test_extend_late(self): - env = Environment() - env.add_extension('jinja2.ext.autoescape') - t = env.from_string( - '{% autoescape true %}{{ "" }}{% endautoescape %}') - assert t.render() == '<test>' - - def test_loop_controls(self): - env = Environment(extensions=['jinja2.ext.loopcontrols']) - - tmpl = env.from_string(''' - {%- for item in [1, 2, 3, 4] %} - {%- if item % 2 == 0 %}{% continue %}{% endif -%} - {{ item }} - {%- endfor %}''') - assert tmpl.render() == '13' - - tmpl = env.from_string(''' - {%- for item in [1, 2, 3, 4] %} - {%- if item > 2 %}{% break %}{% endif -%} - {{ item }} - {%- endfor %}''') - assert tmpl.render() == '12' - - def test_do(self): - env = Environment(extensions=['jinja2.ext.do']) - tmpl = env.from_string(''' - {%- set items = [] %} - {%- for char in "foo" %} - {%- do items.append(loop.index0 ~ char) %} - {%- endfor %}{{ items|join(', ') }}''') - assert tmpl.render() == '0f, 1o, 2o' - - def test_with(self): - env = Environment(extensions=['jinja2.ext.with_']) - tmpl = env.from_string('''\ - {% with a=42, b=23 -%} - {{ a }} = {{ b }} - {% endwith -%} - {{ a }} = {{ b }}\ - ''') - assert [x.strip() for x in tmpl.render(a=1, b=2).splitlines()] \ - == ['42 = 23', '1 = 2'] - - def test_extension_nodes(self): - env = Environment(extensions=[TestExtension]) - tmpl = env.from_string('{% test %}') - assert tmpl.render() == 'False|42|23|{}' - - def test_identifier(self): - assert TestExtension.identifier == __name__ + '.TestExtension' - - def test_rebinding(self): - original = Environment(extensions=[TestExtension]) - overlay = original.overlay() - for env in original, overlay: - for ext in itervalues(env.extensions): - assert ext.environment is env - - def test_preprocessor_extension(self): - env = Environment(extensions=[PreprocessorExtension]) - tmpl = env.from_string('{[[TEST]]}') - assert tmpl.render(foo=42) == '{(42)}' - - def test_streamfilter_extension(self): - env = Environment(extensions=[StreamFilterExtension]) - env.globals['gettext'] = lambda x: x.upper() - tmpl = env.from_string('Foo _(bar) Baz') - out = tmpl.render() - assert out == 'Foo BAR Baz' - - def test_extension_ordering(self): - class T1(Extension): - priority = 1 - - class T2(Extension): - priority = 2 - env = Environment(extensions=[T1, T2]) - ext = list(env.iter_extensions()) - assert ext[0].__class__ is T1 - assert ext[1].__class__ is T2 - - -@pytest.mark.ext -class TestInternationalization(): - - def test_trans(self): - tmpl = i18n_env.get_template('child.html') - assert tmpl.render(LANGUAGE='de') == 'fehlendpass auf' - - def test_trans_plural(self): - tmpl = i18n_env.get_template('plural.html') - assert tmpl.render(LANGUAGE='de', user_count=1) \ - == 'Ein Benutzer online' - assert tmpl.render(LANGUAGE='de', user_count=2) == '2 Benutzer online' - - def test_trans_plural_with_functions(self): - tmpl = i18n_env.get_template('plural2.html') - - def get_user_count(): - get_user_count.called += 1 - return 1 - get_user_count.called = 0 - assert tmpl.render(LANGUAGE='de', get_user_count=get_user_count) \ - == '1s' - assert get_user_count.called == 1 - - def test_complex_plural(self): - tmpl = i18n_env.from_string( - '{% trans foo=42, count=2 %}{{ count }} item{% ' - 'pluralize count %}{{ count }} items{% endtrans %}') - assert tmpl.render() == '2 items' - pytest.raises(TemplateAssertionError, i18n_env.from_string, - '{% trans foo %}...{% pluralize bar %}...{% endtrans %}') - - def test_trans_stringformatting(self): - tmpl = i18n_env.get_template('stringformat.html') - assert tmpl.render(LANGUAGE='de', user_count=5) == 'Benutzer: 5' - - def test_extract(self): - from jinja2.ext import babel_extract - source = BytesIO(''' - {{ gettext('Hello World') }} - {% trans %}Hello World{% endtrans %} - {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %} - '''.encode('ascii')) # make python 3 happy - assert list(babel_extract(source, - ('gettext', 'ngettext', '_'), [], {})) == [ - (2, 'gettext', u'Hello World', []), - (3, 'gettext', u'Hello World', []), - (4, 'ngettext', (u'%(users)s user', u'%(users)s users', None), []) - ] - - def test_comment_extract(self): - from jinja2.ext import babel_extract - source = BytesIO(''' - {# trans first #} - {{ gettext('Hello World') }} - {% trans %}Hello World{% endtrans %}{# trans second #} - {#: third #} - {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %} - '''.encode('utf-8')) # make python 3 happy - assert list(babel_extract(source, - ('gettext', 'ngettext', '_'), - ['trans', ':'], {})) == [ - (3, 'gettext', u'Hello World', ['first']), - (4, 'gettext', u'Hello World', ['second']), - (6, 'ngettext', (u'%(users)s user', u'%(users)s users', None), - ['third']) - ] - - -@pytest.mark.ext -class TestNewstyleInternationalization(): - - def test_trans(self): - tmpl = newstyle_i18n_env.get_template('child.html') - assert tmpl.render(LANGUAGE='de') == 'fehlendpass auf' - - def test_trans_plural(self): - tmpl = newstyle_i18n_env.get_template('plural.html') - assert tmpl.render(LANGUAGE='de', user_count=1) \ - == 'Ein Benutzer online' - assert tmpl.render(LANGUAGE='de', user_count=2) == '2 Benutzer online' - - def test_complex_plural(self): - tmpl = newstyle_i18n_env.from_string( - '{% trans foo=42, count=2 %}{{ count }} item{% ' - 'pluralize count %}{{ count }} items{% endtrans %}') - assert tmpl.render() == '2 items' - pytest.raises(TemplateAssertionError, i18n_env.from_string, - '{% trans foo %}...{% pluralize bar %}...{% endtrans %}') - - def test_trans_stringformatting(self): - tmpl = newstyle_i18n_env.get_template('stringformat.html') - assert tmpl.render(LANGUAGE='de', user_count=5) == 'Benutzer: 5' - - def test_newstyle_plural(self): - tmpl = newstyle_i18n_env.get_template('ngettext.html') - assert tmpl.render(LANGUAGE='de', apples=1) == '1 Apfel' - assert tmpl.render(LANGUAGE='de', apples=5) == u'5 Äpfel' - - def test_autoescape_support(self): - env = Environment(extensions=['jinja2.ext.autoescape', - 'jinja2.ext.i18n']) - env.install_gettext_callables( - lambda x: u'Wert: %(name)s', - lambda s, p, n: s, newstyle=True) - t = env.from_string('{% autoescape ae %}{{ gettext("foo", name=' - '"") }}{% endautoescape %}') - assert t.render(ae=True) == 'Wert: <test>' - assert t.render(ae=False) == 'Wert: ' - - def test_num_used_twice(self): - tmpl = newstyle_i18n_env.get_template('ngettext_long.html') - assert tmpl.render(apples=5, LANGUAGE='de') == u'5 Äpfel' - - def test_num_called_num(self): - source = newstyle_i18n_env.compile(''' - {% trans num=3 %}{{ num }} apple{% pluralize - %}{{ num }} apples{% endtrans %} - ''', raw=True) - # quite hacky, but the only way to properly test that. The idea is - # that the generated code does not pass num twice (although that - # would work) for better performance. This only works on the - # newstyle gettext of course - assert re.search(r"l_ngettext, u?'\%\(num\)s apple', u?'\%\(num\)s " - r"apples', 3", source) is not None - - def test_trans_vars(self): - t1 = newstyle_i18n_env.get_template('transvars1.html') - t2 = newstyle_i18n_env.get_template('transvars2.html') - t3 = newstyle_i18n_env.get_template('transvars3.html') - assert t1.render(num=1, LANGUAGE='de') == 'Benutzer: 1' - assert t2.render(count=23, LANGUAGE='de') == 'Benutzer: 23' - assert t3.render(num=42, LANGUAGE='de') == 'Benutzer: 42' - - def test_novars_vars_escaping(self): - t = newstyle_i18n_env.get_template('novars.html') - assert t.render() == '%(hello)s' - t = newstyle_i18n_env.get_template('vars.html') - assert t.render(foo='42') == '42%(foo)s' - t = newstyle_i18n_env.get_template('explicitvars.html') - assert t.render() == '%(foo)s' - - -@pytest.mark.ext -class TestAutoEscape(): - - def test_scoped_setting(self): - env = Environment(extensions=['jinja2.ext.autoescape'], - autoescape=True) - tmpl = env.from_string(''' - {{ "" }} - {% autoescape false %} - {{ "" }} - {% endautoescape %} - {{ "" }} - ''') - assert tmpl.render().split() == \ - [u'<HelloWorld>', u'', u'<HelloWorld>'] - - env = Environment(extensions=['jinja2.ext.autoescape'], - autoescape=False) - tmpl = env.from_string(''' - {{ "" }} - {% autoescape true %} - {{ "" }} - {% endautoescape %} - {{ "" }} - ''') - assert tmpl.render().split() == \ - [u'', u'<HelloWorld>', u''] - - def test_nonvolatile(self): - env = Environment(extensions=['jinja2.ext.autoescape'], - autoescape=True) - tmpl = env.from_string('{{ {"foo": ""}|xmlattr|escape }}') - assert tmpl.render() == ' foo="<test>"' - tmpl = env.from_string('{% autoescape false %}{{ {"foo": ""}' - '|xmlattr|escape }}{% endautoescape %}') - assert tmpl.render() == ' foo="&lt;test&gt;"' - - def test_volatile(self): - env = Environment(extensions=['jinja2.ext.autoescape'], - autoescape=True) - tmpl = env.from_string('{% autoescape foo %}{{ {"foo": ""}' - '|xmlattr|escape }}{% endautoescape %}') - assert tmpl.render(foo=False) == ' foo="&lt;test&gt;"' - assert tmpl.render(foo=True) == ' foo="<test>"' - - def test_scoping(self): - env = Environment(extensions=['jinja2.ext.autoescape']) - tmpl = env.from_string( - '{% autoescape true %}{% set x = "" %}{{ x }}' - '{% endautoescape %}{{ x }}{{ "" }}') - assert tmpl.render(x=1) == '<x>1' - - def test_volatile_scoping(self): - env = Environment(extensions=['jinja2.ext.autoescape']) - tmplsource = ''' - {% autoescape val %} - {% macro foo(x) %} - [{{ x }}] - {% endmacro %} - {{ foo().__class__.__name__ }} - {% endautoescape %} - {{ '' }} - ''' - tmpl = env.from_string(tmplsource) - assert tmpl.render(val=True).split()[0] == 'Markup' - assert tmpl.render(val=False).split()[0] == text_type.__name__ - - # looking at the source we should see there in raw - # (and then escaped as well) - env = Environment(extensions=['jinja2.ext.autoescape']) - pysource = env.compile(tmplsource, raw=True) - assert '\\n' in pysource - - env = Environment(extensions=['jinja2.ext.autoescape'], - autoescape=True) - pysource = env.compile(tmplsource, raw=True) - assert '<testing>\\n' in pysource diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_filters.py b/deps/v8_inspector/third_party/jinja2/tests/test_filters.py deleted file mode 100644 index 741ef341b1b0f7..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_filters.py +++ /dev/null @@ -1,558 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.filters - ~~~~~~~~~~~~~~~~~~~~~~~~ - - Tests for the jinja filters. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest -from jinja2 import Markup, Environment -from jinja2._compat import text_type, implements_to_string - - -@pytest.mark.filter -class TestFilter(): - - def test_filter_calling(self, env): - rv = env.call_filter('sum', [1, 2, 3]) - assert rv == 6 - - def test_capitalize(self, env): - tmpl = env.from_string('{{ "foo bar"|capitalize }}') - assert tmpl.render() == 'Foo bar' - - def test_center(self, env): - tmpl = env.from_string('{{ "foo"|center(9) }}') - assert tmpl.render() == ' foo ' - - def test_default(self, env): - tmpl = env.from_string( - "{{ missing|default('no') }}|{{ false|default('no') }}|" - "{{ false|default('no', true) }}|{{ given|default('no') }}" - ) - assert tmpl.render(given='yes') == 'no|False|no|yes' - - def test_dictsort(self, env): - tmpl = env.from_string( - '{{ foo|dictsort }}|' - '{{ foo|dictsort(true) }}|' - '{{ foo|dictsort(false, "value") }}' - ) - out = tmpl.render(foo={"aa": 0, "b": 1, "c": 2, "AB": 3}) - assert out == ("[('aa', 0), ('AB', 3), ('b', 1), ('c', 2)]|" - "[('AB', 3), ('aa', 0), ('b', 1), ('c', 2)]|" - "[('aa', 0), ('b', 1), ('c', 2), ('AB', 3)]") - - def test_batch(self, env): - tmpl = env.from_string("{{ foo|batch(3)|list }}|" - "{{ foo|batch(3, 'X')|list }}") - out = tmpl.render(foo=list(range(10))) - assert out == ("[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]|" - "[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 'X', 'X']]") - - def test_slice(self, env): - tmpl = env.from_string('{{ foo|slice(3)|list }}|' - '{{ foo|slice(3, "X")|list }}') - out = tmpl.render(foo=list(range(10))) - assert out == ("[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|" - "[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]") - - def test_escape(self, env): - tmpl = env.from_string('''{{ '<">&'|escape }}''') - out = tmpl.render() - assert out == '<">&' - - def test_striptags(self, env): - tmpl = env.from_string('''{{ foo|striptags }}''') - out = tmpl.render(foo='

just a small \n ' - 'example link

\n

to a webpage

' - '') - assert out == 'just a small example link to a webpage' - - def test_filesizeformat(self, env): - tmpl = env.from_string( - '{{ 100|filesizeformat }}|' - '{{ 1000|filesizeformat }}|' - '{{ 1000000|filesizeformat }}|' - '{{ 1000000000|filesizeformat }}|' - '{{ 1000000000000|filesizeformat }}|' - '{{ 100|filesizeformat(true) }}|' - '{{ 1000|filesizeformat(true) }}|' - '{{ 1000000|filesizeformat(true) }}|' - '{{ 1000000000|filesizeformat(true) }}|' - '{{ 1000000000000|filesizeformat(true) }}' - ) - out = tmpl.render() - assert out == ( - '100 Bytes|1.0 kB|1.0 MB|1.0 GB|1.0 TB|100 Bytes|' - '1000 Bytes|976.6 KiB|953.7 MiB|931.3 GiB' - ) - - def test_filesizeformat_issue59(self, env): - tmpl = env.from_string( - '{{ 300|filesizeformat }}|' - '{{ 3000|filesizeformat }}|' - '{{ 3000000|filesizeformat }}|' - '{{ 3000000000|filesizeformat }}|' - '{{ 3000000000000|filesizeformat }}|' - '{{ 300|filesizeformat(true) }}|' - '{{ 3000|filesizeformat(true) }}|' - '{{ 3000000|filesizeformat(true) }}' - ) - out = tmpl.render() - assert out == ( - '300 Bytes|3.0 kB|3.0 MB|3.0 GB|3.0 TB|300 Bytes|' - '2.9 KiB|2.9 MiB' - ) - - def test_first(self, env): - tmpl = env.from_string('{{ foo|first }}') - out = tmpl.render(foo=list(range(10))) - assert out == '0' - - def test_float(self, env): - tmpl = env.from_string('{{ "42"|float }}|' - '{{ "ajsghasjgd"|float }}|' - '{{ "32.32"|float }}') - out = tmpl.render() - assert out == '42.0|0.0|32.32' - - def test_format(self, env): - tmpl = env.from_string('''{{ "%s|%s"|format("a", "b") }}''') - out = tmpl.render() - assert out == 'a|b' - - def test_indent(self, env): - tmpl = env.from_string('{{ foo|indent(2) }}|{{ foo|indent(2, true) }}') - text = '\n'.join([' '.join(['foo', 'bar'] * 2)] * 2) - out = tmpl.render(foo=text) - assert out == ('foo bar foo bar\n foo bar foo bar| ' - 'foo bar foo bar\n foo bar foo bar') - - def test_int(self, env): - tmpl = env.from_string('{{ "42"|int }}|{{ "ajsghasjgd"|int }}|' - '{{ "32.32"|int }}|{{ "0x4d32"|int(0, 16) }}|' - '{{ "011"|int(0, 8)}}|{{ "0x33FU"|int(0, 16) }}') - out = tmpl.render() - assert out == '42|0|32|19762|9|0' - - def test_join(self, env): - tmpl = env.from_string('{{ [1, 2, 3]|join("|") }}') - out = tmpl.render() - assert out == '1|2|3' - - env2 = Environment(autoescape=True) - tmpl = env2.from_string( - '{{ ["", "foo"|safe]|join }}') - assert tmpl.render() == '<foo>foo' - - def test_join_attribute(self, env): - class User(object): - def __init__(self, username): - self.username = username - tmpl = env.from_string('''{{ users|join(', ', 'username') }}''') - assert tmpl.render(users=map(User, ['foo', 'bar'])) == 'foo, bar' - - def test_last(self, env): - tmpl = env.from_string('''{{ foo|last }}''') - out = tmpl.render(foo=list(range(10))) - assert out == '9' - - def test_length(self, env): - tmpl = env.from_string('''{{ "hello world"|length }}''') - out = tmpl.render() - assert out == '11' - - def test_lower(self, env): - tmpl = env.from_string('''{{ "FOO"|lower }}''') - out = tmpl.render() - assert out == 'foo' - - def test_pprint(self, env): - from pprint import pformat - tmpl = env.from_string('''{{ data|pprint }}''') - data = list(range(1000)) - assert tmpl.render(data=data) == pformat(data) - - def test_random(self, env): - tmpl = env.from_string('''{{ seq|random }}''') - seq = list(range(100)) - for _ in range(10): - assert int(tmpl.render(seq=seq)) in seq - - def test_reverse(self, env): - tmpl = env.from_string('{{ "foobar"|reverse|join }}|' - '{{ [1, 2, 3]|reverse|list }}') - assert tmpl.render() == 'raboof|[3, 2, 1]' - - def test_string(self, env): - x = [1, 2, 3, 4, 5] - tmpl = env.from_string('''{{ obj|string }}''') - assert tmpl.render(obj=x) == text_type(x) - - def test_title(self, env): - tmpl = env.from_string('''{{ "foo bar"|title }}''') - assert tmpl.render() == "Foo Bar" - tmpl = env.from_string('''{{ "foo's bar"|title }}''') - assert tmpl.render() == "Foo's Bar" - tmpl = env.from_string('''{{ "foo bar"|title }}''') - assert tmpl.render() == "Foo Bar" - tmpl = env.from_string('''{{ "f bar f"|title }}''') - assert tmpl.render() == "F Bar F" - tmpl = env.from_string('''{{ "foo-bar"|title }}''') - assert tmpl.render() == "Foo-Bar" - tmpl = env.from_string('''{{ "foo\tbar"|title }}''') - assert tmpl.render() == "Foo\tBar" - tmpl = env.from_string('''{{ "FOO\tBAR"|title }}''') - assert tmpl.render() == "Foo\tBar" - - class Foo: - def __str__(self): - return 'foo-bar' - - tmpl = env.from_string('''{{ data|title }}''') - out = tmpl.render(data=Foo()) - assert out == 'Foo-Bar' - - def test_truncate(self, env): - tmpl = env.from_string( - '{{ data|truncate(15, true, ">>>") }}|' - '{{ data|truncate(15, false, ">>>") }}|' - '{{ smalldata|truncate(15) }}' - ) - out = tmpl.render(data='foobar baz bar' * 1000, - smalldata='foobar baz bar') - msg = 'Current output: %s' % out - assert out == 'foobar baz b>>>|foobar baz >>>|foobar baz bar', msg - - def test_truncate_very_short(self, env): - tmpl = env.from_string( - '{{ "foo bar baz"|truncate(9) }}|' - '{{ "foo bar baz"|truncate(9, true) }}' - ) - out = tmpl.render() - assert out == 'foo ...|foo ba...', out - - def test_truncate_end_length(self, env): - tmpl = env.from_string('{{ "Joel is a slug"|truncate(9, true) }}') - out = tmpl.render() - assert out == 'Joel i...', 'Current output: %s' % out - - def test_upper(self, env): - tmpl = env.from_string('{{ "foo"|upper }}') - assert tmpl.render() == 'FOO' - - def test_urlize(self, env): - tmpl = env.from_string( - '{{ "foo http://www.example.com/ bar"|urlize }}') - assert tmpl.render() == 'foo '\ - 'http://www.example.com/ bar' - - def test_urlize_target_parameter(self, env): - tmpl = env.from_string( - '{{ "foo http://www.example.com/ bar"|urlize(target="_blank") }}' - ) - assert tmpl.render() \ - == 'foo '\ - 'http://www.example.com/ bar' - tmpl = env.from_string( - '{{ "foo http://www.example.com/ bar"|urlize(target=42) }}' - ) - assert tmpl.render() == 'foo '\ - 'http://www.example.com/ bar' - - def test_wordcount(self, env): - tmpl = env.from_string('{{ "foo bar baz"|wordcount }}') - assert tmpl.render() == '3' - - def test_block(self, env): - tmpl = env.from_string( - '{% filter lower|escape %}{% endfilter %}' - ) - assert tmpl.render() == '<hehe>' - - def test_chaining(self, env): - tmpl = env.from_string( - '''{{ ['', '']|first|upper|escape }}''' - ) - assert tmpl.render() == '<FOO>' - - def test_sum(self, env): - tmpl = env.from_string('''{{ [1, 2, 3, 4, 5, 6]|sum }}''') - assert tmpl.render() == '21' - - def test_sum_attributes(self, env): - tmpl = env.from_string('''{{ values|sum('value') }}''') - assert tmpl.render(values=[ - {'value': 23}, - {'value': 1}, - {'value': 18}, - ]) == '42' - - def test_sum_attributes_nested(self, env): - tmpl = env.from_string('''{{ values|sum('real.value') }}''') - assert tmpl.render(values=[ - {'real': {'value': 23}}, - {'real': {'value': 1}}, - {'real': {'value': 18}}, - ]) == '42' - - def test_sum_attributes_tuple(self, env): - tmpl = env.from_string('''{{ values.items()|sum('1') }}''') - assert tmpl.render(values={ - 'foo': 23, - 'bar': 1, - 'baz': 18, - }) == '42' - - def test_abs(self, env): - tmpl = env.from_string('''{{ -1|abs }}|{{ 1|abs }}''') - assert tmpl.render() == '1|1', tmpl.render() - - def test_round_positive(self, env): - tmpl = env.from_string('{{ 2.7|round }}|{{ 2.1|round }}|' - "{{ 2.1234|round(3, 'floor') }}|" - "{{ 2.1|round(0, 'ceil') }}") - assert tmpl.render() == '3.0|2.0|2.123|3.0', tmpl.render() - - def test_round_negative(self, env): - tmpl = env.from_string('{{ 21.3|round(-1)}}|' - "{{ 21.3|round(-1, 'ceil')}}|" - "{{ 21.3|round(-1, 'floor')}}") - assert tmpl.render() == '20.0|30.0|20.0', tmpl.render() - - def test_xmlattr(self, env): - tmpl = env.from_string( - "{{ {'foo': 42, 'bar': 23, 'fish': none, " - "'spam': missing, 'blub:blub': ''}|xmlattr }}") - out = tmpl.render().split() - assert len(out) == 3 - assert 'foo="42"' in out - assert 'bar="23"' in out - assert 'blub:blub="<?>"' in out - - def test_sort1(self, env): - tmpl = env.from_string( - '{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}') - assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]' - - def test_sort2(self, env): - tmpl = env.from_string('{{ "".join(["c", "A", "b", "D"]|sort) }}') - assert tmpl.render() == 'AbcD' - - def test_sort3(self, env): - tmpl = env.from_string('''{{ ['foo', 'Bar', 'blah']|sort }}''') - assert tmpl.render() == "['Bar', 'blah', 'foo']" - - def test_sort4(self, env): - @implements_to_string - class Magic(object): - def __init__(self, value): - self.value = value - - def __str__(self): - return text_type(self.value) - tmpl = env.from_string('''{{ items|sort(attribute='value')|join }}''') - assert tmpl.render(items=map(Magic, [3, 2, 4, 1])) == '1234' - - def test_groupby(self, env): - tmpl = env.from_string(''' - {%- for grouper, list in [{'foo': 1, 'bar': 2}, - {'foo': 2, 'bar': 3}, - {'foo': 1, 'bar': 1}, - {'foo': 3, 'bar': 4}]|groupby('foo') -%} - {{ grouper }}{% for x in list %}: {{ x.foo }}, {{ x.bar }}{% endfor %}| - {%- endfor %}''') - assert tmpl.render().split('|') == [ - "1: 1, 2: 1, 1", - "2: 2, 3", - "3: 3, 4", - "" - ] - - def test_groupby_tuple_index(self, env): - tmpl = env.from_string(''' - {%- for grouper, list in [('a', 1), ('a', 2), ('b', 1)]|groupby(0) -%} - {{ grouper }}{% for x in list %}:{{ x.1 }}{% endfor %}| - {%- endfor %}''') - assert tmpl.render() == 'a:1:2|b:1|' - - def test_groupby_multidot(self, env): - class Date(object): - def __init__(self, day, month, year): - self.day = day - self.month = month - self.year = year - - class Article(object): - def __init__(self, title, *date): - self.date = Date(*date) - self.title = title - articles = [ - Article('aha', 1, 1, 1970), - Article('interesting', 2, 1, 1970), - Article('really?', 3, 1, 1970), - Article('totally not', 1, 1, 1971) - ] - tmpl = env.from_string(''' - {%- for year, list in articles|groupby('date.year') -%} - {{ year }}{% for x in list %}[{{ x.title }}]{% endfor %}| - {%- endfor %}''') - assert tmpl.render(articles=articles).split('|') == [ - '1970[aha][interesting][really?]', - '1971[totally not]', - '' - ] - - def test_filtertag(self, env): - tmpl = env.from_string("{% filter upper|replace('FOO', 'foo') %}" - "foobar{% endfilter %}") - assert tmpl.render() == 'fooBAR' - - def test_replace(self, env): - env = Environment() - tmpl = env.from_string('{{ string|replace("o", 42) }}') - assert tmpl.render(string='') == '' - env = Environment(autoescape=True) - tmpl = env.from_string('{{ string|replace("o", 42) }}') - assert tmpl.render(string='') == '<f4242>' - tmpl = env.from_string('{{ string|replace("<", 42) }}') - assert tmpl.render(string='') == '42foo>' - tmpl = env.from_string('{{ string|replace("o", ">x<") }}') - assert tmpl.render(string=Markup('foo')) == 'f>x<>x<' - - def test_forceescape(self, env): - tmpl = env.from_string('{{ x|forceescape }}') - assert tmpl.render(x=Markup('
')) == u'<div />' - - def test_safe(self, env): - env = Environment(autoescape=True) - tmpl = env.from_string('{{ "
foo
"|safe }}') - assert tmpl.render() == '
foo
' - tmpl = env.from_string('{{ "
foo
" }}') - assert tmpl.render() == '<div>foo</div>' - - def test_urlencode(self, env): - env = Environment(autoescape=True) - tmpl = env.from_string('{{ "Hello, world!"|urlencode }}') - assert tmpl.render() == 'Hello%2C%20world%21' - tmpl = env.from_string('{{ o|urlencode }}') - assert tmpl.render(o=u"Hello, world\u203d") \ - == "Hello%2C%20world%E2%80%BD" - assert tmpl.render(o=(("f", 1),)) == "f=1" - assert tmpl.render(o=(('f', 1), ("z", 2))) == "f=1&z=2" - assert tmpl.render(o=((u"\u203d", 1),)) == "%E2%80%BD=1" - assert tmpl.render(o={u"\u203d": 1}) == "%E2%80%BD=1" - assert tmpl.render(o={0: 1}) == "0=1" - - def test_simple_map(self, env): - env = Environment() - tmpl = env.from_string('{{ ["1", "2", "3"]|map("int")|sum }}') - assert tmpl.render() == '6' - - def test_attribute_map(self, env): - class User(object): - def __init__(self, name): - self.name = name - env = Environment() - users = [ - User('john'), - User('jane'), - User('mike'), - ] - tmpl = env.from_string('{{ users|map(attribute="name")|join("|") }}') - assert tmpl.render(users=users) == 'john|jane|mike' - - def test_empty_map(self, env): - env = Environment() - tmpl = env.from_string('{{ none|map("upper")|list }}') - assert tmpl.render() == '[]' - - def test_simple_select(self, env): - env = Environment() - tmpl = env.from_string('{{ [1, 2, 3, 4, 5]|select("odd")|join("|") }}') - assert tmpl.render() == '1|3|5' - - def test_bool_select(self, env): - env = Environment() - tmpl = env.from_string( - '{{ [none, false, 0, 1, 2, 3, 4, 5]|select|join("|") }}' - ) - assert tmpl.render() == '1|2|3|4|5' - - def test_simple_reject(self, env): - env = Environment() - tmpl = env.from_string('{{ [1, 2, 3, 4, 5]|reject("odd")|join("|") }}') - assert tmpl.render() == '2|4' - - def test_bool_reject(self, env): - env = Environment() - tmpl = env.from_string( - '{{ [none, false, 0, 1, 2, 3, 4, 5]|reject|join("|") }}' - ) - assert tmpl.render() == 'None|False|0' - - def test_simple_select_attr(self, env): - class User(object): - def __init__(self, name, is_active): - self.name = name - self.is_active = is_active - env = Environment() - users = [ - User('john', True), - User('jane', True), - User('mike', False), - ] - tmpl = env.from_string( - '{{ users|selectattr("is_active")|' - 'map(attribute="name")|join("|") }}' - ) - assert tmpl.render(users=users) == 'john|jane' - - def test_simple_reject_attr(self, env): - class User(object): - def __init__(self, name, is_active): - self.name = name - self.is_active = is_active - env = Environment() - users = [ - User('john', True), - User('jane', True), - User('mike', False), - ] - tmpl = env.from_string('{{ users|rejectattr("is_active")|' - 'map(attribute="name")|join("|") }}') - assert tmpl.render(users=users) == 'mike' - - def test_func_select_attr(self, env): - class User(object): - def __init__(self, id, name): - self.id = id - self.name = name - env = Environment() - users = [ - User(1, 'john'), - User(2, 'jane'), - User(3, 'mike'), - ] - tmpl = env.from_string('{{ users|selectattr("id", "odd")|' - 'map(attribute="name")|join("|") }}') - assert tmpl.render(users=users) == 'john|mike' - - def test_func_reject_attr(self, env): - class User(object): - def __init__(self, id, name): - self.id = id - self.name = name - env = Environment() - users = [ - User(1, 'john'), - User(2, 'jane'), - User(3, 'mike'), - ] - tmpl = env.from_string('{{ users|rejectattr("id", "odd")|' - 'map(attribute="name")|join("|") }}') - assert tmpl.render(users=users) == 'jane' diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_imports.py b/deps/v8_inspector/third_party/jinja2/tests/test_imports.py deleted file mode 100644 index 643c995c6e6ade..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_imports.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.imports - ~~~~~~~~~~~~~~~~~~~~~~~~ - - Tests the import features (with includes). - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest - -from jinja2 import Environment, DictLoader -from jinja2.exceptions import TemplateNotFound, TemplatesNotFound - - -@pytest.fixture -def test_env(): - env = Environment(loader=DictLoader(dict( - module='{% macro test() %}[{{ foo }}|{{ bar }}]{% endmacro %}', - header='[{{ foo }}|{{ 23 }}]', - o_printer='({{ o }})' - ))) - env.globals['bar'] = 23 - return env - - -@pytest.mark.imports -class TestImports(): - - def test_context_imports(self, test_env): - t = test_env.from_string('{% import "module" as m %}{{ m.test() }}') - assert t.render(foo=42) == '[|23]' - t = test_env.from_string( - '{% import "module" as m without context %}{{ m.test() }}' - ) - assert t.render(foo=42) == '[|23]' - t = test_env.from_string( - '{% import "module" as m with context %}{{ m.test() }}' - ) - assert t.render(foo=42) == '[42|23]' - t = test_env.from_string('{% from "module" import test %}{{ test() }}') - assert t.render(foo=42) == '[|23]' - t = test_env.from_string( - '{% from "module" import test without context %}{{ test() }}' - ) - assert t.render(foo=42) == '[|23]' - t = test_env.from_string( - '{% from "module" import test with context %}{{ test() }}' - ) - assert t.render(foo=42) == '[42|23]' - - def test_trailing_comma(self, test_env): - test_env.from_string('{% from "foo" import bar, baz with context %}') - test_env.from_string('{% from "foo" import bar, baz, with context %}') - test_env.from_string('{% from "foo" import bar, with context %}') - test_env.from_string('{% from "foo" import bar, with, context %}') - test_env.from_string('{% from "foo" import bar, with with context %}') - - def test_exports(self, test_env): - m = test_env.from_string(''' - {% macro toplevel() %}...{% endmacro %} - {% macro __private() %}...{% endmacro %} - {% set variable = 42 %} - {% for item in [1] %} - {% macro notthere() %}{% endmacro %} - {% endfor %} - ''').module - assert m.toplevel() == '...' - assert not hasattr(m, '__missing') - assert m.variable == 42 - assert not hasattr(m, 'notthere') - - -@pytest.mark.imports -@pytest.mark.includes -class TestIncludes(): - - def test_context_include(self, test_env): - t = test_env.from_string('{% include "header" %}') - assert t.render(foo=42) == '[42|23]' - t = test_env.from_string('{% include "header" with context %}') - assert t.render(foo=42) == '[42|23]' - t = test_env.from_string('{% include "header" without context %}') - assert t.render(foo=42) == '[|23]' - - def test_choice_includes(self, test_env): - t = test_env.from_string('{% include ["missing", "header"] %}') - assert t.render(foo=42) == '[42|23]' - - t = test_env.from_string( - '{% include ["missing", "missing2"] ignore missing %}' - ) - assert t.render(foo=42) == '' - - t = test_env.from_string('{% include ["missing", "missing2"] %}') - pytest.raises(TemplateNotFound, t.render) - try: - t.render() - except TemplatesNotFound as e: - assert e.templates == ['missing', 'missing2'] - assert e.name == 'missing2' - else: - assert False, 'thou shalt raise' - - def test_includes(t, **ctx): - ctx['foo'] = 42 - assert t.render(ctx) == '[42|23]' - - t = test_env.from_string('{% include ["missing", "header"] %}') - test_includes(t) - t = test_env.from_string('{% include x %}') - test_includes(t, x=['missing', 'header']) - t = test_env.from_string('{% include [x, "header"] %}') - test_includes(t, x='missing') - t = test_env.from_string('{% include x %}') - test_includes(t, x='header') - t = test_env.from_string('{% include x %}') - test_includes(t, x='header') - t = test_env.from_string('{% include [x] %}') - test_includes(t, x='header') - - def test_include_ignoring_missing(self, test_env): - t = test_env.from_string('{% include "missing" %}') - pytest.raises(TemplateNotFound, t.render) - for extra in '', 'with context', 'without context': - t = test_env.from_string('{% include "missing" ignore missing ' + - extra + ' %}') - assert t.render() == '' - - def test_context_include_with_overrides(self, test_env): - env = Environment(loader=DictLoader(dict( - main="{% for item in [1, 2, 3] %}{% include 'item' %}{% endfor %}", - item="{{ item }}" - ))) - assert env.get_template("main").render() == "123" - - def test_unoptimized_scopes(self, test_env): - t = test_env.from_string(""" - {% macro outer(o) %} - {% macro inner() %} - {% include "o_printer" %} - {% endmacro %} - {{ inner() }} - {% endmacro %} - {{ outer("FOO") }} - """) - assert t.render().strip() == '(FOO)' diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_inheritance.py b/deps/v8_inspector/third_party/jinja2/tests/test_inheritance.py deleted file mode 100644 index 1cb7390441c09e..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_inheritance.py +++ /dev/null @@ -1,248 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.inheritance - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Tests the template inheritance feature. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest - -from jinja2 import Environment, DictLoader, TemplateError - - -LAYOUTTEMPLATE = '''\ -|{% block block1 %}block 1 from layout{% endblock %} -|{% block block2 %}block 2 from layout{% endblock %} -|{% block block3 %} -{% block block4 %}nested block 4 from layout{% endblock %} -{% endblock %}|''' - -LEVEL1TEMPLATE = '''\ -{% extends "layout" %} -{% block block1 %}block 1 from level1{% endblock %}''' - -LEVEL2TEMPLATE = '''\ -{% extends "level1" %} -{% block block2 %}{% block block5 %}nested block 5 from level2{% -endblock %}{% endblock %}''' - -LEVEL3TEMPLATE = '''\ -{% extends "level2" %} -{% block block5 %}block 5 from level3{% endblock %} -{% block block4 %}block 4 from level3{% endblock %} -''' - -LEVEL4TEMPLATE = '''\ -{% extends "level3" %} -{% block block3 %}block 3 from level4{% endblock %} -''' - -WORKINGTEMPLATE = '''\ -{% extends "layout" %} -{% block block1 %} - {% if false %} - {% block block2 %} - this should workd - {% endblock %} - {% endif %} -{% endblock %} -''' - -DOUBLEEXTENDS = '''\ -{% extends "layout" %} -{% extends "layout" %} -{% block block1 %} - {% if false %} - {% block block2 %} - this should workd - {% endblock %} - {% endif %} -{% endblock %} -''' - - -@pytest.fixture -def env(): - return Environment(loader=DictLoader({ - 'layout': LAYOUTTEMPLATE, - 'level1': LEVEL1TEMPLATE, - 'level2': LEVEL2TEMPLATE, - 'level3': LEVEL3TEMPLATE, - 'level4': LEVEL4TEMPLATE, - 'working': WORKINGTEMPLATE, - 'doublee': DOUBLEEXTENDS, - }), trim_blocks=True) - - -@pytest.mark.inheritance -class TestInheritance(): - - def test_layout(self, env): - tmpl = env.get_template('layout') - assert tmpl.render() == ('|block 1 from layout|block 2 from ' - 'layout|nested block 4 from layout|') - - def test_level1(self, env): - tmpl = env.get_template('level1') - assert tmpl.render() == ('|block 1 from level1|block 2 from ' - 'layout|nested block 4 from layout|') - - def test_level2(self, env): - tmpl = env.get_template('level2') - assert tmpl.render() == ('|block 1 from level1|nested block 5 from ' - 'level2|nested block 4 from layout|') - - def test_level3(self, env): - tmpl = env.get_template('level3') - assert tmpl.render() == ('|block 1 from level1|block 5 from level3|' - 'block 4 from level3|') - - def test_level4(self, env): - tmpl = env.get_template('level4') - assert tmpl.render() == ('|block 1 from level1|block 5 from ' - 'level3|block 3 from level4|') - - def test_super(self, env): - env = Environment(loader=DictLoader({ - 'a': '{% block intro %}INTRO{% endblock %}|' - 'BEFORE|{% block data %}INNER{% endblock %}|AFTER', - 'b': '{% extends "a" %}{% block data %}({{ ' - 'super() }}){% endblock %}', - 'c': '{% extends "b" %}{% block intro %}--{{ ' - 'super() }}--{% endblock %}\n{% block data ' - '%}[{{ super() }}]{% endblock %}' - })) - tmpl = env.get_template('c') - assert tmpl.render() == '--INTRO--|BEFORE|[(INNER)]|AFTER' - - def test_working(self, env): - tmpl = env.get_template('working') - - def test_reuse_blocks(self, env): - tmpl = env.from_string('{{ self.foo() }}|{% block foo %}42' - '{% endblock %}|{{ self.foo() }}') - assert tmpl.render() == '42|42|42' - - def test_preserve_blocks(self, env): - env = Environment(loader=DictLoader({ - 'a': '{% if false %}{% block x %}A{% endblock %}' - '{% endif %}{{ self.x() }}', - 'b': '{% extends "a" %}{% block x %}B{{ super() }}{% endblock %}' - })) - tmpl = env.get_template('b') - assert tmpl.render() == 'BA' - - def test_dynamic_inheritance(self, env): - env = Environment(loader=DictLoader({ - 'master1': 'MASTER1{% block x %}{% endblock %}', - 'master2': 'MASTER2{% block x %}{% endblock %}', - 'child': '{% extends master %}{% block x %}CHILD{% endblock %}' - })) - tmpl = env.get_template('child') - for m in range(1, 3): - assert tmpl.render(master='master%d' % m) == 'MASTER%dCHILD' % m - - def test_multi_inheritance(self, env): - env = Environment(loader=DictLoader({ - 'master1': 'MASTER1{% block x %}{% endblock %}', - 'master2': 'MASTER2{% block x %}{% endblock %}', - 'child': - '''{% if master %}{% extends master %}{% else %}{% extends - 'master1' %}{% endif %}{% block x %}CHILD{% endblock %}''' - })) - tmpl = env.get_template('child') - assert tmpl.render(master='master2') == 'MASTER2CHILD' - assert tmpl.render(master='master1') == 'MASTER1CHILD' - assert tmpl.render() == 'MASTER1CHILD' - - def test_scoped_block(self, env): - env = Environment(loader=DictLoader({ - 'master.html': '{% for item in seq %}[{% block item scoped %}' - '{% endblock %}]{% endfor %}' - })) - t = env.from_string('{% extends "master.html" %}{% block item %}' - '{{ item }}{% endblock %}') - assert t.render(seq=list(range(5))) == '[0][1][2][3][4]' - - def test_super_in_scoped_block(self, env): - env = Environment(loader=DictLoader({ - 'master.html': '{% for item in seq %}[{% block item scoped %}' - '{{ item }}{% endblock %}]{% endfor %}' - })) - t = env.from_string('{% extends "master.html" %}{% block item %}' - '{{ super() }}|{{ item * 2 }}{% endblock %}') - assert t.render(seq=list(range(5))) == '[0|0][1|2][2|4][3|6][4|8]' - - def test_scoped_block_after_inheritance(self, env): - env = Environment(loader=DictLoader({ - 'layout.html': ''' - {% block useless %}{% endblock %} - ''', - 'index.html': ''' - {%- extends 'layout.html' %} - {% from 'helpers.html' import foo with context %} - {% block useless %} - {% for x in [1, 2, 3] %} - {% block testing scoped %} - {{ foo(x) }} - {% endblock %} - {% endfor %} - {% endblock %} - ''', - 'helpers.html': ''' - {% macro foo(x) %}{{ the_foo + x }}{% endmacro %} - ''' - })) - rv = env.get_template('index.html').render(the_foo=42).split() - assert rv == ['43', '44', '45'] - - -@pytest.mark.inheritance -class TestBugFix(): - - def test_fixed_macro_scoping_bug(self, env): - assert Environment(loader=DictLoader({ - 'test.html': '''\ - {% extends 'details.html' %} - - {% macro my_macro() %} - my_macro - {% endmacro %} - - {% block inner_box %} - {{ my_macro() }} - {% endblock %} - ''', - 'details.html': '''\ - {% extends 'standard.html' %} - - {% macro my_macro() %} - my_macro - {% endmacro %} - - {% block content %} - {% block outer_box %} - outer_box - {% block inner_box %} - inner_box - {% endblock %} - {% endblock %} - {% endblock %} - ''', - 'standard.html': ''' - {% block content %} {% endblock %} - ''' - })).get_template("test.html").render().split() \ - == [u'outer_box', u'my_macro'] - - def test_double_extends(self, env): - """Ensures that a template with more than 1 {% extends ... %} usage - raises a ``TemplateError``. - """ - try: - tmpl = env.get_template('doublee') - except Exception as e: - assert isinstance(e, TemplateError) diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_lexnparse.py b/deps/v8_inspector/third_party/jinja2/tests/test_lexnparse.py deleted file mode 100644 index ff334bf0ca8b08..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_lexnparse.py +++ /dev/null @@ -1,609 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.lexnparse - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - All the unittests regarding lexing, parsing and syntax. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest - -from jinja2 import Environment, Template, TemplateSyntaxError, \ - UndefinedError, nodes -from jinja2._compat import iteritems, text_type, PY2 -from jinja2.lexer import Token, TokenStream, TOKEN_EOF, \ - TOKEN_BLOCK_BEGIN, TOKEN_BLOCK_END - - -# how does a string look like in jinja syntax? -if PY2: - def jinja_string_repr(string): - return repr(string)[1:] -else: - jinja_string_repr = repr - - -@pytest.mark.lexnparse -@pytest.mark.tokenstream -class TestTokenStream(): - test_tokens = [Token(1, TOKEN_BLOCK_BEGIN, ''), - Token(2, TOKEN_BLOCK_END, ''), - ] - - def test_simple(self, env): - ts = TokenStream(self.test_tokens, "foo", "bar") - assert ts.current.type is TOKEN_BLOCK_BEGIN - assert bool(ts) - assert not bool(ts.eos) - next(ts) - assert ts.current.type is TOKEN_BLOCK_END - assert bool(ts) - assert not bool(ts.eos) - next(ts) - assert ts.current.type is TOKEN_EOF - assert not bool(ts) - assert bool(ts.eos) - - def test_iter(self, env): - token_types = [ - t.type for t in TokenStream(self.test_tokens, "foo", "bar") - ] - assert token_types == ['block_begin', 'block_end', ] - - -@pytest.mark.lexnparse -@pytest.mark.lexer -class TestLexer(): - - def test_raw1(self, env): - tmpl = env.from_string( - '{% raw %}foo{% endraw %}|' - '{%raw%}{{ bar }}|{% baz %}{% endraw %}') - assert tmpl.render() == 'foo|{{ bar }}|{% baz %}' - - def test_raw2(self, env): - tmpl = env.from_string('1 {%- raw -%} 2 {%- endraw -%} 3') - assert tmpl.render() == '123' - - def test_balancing(self, env): - env = Environment('{%', '%}', '${', '}') - tmpl = env.from_string('''{% for item in seq - %}${{'foo': item}|upper}{% endfor %}''') - assert tmpl.render(seq=list(range(3))) \ - == "{'FOO': 0}{'FOO': 1}{'FOO': 2}" - - def test_comments(self, env): - env = Environment('', '{', '}') - tmpl = env.from_string('''\ -
    - -
  • {item}
  • - -
''') - assert tmpl.render(seq=list(range(3))) \ - == ("
    \n
  • 0
  • \n ""
  • 1
  • \n
  • 2
  • \n
") - - def test_string_escapes(self, env): - for char in u'\0', u'\u2668', u'\xe4', u'\t', u'\r', u'\n': - tmpl = env.from_string('{{ %s }}' % jinja_string_repr(char)) - assert tmpl.render() == char - assert env.from_string('{{ "\N{HOT SPRINGS}" }}').render() == u'\u2668' - - def test_bytefallback(self, env): - from pprint import pformat - tmpl = env.from_string(u'''{{ 'foo'|pprint }}|{{ 'bär'|pprint }}''') - assert tmpl.render() == pformat('foo') + '|' + pformat(u'bär') - - def test_operators(self, env): - from jinja2.lexer import operators - for test, expect in iteritems(operators): - if test in '([{}])': - continue - stream = env.lexer.tokenize('{{ %s }}' % test) - next(stream) - assert stream.current.type == expect - - def test_normalizing(self, env): - for seq in '\r', '\r\n', '\n': - env = Environment(newline_sequence=seq) - tmpl = env.from_string('1\n2\r\n3\n4\n') - result = tmpl.render() - assert result.replace(seq, 'X') == '1X2X3X4' - - def test_trailing_newline(self, env): - for keep in [True, False]: - env = Environment(keep_trailing_newline=keep) - for template, expected in [ - ('', {}), - ('no\nnewline', {}), - ('with\nnewline\n', {False: 'with\nnewline'}), - ('with\nseveral\n\n\n', {False: 'with\nseveral\n\n'}), - ]: - tmpl = env.from_string(template) - expect = expected.get(keep, template) - result = tmpl.render() - assert result == expect, (keep, template, result, expect) - - -@pytest.mark.lexnparse -@pytest.mark.parser -class TestParser(): - - def test_php_syntax(self, env): - env = Environment('', '', '') - tmpl = env.from_string('''\ -\ - - -''') - assert tmpl.render(seq=list(range(5))) == '01234' - - def test_erb_syntax(self, env): - env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>') - tmpl = env.from_string('''\ -<%# I'm a comment, I'm not interesting %>\ -<% for item in seq -%> - <%= item %> -<%- endfor %>''') - assert tmpl.render(seq=list(range(5))) == '01234' - - def test_comment_syntax(self, env): - env = Environment('', '${', '}', '') - tmpl = env.from_string('''\ -\ - - ${item} -''') - assert tmpl.render(seq=list(range(5))) == '01234' - - def test_balancing(self, env): - tmpl = env.from_string('''{{{'foo':'bar'}.foo}}''') - assert tmpl.render() == 'bar' - - def test_start_comment(self, env): - tmpl = env.from_string('''{# foo comment -and bar comment #} -{% macro blub() %}foo{% endmacro %} -{{ blub() }}''') - assert tmpl.render().strip() == 'foo' - - def test_line_syntax(self, env): - env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%') - tmpl = env.from_string('''\ -<%# regular comment %> -% for item in seq: - ${item} -% endfor''') - assert [ - int(x.strip()) for x in tmpl.render(seq=list(range(5))).split() - ] == list(range(5)) - - env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##') - tmpl = env.from_string('''\ -<%# regular comment %> -% for item in seq: - ${item} ## the rest of the stuff -% endfor''') - assert [ - int(x.strip()) for x in tmpl.render(seq=list(range(5))).split() - ] == list(range(5)) - - def test_line_syntax_priority(self, env): - # XXX: why is the whitespace there in front of the newline? - env = Environment('{%', '%}', '${', '}', '/*', '*/', '##', '#') - tmpl = env.from_string('''\ -/* ignore me. - I'm a multiline comment */ -## for item in seq: -* ${item} # this is just extra stuff -## endfor''') - assert tmpl.render(seq=[1, 2]).strip() == '* 1\n* 2' - env = Environment('{%', '%}', '${', '}', '/*', '*/', '#', '##') - tmpl = env.from_string('''\ -/* ignore me. - I'm a multiline comment */ -# for item in seq: -* ${item} ## this is just extra stuff - ## extra stuff i just want to ignore -# endfor''') - assert tmpl.render(seq=[1, 2]).strip() == '* 1\n\n* 2' - - def test_error_messages(self, env): - def assert_error(code, expected): - try: - Template(code) - except TemplateSyntaxError as e: - assert str(e) == expected, 'unexpected error message' - else: - assert False, 'that was supposed to be an error' - - assert_error('{% for item in seq %}...{% endif %}', - "Encountered unknown tag 'endif'. Jinja was looking " - "for the following tags: 'endfor' or 'else'. The " - "innermost block that needs to be closed is 'for'.") - assert_error( - '{% if foo %}{% for item in seq %}...{% endfor %}{% endfor %}', - "Encountered unknown tag 'endfor'. Jinja was looking for " - "the following tags: 'elif' or 'else' or 'endif'. The " - "innermost block that needs to be closed is 'if'.") - assert_error('{% if foo %}', - "Unexpected end of template. Jinja was looking for the " - "following tags: 'elif' or 'else' or 'endif'. The " - "innermost block that needs to be closed is 'if'.") - assert_error('{% for item in seq %}', - "Unexpected end of template. Jinja was looking for the " - "following tags: 'endfor' or 'else'. The innermost block " - "that needs to be closed is 'for'.") - assert_error( - '{% block foo-bar-baz %}', - "Block names in Jinja have to be valid Python identifiers " - "and may not contain hyphens, use an underscore instead.") - assert_error('{% unknown_tag %}', - "Encountered unknown tag 'unknown_tag'.") - - -@pytest.mark.lexnparse -@pytest.mark.syntax -class TestSyntax(): - - def test_call(self, env): - env = Environment() - env.globals['foo'] = lambda a, b, c, e, g: a + b + c + e + g - tmpl = env.from_string( - "{{ foo('a', c='d', e='f', *['b'], **{'g': 'h'}) }}" - ) - assert tmpl.render() == 'abdfh' - - def test_slicing(self, env): - tmpl = env.from_string('{{ [1, 2, 3][:] }}|{{ [1, 2, 3][::-1] }}') - assert tmpl.render() == '[1, 2, 3]|[3, 2, 1]' - - def test_attr(self, env): - tmpl = env.from_string("{{ foo.bar }}|{{ foo['bar'] }}") - assert tmpl.render(foo={'bar': 42}) == '42|42' - - def test_subscript(self, env): - tmpl = env.from_string("{{ foo[0] }}|{{ foo[-1] }}") - assert tmpl.render(foo=[0, 1, 2]) == '0|2' - - def test_tuple(self, env): - tmpl = env.from_string('{{ () }}|{{ (1,) }}|{{ (1, 2) }}') - assert tmpl.render() == '()|(1,)|(1, 2)' - - def test_math(self, env): - tmpl = env.from_string('{{ (1 + 1 * 2) - 3 / 2 }}|{{ 2**3 }}') - assert tmpl.render() == '1.5|8' - - def test_div(self, env): - tmpl = env.from_string('{{ 3 // 2 }}|{{ 3 / 2 }}|{{ 3 % 2 }}') - assert tmpl.render() == '1|1.5|1' - - def test_unary(self, env): - tmpl = env.from_string('{{ +3 }}|{{ -3 }}') - assert tmpl.render() == '3|-3' - - def test_concat(self, env): - tmpl = env.from_string("{{ [1, 2] ~ 'foo' }}") - assert tmpl.render() == '[1, 2]foo' - - def test_compare(self, env): - tmpl = env.from_string('{{ 1 > 0 }}|{{ 1 >= 1 }}|{{ 2 < 3 }}|' - '{{ 2 == 2 }}|{{ 1 <= 1 }}') - assert tmpl.render() == 'True|True|True|True|True' - - def test_inop(self, env): - tmpl = env.from_string('{{ 1 in [1, 2, 3] }}|{{ 1 not in [1, 2, 3] }}') - assert tmpl.render() == 'True|False' - - def test_literals(self, env): - tmpl = env.from_string('{{ [] }}|{{ {} }}|{{ () }}') - assert tmpl.render().lower() == '[]|{}|()' - - def test_bool(self, env): - tmpl = env.from_string('{{ true and false }}|{{ false ' - 'or true }}|{{ not false }}') - assert tmpl.render() == 'False|True|True' - - def test_grouping(self, env): - tmpl = env.from_string( - '{{ (true and false) or (false and true) and not false }}') - assert tmpl.render() == 'False' - - def test_django_attr(self, env): - tmpl = env.from_string('{{ [1, 2, 3].0 }}|{{ [[1]].0.0 }}') - assert tmpl.render() == '1|1' - - def test_conditional_expression(self, env): - tmpl = env.from_string('''{{ 0 if true else 1 }}''') - assert tmpl.render() == '0' - - def test_short_conditional_expression(self, env): - tmpl = env.from_string('<{{ 1 if false }}>') - assert tmpl.render() == '<>' - - tmpl = env.from_string('<{{ (1 if false).bar }}>') - pytest.raises(UndefinedError, tmpl.render) - - def test_filter_priority(self, env): - tmpl = env.from_string('{{ "foo"|upper + "bar"|upper }}') - assert tmpl.render() == 'FOOBAR' - - def test_function_calls(self, env): - tests = [ - (True, '*foo, bar'), - (True, '*foo, *bar'), - (True, '*foo, bar=42'), - (True, '**foo, *bar'), - (True, '**foo, bar'), - (False, 'foo, bar'), - (False, 'foo, bar=42'), - (False, 'foo, bar=23, *args'), - (False, 'a, b=c, *d, **e'), - (False, '*foo, **bar') - ] - for should_fail, sig in tests: - if should_fail: - pytest.raises(TemplateSyntaxError, - env.from_string, '{{ foo(%s) }}' % sig) - else: - env.from_string('foo(%s)' % sig) - - def test_tuple_expr(self, env): - for tmpl in [ - '{{ () }}', - '{{ (1, 2) }}', - '{{ (1, 2,) }}', - '{{ 1, }}', - '{{ 1, 2 }}', - '{% for foo, bar in seq %}...{% endfor %}', - '{% for x in foo, bar %}...{% endfor %}', - '{% for x in foo, %}...{% endfor %}' - ]: - assert env.from_string(tmpl) - - def test_trailing_comma(self, env): - tmpl = env.from_string('{{ (1, 2,) }}|{{ [1, 2,] }}|{{ {1: 2,} }}') - assert tmpl.render().lower() == '(1, 2)|[1, 2]|{1: 2}' - - def test_block_end_name(self, env): - env.from_string('{% block foo %}...{% endblock foo %}') - pytest.raises(TemplateSyntaxError, env.from_string, - '{% block x %}{% endblock y %}') - - def test_constant_casing(self, env): - for const in True, False, None: - tmpl = env.from_string('{{ %s }}|{{ %s }}|{{ %s }}' % ( - str(const), str(const).lower(), str(const).upper() - )) - assert tmpl.render() == '%s|%s|' % (const, const) - - def test_test_chaining(self, env): - pytest.raises(TemplateSyntaxError, env.from_string, - '{{ foo is string is sequence }}') - assert env.from_string( - '{{ 42 is string or 42 is number }}' - ).render() == 'True' - - def test_string_concatenation(self, env): - tmpl = env.from_string('{{ "foo" "bar" "baz" }}') - assert tmpl.render() == 'foobarbaz' - - def test_notin(self, env): - bar = range(100) - tmpl = env.from_string('''{{ not 42 in bar }}''') - assert tmpl.render(bar=bar) == text_type(not 42 in bar) - - def test_implicit_subscribed_tuple(self, env): - class Foo(object): - def __getitem__(self, x): - return x - t = env.from_string('{{ foo[1, 2] }}') - assert t.render(foo=Foo()) == u'(1, 2)' - - def test_raw2(self, env): - tmpl = env.from_string('{% raw %}{{ FOO }} and {% BAR %}{% endraw %}') - assert tmpl.render() == '{{ FOO }} and {% BAR %}' - - def test_const(self, env): - tmpl = env.from_string( - '{{ true }}|{{ false }}|{{ none }}|' - '{{ none is defined }}|{{ missing is defined }}') - assert tmpl.render() == 'True|False|None|True|False' - - def test_neg_filter_priority(self, env): - node = env.parse('{{ -1|foo }}') - assert isinstance(node.body[0].nodes[0], nodes.Filter) - assert isinstance(node.body[0].nodes[0].node, nodes.Neg) - - def test_const_assign(self, env): - constass1 = '''{% set true = 42 %}''' - constass2 = '''{% for none in seq %}{% endfor %}''' - for tmpl in constass1, constass2: - pytest.raises(TemplateSyntaxError, env.from_string, tmpl) - - def test_localset(self, env): - tmpl = env.from_string('''{% set foo = 0 %}\ -{% for item in [1, 2] %}{% set foo = 1 %}{% endfor %}\ -{{ foo }}''') - assert tmpl.render() == '0' - - def test_parse_unary(self, env): - tmpl = env.from_string('{{ -foo["bar"] }}') - assert tmpl.render(foo={'bar': 42}) == '-42' - tmpl = env.from_string('{{ -foo["bar"]|abs }}') - assert tmpl.render(foo={'bar': 42}) == '42' - - -@pytest.mark.lexnparse -@pytest.mark.lstripblocks -class TestLstripBlocks(): - - def test_lstrip(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=False) - tmpl = env.from_string(''' {% if True %}\n {% endif %}''') - assert tmpl.render() == "\n" - - def test_lstrip_trim(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string(''' {% if True %}\n {% endif %}''') - assert tmpl.render() == "" - - def test_no_lstrip(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=False) - tmpl = env.from_string(''' {%+ if True %}\n {%+ endif %}''') - assert tmpl.render() == " \n " - - def test_lstrip_endline(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=False) - tmpl = env.from_string( - ''' hello{% if True %}\n goodbye{% endif %}''') - assert tmpl.render() == " hello\n goodbye" - - def test_lstrip_inline(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=False) - tmpl = env.from_string(''' {% if True %}hello {% endif %}''') - assert tmpl.render() == 'hello ' - - def test_lstrip_nested(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=False) - tmpl = env.from_string( - ''' {% if True %}a {% if True %}b {% endif %}c {% endif %}''') - assert tmpl.render() == 'a b c ' - - def test_lstrip_left_chars(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=False) - tmpl = env.from_string(''' abc {% if True %} - hello{% endif %}''') - assert tmpl.render() == ' abc \n hello' - - def test_lstrip_embeded_strings(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=False) - tmpl = env.from_string(''' {% set x = " {% str %} " %}{{ x }}''') - assert tmpl.render() == ' {% str %} ' - - def test_lstrip_preserve_leading_newlines(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=False) - tmpl = env.from_string('''\n\n\n{% set hello = 1 %}''') - assert tmpl.render() == '\n\n\n' - - def test_lstrip_comment(self, env): - env = Environment(lstrip_blocks=True, trim_blocks=False) - tmpl = env.from_string(''' {# if True #} -hello - {#endif#}''') - assert tmpl.render() == '\nhello\n' - - def test_lstrip_angle_bracket_simple(self, env): - env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string(''' <% if True %>hello <% endif %>''') - assert tmpl.render() == 'hello ' - - def test_lstrip_angle_bracket_comment(self, env): - env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string(''' <%# if True %>hello <%# endif %>''') - assert tmpl.render() == 'hello ' - - def test_lstrip_angle_bracket(self, env): - env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string('''\ - <%# regular comment %> - <% for item in seq %> -${item} ## the rest of the stuff - <% endfor %>''') - assert tmpl.render(seq=range(5)) == \ - ''.join('%s\n' % x for x in range(5)) - - def test_lstrip_angle_bracket_compact(self, env): - env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string('''\ - <%#regular comment%> - <%for item in seq%> -${item} ## the rest of the stuff - <%endfor%>''') - assert tmpl.render(seq=range(5)) == \ - ''.join('%s\n' % x for x in range(5)) - - def test_php_syntax_with_manual(self, env): - env = Environment('', '', '', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string('''\ - - - - ''') - assert tmpl.render(seq=range(5)) == '01234' - - def test_php_syntax(self, env): - env = Environment('', '', '', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string('''\ - - - - ''') - assert tmpl.render(seq=range(5)) \ - == ''.join(' %s\n' % x for x in range(5)) - - def test_php_syntax_compact(self, env): - env = Environment('', '', '', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string('''\ - - - - ''') - assert tmpl.render(seq=range(5)) \ - == ''.join(' %s\n' % x for x in range(5)) - - def test_erb_syntax(self, env): - env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>', - lstrip_blocks=True, trim_blocks=True) - # env.from_string('') - # for n,r in env.lexer.rules.iteritems(): - # print n - # print env.lexer.rules['root'][0][0].pattern - # print "'%s'" % tmpl.render(seq=range(5)) - tmpl = env.from_string('''\ -<%# I'm a comment, I'm not interesting %> - <% for item in seq %> - <%= item %> - <% endfor %> -''') - assert tmpl.render(seq=range(5)) \ - == ''.join(' %s\n' % x for x in range(5)) - - def test_erb_syntax_with_manual(self, env): - env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string('''\ -<%# I'm a comment, I'm not interesting %> - <% for item in seq -%> - <%= item %> - <%- endfor %>''') - assert tmpl.render(seq=range(5)) == '01234' - - def test_erb_syntax_no_lstrip(self, env): - env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string('''\ -<%# I'm a comment, I'm not interesting %> - <%+ for item in seq -%> - <%= item %> - <%- endfor %>''') - assert tmpl.render(seq=range(5)) == ' 01234' - - def test_comment_syntax(self, env): - env = Environment('', '${', '}', '', - lstrip_blocks=True, trim_blocks=True) - tmpl = env.from_string('''\ -\ - - ${item} -''') - assert tmpl.render(seq=range(5)) == '01234' diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_loader.py b/deps/v8_inspector/third_party/jinja2/tests/test_loader.py deleted file mode 100644 index 6d22fad390cb80..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_loader.py +++ /dev/null @@ -1,220 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.loader - ~~~~~~~~~~~~~~~~~~~~~~~ - - Test the loaders. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import os -import sys -import tempfile -import shutil -import pytest - -from jinja2 import Environment, loaders -from jinja2._compat import PYPY, PY2 -from jinja2.loaders import split_template_path -from jinja2.exceptions import TemplateNotFound - - -@pytest.mark.loaders -class TestLoaders(): - - def test_dict_loader(self, dict_loader): - env = Environment(loader=dict_loader) - tmpl = env.get_template('justdict.html') - assert tmpl.render().strip() == 'FOO' - pytest.raises(TemplateNotFound, env.get_template, 'missing.html') - - def test_package_loader(self, package_loader): - env = Environment(loader=package_loader) - tmpl = env.get_template('test.html') - assert tmpl.render().strip() == 'BAR' - pytest.raises(TemplateNotFound, env.get_template, 'missing.html') - - def test_filesystem_loader(self, filesystem_loader): - env = Environment(loader=filesystem_loader) - tmpl = env.get_template('test.html') - assert tmpl.render().strip() == 'BAR' - tmpl = env.get_template('foo/test.html') - assert tmpl.render().strip() == 'FOO' - pytest.raises(TemplateNotFound, env.get_template, 'missing.html') - - def test_choice_loader(self, choice_loader): - env = Environment(loader=choice_loader) - tmpl = env.get_template('justdict.html') - assert tmpl.render().strip() == 'FOO' - tmpl = env.get_template('test.html') - assert tmpl.render().strip() == 'BAR' - pytest.raises(TemplateNotFound, env.get_template, 'missing.html') - - def test_function_loader(self, function_loader): - env = Environment(loader=function_loader) - tmpl = env.get_template('justfunction.html') - assert tmpl.render().strip() == 'FOO' - pytest.raises(TemplateNotFound, env.get_template, 'missing.html') - - def test_prefix_loader(self, prefix_loader): - env = Environment(loader=prefix_loader) - tmpl = env.get_template('a/test.html') - assert tmpl.render().strip() == 'BAR' - tmpl = env.get_template('b/justdict.html') - assert tmpl.render().strip() == 'FOO' - pytest.raises(TemplateNotFound, env.get_template, 'missing') - - def test_caching(self): - changed = False - - class TestLoader(loaders.BaseLoader): - def get_source(self, environment, template): - return u'foo', None, lambda: not changed - env = Environment(loader=TestLoader(), cache_size=-1) - tmpl = env.get_template('template') - assert tmpl is env.get_template('template') - changed = True - assert tmpl is not env.get_template('template') - changed = False - - env = Environment(loader=TestLoader(), cache_size=0) - assert env.get_template('template') \ - is not env.get_template('template') - - env = Environment(loader=TestLoader(), cache_size=2) - t1 = env.get_template('one') - t2 = env.get_template('two') - assert t2 is env.get_template('two') - assert t1 is env.get_template('one') - t3 = env.get_template('three') - assert 'one' in env.cache - assert 'two' not in env.cache - assert 'three' in env.cache - - def test_dict_loader_cache_invalidates(self): - mapping = {'foo': "one"} - env = Environment(loader=loaders.DictLoader(mapping)) - assert env.get_template('foo').render() == "one" - mapping['foo'] = "two" - assert env.get_template('foo').render() == "two" - - def test_split_template_path(self): - assert split_template_path('foo/bar') == ['foo', 'bar'] - assert split_template_path('./foo/bar') == ['foo', 'bar'] - pytest.raises(TemplateNotFound, split_template_path, '../foo') - - -@pytest.mark.loaders -@pytest.mark.moduleloader -class TestModuleLoader(): - archive = None - - def compile_down(self, prefix_loader, zip='deflated', py_compile=False): - log = [] - self.reg_env = Environment(loader=prefix_loader) - if zip is not None: - fd, self.archive = tempfile.mkstemp(suffix='.zip') - os.close(fd) - else: - self.archive = tempfile.mkdtemp() - self.reg_env.compile_templates(self.archive, zip=zip, - log_function=log.append, - py_compile=py_compile) - self.mod_env = Environment(loader=loaders.ModuleLoader(self.archive)) - return ''.join(log) - - def teardown(self): - if hasattr(self, 'mod_env'): - if os.path.isfile(self.archive): - os.remove(self.archive) - else: - shutil.rmtree(self.archive) - self.archive = None - - def test_log(self, prefix_loader): - log = self.compile_down(prefix_loader) - assert 'Compiled "a/foo/test.html" as ' \ - 'tmpl_a790caf9d669e39ea4d280d597ec891c4ef0404a' in log - assert 'Finished compiling templates' in log - assert 'Could not compile "a/syntaxerror.html": ' \ - 'Encountered unknown tag \'endif\'' in log - - def _test_common(self): - tmpl1 = self.reg_env.get_template('a/test.html') - tmpl2 = self.mod_env.get_template('a/test.html') - assert tmpl1.render() == tmpl2.render() - - tmpl1 = self.reg_env.get_template('b/justdict.html') - tmpl2 = self.mod_env.get_template('b/justdict.html') - assert tmpl1.render() == tmpl2.render() - - def test_deflated_zip_compile(self, prefix_loader): - self.compile_down(prefix_loader, zip='deflated') - self._test_common() - - def test_stored_zip_compile(self, prefix_loader): - self.compile_down(prefix_loader, zip='stored') - self._test_common() - - def test_filesystem_compile(self, prefix_loader): - self.compile_down(prefix_loader, zip=None) - self._test_common() - - def test_weak_references(self, prefix_loader): - self.compile_down(prefix_loader) - tmpl = self.mod_env.get_template('a/test.html') - key = loaders.ModuleLoader.get_template_key('a/test.html') - name = self.mod_env.loader.module.__name__ - - assert hasattr(self.mod_env.loader.module, key) - assert name in sys.modules - - # unset all, ensure the module is gone from sys.modules - self.mod_env = tmpl = None - - try: - import gc - gc.collect() - except: - pass - - assert name not in sys.modules - - # This test only makes sense on non-pypy python 2 - @pytest.mark.skipif( - not (PY2 and not PYPY), - reason='This test only makes sense on non-pypy python 2') - def test_byte_compilation(self, prefix_loader): - log = self.compile_down(prefix_loader, py_compile=True) - assert 'Byte-compiled "a/test.html"' in log - tmpl1 = self.mod_env.get_template('a/test.html') - mod = self.mod_env.loader.module. \ - tmpl_3c4ddf650c1a73df961a6d3d2ce2752f1b8fd490 - assert mod.__file__.endswith('.pyc') - - def test_choice_loader(self, prefix_loader): - log = self.compile_down(prefix_loader) - - self.mod_env.loader = loaders.ChoiceLoader([ - self.mod_env.loader, - loaders.DictLoader({'DICT_SOURCE': 'DICT_TEMPLATE'}) - ]) - - tmpl1 = self.mod_env.get_template('a/test.html') - assert tmpl1.render() == 'BAR' - tmpl2 = self.mod_env.get_template('DICT_SOURCE') - assert tmpl2.render() == 'DICT_TEMPLATE' - - def test_prefix_loader(self, prefix_loader): - log = self.compile_down(prefix_loader) - - self.mod_env.loader = loaders.PrefixLoader({ - 'MOD': self.mod_env.loader, - 'DICT': loaders.DictLoader({'test.html': 'DICT_TEMPLATE'}) - }) - - tmpl1 = self.mod_env.get_template('MOD/a/test.html') - assert tmpl1.render() == 'BAR' - tmpl2 = self.mod_env.get_template('DICT/test.html') - assert tmpl2.render() == 'DICT_TEMPLATE' diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_regression.py b/deps/v8_inspector/third_party/jinja2/tests/test_regression.py deleted file mode 100644 index a4aa157110395f..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_regression.py +++ /dev/null @@ -1,278 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.regression - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Tests corner cases and bugs. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest - -from jinja2 import Template, Environment, DictLoader, TemplateSyntaxError, \ - TemplateNotFound, PrefixLoader -from jinja2._compat import text_type - - -@pytest.mark.regression -class TestCorner(): - - def test_assigned_scoping(self, env): - t = env.from_string(''' - {%- for item in (1, 2, 3, 4) -%} - [{{ item }}] - {%- endfor %} - {{- item -}} - ''') - assert t.render(item=42) == '[1][2][3][4]42' - - t = env.from_string(''' - {%- for item in (1, 2, 3, 4) -%} - [{{ item }}] - {%- endfor %} - {%- set item = 42 %} - {{- item -}} - ''') - assert t.render() == '[1][2][3][4]42' - - t = env.from_string(''' - {%- set item = 42 %} - {%- for item in (1, 2, 3, 4) -%} - [{{ item }}] - {%- endfor %} - {{- item -}} - ''') - assert t.render() == '[1][2][3][4]42' - - def test_closure_scoping(self, env): - t = env.from_string(''' - {%- set wrapper = "" %} - {%- for item in (1, 2, 3, 4) %} - {%- macro wrapper() %}[{{ item }}]{% endmacro %} - {{- wrapper() }} - {%- endfor %} - {{- wrapper -}} - ''') - assert t.render() == '[1][2][3][4]' - - t = env.from_string(''' - {%- for item in (1, 2, 3, 4) %} - {%- macro wrapper() %}[{{ item }}]{% endmacro %} - {{- wrapper() }} - {%- endfor %} - {%- set wrapper = "" %} - {{- wrapper -}} - ''') - assert t.render() == '[1][2][3][4]' - - t = env.from_string(''' - {%- for item in (1, 2, 3, 4) %} - {%- macro wrapper() %}[{{ item }}]{% endmacro %} - {{- wrapper() }} - {%- endfor %} - {{- wrapper -}} - ''') - assert t.render(wrapper=23) == '[1][2][3][4]23' - - -@pytest.mark.regression -class TestBug(): - - def test_keyword_folding(self, env): - env = Environment() - env.filters['testing'] = lambda value, some: value + some - assert env.from_string("{{ 'test'|testing(some='stuff') }}") \ - .render() == 'teststuff' - - def test_extends_output_bugs(self, env): - env = Environment(loader=DictLoader({ - 'parent.html': '(({% block title %}{% endblock %}))' - })) - - t = env.from_string( - '{% if expr %}{% extends "parent.html" %}{% endif %}' - '[[{% block title %}title{% endblock %}]]' - '{% for item in [1, 2, 3] %}({{ item }}){% endfor %}' - ) - assert t.render(expr=False) == '[[title]](1)(2)(3)' - assert t.render(expr=True) == '((title))' - - def test_urlize_filter_escaping(self, env): - tmpl = env.from_string('{{ "http://www.example.org/'\ - 'http://www.example.org/<foo' - - def test_loop_call_loop(self, env): - tmpl = env.from_string(''' - - {% macro test() %} - {{ caller() }} - {% endmacro %} - - {% for num1 in range(5) %} - {% call test() %} - {% for num2 in range(10) %} - {{ loop.index }} - {% endfor %} - {% endcall %} - {% endfor %} - - ''') - - assert tmpl.render().split() \ - == [text_type(x) for x in range(1, 11)] * 5 - - def test_weird_inline_comment(self, env): - env = Environment(line_statement_prefix='%') - pytest.raises(TemplateSyntaxError, env.from_string, - '% for item in seq {# missing #}\n...% endfor') - - def test_old_macro_loop_scoping_bug(self, env): - tmpl = env.from_string('{% for i in (1, 2) %}{{ i }}{% endfor %}' - '{% macro i() %}3{% endmacro %}{{ i() }}') - assert tmpl.render() == '123' - - def test_partial_conditional_assignments(self, env): - tmpl = env.from_string('{% if b %}{% set a = 42 %}{% endif %}{{ a }}') - assert tmpl.render(a=23) == '23' - assert tmpl.render(b=True) == '42' - - def test_stacked_locals_scoping_bug(self, env): - env = Environment(line_statement_prefix='#') - t = env.from_string('''\ -# for j in [1, 2]: -# set x = 1 -# for i in [1, 2]: -# print x -# if i % 2 == 0: -# set x = x + 1 -# endif -# endfor -# endfor -# if a -# print 'A' -# elif b -# print 'B' -# elif c == d -# print 'C' -# else -# print 'D' -# endif - ''') - assert t.render(a=0, b=False, c=42, d=42.0) == '1111C' - - def test_stacked_locals_scoping_bug_twoframe(self, env): - t = Template(''' - {% set x = 1 %} - {% for item in foo %} - {% if item == 1 %} - {% set x = 2 %} - {% endif %} - {% endfor %} - {{ x }} - ''') - rv = t.render(foo=[1]).strip() - assert rv == u'1' - - def test_call_with_args(self, env): - t = Template("""{% macro dump_users(users) -%} -
    - {%- for user in users -%} -
  • {{ user.username|e }}

    {{ caller(user) }}
  • - {%- endfor -%} -
- {%- endmacro -%} - - {% call(user) dump_users(list_of_user) -%} -
-
Realname
-
{{ user.realname|e }}
-
Description
-
{{ user.description }}
-
- {% endcall %}""") - - assert [x.strip() for x in t.render(list_of_user=[{ - 'username': 'apo', - 'realname': 'something else', - 'description': 'test' - }]).splitlines()] == [ - u'
  • apo

    ', - u'
    Realname
    ', - u'
    something else
    ', - u'
    Description
    ', - u'
    test
    ', - u'
    ', - u'
' - ] - - def test_empty_if_condition_fails(self, env): - pytest.raises(TemplateSyntaxError, - Template, '{% if %}....{% endif %}') - pytest.raises(TemplateSyntaxError, - Template, '{% if foo %}...{% elif %}...{% endif %}') - pytest.raises(TemplateSyntaxError, - Template, '{% for x in %}..{% endfor %}') - - def test_recursive_loop_bug(self, env): - tpl1 = Template(""" - {% for p in foo recursive%} - {{p.bar}} - {% for f in p.fields recursive%} - {{f.baz}} - {{p.bar}} - {% if f.rec %} - {{ loop(f.sub) }} - {% endif %} - {% endfor %} - {% endfor %} - """) - - tpl2 = Template(""" - {% for p in foo%} - {{p.bar}} - {% for f in p.fields recursive%} - {{f.baz}} - {{p.bar}} - {% if f.rec %} - {{ loop(f.sub) }} - {% endif %} - {% endfor %} - {% endfor %} - """) - - def test_else_loop_bug(self, env): - t = Template(''' - {% for x in y %} - {{ loop.index0 }} - {% else %} - {% for i in range(3) %}{{ i }}{% endfor %} - {% endfor %} - ''') - assert t.render(y=[]).strip() == '012' - - def test_correct_prefix_loader_name(self, env): - env = Environment(loader=PrefixLoader({ - 'foo': DictLoader({}) - })) - try: - env.get_template('foo/bar.html') - except TemplateNotFound as e: - assert e.name == 'foo/bar.html' - else: - assert False, 'expected error here' - - def test_contextfunction_callable_classes(self, env): - from jinja2.utils import contextfunction - - class CallableClass(object): - @contextfunction - def __call__(self, ctx): - return ctx.resolve('hello') - - tpl = Template("""{{ callableclass() }}""") - output = tpl.render(callableclass=CallableClass(), hello='TEST') - expected = 'TEST' - - assert output == expected diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_security.py b/deps/v8_inspector/third_party/jinja2/tests/test_security.py deleted file mode 100644 index e5b463fc989263..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_security.py +++ /dev/null @@ -1,161 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.security - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - Checks the sandbox and other security features. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest - -from jinja2 import Environment -from jinja2.sandbox import SandboxedEnvironment, \ - ImmutableSandboxedEnvironment, unsafe -from jinja2 import Markup, escape -from jinja2.exceptions import SecurityError, TemplateSyntaxError, \ - TemplateRuntimeError -from jinja2._compat import text_type - - -class PrivateStuff(object): - - def bar(self): - return 23 - - @unsafe - def foo(self): - return 42 - - def __repr__(self): - return 'PrivateStuff' - - -class PublicStuff(object): - bar = lambda self: 23 - _foo = lambda self: 42 - - def __repr__(self): - return 'PublicStuff' - - -@pytest.mark.sandbox -class TestSandbox(): - - def test_unsafe(self, env): - env = SandboxedEnvironment() - pytest.raises(SecurityError, env.from_string("{{ foo.foo() }}").render, - foo=PrivateStuff()) - assert env.from_string("{{ foo.bar() }}").render(foo=PrivateStuff()) == '23' - - pytest.raises(SecurityError, - env.from_string("{{ foo._foo() }}").render, - foo=PublicStuff()) - assert env.from_string("{{ foo.bar() }}").render(foo=PublicStuff()) == '23' - assert env.from_string("{{ foo.__class__ }}").render(foo=42) == '' - assert env.from_string("{{ foo.func_code }}").render(foo=lambda:None) == '' - # security error comes from __class__ already. - pytest.raises(SecurityError, env.from_string( - "{{ foo.__class__.__subclasses__() }}").render, foo=42) - - def test_immutable_environment(self, env): - env = ImmutableSandboxedEnvironment() - pytest.raises(SecurityError, env.from_string( - '{{ [].append(23) }}').render) - pytest.raises(SecurityError, env.from_string( - '{{ {1:2}.clear() }}').render) - - def test_restricted(self, env): - env = SandboxedEnvironment() - pytest.raises(TemplateSyntaxError, env.from_string, - "{% for item.attribute in seq %}...{% endfor %}") - pytest.raises(TemplateSyntaxError, env.from_string, - "{% for foo, bar.baz in seq %}...{% endfor %}") - - def test_markup_operations(self, env): - # adding two strings should escape the unsafe one - unsafe = '' - safe = Markup('username') - assert unsafe + safe == text_type(escape(unsafe)) + text_type(safe) - - # string interpolations are safe to use too - assert Markup('%s') % '' == \ - '<bad user>' - assert Markup('%(username)s') % { - 'username': '' - } == '<bad user>' - - # an escaped object is markup too - assert type(Markup('foo') + 'bar') is Markup - - # and it implements __html__ by returning itself - x = Markup("foo") - assert x.__html__() is x - - # it also knows how to treat __html__ objects - class Foo(object): - def __html__(self): - return 'awesome' - - def __unicode__(self): - return 'awesome' - assert Markup(Foo()) == 'awesome' - assert Markup('%s') % Foo() == \ - 'awesome' - - # escaping and unescaping - assert escape('"<>&\'') == '"<>&'' - assert Markup("Foo & Bar").striptags() == "Foo & Bar" - assert Markup("<test>").unescape() == "" - - def test_template_data(self, env): - env = Environment(autoescape=True) - t = env.from_string('{% macro say_hello(name) %}' - '

Hello {{ name }}!

{% endmacro %}' - '{{ say_hello("foo") }}') - escaped_out = '

Hello <blink>foo</blink>!

' - assert t.render() == escaped_out - assert text_type(t.module) == escaped_out - assert escape(t.module) == escaped_out - assert t.module.say_hello('foo') == escaped_out - assert escape(t.module.say_hello('foo')) == escaped_out - - def test_attr_filter(self, env): - env = SandboxedEnvironment() - tmpl = env.from_string('{{ cls|attr("__subclasses__")() }}') - pytest.raises(SecurityError, tmpl.render, cls=int) - - def test_binary_operator_intercepting(self, env): - def disable_op(left, right): - raise TemplateRuntimeError('that operator so does not work') - for expr, ctx, rv in ('1 + 2', {}, '3'), ('a + 2', {'a': 2}, '4'): - env = SandboxedEnvironment() - env.binop_table['+'] = disable_op - t = env.from_string('{{ %s }}' % expr) - assert t.render(ctx) == rv - env.intercepted_binops = frozenset(['+']) - t = env.from_string('{{ %s }}' % expr) - try: - t.render(ctx) - except TemplateRuntimeError as e: - pass - else: - assert False, 'expected runtime error' - - def test_unary_operator_intercepting(self, env): - def disable_op(arg): - raise TemplateRuntimeError('that operator so does not work') - for expr, ctx, rv in ('-1', {}, '-1'), ('-a', {'a': 2}, '-2'): - env = SandboxedEnvironment() - env.unop_table['-'] = disable_op - t = env.from_string('{{ %s }}' % expr) - assert t.render(ctx) == rv - env.intercepted_unops = frozenset(['-']) - t = env.from_string('{{ %s }}' % expr) - try: - t.render(ctx) - except TemplateRuntimeError as e: - pass - else: - assert False, 'expected runtime error' diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_tests.py b/deps/v8_inspector/third_party/jinja2/tests/test_tests.py deleted file mode 100644 index 9e54038c9a2dc1..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_tests.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.tests - ~~~~~~~~~~~~~~~~~~~~~~ - - Who tests the tests? - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import pytest - -from jinja2 import Markup, Environment - - -@pytest.mark.test_tests -class TestTestsCase(): - - def test_defined(self, env): - tmpl = env.from_string('{{ missing is defined }}|' - '{{ true is defined }}') - assert tmpl.render() == 'False|True' - - def test_even(self, env): - tmpl = env.from_string('''{{ 1 is even }}|{{ 2 is even }}''') - assert tmpl.render() == 'False|True' - - def test_odd(self, env): - tmpl = env.from_string('''{{ 1 is odd }}|{{ 2 is odd }}''') - assert tmpl.render() == 'True|False' - - def test_lower(self, env): - tmpl = env.from_string('''{{ "foo" is lower }}|{{ "FOO" is lower }}''') - assert tmpl.render() == 'True|False' - - def test_typechecks(self, env): - tmpl = env.from_string(''' - {{ 42 is undefined }} - {{ 42 is defined }} - {{ 42 is none }} - {{ none is none }} - {{ 42 is number }} - {{ 42 is string }} - {{ "foo" is string }} - {{ "foo" is sequence }} - {{ [1] is sequence }} - {{ range is callable }} - {{ 42 is callable }} - {{ range(5) is iterable }} - {{ {} is mapping }} - {{ mydict is mapping }} - {{ [] is mapping }} - {{ 10 is number }} - {{ (10 ** 100) is number }} - {{ 3.14159 is number }} - {{ complex is number }} - ''') - - class MyDict(dict): - pass - - assert tmpl.render(mydict=MyDict(), complex=complex(1, 2)).split() == [ - 'False', 'True', 'False', 'True', 'True', 'False', - 'True', 'True', 'True', 'True', 'False', 'True', - 'True', 'True', 'False', 'True', 'True', 'True', 'True' - ] - - def test_sequence(self, env): - tmpl = env.from_string( - '{{ [1, 2, 3] is sequence }}|' - '{{ "foo" is sequence }}|' - '{{ 42 is sequence }}' - ) - assert tmpl.render() == 'True|True|False' - - def test_upper(self, env): - tmpl = env.from_string('{{ "FOO" is upper }}|{{ "foo" is upper }}') - assert tmpl.render() == 'True|False' - - def test_equalto(self, env): - tmpl = env.from_string('{{ foo is equalto 12 }}|' - '{{ foo is equalto 0 }}|' - '{{ foo is equalto (3 * 4) }}|' - '{{ bar is equalto "baz" }}|' - '{{ bar is equalto "zab" }}|' - '{{ bar is equalto ("ba" + "z") }}|' - '{{ bar is equalto bar }}|' - '{{ bar is equalto foo }}') - assert tmpl.render(foo=12, bar="baz") \ - == 'True|False|True|True|False|True|True|False' - - def test_sameas(self, env): - tmpl = env.from_string('{{ foo is sameas false }}|' - '{{ 0 is sameas false }}') - assert tmpl.render(foo=False) == 'True|False' - - def test_no_paren_for_arg1(self, env): - tmpl = env.from_string('{{ foo is sameas none }}') - assert tmpl.render(foo=None) == 'True' - - def test_escaped(self, env): - env = Environment(autoescape=True) - tmpl = env.from_string('{{ x is escaped }}|{{ y is escaped }}') - assert tmpl.render(x='foo', y=Markup('foo')) == 'False|True' diff --git a/deps/v8_inspector/third_party/jinja2/tests/test_utils.py b/deps/v8_inspector/third_party/jinja2/tests/test_utils.py deleted file mode 100644 index 373103618d2f30..00000000000000 --- a/deps/v8_inspector/third_party/jinja2/tests/test_utils.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -""" - jinja2.testsuite.utils - ~~~~~~~~~~~~~~~~~~~~~~ - - Tests utilities jinja uses. - - :copyright: (c) 2010 by the Jinja Team. - :license: BSD, see LICENSE for more details. -""" -import gc - -import pytest - -import pickle - -from jinja2.utils import LRUCache, escape, object_type_repr - - -@pytest.mark.utils -@pytest.mark.lrucache -class TestLRUCache(): - - def test_simple(self): - d = LRUCache(3) - d["a"] = 1 - d["b"] = 2 - d["c"] = 3 - d["a"] - d["d"] = 4 - assert len(d) == 3 - assert 'a' in d and 'c' in d and 'd' in d and 'b' not in d - - def test_pickleable(self): - cache = LRUCache(2) - cache["foo"] = 42 - cache["bar"] = 23 - cache["foo"] - - for protocol in range(3): - copy = pickle.loads(pickle.dumps(cache, protocol)) - assert copy.capacity == cache.capacity - assert copy._mapping == cache._mapping - assert copy._queue == cache._queue - - -@pytest.mark.utils -@pytest.mark.helpers -class TestHelpers(): - - def test_object_type_repr(self): - class X(object): - pass - assert object_type_repr(42) == 'int object' - assert object_type_repr([]) == 'list object' - assert object_type_repr(X()) == 'test_utils.X object' - assert object_type_repr(None) == 'None' - assert object_type_repr(Ellipsis) == 'Ellipsis' - - -@pytest.mark.utils -@pytest.mark.markupleak -@pytest.mark.skipif(hasattr(escape, 'func_code'), - reason='this test only tests the c extension') -class TestMarkupLeak(): - - def test_markup_leaks(self): - counts = set() - for count in range(20): - for item in range(1000): - escape("foo") - escape("") - escape(u"foo") - escape(u"") - counts.add(len(gc.get_objects())) - assert len(counts) == 1, 'ouch, c extension seems to leak objects' From 2e435998ebff9de26493a9aaf226e7289a736957 Mon Sep 17 00:00:00 2001 From: Michael Dawson Date: Thu, 11 Aug 2016 09:48:33 -0400 Subject: [PATCH 131/144] test: mark test failing on AIX as flaky MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now have adequate AIX hardware to add AIX to the regular regression runs. However, there are a couple of failing tests even though AIX was green at one point. This PR marks those tests as flaky so that we can add AIX so that we can spot any new regressions without making the builds RED The tests are being worked under the following PRs - being worked under https://github.com/nodejs/node/pull/7564 test-async-wrap-post-did-throw test-async-wrap-throw-from-callback test-crypto-random - being worked under https://github.com/nodejs/node/issues/7973 test-stdio-closed - covered by https://github.com/nodejs/node/issues/3796 test-debug-signal-cluster PR-URL: https://github.com/nodejs/node/pull/8065 Reviewed-By: joaocgreis - João Reis Reviewed-By: Rich Trott Reviewed-By: Anna Henningsen --- test/parallel/parallel.status | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/parallel/parallel.status b/test/parallel/parallel.status index 88d0cb9465353e..80b70ecee3c37c 100644 --- a/test/parallel/parallel.status +++ b/test/parallel/parallel.status @@ -26,3 +26,15 @@ test-debug-signal-cluster : PASS,FLAKY [$system==aix] test-fs-watch-enoent : FAIL, PASS test-fs-watch-encoding : FAIL, PASS + +# being worked under https://github.com/nodejs/node/pull/7564 +test-async-wrap-post-did-throw : PASS, FLAKY +test-async-wrap-throw-from-callback : PASS, FLAKY +test-crypto-random : PASS, FLAKY + +#being worked under https://github.com/nodejs/node/issues/7973 +test-stdio-closed : PASS, FLAKY + +#covered by https://github.com/nodejs/node/issues/3796 +# but more frequent on AIX ? +test-debug-signal-cluster : PASS, FLAKY From a9fe85ee9c684308f8f1f50115f0f3f15edf2e55 Mon Sep 17 00:00:00 2001 From: Ali Ijaz Sheikh Date: Wed, 10 Aug 2016 15:02:32 -0700 Subject: [PATCH 132/144] deps: v8_inspector update Pick up latest from [1] corresponding to the Blink commit 62cd277. [1]: https://github.com/pavelfeldman/v8_inspector/commit/e6b8355 PR-URL: https://github.com/nodejs/node/pull/8014 Reviewed-By: bnoordhuis - Ben Noordhuis Reviewed-By: cjihrig - Colin Ihrig --- deps/v8_inspector/README.md | 1 + .../platform/inspector_protocol/Array.h | 52 +- .../inspector_protocol/CodeGenerator.py | 179 ++++-- .../inspector_protocol/DispatcherBase.cpp | 2 +- .../inspector_protocol/Exported_h.template | 65 +++ .../inspector_protocol/Imported_h.template | 49 ++ .../inspector_protocol/String16STL.cpp | 8 - .../platform/inspector_protocol/String16STL.h | 3 +- .../TypeBuilder_cpp.template | 101 +++- .../inspector_protocol/TypeBuilder_h.template | 27 +- .../inspector_protocol/ValueConversions.cpp | 51 -- .../inspector_protocol/ValueConversions.h | 111 ++-- .../platform/inspector_protocol/Values.cpp | 22 + .../platform/inspector_protocol/Values.h | 22 +- .../generate-inspector-protocol-version | 7 +- .../platform/v8_inspector/DebuggerScript.js | 25 +- .../platform/v8_inspector/InjectedScript.cpp | 79 +-- .../platform/v8_inspector/InjectedScript.h | 17 +- .../v8_inspector/InjectedScriptSource.js | 79 ++- .../v8_inspector/InspectedContext.cpp | 22 +- .../platform/v8_inspector/InspectedContext.h | 16 +- .../platform/v8_inspector/V8Compat.h | 6 +- .../platform/v8_inspector/V8Console.cpp | 43 +- .../v8_inspector/V8ConsoleAgentImpl.cpp | 8 +- .../v8_inspector/V8ConsoleMessage.cpp | 75 ++- .../platform/v8_inspector/V8ConsoleMessage.h | 24 +- .../{V8DebuggerImpl.cpp => V8Debugger.cpp} | 547 ++++-------------- .../platform/v8_inspector/V8Debugger.h | 131 +++++ .../v8_inspector/V8DebuggerAgentImpl.cpp | 179 +++--- .../v8_inspector/V8DebuggerAgentImpl.h | 12 +- .../platform/v8_inspector/V8DebuggerImpl.h | 209 ------- .../v8_inspector/V8DebuggerScript.cpp | 4 +- .../platform/v8_inspector/V8DebuggerScript.h | 14 +- .../platform/v8_inspector/V8FunctionCall.cpp | 43 +- .../platform/v8_inspector/V8FunctionCall.h | 9 +- .../v8_inspector/V8HeapProfilerAgentImpl.cpp | 33 +- .../v8_inspector/V8InjectedScriptHost.cpp | 98 +--- .../v8_inspector/V8InjectedScriptHost.h | 10 +- .../platform/v8_inspector/V8InspectorImpl.cpp | 350 +++++++++++ .../platform/v8_inspector/V8InspectorImpl.h | 126 ++++ .../v8_inspector/V8InspectorSessionImpl.cpp | 94 +-- .../v8_inspector/V8InspectorSessionImpl.h | 25 +- .../v8_inspector/V8ProfilerAgentImpl.cpp | 51 +- .../v8_inspector/V8ProfilerAgentImpl.h | 4 +- .../platform/v8_inspector/V8Regex.cpp | 16 +- .../platform/v8_inspector/V8Regex.h | 6 +- .../v8_inspector/V8RuntimeAgentImpl.cpp | 390 ++++++++++--- .../v8_inspector/V8RuntimeAgentImpl.h | 34 +- .../v8_inspector/V8StackTraceImpl.cpp | 37 +- .../platform/v8_inspector/V8StackTraceImpl.h | 18 +- .../platform/v8_inspector/V8StringUtil.cpp | 37 +- .../platform/v8_inspector/V8StringUtil.h | 8 + .../v8_inspector/debugger_script_externs.js | 2 +- .../v8_inspector/injected_script_externs.js | 15 +- .../platform/v8_inspector/js_protocol.json | 215 ++++--- .../v8_inspector/public/InspectorVersion.h | 6 + .../v8_inspector/public/V8ConsoleTypes.h | 20 - .../v8_inspector/public/V8ContentSearchUtil.h | 26 - .../v8_inspector/public/V8ContextInfo.h | 15 +- .../platform/v8_inspector/public/V8Debugger.h | 67 --- .../v8_inspector/public/V8DebuggerClient.h | 54 -- .../v8_inspector/public/V8Inspector.cpp | 74 --- .../v8_inspector/public/V8Inspector.h | 99 ++-- .../v8_inspector/public/V8InspectorClient.h | 60 ++ .../v8_inspector/public/V8InspectorSession.h | 17 +- .../public/V8InspectorSessionClient.h | 29 - .../v8_inspector/public/V8StackTrace.h | 8 +- .../platform/v8_inspector/v8_inspector.gyp | 21 +- src/inspector_agent.cc | 38 +- 69 files changed, 2404 insertions(+), 1941 deletions(-) create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Exported_h.template create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Imported_h.template delete mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.cpp rename deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/{V8DebuggerImpl.cpp => V8Debugger.cpp} (53%) create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Debugger.h delete mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorImpl.cpp create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorImpl.h create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/InspectorVersion.h delete mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ConsoleTypes.h delete mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h delete mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Debugger.h delete mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h delete mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp create mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorClient.h delete mode 100644 deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h diff --git a/deps/v8_inspector/README.md b/deps/v8_inspector/README.md index d99d25f94ce3aa..60578c90324ed0 100644 --- a/deps/v8_inspector/README.md +++ b/deps/v8_inspector/README.md @@ -7,4 +7,5 @@ Node.js support for the [Chrome Debug Protocol][https://developer.chrome.com/dev * third_party/v8_inspector/platform/v8_inspector: vendored from https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/platform/v8_inspector * third_party/v8_inspector/platform/inspector_protocol: vendored from https://chromium.googlesource.com/chromium/src/third_party/WebKit/Source/platform/inspector_protocol * third_party/jinja2: vendored from https://github.com/mitsuhiko/jinja2 + * The `tests/` directory `ext/jinja.el` file have been deleted. * third_party/markupsafe: vendored from https://github.com/mitsuhiko/markupsafe diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Array.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Array.h index d92af3a5ed7d05..720182258b9533 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Array.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Array.h @@ -17,7 +17,7 @@ namespace blink { namespace protocol { template -class ArrayBase { +class Array { public: static std::unique_ptr> create() { @@ -31,12 +31,12 @@ class ArrayBase { errors->addError("array expected"); return nullptr; } - errors->push(); std::unique_ptr> result(new Array()); + errors->push(); for (size_t i = 0; i < array->size(); ++i) { errors->setName(String16::fromInteger(i)); - T item = FromValue::parse(array->at(i), errors); - result->m_vector.push_back(item); + std::unique_ptr item = ValueConversions::parse(array->at(i), errors); + result->m_vector.push_back(std::move(item)); } errors->pop(); if (errors->hasErrors()) @@ -44,9 +44,9 @@ class ArrayBase { return result; } - void addItem(const T& value) + void addItem(std::unique_ptr value) { - m_vector.push_back(value); + m_vector.push_back(std::move(value)); } size_t length() @@ -54,31 +54,25 @@ class ArrayBase { return m_vector.size(); } - T get(size_t index) + T* get(size_t index) { - return m_vector[index]; + return m_vector[index].get(); } std::unique_ptr serialize() { std::unique_ptr result = ListValue::create(); for (auto& item : m_vector) - result->pushValue(toValue(item)); + result->pushValue(ValueConversions::serialize(item)); return result; } private: - std::vector m_vector; + std::vector> m_vector; }; -template<> class Array : public ArrayBase {}; -template<> class Array : public ArrayBase {}; -template<> class Array : public ArrayBase {}; -template<> class Array : public ArrayBase {}; -template<> class Array : public ArrayBase {}; - template -class Array { +class ArrayBase { public: static std::unique_ptr> create() { @@ -92,12 +86,12 @@ class Array { errors->addError("array expected"); return nullptr; } - std::unique_ptr> result(new Array()); errors->push(); + std::unique_ptr> result(new Array()); for (size_t i = 0; i < array->size(); ++i) { errors->setName(String16::fromInteger(i)); - std::unique_ptr item = FromValue::parse(array->at(i), errors); - result->m_vector.push_back(std::move(item)); + T item = ValueConversions::parse(array->at(i), errors); + result->m_vector.push_back(item); } errors->pop(); if (errors->hasErrors()) @@ -105,9 +99,9 @@ class Array { return result; } - void addItem(std::unique_ptr value) + void addItem(const T& value) { - m_vector.push_back(std::move(value)); + m_vector.push_back(value); } size_t length() @@ -115,23 +109,29 @@ class Array { return m_vector.size(); } - T* get(size_t index) + T get(size_t index) { - return m_vector[index].get(); + return m_vector[index]; } std::unique_ptr serialize() { std::unique_ptr result = ListValue::create(); for (auto& item : m_vector) - result->pushValue(toValue(item)); + result->pushValue(ValueConversions::serialize(item)); return result; } private: - std::vector> m_vector; + std::vector m_vector; }; +template<> class Array : public ArrayBase {}; +template<> class Array : public ArrayBase {}; +template<> class Array : public ArrayBase {}; +template<> class Array : public ArrayBase {}; +template<> class Array : public ArrayBase {}; + } // namespace platform } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/CodeGenerator.py b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/CodeGenerator.py index c785c79b528fd1..0b09c8e90401dd 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/CodeGenerator.py +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/CodeGenerator.py @@ -24,11 +24,18 @@ # In Blink, jinja2 is in chromium's third_party directory. # Insert at 1 so at front to override system libraries, and # after path[0] == invoking script dir -third_party_dir = os.path.normpath(os.path.join( +blink_third_party_dir = os.path.normpath(os.path.join( module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, "third_party")) -if os.path.isdir(third_party_dir): - sys.path.insert(1, third_party_dir) +if os.path.isdir(blink_third_party_dir): + sys.path.insert(1, blink_third_party_dir) + +# In V8, it is in third_party folder +v8_third_party_dir = os.path.normpath(os.path.join( + module_path, os.pardir, os.pardir, "third_party")) + +if os.path.isdir(v8_third_party_dir): + sys.path.insert(1, v8_third_party_dir) # In Node, it is in deps folder deps_dir = os.path.normpath(os.path.join( @@ -43,10 +50,13 @@ cmdline_parser = optparse.OptionParser() cmdline_parser.add_option("--protocol") cmdline_parser.add_option("--include") +cmdline_parser.add_option("--include_package") cmdline_parser.add_option("--string_type") cmdline_parser.add_option("--export_macro") cmdline_parser.add_option("--output_dir") cmdline_parser.add_option("--output_package") +cmdline_parser.add_option("--exported_dir") +cmdline_parser.add_option("--exported_package") try: arg_options, arg_values = cmdline_parser.parse_args() @@ -54,12 +64,23 @@ if not protocol_file: raise Exception("Protocol directory must be specified") include_file = arg_options.include + include_package = arg_options.include_package + if include_file and not include_package: + raise Exception("Include package must be specified when using include file") + if include_package and not include_file: + raise Exception("Include file must be specified when using include package") output_dirname = arg_options.output_dir if not output_dirname: raise Exception("Output directory must be specified") output_package = arg_options.output_package if not output_package: raise Exception("Output package must be specified") + exported_dirname = arg_options.exported_dir + if not exported_dirname: + exported_dirname = os.path.join(output_dirname, "exported") + exported_package = arg_options.exported_package + if not exported_package: + exported_package = os.path.join(output_package, "exported") string_type = arg_options.string_type if not string_type: raise Exception("String type must be specified") @@ -84,30 +105,38 @@ def up_to_date(): os.path.getmtime(__file__), os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_h.template")), os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_cpp.template")), + os.path.getmtime(os.path.join(templates_dir, "Exported_h.template")), + os.path.getmtime(os.path.join(templates_dir, "Imported_h.template")), os.path.getmtime(protocol_file)) for domain in parsed_json["domains"]: name = domain["domain"] - h_path = os.path.join(output_dirname, name + ".h") - cpp_path = os.path.join(output_dirname, name + ".cpp") - if not os.path.exists(h_path) or not os.path.exists(cpp_path): - return False - generated_ts = max(os.path.getmtime(h_path), os.path.getmtime(cpp_path)) - if generated_ts < template_ts: - return False + paths = [] + if name in generate_domains: + paths = [os.path.join(output_dirname, name + ".h"), os.path.join(output_dirname, name + ".cpp")] + if domain["has_exports"]: + paths.append(os.path.join(exported_dirname, name + ".h")) + if name in include_domains and domain["has_exports"]: + paths = [os.path.join(output_dirname, name + '.h')] + for path in paths: + if not os.path.exists(path): + return False + generated_ts = os.path.getmtime(path) + if generated_ts < template_ts: + return False return True -if up_to_date(): - sys.exit() - - def to_title_case(name): return name[:1].upper() + name[1:] def dash_to_camelcase(word): - return "".join(to_title_case(x) or "-" for x in word.split("-")) + prefix = "" + if word[0] == "-": + prefix = "Negative" + word = word[1:] + return prefix + "".join(to_title_case(x) or "-" for x in word.split("-")) def initialize_jinja_env(cache_dir): @@ -144,12 +173,47 @@ def patch_full_qualified_refs_in_domain(json, domain_name): continue if json["$ref"].find(".") == -1: json["$ref"] = domain_name + "." + json["$ref"] + return for domain in json_api["domains"]: patch_full_qualified_refs_in_domain(domain, domain["domain"]) +def calculate_exports(): + def calculate_exports_in_json(json_value): + has_exports = False + if isinstance(json_value, list): + for item in json_value: + has_exports = calculate_exports_in_json(item) or has_exports + if isinstance(json_value, dict): + has_exports = ("exported" in json_value and json_value["exported"]) or has_exports + for key in json_value: + has_exports = calculate_exports_in_json(json_value[key]) or has_exports + return has_exports + + json_api["has_exports"] = False + for domain_json in json_api["domains"]: + domain_json["has_exports"] = calculate_exports_in_json(domain_json) + json_api["has_exports"] = json_api["has_exports"] or domain_json["has_exports"] + + +def create_include_type_definition(domain_name, type): + # pylint: disable=W0622 + return { + "return_type": "std::unique_ptr" % (domain_name, type["id"]), + "pass_type": "std::unique_ptr" % (domain_name, type["id"]), + "to_raw_type": "%s.get()", + "to_pass_type": "std::move(%s)", + "to_rvalue": "std::move(%s)", + "type": "std::unique_ptr" % (domain_name, type["id"]), + "raw_type": "protocol::%s::API::%s" % (domain_name, type["id"]), + "raw_pass_type": "protocol::%s::API::%s*" % (domain_name, type["id"]), + "raw_return_type": "protocol::%s::API::%s*" % (domain_name, type["id"]), + } + + def create_user_type_definition(domain_name, type): + # pylint: disable=W0622 return { "return_type": "std::unique_ptr" % (domain_name, type["id"]), "pass_type": "std::unique_ptr" % (domain_name, type["id"]), @@ -164,6 +228,7 @@ def create_user_type_definition(domain_name, type): def create_object_type_definition(): + # pylint: disable=W0622 return { "return_type": "std::unique_ptr", "pass_type": "std::unique_ptr", @@ -178,6 +243,7 @@ def create_object_type_definition(): def create_any_type_definition(): + # pylint: disable=W0622 return { "return_type": "std::unique_ptr", "pass_type": "std::unique_ptr", @@ -192,6 +258,7 @@ def create_any_type_definition(): def create_string_type_definition(domain): + # pylint: disable=W0622 return { "return_type": string_type, "pass_type": ("const %s&" % string_type), @@ -206,6 +273,7 @@ def create_string_type_definition(domain): def create_primitive_type_definition(type): + # pylint: disable=W0622 typedefs = { "number": "double", "integer": "int", @@ -244,6 +312,7 @@ def create_primitive_type_definition(type): def wrap_array_definition(type): + # pylint: disable=W0622 return { "return_type": "std::unique_ptr>" % type["raw_type"], "pass_type": "std::unique_ptr>" % type["raw_type"], @@ -265,15 +334,18 @@ def create_type_definitions(): if not ("types" in domain): continue for type in domain["types"]: - if type["type"] == "object": - type_definitions[domain["domain"] + "." + type["id"]] = create_user_type_definition(domain["domain"], type) + type_name = domain["domain"] + "." + type["id"] + if type["type"] == "object" and domain["domain"] in include_domains: + type_definitions[type_name] = create_include_type_definition(domain["domain"], type) + elif type["type"] == "object": + type_definitions[type_name] = create_user_type_definition(domain["domain"], type) elif type["type"] == "array": items_type = type["items"]["type"] - type_definitions[domain["domain"] + "." + type["id"]] = wrap_array_definition(type_definitions[items_type]) + type_definitions[type_name] = wrap_array_definition(type_definitions[items_type]) elif type["type"] == domain["domain"] + ".string": - type_definitions[domain["domain"] + "." + type["id"]] = create_string_type_definition(domain["domain"]) + type_definitions[type_name] = create_string_type_definition(domain["domain"]) else: - type_definitions[domain["domain"] + "." + type["id"]] = create_primitive_type_definition(type["type"]) + type_definitions[type_name] = create_primitive_type_definition(type["type"]) def type_definition(name): @@ -303,7 +375,25 @@ def has_disable(commands): return False +def generate(domain_object, template, file_name): + template_context = { + "domain": domain_object, + "join_arrays": join_arrays, + "resolve_type": resolve_type, + "type_definition": type_definition, + "has_disable": has_disable, + "export_macro": export_macro, + "output_package": output_package, + "exported_package": exported_package, + "include_package": include_package + } + out_file = output_file(file_name) + out_file.write(template.render(template_context)) + out_file.close() + + generate_domains = [] +include_domains = [] json_api = {} json_api["domains"] = parsed_json["domains"] @@ -314,44 +404,33 @@ def has_disable(commands): input_file = open(include_file, "r") json_string = input_file.read() parsed_json = json.loads(json_string) + for domain in parsed_json["domains"]: + include_domains.append(domain["domain"]) json_api["domains"] += parsed_json["domains"] - patch_full_qualified_refs() +calculate_exports() create_type_definitions() +if up_to_date(): + sys.exit() if not os.path.exists(output_dirname): os.mkdir(output_dirname) -jinja_env = initialize_jinja_env(output_dirname) - -h_template_name = "/TypeBuilder_h.template" -cpp_template_name = "/TypeBuilder_cpp.template" -h_template = jinja_env.get_template(h_template_name) -cpp_template = jinja_env.get_template(cpp_template_name) - - -def generate(domain): - class_name = domain["domain"] - h_file_name = output_dirname + "/" + class_name + ".h" - cpp_file_name = output_dirname + "/" + class_name + ".cpp" - - template_context = { - "domain": domain, - "join_arrays": join_arrays, - "resolve_type": resolve_type, - "type_definition": type_definition, - "has_disable": has_disable, - "export_macro": export_macro, - "output_package": output_package, - } - h_file = output_file(h_file_name) - cpp_file = output_file(cpp_file_name) - h_file.write(h_template.render(template_context)) - cpp_file.write(cpp_template.render(template_context)) - h_file.close() - cpp_file.close() +if json_api["has_exports"] and not os.path.exists(exported_dirname): + os.mkdir(exported_dirname) +jinja_env = initialize_jinja_env(output_dirname) +h_template = jinja_env.get_template("/TypeBuilder_h.template") +cpp_template = jinja_env.get_template("/TypeBuilder_cpp.template") +exported_template = jinja_env.get_template("/Exported_h.template") +imported_template = jinja_env.get_template("/Imported_h.template") for domain in json_api["domains"]: + class_name = domain["domain"] if domain["domain"] in generate_domains: - generate(domain) + generate(domain, h_template, output_dirname + "/" + class_name + ".h") + generate(domain, cpp_template, output_dirname + "/" + class_name + ".cpp") + if domain["has_exports"]: + generate(domain, exported_template, exported_dirname + "/" + class_name + ".h") + if domain["domain"] in include_domains and domain["has_exports"]: + generate(domain, imported_template, output_dirname + "/" + class_name + ".h") diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp index 49422eba09a9ca..8f154f42ac286f 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/DispatcherBase.cpp @@ -34,7 +34,7 @@ void DispatcherBase::Callback::dispose() void DispatcherBase::Callback::sendIfActive(std::unique_ptr partialMessage, const ErrorString& invocationError) { - if (!m_backendImpl->get()) + if (!m_backendImpl || !m_backendImpl->get()) return; m_backendImpl->get()->sendResponse(m_callId, invocationError, nullptr, std::move(partialMessage)); m_backendImpl = nullptr; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Exported_h.template b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Exported_h.template new file mode 100644 index 00000000000000..5cfabc53cf1fbe --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Exported_h.template @@ -0,0 +1,65 @@ +// This file is generated + +// Copyright (c) 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef protocol_{{domain.domain}}_api_h +#define protocol_{{domain.domain}}_api_h + +{% if export_macro == "PLATFORM_EXPORT" %} +#include "platform/inspector_protocol/Platform.h" +{% else %} +#include "core/CoreExport.h" +{% endif %} +#include "platform/inspector_protocol/String16.h" + +namespace blink { +namespace protocol { +namespace {{domain.domain}} { +namespace API { + +// ------------- Enums. + {% for type in domain.types %} + {% if ("enum" in type) and type.exported %} + +namespace {{type.id}}Enum { + {% for literal in type.enum %} +{{export_macro}} extern const char* {{ literal | dash_to_camelcase}}; + {% endfor %} +} // {{type.id}}Enum + {% endif %} + {% endfor %} + {% for command in join_arrays(domain, ["commands", "events"]) %} + {% for param in join_arrays(command, ["parameters", "returns"]) %} + {% if ("enum" in param) and (param.exported) %} + +namespace {{command.name | to_title_case}} { +namespace {{param.name | to_title_case}}Enum { + {% for literal in param.enum %} +{{export_macro}} extern const char* {{ literal | dash_to_camelcase}}; + {% endfor %} +} // {{param.name | to_title_case}}Enum +} // {{command.name | to_title_case }} + {% endif %} + {% endfor %} + {% endfor %} + +// ------------- Types. + {% for type in domain.types %} + {% if not (type.type == "object") or not ("properties" in type) or not (type.exported) %}{% continue %}{% endif %} + +class {{export_macro}} {{type.id}} { +public: + virtual String16 toJSONString() const = 0; + virtual ~{{type.id}}() { } + static std::unique_ptr fromJSONString(const String16& json); +}; + {% endfor %} + +} // namespace API +} // namespace {{domain.domain}} +} // namespace protocol +} // namespace blink + +#endif // !defined(protocol_{{domain.domain}}_api_h) diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Imported_h.template b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Imported_h.template new file mode 100644 index 00000000000000..a9abdad172642e --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Imported_h.template @@ -0,0 +1,49 @@ +// This file is generated + +// Copyright (c) 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef protocol_{{domain.domain}}_imported_h +#define protocol_{{domain.domain}}_imported_h + +#include "platform/inspector_protocol/ErrorSupport.h" +#include "platform/inspector_protocol/ValueConversions.h" +#include "platform/inspector_protocol/Values.h" +#include "{{include_package}}/{{domain.domain}}.h" + +namespace blink { +namespace protocol { + {% for type in domain.types %} + {% if not (type.type == "object") or not ("properties" in type) or not (type.exported) %}{% continue %}{% endif %} + +template<> +struct ValueConversions<{{domain.domain}}::API::{{type.id}}> { + static std::unique_ptr<{{domain.domain}}::API::{{type.id}}> parse(protocol::Value* value, ErrorSupport* errors) + { + if (!value) { + errors->addError("value expected"); + return nullptr; + } + std::unique_ptr<{{domain.domain}}::API::{{type.id}}> result = {{domain.domain}}::API::{{type.id}}::fromJSONString(value->toJSONString()); + if (!result) + errors->addError("cannot parse"); + return result; + } + + static std::unique_ptr serialize({{domain.domain}}::API::{{type.id}}* value) + { + return SerializedValue::create(value->toJSONString()); + } + + static std::unique_ptr serialize(const std::unique_ptr<{{domain.domain}}::API::{{type.id}}>& value) + { + return SerializedValue::create(value->toJSONString()); + } +}; + {% endfor %} + +} // namespace protocol +} // namespace blink + +#endif // !defined(protocol_{{domain.domain}}_imported_h) diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.cpp index 4883f4ceda46e1..10c7fa61017dd7 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.cpp @@ -113,14 +113,6 @@ inline char upperNibbleToASCIIHexDigit(char c) return nibble < 10 ? '0' + nibble : 'A' + nibble - 10; } -template inline bool isASCIIAlphaCaselessEqual(CharType cssCharacter, char character) -{ - // This function compares a (preferrably) constant ASCII - // lowercase letter to any input character. - DCHECK(character >= 'a' && character <= 'z'); - return LIKELY(toASCIILowerUnchecked(cssCharacter) == character); -} - inline int inlineUTF8SequenceLengthNonASCII(char b0) { if ((b0 & 0xC0) != 0xC0) diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.h index 703e5b0f025d94..4dd4369ebdd788 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/String16STL.h @@ -5,6 +5,7 @@ #ifndef String16STL_h #define String16STL_h +#include #include #include #include @@ -141,7 +142,7 @@ class String16 { static inline bool isSpaceOrNewline(UChar c) { - return false; + return std::isspace(c); // NOLINT } class String16Builder { diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template index 909fea4e71a7ff..e3c2fa1de6761d 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_cpp.template @@ -7,6 +7,7 @@ #include "{{output_package}}/{{domain.domain}}.h" #include "platform/inspector_protocol/DispatcherBase.h" +#include "platform/inspector_protocol/Parser.h" namespace blink { namespace protocol { @@ -15,6 +16,7 @@ namespace {{domain.domain}} { // ------------- Enum values from types. const char Metainfo::domainName[] = "{{domain.domain}}"; +const char Metainfo::commandPrefix[] = "{{domain.domain}}."; {% for type in domain.types %} {% if "enum" in type %} @@ -22,7 +24,17 @@ namespace {{type.id}}Enum { {% for literal in type.enum %} const char* {{ literal | dash_to_camelcase}} = "{{literal}}"; {% endfor %} -} // {{type.id}}Enum +} // namespace {{type.id}}Enum + {% if type.exported %} + +namespace API { +namespace {{type.id}}Enum { + {% for literal in type.enum %} +const char* {{ literal | dash_to_camelcase}} = "{{literal}}"; + {% endfor %} +} // namespace {{type.id}}Enum +} // namespace API + {% endif %} {% endif %} {% for property in type.properties %} {% if "enum" in property %} @@ -49,11 +61,11 @@ std::unique_ptr<{{type.id}}> {{type.id}}::parse(protocol::Value* value, ErrorSup {% if property.optional %} if ({{property.name}}Value) { errors->setName("{{property.name}}"); - result->m_{{property.name}} = FromValue<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); + result->m_{{property.name}} = ValueConversions<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); } {% else %} errors->setName("{{property.name}}"); - result->m_{{property.name}} = FromValue<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); + result->m_{{property.name}} = ValueConversions<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); {% endif %} {% endfor %} errors->pop(); @@ -68,9 +80,9 @@ std::unique_ptr {{type.id}}::serialize() const {% for property in type.properties %} {% if property.optional %} if (m_{{property.name}}.isJust()) - result->setValue("{{property.name}}", toValue(m_{{property.name}}.fromJust())); + result->setValue("{{property.name}}", ValueConversions<{{resolve_type(property).raw_type}}>::serialize(m_{{property.name}}.fromJust())); {% else %} - result->setValue("{{property.name}}", toValue({{resolve_type(property).to_raw_type % ("m_" + property.name)}})); + result->setValue("{{property.name}}", ValueConversions<{{resolve_type(property).raw_type}}>::serialize({{resolve_type(property).to_raw_type % ("m_" + property.name)}})); {% endif %} {% endfor %} return result; @@ -81,6 +93,23 @@ std::unique_ptr<{{type.id}}> {{type.id}}::clone() const ErrorSupport errors; return parse(serialize().get(), &errors); } + {% if type.exported %} + +String16 {{type.id}}::toJSONString() const +{ + return serialize()->toJSONString(); +} + +// static +std::unique_ptr API::{{type.id}}::fromJSONString(const String16& json) +{ + ErrorSupport errors; + std::unique_ptr value = parseJSON(json); + if (!value) + return nullptr; + return protocol::{{domain.domain}}::{{type.id}}::parse(value.get(), &errors); +} + {% endif %} {% endfor %} // ------------- Enum values from params. @@ -94,8 +123,20 @@ namespace {{param.name | to_title_case}}Enum { {% for literal in param.enum %} const char* {{ literal | to_title_case}} = "{{literal}}"; {% endfor %} -} // {{param.name | to_title_case}}Enum -} // {{command.name | to_title_case }} +} // namespace {{param.name | to_title_case}}Enum +} // namespace {{command.name | to_title_case }} + {% if param.exported %} + +namespace API { +namespace {{command.name | to_title_case}} { +namespace {{param.name | to_title_case}}Enum { + {% for literal in param.enum %} +const char* {{ literal | to_title_case}} = "{{literal}}"; + {% endfor %} +} // namespace {{param.name | to_title_case}}Enum +} // namespace {{command.name | to_title_case }} +} // namespace API + {% endif %} {% endif %} {% endfor %} {% endfor %} @@ -119,9 +160,9 @@ void Frontend::{{event.name}}( {% for parameter in event.parameters %} {% if "optional" in parameter %} if ({{parameter.name}}.isJust()) - paramsObject->setValue("{{parameter.name}}", toValue({{parameter.name}}.fromJust())); + paramsObject->setValue("{{parameter.name}}", ValueConversions<{{resolve_type(parameter).raw_type}}>::serialize({{parameter.name}}.fromJust())); {% else %} - paramsObject->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).to_raw_type % parameter.name}})); + paramsObject->setValue("{{parameter.name}}", ValueConversions<{{resolve_type(parameter).raw_type}}>::serialize({{resolve_type(parameter).to_raw_type % parameter.name}})); {% endif %} {% endfor %} jsonMessage->setObject("params", std::move(paramsObject)); @@ -196,9 +237,9 @@ public: {% for parameter in command.returns %} {% if "optional" in parameter %} if ({{parameter.name}}.isJust()) - resultObject->setValue("{{parameter.name}}", toValue({{parameter.name}}.fromJust())); + resultObject->setValue("{{parameter.name}}", ValueConversions<{{resolve_type(parameter).raw_type}}>::serialize({{parameter.name}}.fromJust())); {% else %} - resultObject->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).to_raw_type % parameter.name}})); + resultObject->setValue("{{parameter.name}}", ValueConversions<{{resolve_type(parameter).raw_type}}>::serialize({{resolve_type(parameter).to_raw_type % parameter.name}})); {% endif %} {% endfor %} sendIfActive(std::move(resultObject), ErrorString()); @@ -225,11 +266,11 @@ void DispatcherImpl::{{command.name}}(int callId, std::unique_ptr in_{{property.name}}; if ({{property.name}}Value) { errors->setName("{{property.name}}"); - in_{{property.name}} = FromValue<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); + in_{{property.name}} = ValueConversions<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); } {% else %} errors->setName("{{property.name}}"); - {{resolve_type(property).type}} in_{{property.name}} = FromValue<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); + {{resolve_type(property).type}} in_{{property.name}} = ValueConversions<{{resolve_type(property).raw_type}}>::parse({{property.name}}Value, errors); {% endif %} {% endfor %} errors->pop(); @@ -253,6 +294,7 @@ void DispatcherImpl::{{command.name}}(int callId, std::unique_ptr weak = weakPtr(); + {% if not("async" in command) %} ErrorString error; m_backend->{{command.name}}(&error {%- for property in command.parameters -%} @@ -262,29 +304,38 @@ void DispatcherImpl::{{command.name}}(int callId, std::unique_ptrsetValue("{{parameter.name}}", toValue(out_{{parameter.name}}.fromJust())); - {% else %} - result->setValue("{{parameter.name}}", toValue({{resolve_type(parameter).to_raw_type % ("out_" + parameter.name)}})); - {% endif %} - {% endfor %} + result->setValue("{{parameter.name}}", ValueConversions<{{resolve_type(parameter).raw_type}}>::serialize(out_{{parameter.name}}.fromJust())); + {% else %} + result->setValue("{{parameter.name}}", ValueConversions<{{resolve_type(parameter).raw_type}}>::serialize({{resolve_type(parameter).to_raw_type % ("out_" + parameter.name)}})); + {% endif %} + {% endfor %} } if (weak->get()) weak->get()->sendResponse(callId, error, std::move(result)); - {% elif not("async" in command) %} + {% else %} if (weak->get()) weak->get()->sendResponse(callId, error); + {% endif %} + {%- else %} + m_backend->{{command.name}}( + {%- for property in command.parameters -%} + {%- if "optional" in property -%} + in_{{property.name}}, + {%- else -%} + {{resolve_type(property).to_pass_type % ("in_" + property.name)}}, + {%- endif -%} + {%- endfor -%} + std::move(callback)); {% endif %} } {% endfor %} diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_h.template b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_h.template index 05ca81d3a5714e..83310065e0f0da 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_h.template +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/TypeBuilder_h.template @@ -23,9 +23,14 @@ #include "platform/inspector_protocol/String16.h" #include "platform/inspector_protocol/Values.h" #include "platform/inspector_protocol/ValueConversions.h" +// For each imported domain we generate a ValueConversions struct instead of a full domain definition +// and include Domain::API version from there. {% for name in domain.dependencies %} #include "{{output_package}}/{{name}}.h" {% endfor %} +{% if domain["has_exports"] %} +#include "{{exported_package}}/{{domain.domain}}.h" +{% endif %} namespace blink { namespace protocol { @@ -53,7 +58,7 @@ namespace {{type.id}}Enum { {% for literal in type.enum %} {{export_macro}} extern const char* {{ literal | dash_to_camelcase}}; {% endfor %} -} // {{type.id}}Enum +} // namespace {{type.id}}Enum {% endif %} {% endfor %} {% for command in join_arrays(domain, ["commands", "events"]) %} @@ -77,7 +82,8 @@ namespace {{param.name | to_title_case}}Enum { {% set type_def = type_definition(domain.domain + "." + type.id)%} // {{type.description}} -class {{export_macro}} {{type.id}} { +class {{export_macro}} {{type.id}} {% if type.exported %}: public API::{{type.id}} {% endif %}{ + PROTOCOL_DISALLOW_COPY({{type.id}}); public: static std::unique_ptr<{{type.id}}> parse(protocol::Value* value, ErrorSupport* errors); @@ -103,6 +109,9 @@ public: std::unique_ptr serialize() const; std::unique_ptr<{{type.id}}> clone() const; + {% if type.exported %} + String16 toJSONString() const override; + {% endif %} template class {{type.id}}Builder { @@ -205,16 +214,21 @@ public: ) = 0; }; {% endif %} - virtual void {{command.name}}(ErrorString* + virtual void {{command.name}}( + {%- if not("async" in command) -%} + ErrorString* + {%- endif -%} {%- for parameter in command.parameters -%} + {%- if (not loop.first) or not("async" in command) -%}, {% endif -%} {%- if "optional" in parameter -%} - , const Maybe<{{resolve_type(parameter).raw_type}}>& in_{{parameter.name}} + const Maybe<{{resolve_type(parameter).raw_type}}>& in_{{parameter.name}} {%- else -%} - , {{resolve_type(parameter).pass_type}} in_{{parameter.name}} + {{resolve_type(parameter).pass_type}} in_{{parameter.name}} {%- endif -%} {%- endfor -%} {%- if "async" in command -%} - , std::unique_ptr<{{command.name | to_title_case}}Callback> callback + {%- if command.parameters -%}, {% endif -%} + std::unique_ptr<{{command.name | to_title_case}}Callback> callback {%- else -%} {%- for parameter in command.returns -%} {%- if "optional" in parameter -%} @@ -276,6 +290,7 @@ public: using FrontendClass = Frontend; using DispatcherClass = Dispatcher; static const char domainName[]; + static const char commandPrefix[]; }; } // namespace {{domain.domain}} diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.cpp deleted file mode 100644 index 98b8e7f5dff48d..00000000000000 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "platform/inspector_protocol/ValueConversions.h" - -namespace blink { -namespace protocol { - -std::unique_ptr toValue(int value) -{ - return FundamentalValue::create(value); -} - -std::unique_ptr toValue(double value) -{ - return FundamentalValue::create(value); -} - -std::unique_ptr toValue(bool value) -{ - return FundamentalValue::create(value); -} - -std::unique_ptr toValue(const String16& param) -{ - return StringValue::create(param); -} - -std::unique_ptr toValue(const String& param) -{ - return StringValue::create(param); -} - -std::unique_ptr toValue(Value* param) -{ - return param->clone(); -} - -std::unique_ptr toValue(DictionaryValue* param) -{ - return param->clone(); -} - -std::unique_ptr toValue(ListValue* param) -{ - return param->clone(); -} - -} // namespace protocol -} // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.h index dd7b2e78641054..ba1d08047aa6bf 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/ValueConversions.h @@ -13,42 +13,26 @@ namespace blink { namespace protocol { -PLATFORM_EXPORT std::unique_ptr toValue(int value); - -PLATFORM_EXPORT std::unique_ptr toValue(double value); - -PLATFORM_EXPORT std::unique_ptr toValue(bool value); - -PLATFORM_EXPORT std::unique_ptr toValue(const String16& param); - -PLATFORM_EXPORT std::unique_ptr toValue(const String& param); - -PLATFORM_EXPORT std::unique_ptr toValue(protocol::Value* param); - -PLATFORM_EXPORT std::unique_ptr toValue(protocol::DictionaryValue* param); - -PLATFORM_EXPORT std::unique_ptr toValue(protocol::ListValue* param); - -template std::unique_ptr toValue(T* param) -{ - return param->serialize(); -} - -template std::unique_ptr toValue(const std::unique_ptr& param) -{ - return toValue(param.get()); -} - template -struct FromValue { +struct ValueConversions { static std::unique_ptr parse(protocol::Value* value, ErrorSupport* errors) { return T::parse(value, errors); } + + static std::unique_ptr serialize(T* value) + { + return value->serialize(); + } + + static std::unique_ptr serialize(const std::unique_ptr& value) + { + return value->serialize(); + } }; template<> -struct FromValue { +struct ValueConversions { static bool parse(protocol::Value* value, ErrorSupport* errors) { bool result = false; @@ -57,10 +41,15 @@ struct FromValue { errors->addError("boolean value expected"); return result; } + + static std::unique_ptr serialize(bool value) + { + return FundamentalValue::create(value); + } }; template<> -struct FromValue { +struct ValueConversions { static int parse(protocol::Value* value, ErrorSupport* errors) { int result = 0; @@ -69,10 +58,15 @@ struct FromValue { errors->addError("integer value expected"); return result; } + + static std::unique_ptr serialize(int value) + { + return FundamentalValue::create(value); + } }; template<> -struct FromValue { +struct ValueConversions { static double parse(protocol::Value* value, ErrorSupport* errors) { double result = 0; @@ -81,10 +75,15 @@ struct FromValue { errors->addError("double value expected"); return result; } + + static std::unique_ptr serialize(double value) + { + return FundamentalValue::create(value); + } }; template<> -struct FromValue { +struct ValueConversions { static String parse(protocol::Value* value, ErrorSupport* errors) { String16 result; @@ -93,10 +92,15 @@ struct FromValue { errors->addError("string value expected"); return result; } + + static std::unique_ptr serialize(const String& value) + { + return StringValue::create(value); + } }; template<> -struct FromValue { +struct ValueConversions { static String16 parse(protocol::Value* value, ErrorSupport* errors) { String16 result; @@ -105,10 +109,15 @@ struct FromValue { errors->addError("string value expected"); return result; } + + static std::unique_ptr serialize(const String16& value) + { + return StringValue::create(value); + } }; template<> -struct FromValue { +struct ValueConversions { static std::unique_ptr parse(protocol::Value* value, ErrorSupport* errors) { bool success = !!value; @@ -118,10 +127,20 @@ struct FromValue { } return value->clone(); } + + static std::unique_ptr serialize(Value* value) + { + return value->clone(); + } + + static std::unique_ptr serialize(const std::unique_ptr& value) + { + return value->clone(); + } }; template<> -struct FromValue { +struct ValueConversions { static std::unique_ptr parse(protocol::Value* value, ErrorSupport* errors) { bool success = value && value->type() == protocol::Value::TypeObject; @@ -129,10 +148,20 @@ struct FromValue { errors->addError("object expected"); return DictionaryValue::cast(value->clone()); } + + static std::unique_ptr serialize(DictionaryValue* value) + { + return value->clone(); + } + + static std::unique_ptr serialize(const std::unique_ptr& value) + { + return value->clone(); + } }; template<> -struct FromValue { +struct ValueConversions { static std::unique_ptr parse(protocol::Value* value, ErrorSupport* errors) { bool success = value && value->type() == protocol::Value::TypeArray; @@ -140,15 +169,15 @@ struct FromValue { errors->addError("list expected"); return ListValue::cast(value->clone()); } -}; -template class Array; + static std::unique_ptr serialize(ListValue* value) + { + return value->clone(); + } -template -struct FromValue> { - static std::unique_ptr> parse(protocol::Value* value, ErrorSupport* errors) + static std::unique_ptr serialize(const std::unique_ptr& value) { - return protocol::Array::parse(value, errors); + return value->clone(); } }; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.cpp index 7d4ec242ae4c51..5b8f13b4930e27 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.cpp @@ -92,6 +92,11 @@ bool Value::asString(String16*) const return false; } +bool Value::asSerialized(String16*) const +{ + return false; +} + String16 Value::toJSONString() const { String16Builder result; @@ -188,6 +193,23 @@ std::unique_ptr StringValue::clone() const return StringValue::create(m_stringValue); } +bool SerializedValue::asSerialized(String16* output) const +{ + *output = m_serializedValue; + return true; +} + +void SerializedValue::writeJSON(String16Builder* output) const +{ + DCHECK(type() == TypeSerialized); + output->append(m_serializedValue); +} + +std::unique_ptr SerializedValue::clone() const +{ + return SerializedValue::create(m_serializedValue); +} + DictionaryValue::~DictionaryValue() { } diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.h b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.h index 07a2cac9249f47..48a2012758a16b 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/Values.h @@ -38,7 +38,8 @@ class PLATFORM_EXPORT Value { TypeDouble, TypeString, TypeObject, - TypeArray + TypeArray, + TypeSerialized }; ValueType type() const { return m_type; } @@ -49,6 +50,7 @@ class PLATFORM_EXPORT Value { virtual bool asDouble(double* output) const; virtual bool asInteger(int* output) const; virtual bool asString(String16* output) const; + virtual bool asSerialized(String16* output) const; String16 toJSONString() const; virtual void writeJSON(String16Builder* output) const; @@ -123,6 +125,24 @@ class PLATFORM_EXPORT StringValue : public Value { String16 m_stringValue; }; +class PLATFORM_EXPORT SerializedValue : public Value { +public: + static std::unique_ptr create(const String16& value) + { + return wrapUnique(new SerializedValue(value)); + } + + bool asSerialized(String16* output) const override; + void writeJSON(String16Builder* output) const override; + std::unique_ptr clone() const override; + +private: + explicit SerializedValue(const String16& value) : Value(TypeSerialized), m_serializedValue(value) { } + explicit SerializedValue(const char* value) : Value(TypeSerialized), m_serializedValue(value) { } + + String16 m_serializedValue; +}; + class PLATFORM_EXPORT DictionaryValue : public Value { public: using Entry = std::pair; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version index 838a3ed2dd815a..0c01e163bbd3f8 100755 --- a/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version +++ b/deps/v8_inspector/third_party/v8_inspector/platform/inspector_protocol/generate-inspector-protocol-version @@ -60,7 +60,7 @@ except ImportError: def list_to_map(items, key): result = {} for item in items: - if not "hidden" in item: + if not "experimental" in item and not "hidden" in item: result[item[key]] = item return result @@ -287,7 +287,7 @@ def self_test(): { "name": "requestWillBeSent", "parameters": [ - { "name": "frameId", "type": "string", "hidden": True }, + { "name": "frameId", "type": "string", "experimental": True }, { "name": "request", "$ref": "Request" }, { "name": "becameOptional", "type": "string" }, { "name": "removedRequired", "type": "string" }, @@ -451,7 +451,8 @@ def main(): load_domains_and_baselines(arg_values[1], domains, baseline_domains) expected_errors = [ - "Debugger.globalObjectCleared: event has been removed" + "Debugger.globalObjectCleared: event has been removed", + "Runtime.executionContextCreated.context parameter->Runtime.ExecutionContextDescription.frameId: required property has been removed" ] errors = compare_schemas(baseline_domains, domains, False) diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/DebuggerScript.js b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/DebuggerScript.js index 5b534f322160f3..cd9a2bd56dd860 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/DebuggerScript.js +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/DebuggerScript.js @@ -141,14 +141,22 @@ DebuggerScript._executionContextId = function(contextData) { if (!contextData) return 0; - var firstComma = contextData.indexOf(","); - if (firstComma === -1) - return 0; - var secondComma = contextData.indexOf(",", firstComma + 1); - if (secondComma === -1) + var match = contextData.match(/^[^,]*,([^,]*),.*$/); + if (!match) return 0; + return parseInt(match[1], 10) || 0; +} - return parseInt(contextData.substring(firstComma + 1, secondComma), 10) || 0; +/** + * @param {string|undefined} contextData + * @return {string} + */ +DebuggerScript._executionContextAuxData = function(contextData) +{ + if (!contextData) + return ""; + var match = contextData.match(/^[^,]*,[^,]*,(.*)$/); + return match ? match[1] : ""; } /** @@ -168,7 +176,7 @@ DebuggerScript.getScripts = function(contextGroupId) if (!script.context_data) continue; // Context data is a string in the following format: - // ,,("default"|"nondefault") + // ,, if (script.context_data.indexOf(contextDataPrefix) !== 0) continue; } @@ -208,7 +216,8 @@ DebuggerScript._formatScript = function(script) endLine: endLine, endColumn: endColumn, executionContextId: DebuggerScript._executionContextId(script.context_data), - isContentScript: !!script.context_data && script.context_data.endsWith(",nondefault"), + // Note that we cannot derive aux data from context id because of compilation cache. + executionContextAuxData: DebuggerScript._executionContextAuxData(script.context_data), isInternalScript: script.is_debugger_script }; } diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.cpp index 302b635ed47a1b..3b4552ee8d9147 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.cpp @@ -39,14 +39,13 @@ #include "platform/v8_inspector/RemoteObjectId.h" #include "platform/v8_inspector/V8Compat.h" #include "platform/v8_inspector/V8Console.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" #include "platform/v8_inspector/V8FunctionCall.h" #include "platform/v8_inspector/V8InjectedScriptHost.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8StackTraceImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8Debugger.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" using blink::protocol::Array; using blink::protocol::Debugger::CallFrame; @@ -72,7 +71,7 @@ std::unique_ptr InjectedScript::create(InspectedContext* inspect v8::Context::Scope scope(context); std::unique_ptr injectedScriptNative(new InjectedScriptNative(isolate)); - v8::Local scriptHostWrapper = V8InjectedScriptHost::create(context, inspectedContext->debugger()); + v8::Local scriptHostWrapper = V8InjectedScriptHost::create(context, inspectedContext->inspector()); injectedScriptNative->setOnInjectedScriptHost(scriptHostWrapper); // Inject javascript into the context. The compiled script is supposed to evaluate into @@ -82,7 +81,7 @@ std::unique_ptr InjectedScript::create(InspectedContext* inspect // to create and configure InjectedScript instance that is going to be used by the inspector. String16 injectedScriptSource(reinterpret_cast(InjectedScriptSource_js), sizeof(InjectedScriptSource_js)); v8::Local value; - if (!inspectedContext->debugger()->compileAndRunInternalScript(context, toV8String(isolate, injectedScriptSource)).ToLocal(&value)) + if (!inspectedContext->inspector()->compileAndRunInternalScript(context, toV8String(isolate, injectedScriptSource)).ToLocal(&value)) return nullptr; DCHECK(value->IsFunction()); v8::Local function = v8::Local::Cast(value); @@ -111,7 +110,7 @@ InjectedScript::~InjectedScript() void InjectedScript::getProperties(ErrorString* errorString, v8::Local object, const String16& groupName, bool ownProperties, bool accessorPropertiesOnly, bool generatePreview, std::unique_ptr>* properties, Maybe* exceptionDetails) { v8::HandleScope handles(m_context->isolate()); - V8FunctionCall function(m_context->debugger(), m_context->context(), v8Value(), "getProperties"); + V8FunctionCall function(m_context->inspector(), m_context->context(), v8Value(), "getProperties"); function.appendArgument(object); function.appendArgument(groupName); function.appendArgument(ownProperties); @@ -127,7 +126,7 @@ void InjectedScript::getProperties(ErrorString* errorString, v8::Local protocolValue = toProtocolValue(function.context(), resultValue); + std::unique_ptr protocolValue = toProtocolValue(m_context->context(), resultValue); if (hasInternalError(errorString, !protocolValue)) return; protocol::ErrorSupport errors(errorString); @@ -179,7 +178,7 @@ bool InjectedScript::wrapObjectProperty(ErrorString* errorString, v8::Local array, v8::Local property, const String16& groupName, bool forceValueType, bool generatePreview) const { - V8FunctionCall function(m_context->debugger(), m_context->context(), v8Value(), "wrapPropertyInArray"); + V8FunctionCall function(m_context->inspector(), m_context->context(), v8Value(), "wrapPropertyInArray"); function.appendArgument(array); function.appendArgument(property); function.appendArgument(groupName); @@ -192,7 +191,7 @@ bool InjectedScript::wrapPropertyInArray(ErrorString* errorString, v8::Local array, const String16& groupName, bool forceValueType, bool generatePreview) const { - V8FunctionCall function(m_context->debugger(), m_context->context(), v8Value(), "wrapObjectsInArray"); + V8FunctionCall function(m_context->inspector(), m_context->context(), v8Value(), "wrapObjectsInArray"); function.appendArgument(array); function.appendArgument(groupName); function.appendArgument(forceValueType); @@ -204,7 +203,7 @@ bool InjectedScript::wrapObjectsInArray(ErrorString* errorString, v8::Local InjectedScript::wrapValue(ErrorString* errorString, v8::Local value, const String16& groupName, bool forceValueType, bool generatePreview) const { - V8FunctionCall function(m_context->debugger(), m_context->context(), v8Value(), "wrapObject"); + V8FunctionCall function(m_context->inspector(), m_context->context(), v8Value(), "wrapObject"); function.appendArgument(value); function.appendArgument(groupName); function.appendArgument(forceValueType); @@ -219,7 +218,7 @@ v8::MaybeLocal InjectedScript::wrapValue(ErrorString* errorString, v8 std::unique_ptr InjectedScript::wrapTable(v8::Local table, v8::Local columns) const { v8::HandleScope handles(m_context->isolate()); - V8FunctionCall function(m_context->debugger(), m_context->context(), v8Value(), "wrapTable"); + V8FunctionCall function(m_context->inspector(), m_context->context(), v8Value(), "wrapTable"); function.appendArgument(table); if (columns.IsEmpty()) function.appendArgument(false); @@ -256,7 +255,7 @@ void InjectedScript::releaseObjectGroup(const String16& objectGroup) void InjectedScript::setCustomObjectFormatterEnabled(bool enabled) { v8::HandleScope handles(m_context->isolate()); - V8FunctionCall function(m_context->debugger(), m_context->context(), v8Value(), "setCustomObjectFormatterEnabled"); + V8FunctionCall function(m_context->inspector(), m_context->context(), v8Value(), "setCustomObjectFormatterEnabled"); function.appendArgument(enabled); bool hadException = false; function.call(hadException); @@ -290,12 +289,12 @@ v8::MaybeLocal InjectedScript::resolveCallArgument(ErrorString* error return v8::MaybeLocal(); return object; } - if (callArgument->hasValue()) { - String16 value = callArgument->getValue(nullptr)->toJSONString(); - if (callArgument->getType(String16()) == "number") - value = "Number(" + value + ")"; + if (callArgument->hasValue() || callArgument->hasUnserializableValue()) { + String16 value = callArgument->hasValue() ? + callArgument->getValue(nullptr)->toJSONString() : + "Number(\"" + callArgument->getUnserializableValue("") + "\")"; v8::Local object; - if (!m_context->debugger()->compileAndRunInternalScript(m_context->context(), toV8String(m_context->isolate(), value)).ToLocal(&object)) { + if (!m_context->inspector()->compileAndRunInternalScript(m_context->context(), toV8String(m_context->isolate(), value)).ToLocal(&object)) { *errorString = "Couldn't parse value object in call argument"; return v8::MaybeLocal(); } @@ -315,7 +314,7 @@ std::unique_ptr InjectedScript::createExcep v8::Local stackTrace = message->GetStackTrace(); if (!stackTrace.IsEmpty() && stackTrace->GetFrameCount() > 0) - exceptionDetailsObject->setStackTrace(m_context->debugger()->createStackTrace(stackTrace)->buildInspectorObject()); + exceptionDetailsObject->setStackTrace(m_context->inspector()->debugger()->createStackTrace(stackTrace)->buildInspectorObjectImpl()); return exceptionDetailsObject; } @@ -353,15 +352,15 @@ v8::Local InjectedScript::commandLineAPI() return m_commandLineAPI.Get(m_context->isolate()); } -InjectedScript::Scope::Scope(ErrorString* errorString, V8DebuggerImpl* debugger, int contextGroupId) +InjectedScript::Scope::Scope(ErrorString* errorString, V8InspectorImpl* inspector, int contextGroupId) : m_errorString(errorString) - , m_debugger(debugger) + , m_inspector(inspector) , m_contextGroupId(contextGroupId) , m_injectedScript(nullptr) - , m_handleScope(debugger->isolate()) - , m_tryCatch(debugger->isolate()) + , m_handleScope(inspector->isolate()) + , m_tryCatch(inspector->isolate()) , m_ignoreExceptionsAndMuteConsole(false) - , m_previousPauseOnExceptionsState(V8DebuggerImpl::DontPauseOnExceptions) + , m_previousPauseOnExceptionsState(V8Debugger::DontPauseOnExceptions) , m_userGesture(false) { } @@ -370,7 +369,7 @@ bool InjectedScript::Scope::initialize() { cleanup(); // TODO(dgozman): what if we reattach to the same context group during evaluate? Introduce a session id? - V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_contextGroupId); + V8InspectorSessionImpl* session = m_inspector->sessionForContextGroup(m_contextGroupId); if (!session) { *m_errorString = "Internal error"; return false; @@ -394,17 +393,18 @@ void InjectedScript::Scope::ignoreExceptionsAndMuteConsole() { DCHECK(!m_ignoreExceptionsAndMuteConsole); m_ignoreExceptionsAndMuteConsole = true; - m_debugger->client()->muteWarningsAndDeprecations(m_contextGroupId); - m_previousPauseOnExceptionsState = setPauseOnExceptionsState(V8DebuggerImpl::DontPauseOnExceptions); + m_inspector->client()->muteMetrics(m_contextGroupId); + m_inspector->muteExceptions(m_contextGroupId); + m_previousPauseOnExceptionsState = setPauseOnExceptionsState(V8Debugger::DontPauseOnExceptions); } -V8DebuggerImpl::PauseOnExceptionsState InjectedScript::Scope::setPauseOnExceptionsState(V8DebuggerImpl::PauseOnExceptionsState newState) +V8Debugger::PauseOnExceptionsState InjectedScript::Scope::setPauseOnExceptionsState(V8Debugger::PauseOnExceptionsState newState) { - if (!m_debugger->enabled()) + if (!m_inspector->debugger()->enabled()) return newState; - V8DebuggerImpl::PauseOnExceptionsState presentState = m_debugger->getPauseOnExceptionsState(); + V8Debugger::PauseOnExceptionsState presentState = m_inspector->debugger()->getPauseOnExceptionsState(); if (presentState != newState) - m_debugger->setPauseOnExceptionsState(newState); + m_inspector->debugger()->setPauseOnExceptionsState(newState); return presentState; } @@ -412,7 +412,7 @@ void InjectedScript::Scope::pretendUserGesture() { DCHECK(!m_userGesture); m_userGesture = true; - m_debugger->client()->beginUserGesture(); + m_inspector->client()->beginUserGesture(); } void InjectedScript::Scope::cleanup() @@ -428,15 +428,16 @@ InjectedScript::Scope::~Scope() { if (m_ignoreExceptionsAndMuteConsole) { setPauseOnExceptionsState(m_previousPauseOnExceptionsState); - m_debugger->client()->unmuteWarningsAndDeprecations(m_contextGroupId); + m_inspector->client()->unmuteMetrics(m_contextGroupId); + m_inspector->unmuteExceptions(m_contextGroupId); } if (m_userGesture) - m_debugger->client()->endUserGesture(); + m_inspector->client()->endUserGesture(); cleanup(); } -InjectedScript::ContextScope::ContextScope(ErrorString* errorString, V8DebuggerImpl* debugger, int contextGroupId, int executionContextId) - : InjectedScript::Scope(errorString, debugger, contextGroupId) +InjectedScript::ContextScope::ContextScope(ErrorString* errorString, V8InspectorImpl* inspector, int contextGroupId, int executionContextId) + : InjectedScript::Scope(errorString, inspector, contextGroupId) , m_executionContextId(executionContextId) { } @@ -450,8 +451,8 @@ void InjectedScript::ContextScope::findInjectedScript(V8InspectorSessionImpl* se m_injectedScript = session->findInjectedScript(m_errorString, m_executionContextId); } -InjectedScript::ObjectScope::ObjectScope(ErrorString* errorString, V8DebuggerImpl* debugger, int contextGroupId, const String16& remoteObjectId) - : InjectedScript::Scope(errorString, debugger, contextGroupId) +InjectedScript::ObjectScope::ObjectScope(ErrorString* errorString, V8InspectorImpl* inspector, int contextGroupId, const String16& remoteObjectId) + : InjectedScript::Scope(errorString, inspector, contextGroupId) , m_remoteObjectId(remoteObjectId) { } @@ -474,8 +475,8 @@ void InjectedScript::ObjectScope::findInjectedScript(V8InspectorSessionImpl* ses m_injectedScript = injectedScript; } -InjectedScript::CallFrameScope::CallFrameScope(ErrorString* errorString, V8DebuggerImpl* debugger, int contextGroupId, const String16& remoteObjectId) - : InjectedScript::Scope(errorString, debugger, contextGroupId) +InjectedScript::CallFrameScope::CallFrameScope(ErrorString* errorString, V8InspectorImpl* inspector, int contextGroupId, const String16& remoteObjectId) + : InjectedScript::Scope(errorString, inspector, contextGroupId) , m_remoteCallFrameId(remoteObjectId) { } diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.h index ab847ee0412906..b65a857eb90fe6 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScript.h @@ -36,7 +36,7 @@ #include "platform/v8_inspector/InjectedScriptNative.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/V8Console.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8Debugger.h" #include "platform/v8_inspector/protocol/Runtime.h" #include @@ -45,6 +45,7 @@ namespace blink { class RemoteObjectId; class V8FunctionCall; +class V8InspectorImpl; class V8InspectorSessionImpl; namespace protocol { @@ -99,32 +100,32 @@ class InjectedScript final { const v8::TryCatch& tryCatch() const { return m_tryCatch; } protected: - Scope(ErrorString*, V8DebuggerImpl*, int contextGroupId); + Scope(ErrorString*, V8InspectorImpl*, int contextGroupId); ~Scope(); virtual void findInjectedScript(V8InspectorSessionImpl*) = 0; ErrorString* m_errorString; - V8DebuggerImpl* m_debugger; + V8InspectorImpl* m_inspector; int m_contextGroupId; InjectedScript* m_injectedScript; private: void cleanup(); - V8DebuggerImpl::PauseOnExceptionsState setPauseOnExceptionsState(V8DebuggerImpl::PauseOnExceptionsState); + V8Debugger::PauseOnExceptionsState setPauseOnExceptionsState(V8Debugger::PauseOnExceptionsState); v8::HandleScope m_handleScope; v8::TryCatch m_tryCatch; v8::Local m_context; std::unique_ptr m_commandLineAPIScope; bool m_ignoreExceptionsAndMuteConsole; - V8DebuggerImpl::PauseOnExceptionsState m_previousPauseOnExceptionsState; + V8Debugger::PauseOnExceptionsState m_previousPauseOnExceptionsState; bool m_userGesture; }; class ContextScope: public Scope { PROTOCOL_DISALLOW_COPY(ContextScope); public: - ContextScope(ErrorString*, V8DebuggerImpl*, int contextGroupId, int executionContextId); + ContextScope(ErrorString*, V8InspectorImpl*, int contextGroupId, int executionContextId); ~ContextScope(); private: void findInjectedScript(V8InspectorSessionImpl*) override; @@ -134,7 +135,7 @@ class InjectedScript final { class ObjectScope: public Scope { PROTOCOL_DISALLOW_COPY(ObjectScope); public: - ObjectScope(ErrorString*, V8DebuggerImpl*, int contextGroupId, const String16& remoteObjectId); + ObjectScope(ErrorString*, V8InspectorImpl*, int contextGroupId, const String16& remoteObjectId); ~ObjectScope(); const String16& objectGroupName() const { return m_objectGroupName; } v8::Local object() const { return m_object; } @@ -148,7 +149,7 @@ class InjectedScript final { class CallFrameScope: public Scope { PROTOCOL_DISALLOW_COPY(CallFrameScope); public: - CallFrameScope(ErrorString*, V8DebuggerImpl*, int contextGroupId, const String16& remoteCallFrameId); + CallFrameScope(ErrorString*, V8InspectorImpl*, int contextGroupId, const String16& remoteCallFrameId); ~CallFrameScope(); size_t frameOrdinal() const { return m_frameOrdinal; } private: diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptSource.js b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptSource.js index d2b3b2725ee665..7e8b2cb41ba437 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptSource.js +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InjectedScriptSource.js @@ -60,7 +60,7 @@ function push(array, var_args) */ function toString(obj) { - // We don't use String(obj) because String16 could be overridden. + // We don't use String(obj) because String could be overridden. // Also the ("" + obj) expression may throw. try { return "" + obj; @@ -115,7 +115,7 @@ function isArrayLike(obj) return false; try { if (typeof obj.splice === "function") { - if (!InjectedScriptHost.suppressWarningsAndCallFunction(Object.prototype.hasOwnProperty, obj, ["length"])) + if (!InjectedScriptHost.objectHasOwnProperty(/** @type {!Object} */ (obj), "length")) return false; var len = obj.length; return typeof len === "number" && isUInt32(len); @@ -170,12 +170,11 @@ domAttributesWithObservableSideEffectOnGet["Response"]["body"] = true; function doesAttributeHaveObservableSideEffectOnGet(object, attribute) { for (var interfaceName in domAttributesWithObservableSideEffectOnGet) { - var isInstance = InjectedScriptHost.suppressWarningsAndCallFunction(function(object, interfaceName) { - return /* suppressBlacklist */ typeof inspectedGlobalObject[interfaceName] === "function" && object instanceof inspectedGlobalObject[interfaceName]; - }, null, [object, interfaceName]); - if (isInstance) { + var interfaceFunction = inspectedGlobalObject[interfaceName]; + // instanceof call looks safe after typeof check. + var isInstance = typeof interfaceFunction === "function" && /* suppressBlacklist */ object instanceof interfaceFunction; + if (isInstance) return attribute in domAttributesWithObservableSideEffectOnGet[interfaceName]; - } } return false; } @@ -200,18 +199,17 @@ InjectedScript.primitiveTypes = { } /** - * @type {!Map} + * @type {!Object} * @const */ -InjectedScript.closureTypes = new Map([ - ["local", "Local"], - ["closure", "Closure"], - ["catch", "Catch"], - ["block", "Block"], - ["script", "Script"], - ["with", "With Block"], - ["global", "Global"] -]); +InjectedScript.closureTypes = { __proto__: null }; +InjectedScript.closureTypes["local"] = "Local"; +InjectedScript.closureTypes["closure"] = "Closure"; +InjectedScript.closureTypes["catch"] = "Catch"; +InjectedScript.closureTypes["block"] = "Block"; +InjectedScript.closureTypes["script"] = "Script"; +InjectedScript.closureTypes["with"] = "With Block"; +InjectedScript.closureTypes["global"] = "Global"; InjectedScript.prototype = { /** @@ -369,6 +367,21 @@ InjectedScript.prototype = { return descriptors; }, + /** + * @param {!Object} object + * @return {?Object} + */ + _objectPrototype: function(object) + { + if (InjectedScriptHost.subtype(object) === "proxy") + return null; + try { + return Object.getPrototypeOf(object); + } catch (e) { + return null; + } + }, + /** * @param {!Object} object * @param {boolean=} ownProperties @@ -397,12 +410,12 @@ InjectedScript.prototype = { try { propertyProcessed[property] = true; - var descriptor = nullifyObjectProto(InjectedScriptHost.suppressWarningsAndCallFunction(Object.getOwnPropertyDescriptor, Object, [o, property])); + var descriptor = nullifyObjectProto(Object.getOwnPropertyDescriptor(o, property)); if (descriptor) { if (accessorPropertiesOnly && !("get" in descriptor || "set" in descriptor)) continue; if ("get" in descriptor && "set" in descriptor && name != "__proto__" && InjectedScriptHost.formatAccessorsAsProperties(object, descriptor.get) && !doesAttributeHaveObservableSideEffectOnGet(object, name)) { - descriptor.value = InjectedScriptHost.suppressWarningsAndCallFunction(function(attribute) { return this[attribute]; }, object, [property]); + descriptor.value = object[property]; descriptor.isOwn = true; delete descriptor.get; delete descriptor.set; @@ -441,8 +454,8 @@ InjectedScript.prototype = { if (propertyNamesOnly) { for (var i = 0; i < propertyNamesOnly.length; ++i) { var name = propertyNamesOnly[i]; - for (var o = object; this._isDefined(o); o = InjectedScriptHost.prototype(o)) { - if (InjectedScriptHost.suppressWarningsAndCallFunction(Object.prototype.hasOwnProperty, o, [name])) { + for (var o = object; this._isDefined(o); o = this._objectPrototype(o)) { + if (InjectedScriptHost.objectHasOwnProperty(o, name)) { for (var descriptor of process(o, [name])) yield descriptor; break; @@ -465,11 +478,11 @@ InjectedScript.prototype = { var skipGetOwnPropertyNames; try { - skipGetOwnPropertyNames = InjectedScriptHost.isTypedArray(object) && object.length > 500000; + skipGetOwnPropertyNames = InjectedScriptHost.subtype(object) === "typedarray" && object.length > 500000; } catch (e) { } - for (var o = object; this._isDefined(o); o = InjectedScriptHost.prototype(o)) { + for (var o = object; this._isDefined(o); o = this._objectPrototype(o)) { if (InjectedScriptHost.subtype(o) === "proxy") continue; if (skipGetOwnPropertyNames && o === object) { @@ -488,7 +501,7 @@ InjectedScript.prototype = { yield descriptor; } if (ownProperties) { - var proto = InjectedScriptHost.prototype(o); + var proto = this._objectPrototype(o); if (proto && !accessorPropertiesOnly) yield { name: "__proto__", value: proto, writable: true, configurable: true, enumerable: false, isOwn: true, __proto__: null }; break; @@ -613,7 +626,7 @@ InjectedScript.prototype = { return "Proxy"; var className = InjectedScriptHost.internalConstructorName(obj); - if (subtype === "array") { + if (subtype === "array" || subtype === "typedarray") { if (typeof obj.length === "number") className += "[" + obj.length + "]"; return className; @@ -624,7 +637,8 @@ InjectedScript.prototype = { if (isSymbol(obj)) { try { - return /** @type {string} */ (InjectedScriptHost.suppressWarningsAndCallFunction(Symbol.prototype.toString, obj)) || "Symbol"; + // It isn't safe, because Symbol.prototype.toString can be overriden. + return /* suppressBlacklist */ obj.toString() || "Symbol"; } catch (e) { return "Symbol"; } @@ -655,7 +669,7 @@ InjectedScript.prototype = { return "Scopes[" + obj.length + "]"; if (subtype === "internal#scope") - return (InjectedScript.closureTypes.get(obj.type) || "Unknown") + (obj.name ? " (" + obj.name + ")" : ""); + return (InjectedScript.closureTypes[obj.type] || "Unknown") + (obj.name ? " (" + obj.name + ")" : ""); return className; }, @@ -718,13 +732,13 @@ InjectedScript.RemoteObject = function(object, objectGroupName, doNotBind, force // Provide user-friendly number values. if (this.type === "number") { this.description = toStringDescription(object); - // Override "value" property for values that can not be JSON-stringified. switch (this.description) { case "NaN": case "Infinity": case "-Infinity": case "-0": - this.value = this.description; + delete this.value; + this.unserializableValue = this.description; break; } } @@ -780,7 +794,8 @@ InjectedScript.RemoteObject.prototype = { */ function logError(error) { - Promise.resolve().then(inspectedGlobalObject.console.error.bind(inspectedGlobalObject.console, "Custom Formatter Failed: " + error.message)); + // We use user code to generate custom output for object, we can use user code for reporting error too. + Promise.resolve().then(/* suppressBlacklist */ inspectedGlobalObject.console.error.bind(inspectedGlobalObject.console, "Custom Formatter Failed: " + error.message)); } /** @@ -791,7 +806,7 @@ InjectedScript.RemoteObject.prototype = { */ function wrap(object, customObjectConfig) { - return InjectedScriptHost.suppressWarningsAndCallFunction(injectedScript._wrapObject, injectedScript, [ object, objectGroupName, false, false, null, false, false, customObjectConfig ]); + return injectedScript._wrapObject(object, objectGroupName, false, false, null, false, false, customObjectConfig); } try { @@ -915,7 +930,7 @@ InjectedScript.RemoteObject.prototype = { continue; // Ignore length property of array. - if (this.subtype === "array" && name === "length") + if ((this.subtype === "array" || this.subtype === "typedarray") && name === "length") continue; // Ignore size property of map, set. diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.cpp index 5b52e015a54363..16e0f02732265b 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.cpp @@ -6,10 +6,10 @@ #include "platform/v8_inspector/InjectedScript.h" #include "platform/v8_inspector/V8Console.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8StringUtil.h" #include "platform/v8_inspector/public/V8ContextInfo.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" namespace blink { @@ -20,7 +20,7 @@ void InspectedContext::weakCallback(const v8::WeakCallbackInfo context->m_context.Reset(); data.SetSecondPassCallback(&InspectedContext::weakCallback); } else { - context->m_debugger->discardInspectedContext(context->m_contextGroupId, context->m_contextId); + context->m_inspector->discardInspectedContext(context->m_contextGroupId, context->m_contextId); } } @@ -29,20 +29,19 @@ void InspectedContext::consoleWeakCallback(const v8::WeakCallbackInfom_console.Reset(); } -InspectedContext::InspectedContext(V8DebuggerImpl* debugger, const V8ContextInfo& info, int contextId) - : m_debugger(debugger) +InspectedContext::InspectedContext(V8InspectorImpl* inspector, const V8ContextInfo& info, int contextId) + : m_inspector(inspector) , m_context(info.context->GetIsolate(), info.context) , m_contextId(contextId) , m_contextGroupId(info.contextGroupId) - , m_isDefault(info.isDefault) , m_origin(info.origin) , m_humanReadableName(info.humanReadableName) - , m_frameId(info.frameId) + , m_auxData(info.auxData) , m_reported(false) { m_context.SetWeak(this, &InspectedContext::weakCallback, v8::WeakCallbackType::kParameter); - v8::Isolate* isolate = m_debugger->isolate(); + v8::Isolate* isolate = m_inspector->isolate(); v8::Local global = info.context->Global(); v8::Local console = V8Console::createConsole(this, info.hasMemoryOnConsole); if (!global->Set(info.context, toV8StringInternalized(isolate, "console"), console).FromMaybe(false)) @@ -66,17 +65,12 @@ v8::Local InspectedContext::context() const v8::Isolate* InspectedContext::isolate() const { - return m_debugger->isolate(); + return m_inspector->isolate(); } void InspectedContext::createInjectedScript() { DCHECK(!m_injectedScript); - v8::HandleScope handles(isolate()); - v8::Local localContext = context(); - v8::Local callingContext = isolate()->GetCallingContext(); - if (!callingContext.IsEmpty() && !m_debugger->client()->callingContextCanAccessContext(callingContext, localContext)) - return; m_injectedScript = InjectedScript::create(this); } diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.h index ecff5e4012f008..421d3dfe03a419 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/InspectedContext.h @@ -15,7 +15,7 @@ namespace blink { class InjectedScript; class InjectedScriptHost; class V8ContextInfo; -class V8DebuggerImpl; +class V8InspectorImpl; class InspectedContext { PROTOCOL_DISALLOW_COPY(InspectedContext); @@ -25,35 +25,33 @@ class InspectedContext { v8::Local context() const; int contextId() const { return m_contextId; } int contextGroupId() const { return m_contextGroupId; } - bool isDefault() const { return m_isDefault; } String16 origin() const { return m_origin; } String16 humanReadableName() const { return m_humanReadableName; } - String16 frameId() const { return m_frameId; } + String16 auxData() const { return m_auxData; } bool isReported() const { return m_reported; } void setReported(bool reported) { m_reported = reported; } v8::Isolate* isolate() const; - V8DebuggerImpl* debugger() const { return m_debugger; } + V8InspectorImpl* inspector() const { return m_inspector; } InjectedScript* getInjectedScript() { return m_injectedScript.get(); } void createInjectedScript(); void discardInjectedScript(); private: - friend class V8DebuggerImpl; - InspectedContext(V8DebuggerImpl*, const V8ContextInfo&, int contextId); + friend class V8InspectorImpl; + InspectedContext(V8InspectorImpl*, const V8ContextInfo&, int contextId); static void weakCallback(const v8::WeakCallbackInfo&); static void consoleWeakCallback(const v8::WeakCallbackInfo&); - V8DebuggerImpl* m_debugger; + V8InspectorImpl* m_inspector; v8::Global m_context; int m_contextId; int m_contextGroupId; - bool m_isDefault; const String16 m_origin; const String16 m_humanReadableName; - const String16 m_frameId; + const String16 m_auxData; bool m_reported; std::unique_ptr m_injectedScript; v8::Global m_console; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Compat.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Compat.h index 0f5b12cbb6cb07..d623da1a616f39 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Compat.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Compat.h @@ -22,7 +22,11 @@ class V8_EXPORT MicrotasksScope { }; } // namespace v8 - +#define V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, callback, data, length) \ + v8::Function::New((context), (callback), (data), (length)) +#else +#define V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, callback, data, length) \ + v8::Function::New((context), (callback), (data), (length), v8::ConstructorBehavior::kThrow) #endif // V8_MAJOR_VERSION < 5 || (V8_MAJOR_VERSION == 5 && V8_MINOR_VERSION < 1) #endif // V8Compat_h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Console.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Console.cpp index f7e142deeadbf3..1bd738a8660aea 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Console.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Console.cpp @@ -11,13 +11,13 @@ #include "platform/v8_inspector/V8Compat.h" #include "platform/v8_inspector/V8ConsoleMessage.h" #include "platform/v8_inspector/V8DebuggerAgentImpl.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8ProfilerAgentImpl.h" #include "platform/v8_inspector/V8RuntimeAgentImpl.h" #include "platform/v8_inspector/V8StackTraceImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" namespace blink { @@ -36,7 +36,7 @@ class ConsoleHelper { , m_isolate(info.GetIsolate()) , m_context(info.GetIsolate()->GetCurrentContext()) , m_inspectedContext(nullptr) - , m_debuggerClient(nullptr) + , m_inspectorClient(nullptr) { } @@ -65,15 +65,15 @@ class ConsoleHelper { return m_inspectedContext; } - V8DebuggerClient* ensureDebuggerClient() + V8InspectorClient* ensureDebuggerClient() { - if (m_debuggerClient) - return m_debuggerClient; + if (m_inspectorClient) + return m_inspectorClient; InspectedContext* inspectedContext = ensureInspectedContext(); if (!inspectedContext) return nullptr; - m_debuggerClient = inspectedContext->debugger()->client(); - return m_debuggerClient; + m_inspectorClient = inspectedContext->inspector()->client(); + return m_inspectorClient; } void reportCall(ConsoleAPIType type) @@ -107,9 +107,9 @@ class ConsoleHelper { InspectedContext* inspectedContext = ensureInspectedContext(); if (!inspectedContext) return; - V8DebuggerImpl* debugger = inspectedContext->debugger(); - std::unique_ptr message = V8ConsoleMessage::createForConsoleAPI(debugger->client()->currentTimeMS(), type, arguments, debugger->captureStackTrace(false), inspectedContext); - debugger->ensureConsoleMessageStorage(inspectedContext->contextGroupId())->addMessage(std::move(message)); + V8InspectorImpl* inspector = inspectedContext->inspector(); + std::unique_ptr message = V8ConsoleMessage::createForConsoleAPI(inspector->client()->currentTimeMS(), type, arguments, inspector->debugger()->captureStackTrace(false), inspectedContext); + inspector->ensureConsoleMessageStorage(inspectedContext->contextGroupId())->addMessage(std::move(message)); } void reportDeprecatedCall(const char* id, const String16& message) @@ -233,7 +233,7 @@ class ConsoleHelper { InspectedContext* inspectedContext = ensureInspectedContext(); if (!inspectedContext) return nullptr; - return inspectedContext->debugger()->sessionForContextGroup(inspectedContext->contextGroupId()); + return inspectedContext->inspector()->sessionForContextGroup(inspectedContext->contextGroupId()); } private: @@ -242,7 +242,7 @@ class ConsoleHelper { v8::Local m_context; v8::Local m_console; InspectedContext* m_inspectedContext; - V8DebuggerClient* m_debuggerClient; + V8InspectorClient* m_inspectorClient; bool checkAndSetPrivateFlagOnConsole(const char* name, bool defaultValue) { @@ -271,13 +271,13 @@ void createBoundFunctionProperty(v8::Local context, v8::Local funcName = toV8StringInternalized(context->GetIsolate(), name); v8::Local func; - if (!v8::Function::New(context, callback, console, 0, v8::ConstructorBehavior::kThrow).ToLocal(&func)) + if (!V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, callback, console, 0).ToLocal(&func)) return; func->SetName(funcName); if (description) { v8::Local returnValue = toV8String(context->GetIsolate(), description); v8::Local toStringFunction; - if (v8::Function::New(context, returnDataCallback, returnValue, 0, v8::ConstructorBehavior::kThrow).ToLocal(&toStringFunction)) + if (V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, returnDataCallback, returnValue, 0).ToLocal(&toStringFunction)) func->Set(toV8StringInternalized(context->GetIsolate(), "toString"), toStringFunction); } if (!console->Set(context, funcName, func).FromMaybe(false)) @@ -413,7 +413,7 @@ void V8Console::profileEndCallback(const v8::FunctionCallbackInfo& in static void timeFunction(const v8::FunctionCallbackInfo& info, bool timelinePrefix) { ConsoleHelper helper(info); - if (V8DebuggerClient* client = helper.ensureDebuggerClient()) { + if (V8InspectorClient* client = helper.ensureDebuggerClient()) { String16 protocolTitle = helper.firstArgToString("default"); if (timelinePrefix) protocolTitle = "Timeline '" + protocolTitle + "'"; @@ -429,7 +429,7 @@ static void timeFunction(const v8::FunctionCallbackInfo& info, bool t static void timeEndFunction(const v8::FunctionCallbackInfo& info, bool timelinePrefix) { ConsoleHelper helper(info); - if (V8DebuggerClient* client = helper.ensureDebuggerClient()) { + if (V8InspectorClient* client = helper.ensureDebuggerClient()) { String16 protocolTitle = helper.firstArgToString("default"); if (timelinePrefix) protocolTitle = "Timeline '" + protocolTitle + "'"; @@ -469,13 +469,13 @@ void V8Console::timeEndCallback(const v8::FunctionCallbackInfo& info) void V8Console::timeStampCallback(const v8::FunctionCallbackInfo& info) { ConsoleHelper helper(info); - if (V8DebuggerClient* client = helper.ensureDebuggerClient()) + if (V8InspectorClient* client = helper.ensureDebuggerClient()) client->consoleTimeStamp(helper.firstArgToString(String16())); } void V8Console::memoryGetterCallback(const v8::FunctionCallbackInfo& info) { - if (V8DebuggerClient* client = ConsoleHelper(info).ensureDebuggerClient()) { + if (V8InspectorClient* client = ConsoleHelper(info).ensureDebuggerClient()) { v8::Local memoryValue; if (!client->memoryInfo(info.GetIsolate(), info.GetIsolate()->GetCurrentContext()).ToLocal(&memoryValue)) return; @@ -656,6 +656,7 @@ void V8Console::inspectedObject(const v8::FunctionCallbackInfo& info, v8::Local V8Console::createConsole(InspectedContext* inspectedContext, bool hasMemoryAttribute) { v8::Local context = inspectedContext->context(); + v8::Context::Scope contextScope(context); v8::Isolate* isolate = context->GetIsolate(); v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); @@ -689,7 +690,7 @@ v8::Local V8Console::createConsole(InspectedContext* inspectedContex DCHECK(success); if (hasMemoryAttribute) - console->SetAccessorProperty(toV8StringInternalized(isolate, "memory"), v8::Function::New(context, V8Console::memoryGetterCallback, console, 0, v8::ConstructorBehavior::kThrow).ToLocalChecked(), v8::Function::New(context, V8Console::memorySetterCallback, v8::Local(), 0, v8::ConstructorBehavior::kThrow).ToLocalChecked(), static_cast(v8::None), v8::DEFAULT); + console->SetAccessorProperty(toV8StringInternalized(isolate, "memory"), V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, V8Console::memoryGetterCallback, console, 0).ToLocalChecked(), V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, V8Console::memorySetterCallback, v8::Local(), 0).ToLocalChecked(), static_cast(v8::None), v8::DEFAULT); console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::External::New(isolate, inspectedContext)); return console; @@ -731,7 +732,7 @@ v8::Local V8Console::createCommandLineAPI(InspectedContext* inspecte createBoundFunctionProperty(context, commandLineAPI, "$3", V8Console::inspectedObject3); createBoundFunctionProperty(context, commandLineAPI, "$4", V8Console::inspectedObject4); - inspectedContext->debugger()->client()->installAdditionalCommandLineAPI(context, commandLineAPI); + inspectedContext->inspector()->client()->installAdditionalCommandLineAPI(context, commandLineAPI); commandLineAPI->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::External::New(isolate, inspectedContext)); return commandLineAPI; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.cpp index ab4017532f4bd8..0292dbb4ca6ba6 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleAgentImpl.cpp @@ -5,7 +5,7 @@ #include "platform/v8_inspector/V8ConsoleAgentImpl.h" #include "platform/v8_inspector/V8ConsoleMessage.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8StackTraceImpl.h" @@ -33,7 +33,7 @@ void V8ConsoleAgentImpl::enable(ErrorString* errorString) return; m_state->setBoolean(ConsoleAgentState::consoleEnabled, true); m_enabled = true; - m_session->debugger()->enableStackCapturingIfNeeded(); + m_session->inspector()->enableStackCapturingIfNeeded(); reportAllMessages(); } @@ -41,7 +41,7 @@ void V8ConsoleAgentImpl::disable(ErrorString* errorString) { if (!m_enabled) return; - m_session->debugger()->disableStackCapturingIfNeeded(); + m_session->inspector()->disableStackCapturingIfNeeded(); m_state->setBoolean(ConsoleAgentState::consoleEnabled, false); m_enabled = false; } @@ -71,7 +71,7 @@ bool V8ConsoleAgentImpl::enabled() void V8ConsoleAgentImpl::reportAllMessages() { - V8ConsoleMessageStorage* storage = m_session->debugger()->ensureConsoleMessageStorage(m_session->contextGroupId()); + V8ConsoleMessageStorage* storage = m_session->inspector()->ensureConsoleMessageStorage(m_session->contextGroupId()); for (const auto& message : storage->messages()) { if (message->origin() == V8MessageOrigin::kConsole) reportMessage(message.get(), false); diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.cpp index 42fe95bdfcd890..84bcc3d6e54df6 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.cpp @@ -6,12 +6,12 @@ #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/V8ConsoleAgentImpl.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8RuntimeAgentImpl.h" #include "platform/v8_inspector/V8StackTraceImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" namespace blink { @@ -191,7 +191,7 @@ V8ConsoleMessage::~V8ConsoleMessage() { } -void V8ConsoleMessage::setLocation(const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId) +void V8ConsoleMessage::setLocation(const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId) { m_url = url; m_lineNumber = lineNumber; @@ -219,7 +219,7 @@ std::unique_ptr> V8ConsoleMessa { if (!m_arguments.size() || !m_contextId) return nullptr; - InspectedContext* inspectedContext = session->debugger()->getContext(session->contextGroupId(), m_contextId); + InspectedContext* inspectedContext = session->inspector()->getContext(session->contextGroupId(), m_contextId); if (!inspectedContext) return nullptr; @@ -252,9 +252,10 @@ std::unique_ptr> V8ConsoleMessa void V8ConsoleMessage::reportToFrontend(protocol::Runtime::Frontend* frontend, V8InspectorSessionImpl* session, bool generatePreview) const { if (m_origin == V8MessageOrigin::kException) { + std::unique_ptr exception = wrapException(session, generatePreview); // TODO(dgozman): unify with InjectedScript::createExceptionDetails. std::unique_ptr details = protocol::Runtime::ExceptionDetails::create() - .setText(m_message) + .setText(exception ? m_message : m_detailedMessage) .setLineNumber(m_lineNumber ? m_lineNumber - 1 : 0) .setColumnNumber(m_columnNumber ? m_columnNumber - 1 : 0) .setScriptId(m_scriptId ? String16::fromInteger(m_scriptId) : String16()) @@ -262,9 +263,7 @@ void V8ConsoleMessage::reportToFrontend(protocol::Runtime::Frontend* frontend, V if (!m_url.isEmpty()) details->setUrl(m_url); if (m_stackTrace) - details->setStackTrace(m_stackTrace->buildInspectorObject()); - - std::unique_ptr exception = wrapException(session, generatePreview); + details->setStackTrace(m_stackTrace->buildInspectorObjectImpl()); if (exception) frontend->exceptionThrown(m_exceptionId, m_timestamp, std::move(details), std::move(exception), m_contextId); @@ -286,7 +285,7 @@ void V8ConsoleMessage::reportToFrontend(protocol::Runtime::Frontend* frontend, V arguments->addItem(std::move(messageArg)); } } - frontend->consoleAPICalled(consoleAPITypeValue(m_type), std::move(arguments), m_contextId, m_timestamp, m_stackTrace ? m_stackTrace->buildInspectorObject() : nullptr); + frontend->consoleAPICalled(consoleAPITypeValue(m_type), std::move(arguments), m_contextId, m_timestamp, m_stackTrace ? m_stackTrace->buildInspectorObjectImpl() : nullptr); return; } NOTREACHED(); @@ -297,7 +296,7 @@ std::unique_ptr V8ConsoleMessage::wrapException if (!m_arguments.size() || !m_contextId) return nullptr; DCHECK_EQ(1u, m_arguments.size()); - InspectedContext* inspectedContext = session->debugger()->getContext(session->contextGroupId(), m_contextId); + InspectedContext* inspectedContext = session->inspector()->getContext(session->contextGroupId(), m_contextId); if (!inspectedContext) return nullptr; @@ -318,7 +317,7 @@ ConsoleAPIType V8ConsoleMessage::type() const } // static -std::unique_ptr V8ConsoleMessage::createForConsoleAPI(double timestamp, ConsoleAPIType type, const std::vector>& arguments, std::unique_ptr stackTrace, InspectedContext* context) +std::unique_ptr V8ConsoleMessage::createForConsoleAPI(double timestamp, ConsoleAPIType type, const std::vector>& arguments, std::unique_ptr stackTrace, InspectedContext* context) { std::unique_ptr message = wrapUnique(new V8ConsoleMessage(V8MessageOrigin::kConsole, timestamp, String16())); if (stackTrace && !stackTrace->isEmpty()) { @@ -334,31 +333,34 @@ std::unique_ptr V8ConsoleMessage::createForConsoleAPI(double t if (arguments.size()) message->m_message = V8ValueStringBuilder::toString(arguments[0], context->isolate()); - MessageLevel level = LogMessageLevel; + V8ConsoleAPIType clientType = V8ConsoleAPIType::kLog; if (type == ConsoleAPIType::kDebug || type == ConsoleAPIType::kCount || type == ConsoleAPIType::kTimeEnd) - level = DebugMessageLevel; - if (type == ConsoleAPIType::kError || type == ConsoleAPIType::kAssert) - level = ErrorMessageLevel; - if (type == ConsoleAPIType::kWarning) - level = WarningMessageLevel; - if (type == ConsoleAPIType::kInfo) - level = InfoMessageLevel; - context->debugger()->client()->consoleAPIMessage(context->contextGroupId(), level, message->m_message, message->m_url, message->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get()); + clientType = V8ConsoleAPIType::kDebug; + else if (type == ConsoleAPIType::kError || type == ConsoleAPIType::kAssert) + clientType = V8ConsoleAPIType::kError; + else if (type == ConsoleAPIType::kWarning) + clientType = V8ConsoleAPIType::kWarning; + else if (type == ConsoleAPIType::kInfo) + clientType = V8ConsoleAPIType::kInfo; + else if (type == ConsoleAPIType::kClear) + clientType = V8ConsoleAPIType::kClear; + context->inspector()->client()->consoleAPIMessage(context->contextGroupId(), clientType, message->m_message, message->m_url, message->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get()); return message; } // static -std::unique_ptr V8ConsoleMessage::createForException(double timestamp, const String16& messageText, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId, v8::Isolate* isolate, int contextId, v8::Local exception, unsigned exceptionId) +std::unique_ptr V8ConsoleMessage::createForException(double timestamp, const String16& detailedMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId, v8::Isolate* isolate, const String16& message, int contextId, v8::Local exception, unsigned exceptionId) { - std::unique_ptr message = wrapUnique(new V8ConsoleMessage(V8MessageOrigin::kException, timestamp, messageText)); - message->setLocation(url, lineNumber, columnNumber, std::move(stackTrace), scriptId); - message->m_exceptionId = exceptionId; + std::unique_ptr consoleMessage = wrapUnique(new V8ConsoleMessage(V8MessageOrigin::kException, timestamp, message)); + consoleMessage->setLocation(url, lineNumber, columnNumber, std::move(stackTrace), scriptId); + consoleMessage->m_exceptionId = exceptionId; + consoleMessage->m_detailedMessage = detailedMessage; if (contextId && !exception.IsEmpty()) { - message->m_contextId = contextId; - message->m_arguments.push_back(wrapUnique(new v8::Global(isolate, exception))); + consoleMessage->m_contextId = contextId; + consoleMessage->m_arguments.push_back(wrapUnique(new v8::Global(isolate, exception))); } - return message; + return consoleMessage; } // static @@ -382,8 +384,8 @@ void V8ConsoleMessage::contextDestroyed(int contextId) // ------------------------ V8ConsoleMessageStorage ---------------------------- -V8ConsoleMessageStorage::V8ConsoleMessageStorage(V8DebuggerImpl* debugger, int contextGroupId) - : m_debugger(debugger) +V8ConsoleMessageStorage::V8ConsoleMessageStorage(V8InspectorImpl* inspector, int contextGroupId) + : m_inspector(inspector) , m_contextGroupId(contextGroupId) , m_expiredCount(0) { @@ -392,17 +394,14 @@ V8ConsoleMessageStorage::V8ConsoleMessageStorage(V8DebuggerImpl* debugger, int c V8ConsoleMessageStorage::~V8ConsoleMessageStorage() { clear(); - notifyClear(); } void V8ConsoleMessageStorage::addMessage(std::unique_ptr message) { - if (message->type() == ConsoleAPIType::kClear) { + if (message->type() == ConsoleAPIType::kClear) clear(); - notifyClear(); - } - V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_contextGroupId); + V8InspectorSessionImpl* session = m_inspector->sessionForContextGroup(m_contextGroupId); if (session) { if (message->origin() == V8MessageOrigin::kConsole) session->consoleAgent()->messageAdded(message.get()); @@ -421,7 +420,7 @@ void V8ConsoleMessageStorage::clear() { m_messages.clear(); m_expiredCount = 0; - if (V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_contextGroupId)) + if (V8InspectorSessionImpl* session = m_inspector->sessionForContextGroup(m_contextGroupId)) session->releaseObjectGroup("console"); } @@ -431,10 +430,4 @@ void V8ConsoleMessageStorage::contextDestroyed(int contextId) m_messages[i]->contextDestroyed(contextId); } -void V8ConsoleMessageStorage::notifyClear() -{ - if (V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_contextGroupId)) - session->client()->consoleCleared(); -} - } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.h index 923a84e9269080..9c26f5d9e8f3ea 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ConsoleMessage.h @@ -9,17 +9,15 @@ #include "platform/inspector_protocol/String16.h" #include "platform/v8_inspector/protocol/Console.h" #include "platform/v8_inspector/protocol/Runtime.h" -#include "platform/v8_inspector/public/V8ConsoleTypes.h" -#include "platform/v8_inspector/public/V8StackTrace.h" #include #include namespace blink { class InspectedContext; -class V8DebuggerImpl; +class V8InspectorImpl; class V8InspectorSessionImpl; -class V8StackTrace; +class V8StackTraceImpl; enum class V8MessageOrigin { kConsole, kException, kRevokedException }; @@ -33,18 +31,19 @@ class V8ConsoleMessage { double timestamp, ConsoleAPIType, const std::vector>& arguments, - std::unique_ptr, + std::unique_ptr, InspectedContext*); static std::unique_ptr createForException( double timestamp, - const String16& message, + const String16& detailedMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, - std::unique_ptr, + std::unique_ptr, int scriptId, v8::Isolate*, + const String16& message, int contextId, v8::Local exception, unsigned exceptionId); @@ -66,7 +65,7 @@ class V8ConsoleMessage { using Arguments = std::vector>>; std::unique_ptr> wrapArguments(V8InspectorSessionImpl*, bool generatePreview) const; std::unique_ptr wrapException(V8InspectorSessionImpl*, bool generatePreview) const; - void setLocation(const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId); + void setLocation(const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId); V8MessageOrigin m_origin; double m_timestamp; @@ -74,18 +73,19 @@ class V8ConsoleMessage { String16 m_url; unsigned m_lineNumber; unsigned m_columnNumber; - std::unique_ptr m_stackTrace; + std::unique_ptr m_stackTrace; int m_scriptId; int m_contextId; ConsoleAPIType m_type; unsigned m_exceptionId; unsigned m_revokedExceptionId; Arguments m_arguments; + String16 m_detailedMessage; }; class V8ConsoleMessageStorage { public: - V8ConsoleMessageStorage(V8DebuggerImpl*, int contextGroupId); + V8ConsoleMessageStorage(V8InspectorImpl*, int contextGroupId); ~V8ConsoleMessageStorage(); int contextGroupId() { return m_contextGroupId; } @@ -97,9 +97,7 @@ class V8ConsoleMessageStorage { void clear(); private: - void notifyClear(); - - V8DebuggerImpl* m_debugger; + V8InspectorImpl* m_inspector; int m_contextGroupId; int m_expiredCount; std::deque> m_messages; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Debugger.cpp similarity index 53% rename from deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.cpp rename to deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Debugger.cpp index 4d84b32cece21b..a7ebd019f94903 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Debugger.cpp @@ -1,59 +1,24 @@ -/* - * Copyright (c) 2010-2011 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "platform/v8_inspector/V8DebuggerImpl.h" - -#include "platform/inspector_protocol/Values.h" -#include "platform/v8_inspector/Atomics.h" +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/v8_inspector/V8Debugger.h" + #include "platform/v8_inspector/DebuggerScript.h" -#include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/ScriptBreakpoint.h" #include "platform/v8_inspector/V8Compat.h" -#include "platform/v8_inspector/V8ConsoleAgentImpl.h" -#include "platform/v8_inspector/V8ConsoleMessage.h" #include "platform/v8_inspector/V8DebuggerAgentImpl.h" -#include "platform/v8_inspector/V8InjectedScriptHost.h" -#include "platform/v8_inspector/V8InspectorSessionImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InternalValueType.h" -#include "platform/v8_inspector/V8RuntimeAgentImpl.h" #include "platform/v8_inspector/V8StackTraceImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" -#include +#include "platform/v8_inspector/public/V8InspectorClient.h" namespace blink { namespace { const char stepIntoV8MethodName[] = "stepIntoStatement"; const char stepOutV8MethodName[] = "stepOutOfFunction"; -volatile int s_lastContextId = 0; static const char v8AsyncTaskEventEnqueue[] = "enqueue"; static const char v8AsyncTaskEventWillHandle[] = "willHandle"; static const char v8AsyncTaskEventDidHandle[] = "didHandle"; @@ -67,47 +32,46 @@ inline v8::Local v8Boolean(bool value, v8::Isolate* isolate) static bool inLiveEditScope = false; -v8::MaybeLocal V8DebuggerImpl::callDebuggerMethod(const char* functionName, int argc, v8::Local argv[]) +v8::MaybeLocal V8Debugger::callDebuggerMethod(const char* functionName, int argc, v8::Local argv[]) { v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); v8::Local debuggerScript = m_debuggerScript.Get(m_isolate); - v8::Local function = v8::Local::Cast(debuggerScript->Get(v8InternalizedString(functionName))); + v8::Local function = v8::Local::Cast(debuggerScript->Get(toV8StringInternalized(m_isolate, functionName))); DCHECK(m_isolate->InContext()); return function->Call(m_isolate->GetCurrentContext(), debuggerScript, argc, argv); } -std::unique_ptr V8Debugger::create(v8::Isolate* isolate, V8DebuggerClient* client) -{ - return wrapUnique(new V8DebuggerImpl(isolate, client)); -} - -V8DebuggerImpl::V8DebuggerImpl(v8::Isolate* isolate, V8DebuggerClient* client) +V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector) : m_isolate(isolate) - , m_client(client) - , m_capturingStackTracesCount(0) - , m_lastExceptionId(0) - , m_enabledAgentsCount(0) + , m_inspector(inspector) + , m_lastContextId(0) + , m_enableCount(0) , m_breakpointsActivated(true) , m_runningNestedMessageLoop(false) + , m_ignoreScriptParsedEventsCounter(0) , m_maxAsyncCallStackDepth(0) { } -V8DebuggerImpl::~V8DebuggerImpl() +V8Debugger::~V8Debugger() { } -void V8DebuggerImpl::enable() +void V8Debugger::enable() { + if (m_enableCount++) + return; DCHECK(!enabled()); v8::HandleScope scope(m_isolate); - v8::Debug::SetDebugEventListener(m_isolate, &V8DebuggerImpl::v8DebugEventCallback, v8::External::New(m_isolate, this)); + v8::Debug::SetDebugEventListener(m_isolate, &V8Debugger::v8DebugEventCallback, v8::External::New(m_isolate, this)); m_debuggerContext.Reset(m_isolate, v8::Debug::GetDebugContext(m_isolate)); compileDebuggerScript(); } -void V8DebuggerImpl::disable() +void V8Debugger::disable() { + if (--m_enableCount) + return; DCHECK(enabled()); clearBreakpoints(); m_debuggerScript.Reset(); @@ -116,13 +80,13 @@ void V8DebuggerImpl::disable() v8::Debug::SetDebugEventListener(m_isolate, nullptr); } -bool V8DebuggerImpl::enabled() const +bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } // static -int V8DebuggerImpl::contextId(v8::Local context) +int V8Debugger::contextId(v8::Local context) { v8::Local data = context->GetEmbedderData(static_cast(v8::Context::kDebugIdIndex)); if (data.IsEmpty() || !data->IsString()) @@ -140,7 +104,7 @@ int V8DebuggerImpl::contextId(v8::Local context) } // static -int V8DebuggerImpl::getGroupId(v8::Local context) +int V8Debugger::getGroupId(v8::Local context) { v8::Local data = context->GetEmbedderData(static_cast(v8::Context::kDebugIdIndex)); if (data.IsEmpty() || !data->IsString()) @@ -154,43 +118,13 @@ int V8DebuggerImpl::getGroupId(v8::Local context) return dataString.substring(0, commaPos).toInt(); } -void V8DebuggerImpl::debuggerAgentEnabled() -{ - if (!m_enabledAgentsCount++) - enable(); -} - -void V8DebuggerImpl::debuggerAgentDisabled() -{ - if (!--m_enabledAgentsCount) - disable(); -} - -V8DebuggerAgentImpl* V8DebuggerImpl::findEnabledDebuggerAgent(int contextGroupId) -{ - if (!contextGroupId) - return nullptr; - SessionMap::iterator it = m_sessions.find(contextGroupId); - if (it == m_sessions.end()) - return nullptr; - V8DebuggerAgentImpl* agent = it->second->debuggerAgent(); - if (!agent->enabled()) - return nullptr; - return agent; -} - -V8DebuggerAgentImpl* V8DebuggerImpl::findEnabledDebuggerAgent(v8::Local context) -{ - return findEnabledDebuggerAgent(getGroupId(context)); -} - -void V8DebuggerImpl::getCompiledScripts(int contextGroupId, std::vector>& result) +void V8Debugger::getCompiledScripts(int contextGroupId, std::vector>& result) { v8::HandleScope scope(m_isolate); v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); v8::Local debuggerScript = m_debuggerScript.Get(m_isolate); DCHECK(!debuggerScript->IsUndefined()); - v8::Local getScriptsFunction = v8::Local::Cast(debuggerScript->Get(v8InternalizedString("getScripts"))); + v8::Local getScriptsFunction = v8::Local::Cast(debuggerScript->Get(toV8StringInternalized(m_isolate, "getScripts"))); v8::Local argv[] = { v8::Integer::New(m_isolate, contextGroupId) }; v8::Local value; if (!getScriptsFunction->Call(debuggerContext(), debuggerScript, PROTOCOL_ARRAY_LENGTH(argv), argv).ToLocal(&value)) @@ -204,49 +138,49 @@ void V8DebuggerImpl::getCompiledScripts(int contextGroupId, std::vector info = v8::Object::New(m_isolate); - info->Set(v8InternalizedString("sourceID"), toV8String(m_isolate, sourceID)); - info->Set(v8InternalizedString("lineNumber"), v8::Integer::New(m_isolate, scriptBreakpoint.lineNumber)); - info->Set(v8InternalizedString("columnNumber"), v8::Integer::New(m_isolate, scriptBreakpoint.columnNumber)); - info->Set(v8InternalizedString("interstatementLocation"), v8Boolean(interstatementLocation, m_isolate)); - info->Set(v8InternalizedString("condition"), toV8String(m_isolate, scriptBreakpoint.condition)); + info->Set(toV8StringInternalized(m_isolate, "sourceID"), toV8String(m_isolate, sourceID)); + info->Set(toV8StringInternalized(m_isolate, "lineNumber"), v8::Integer::New(m_isolate, scriptBreakpoint.lineNumber)); + info->Set(toV8StringInternalized(m_isolate, "columnNumber"), v8::Integer::New(m_isolate, scriptBreakpoint.columnNumber)); + info->Set(toV8StringInternalized(m_isolate, "interstatementLocation"), v8Boolean(interstatementLocation, m_isolate)); + info->Set(toV8StringInternalized(m_isolate, "condition"), toV8String(m_isolate, scriptBreakpoint.condition)); - v8::Local setBreakpointFunction = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("setBreakpoint"))); + v8::Local setBreakpointFunction = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate, "setBreakpoint"))); v8::Local breakpointId = v8::Debug::Call(debuggerContext(), setBreakpointFunction, info).ToLocalChecked(); if (!breakpointId->IsString()) return ""; - *actualLineNumber = info->Get(v8InternalizedString("lineNumber"))->Int32Value(); - *actualColumnNumber = info->Get(v8InternalizedString("columnNumber"))->Int32Value(); + *actualLineNumber = info->Get(toV8StringInternalized(m_isolate, "lineNumber"))->Int32Value(); + *actualColumnNumber = info->Get(toV8StringInternalized(m_isolate, "columnNumber"))->Int32Value(); return toProtocolString(breakpointId.As()); } -void V8DebuggerImpl::removeBreakpoint(const String16& breakpointId) +void V8Debugger::removeBreakpoint(const String16& breakpointId) { v8::HandleScope scope(m_isolate); v8::Context::Scope contextScope(debuggerContext()); v8::Local info = v8::Object::New(m_isolate); - info->Set(v8InternalizedString("breakpointId"), toV8String(m_isolate, breakpointId)); + info->Set(toV8StringInternalized(m_isolate, "breakpointId"), toV8String(m_isolate, breakpointId)); - v8::Local removeBreakpointFunction = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("removeBreakpoint"))); + v8::Local removeBreakpointFunction = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate, "removeBreakpoint"))); v8::Debug::Call(debuggerContext(), removeBreakpointFunction, info).ToLocalChecked(); } -void V8DebuggerImpl::clearBreakpoints() +void V8Debugger::clearBreakpoints() { v8::HandleScope scope(m_isolate); v8::Context::Scope contextScope(debuggerContext()); - v8::Local clearBreakpoints = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("clearBreakpoints"))); + v8::Local clearBreakpoints = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate, "clearBreakpoints"))); v8::Debug::Call(debuggerContext(), clearBreakpoints).ToLocalChecked(); } -void V8DebuggerImpl::setBreakpointsActivated(bool activated) +void V8Debugger::setBreakpointsActivated(bool activated) { if (!enabled()) { NOTREACHED(); @@ -256,14 +190,14 @@ void V8DebuggerImpl::setBreakpointsActivated(bool activated) v8::Context::Scope contextScope(debuggerContext()); v8::Local info = v8::Object::New(m_isolate); - info->Set(v8InternalizedString("enabled"), v8::Boolean::New(m_isolate, activated)); - v8::Local setBreakpointsActivated = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("setBreakpointsActivated"))); + info->Set(toV8StringInternalized(m_isolate, "enabled"), v8::Boolean::New(m_isolate, activated)); + v8::Local setBreakpointsActivated = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate, "setBreakpointsActivated"))); v8::Debug::Call(debuggerContext(), setBreakpointsActivated, info).ToLocalChecked(); m_breakpointsActivated = activated; } -V8DebuggerImpl::PauseOnExceptionsState V8DebuggerImpl::getPauseOnExceptionsState() +V8Debugger::PauseOnExceptionsState V8Debugger::getPauseOnExceptionsState() { DCHECK(enabled()); v8::HandleScope scope(m_isolate); @@ -271,10 +205,10 @@ V8DebuggerImpl::PauseOnExceptionsState V8DebuggerImpl::getPauseOnExceptionsState v8::Local argv[] = { v8::Undefined(m_isolate) }; v8::Local result = callDebuggerMethod("pauseOnExceptionsState", 0, argv).ToLocalChecked(); - return static_cast(result->Int32Value()); + return static_cast(result->Int32Value()); } -void V8DebuggerImpl::setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState) +void V8Debugger::setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExceptionsState) { DCHECK(enabled()); v8::HandleScope scope(m_isolate); @@ -284,7 +218,7 @@ void V8DebuggerImpl::setPauseOnExceptionsState(PauseOnExceptionsState pauseOnExc callDebuggerMethod("setPauseOnExceptionsState", 1, argv); } -void V8DebuggerImpl::setPauseOnNextStatement(bool pause) +void V8Debugger::setPauseOnNextStatement(bool pause) { if (m_runningNestedMessageLoop) return; @@ -294,14 +228,14 @@ void V8DebuggerImpl::setPauseOnNextStatement(bool pause) v8::Debug::CancelDebugBreak(m_isolate); } -bool V8DebuggerImpl::canBreakProgram() +bool V8Debugger::canBreakProgram() { if (!m_breakpointsActivated) return false; return m_isolate->InContext(); } -void V8DebuggerImpl::breakProgram() +void V8Debugger::breakProgram() { if (isPaused()) { DCHECK(!m_runningNestedMessageLoop); @@ -316,20 +250,20 @@ void V8DebuggerImpl::breakProgram() v8::HandleScope scope(m_isolate); v8::Local breakFunction; - if (!v8::Function::New(m_isolate->GetCurrentContext(), &V8DebuggerImpl::breakProgramCallback, v8::External::New(m_isolate, this), 0, v8::ConstructorBehavior::kThrow).ToLocal(&breakFunction)) + if (!V8_FUNCTION_NEW_REMOVE_PROTOTYPE(m_isolate->GetCurrentContext(), &V8Debugger::breakProgramCallback, v8::External::New(m_isolate, this), 0).ToLocal(&breakFunction)) return; v8::Debug::Call(debuggerContext(), breakFunction).ToLocalChecked(); } -void V8DebuggerImpl::continueProgram() +void V8Debugger::continueProgram() { if (isPaused()) - m_client->quitMessageLoopOnPause(); + m_inspector->client()->quitMessageLoopOnPause(); m_pausedContext.Clear(); m_executionState.Clear(); } -void V8DebuggerImpl::stepIntoStatement() +void V8Debugger::stepIntoStatement() { DCHECK(isPaused()); DCHECK(!m_executionState.IsEmpty()); @@ -339,7 +273,7 @@ void V8DebuggerImpl::stepIntoStatement() continueProgram(); } -void V8DebuggerImpl::stepOverStatement() +void V8Debugger::stepOverStatement() { DCHECK(isPaused()); DCHECK(!m_executionState.IsEmpty()); @@ -349,7 +283,7 @@ void V8DebuggerImpl::stepOverStatement() continueProgram(); } -void V8DebuggerImpl::stepOutOfFunction() +void V8Debugger::stepOutOfFunction() { DCHECK(isPaused()); DCHECK(!m_executionState.IsEmpty()); @@ -359,7 +293,7 @@ void V8DebuggerImpl::stepOutOfFunction() continueProgram(); } -void V8DebuggerImpl::clearStepping() +void V8Debugger::clearStepping() { DCHECK(enabled()); v8::HandleScope scope(m_isolate); @@ -369,7 +303,7 @@ void V8DebuggerImpl::clearStepping() callDebuggerMethod("clearStepping", 0, argv); } -bool V8DebuggerImpl::setScriptSource(const String16& sourceID, v8::Local newSource, bool preview, ErrorString* error, Maybe* exceptionDetails, JavaScriptCallFrames* newCallFrames, Maybe* stackChanged) +bool V8Debugger::setScriptSource(const String16& sourceID, v8::Local newSource, bool preview, ErrorString* error, Maybe* exceptionDetails, JavaScriptCallFrames* newCallFrames, Maybe* stackChanged) { class EnableLiveEditScope { public: @@ -441,13 +375,13 @@ bool V8DebuggerImpl::setScriptSource(const String16& sourceID, v8::LocalInContext()) return JavaScriptCallFrames(); v8::Local currentCallFramesV8; if (m_executionState.IsEmpty()) { - v8::Local currentCallFramesFunction = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(v8InternalizedString("currentCallFrames"))); + v8::Local currentCallFramesFunction = v8::Local::Cast(m_debuggerScript.Get(m_isolate)->Get(toV8StringInternalized(m_isolate, "currentCallFrames"))); currentCallFramesV8 = v8::Debug::Call(debuggerContext(), currentCallFramesFunction, v8::Integer::New(m_isolate, limit)).ToLocalChecked(); } else { v8::Local argv[] = { m_executionState, v8::Integer::New(m_isolate, limit) }; @@ -470,29 +404,31 @@ JavaScriptCallFrames V8DebuggerImpl::currentCallFrames(int limit) return callFrames; } -static V8DebuggerImpl* toV8DebuggerImpl(v8::Local data) +static V8Debugger* toV8Debugger(v8::Local data) { void* p = v8::Local::Cast(data)->Value(); - return static_cast(p); + return static_cast(p); } -void V8DebuggerImpl::breakProgramCallback(const v8::FunctionCallbackInfo& info) +void V8Debugger::breakProgramCallback(const v8::FunctionCallbackInfo& info) { DCHECK_EQ(info.Length(), 2); - V8DebuggerImpl* thisPtr = toV8DebuggerImpl(info.Data()); + V8Debugger* thisPtr = toV8Debugger(info.Data()); + if (!thisPtr->enabled()) + return; v8::Local pausedContext = thisPtr->m_isolate->GetCurrentContext(); v8::Local exception; v8::Local hitBreakpoints; thisPtr->handleProgramBreak(pausedContext, v8::Local::Cast(info[0]), exception, hitBreakpoints); } -void V8DebuggerImpl::handleProgramBreak(v8::Local pausedContext, v8::Local executionState, v8::Local exception, v8::Local hitBreakpointNumbers, bool isPromiseRejection) +void V8Debugger::handleProgramBreak(v8::Local pausedContext, v8::Local executionState, v8::Local exception, v8::Local hitBreakpointNumbers, bool isPromiseRejection) { // Don't allow nested breaks. if (m_runningNestedMessageLoop) return; - V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(pausedContext); + V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(getGroupId(pausedContext)); if (!agent) return; @@ -513,9 +449,9 @@ void V8DebuggerImpl::handleProgramBreak(v8::Local pausedContext, v8 m_runningNestedMessageLoop = true; int groupId = getGroupId(pausedContext); DCHECK(groupId); - m_client->runMessageLoopOnPause(groupId); + m_inspector->client()->runMessageLoopOnPause(groupId); // The agent may have been removed in the nested loop. - agent = findEnabledDebuggerAgent(pausedContext); + agent = m_inspector->enabledDebuggerAgentForGroup(getGroupId(pausedContext)); if (agent) agent->didContinue(); m_runningNestedMessageLoop = false; @@ -535,21 +471,21 @@ void V8DebuggerImpl::handleProgramBreak(v8::Local pausedContext, v8 } } -void V8DebuggerImpl::v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails) +void V8Debugger::v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails) { - V8DebuggerImpl* thisPtr = toV8DebuggerImpl(eventDetails.GetCallbackData()); + V8Debugger* thisPtr = toV8Debugger(eventDetails.GetCallbackData()); thisPtr->handleV8DebugEvent(eventDetails); } -v8::Local V8DebuggerImpl::callInternalGetterFunction(v8::Local object, const char* functionName) +v8::Local V8Debugger::callInternalGetterFunction(v8::Local object, const char* functionName) { v8::MicrotasksScope microtasks(m_isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); - v8::Local getterValue = object->Get(v8InternalizedString(functionName)); + v8::Local getterValue = object->Get(toV8StringInternalized(m_isolate, functionName)); DCHECK(!getterValue.IsEmpty() && getterValue->IsFunction()); return v8::Local::Cast(getterValue)->Call(m_isolate->GetCurrentContext(), object, 0, 0).ToLocalChecked(); } -void V8DebuggerImpl::handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails) +void V8Debugger::handleV8DebugEvent(const v8::Debug::EventDetails& eventDetails) { if (!enabled()) return; @@ -566,10 +502,10 @@ void V8DebuggerImpl::handleV8DebugEvent(const v8::Debug::EventDetails& eventDeta return; } - V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(eventContext); + V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(getGroupId(eventContext)); if (agent) { v8::HandleScope scope(m_isolate); - if (event == v8::AfterCompile || event == v8::CompileError) { + if (m_ignoreScriptParsedEventsCounter == 0 && (event == v8::AfterCompile || event == v8::CompileError)) { v8::Context::Scope contextScope(debuggerContext()); v8::Local argv[] = { eventDetails.GetEventData() }; v8::Local value = callDebuggerMethod("getAfterCompileScript", 1, argv).ToLocalChecked(); @@ -591,7 +527,7 @@ void V8DebuggerImpl::handleV8DebugEvent(const v8::Debug::EventDetails& eventDeta } } -void V8DebuggerImpl::handleV8AsyncTaskEvent(v8::Local context, v8::Local executionState, v8::Local eventData) +void V8Debugger::handleV8AsyncTaskEvent(v8::Local context, v8::Local executionState, v8::Local eventData) { if (!m_maxAsyncCallStackDepth) return; @@ -611,14 +547,14 @@ void V8DebuggerImpl::handleV8AsyncTaskEvent(v8::Local context, v8:: NOTREACHED(); } -V8StackTraceImpl* V8DebuggerImpl::currentAsyncCallChain() +V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { if (!m_currentStacks.size()) return nullptr; return m_currentStacks.back().get(); } -void V8DebuggerImpl::compileDebuggerScript() +void V8Debugger::compileDebuggerScript() { if (!m_debuggerScript.IsEmpty()) { NOTREACHED(); @@ -630,24 +566,21 @@ void V8DebuggerImpl::compileDebuggerScript() v8::Local scriptValue = v8::String::NewFromUtf8(m_isolate, DebuggerScript_js, v8::NewStringType::kInternalized, sizeof(DebuggerScript_js)).ToLocalChecked(); v8::Local value; - if (!compileAndRunInternalScript(debuggerContext(), scriptValue).ToLocal(&value)) + if (!m_inspector->compileAndRunInternalScript(debuggerContext(), scriptValue).ToLocal(&value)) { + NOTREACHED(); return; + } DCHECK(value->IsObject()); m_debuggerScript.Reset(m_isolate, value.As()); } -v8::Local V8DebuggerImpl::debuggerContext() const +v8::Local V8Debugger::debuggerContext() const { DCHECK(!m_debuggerContext.IsEmpty()); return m_debuggerContext.Get(m_isolate); } -v8::Local V8DebuggerImpl::v8InternalizedString(const char* str) const -{ - return v8::String::NewFromUtf8(m_isolate, str, v8::NewStringType::kInternalized).ToLocalChecked(); -} - -v8::MaybeLocal V8DebuggerImpl::functionScopes(v8::Local function) +v8::MaybeLocal V8Debugger::functionScopes(v8::Local function) { if (!enabled()) { NOTREACHED(); @@ -668,7 +601,7 @@ v8::MaybeLocal V8DebuggerImpl::functionScopes(v8::Local return scopes; } -v8::MaybeLocal V8DebuggerImpl::internalProperties(v8::Local context, v8::Local value) +v8::MaybeLocal V8Debugger::internalProperties(v8::Local context, v8::Local value) { v8::Local properties; if (!v8::Debug::GetInternalProperties(m_isolate, value).ToLocal(&properties)) @@ -677,11 +610,11 @@ v8::MaybeLocal V8DebuggerImpl::internalProperties(v8::Local function = value.As(); v8::Local location = functionLocation(context, function); if (location->IsObject()) { - properties->Set(properties->Length(), v8InternalizedString("[[FunctionLocation]]")); + properties->Set(properties->Length(), toV8StringInternalized(m_isolate, "[[FunctionLocation]]")); properties->Set(properties->Length(), location); } if (function->IsGeneratorFunction()) { - properties->Set(properties->Length(), v8InternalizedString("[[IsGenerator]]")); + properties->Set(properties->Length(), toV8StringInternalized(m_isolate, "[[IsGenerator]]")); properties->Set(properties->Length(), v8::True(m_isolate)); } } @@ -690,14 +623,14 @@ v8::MaybeLocal V8DebuggerImpl::internalProperties(v8::LocalIsMap() || value->IsWeakMap() || value->IsSet() || value->IsWeakSet() || value->IsSetIterator() || value->IsMapIterator()) { v8::Local entries = collectionEntries(context, v8::Local::Cast(value)); if (entries->IsArray()) { - properties->Set(properties->Length(), v8InternalizedString("[[Entries]]")); + properties->Set(properties->Length(), toV8StringInternalized(m_isolate, "[[Entries]]")); properties->Set(properties->Length(), entries); } } if (value->IsGeneratorObject()) { v8::Local location = generatorObjectLocation(v8::Local::Cast(value)); if (location->IsObject()) { - properties->Set(properties->Length(), v8InternalizedString("[[GeneratorLocation]]")); + properties->Set(properties->Length(), toV8StringInternalized(m_isolate, "[[GeneratorLocation]]")); properties->Set(properties->Length(), location); } } @@ -706,14 +639,14 @@ v8::MaybeLocal V8DebuggerImpl::internalProperties(v8::Local boundFunction = function->GetBoundFunction(); v8::Local scopes; if (boundFunction->IsUndefined() && functionScopes(function).ToLocal(&scopes)) { - properties->Set(properties->Length(), v8InternalizedString("[[Scopes]]")); + properties->Set(properties->Length(), toV8StringInternalized(m_isolate, "[[Scopes]]")); properties->Set(properties->Length(), scopes); } } return properties; } -v8::Local V8DebuggerImpl::collectionEntries(v8::Local context, v8::Local object) +v8::Local V8Debugger::collectionEntries(v8::Local context, v8::Local object) { if (!enabled()) { NOTREACHED(); @@ -731,7 +664,7 @@ v8::Local V8DebuggerImpl::collectionEntries(v8::Local co return entries; } -v8::Local V8DebuggerImpl::generatorObjectLocation(v8::Local object) +v8::Local V8Debugger::generatorObjectLocation(v8::Local object) { if (!enabled()) { NOTREACHED(); @@ -747,7 +680,7 @@ v8::Local V8DebuggerImpl::generatorObjectLocation(v8::Local V8DebuggerImpl::functionLocation(v8::Local context, v8::Local function) +v8::Local V8Debugger::functionLocation(v8::Local context, v8::Local function) { int scriptId = function->ScriptId(); if (scriptId == v8::UnboundScript::kNoScriptId) @@ -757,193 +690,39 @@ v8::Local V8DebuggerImpl::functionLocation(v8::Local con if (lineNumber == v8::Function::kLineOffsetNotFound || columnNumber == v8::Function::kLineOffsetNotFound) return v8::Null(m_isolate); v8::Local location = v8::Object::New(m_isolate); - if (!location->Set(context, v8InternalizedString("scriptId"), toV8String(m_isolate, String16::fromInteger(scriptId))).FromMaybe(false)) + if (!location->Set(context, toV8StringInternalized(m_isolate, "scriptId"), toV8String(m_isolate, String16::fromInteger(scriptId))).FromMaybe(false)) return v8::Null(m_isolate); - if (!location->Set(context, v8InternalizedString("lineNumber"), v8::Integer::New(m_isolate, lineNumber)).FromMaybe(false)) + if (!location->Set(context, toV8StringInternalized(m_isolate, "lineNumber"), v8::Integer::New(m_isolate, lineNumber)).FromMaybe(false)) return v8::Null(m_isolate); - if (!location->Set(context, v8InternalizedString("columnNumber"), v8::Integer::New(m_isolate, columnNumber)).FromMaybe(false)) + if (!location->Set(context, toV8StringInternalized(m_isolate, "columnNumber"), v8::Integer::New(m_isolate, columnNumber)).FromMaybe(false)) return v8::Null(m_isolate); if (!markAsInternal(context, location, V8InternalValueType::kLocation)) return v8::Null(m_isolate); return location; } -bool V8DebuggerImpl::isPaused() +bool V8Debugger::isPaused() { return !m_pausedContext.IsEmpty(); } -v8::MaybeLocal V8DebuggerImpl::runCompiledScript(v8::Local context, v8::Local script) -{ - // TODO(dgozman): get rid of this check. - if (!m_client->isExecutionAllowed()) - return v8::MaybeLocal(); - - v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kRunMicrotasks); - int groupId = getGroupId(context); - if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(groupId)) - agent->willExecuteScript(script->GetUnboundScript()->GetId()); - v8::MaybeLocal result = script->Run(context); - // Get agent from the map again, since it could have detached during script execution. - if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(groupId)) - agent->didExecuteScript(); - return result; -} - -v8::MaybeLocal V8DebuggerImpl::callFunction(v8::Local function, v8::Local context, v8::Local receiver, int argc, v8::Local info[]) -{ - // TODO(dgozman): get rid of this check. - if (!m_client->isExecutionAllowed()) - return v8::MaybeLocal(); - - v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kRunMicrotasks); - int groupId = getGroupId(context); - if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(groupId)) - agent->willExecuteScript(function->ScriptId()); - v8::MaybeLocal result = function->Call(context, receiver, argc, info); - // Get agent from the map again, since it could have detached during script execution. - if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(groupId)) - agent->didExecuteScript(); - return result; -} - -v8::MaybeLocal V8DebuggerImpl::compileAndRunInternalScript(v8::Local context, v8::Local source) -{ - v8::Local script = compileInternalScript(context, source, String()); - if (script.IsEmpty()) - return v8::MaybeLocal(); - v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); - return script->Run(context); -} - -v8::Local V8DebuggerImpl::compileInternalScript(v8::Local context, v8::Local code, const String16& fileName) -{ - // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at - // 1, whereas v8 starts at 0. - v8::ScriptOrigin origin( - toV8String(m_isolate, fileName), - v8::Integer::New(m_isolate, 0), - v8::Integer::New(m_isolate, 0), - v8::False(m_isolate), // sharable - v8::Local(), - v8::True(m_isolate), // internal - toV8String(m_isolate, String16()), // sourceMap - v8::True(m_isolate)); // opaqueresource - v8::ScriptCompiler::Source source(code, origin); - v8::Local script; - if (!v8::ScriptCompiler::Compile(context, &source, v8::ScriptCompiler::kNoCompileOptions).ToLocal(&script)) - return v8::Local(); - return script; -} - -void V8DebuggerImpl::enableStackCapturingIfNeeded() -{ - if (!m_capturingStackTracesCount) - V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate, true); - ++m_capturingStackTracesCount; -} - -void V8DebuggerImpl::disableStackCapturingIfNeeded() -{ - if (!(--m_capturingStackTracesCount)) - V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate, false); -} - -V8ConsoleMessageStorage* V8DebuggerImpl::ensureConsoleMessageStorage(int contextGroupId) -{ - ConsoleStorageMap::iterator storageIt = m_consoleStorageMap.find(contextGroupId); - if (storageIt == m_consoleStorageMap.end()) - storageIt = m_consoleStorageMap.insert(std::make_pair(contextGroupId, wrapUnique(new V8ConsoleMessageStorage(this, contextGroupId)))).first; - return storageIt->second.get(); -} - -std::unique_ptr V8DebuggerImpl::createStackTrace(v8::Local stackTrace) +std::unique_ptr V8Debugger::createStackTrace(v8::Local stackTrace) { int contextGroupId = m_isolate->InContext() ? getGroupId(m_isolate->GetCurrentContext()) : 0; return V8StackTraceImpl::create(this, contextGroupId, stackTrace, V8StackTraceImpl::maxCallStackSizeToCapture); } -std::unique_ptr V8DebuggerImpl::connect(int contextGroupId, protocol::FrontendChannel* channel, V8InspectorSessionClient* client, const String16* state) -{ - DCHECK(m_sessions.find(contextGroupId) == m_sessions.cend()); - std::unique_ptr session = - V8InspectorSessionImpl::create(this, contextGroupId, channel, client, state); - m_sessions[contextGroupId] = session.get(); - return std::move(session); -} - -void V8DebuggerImpl::disconnect(V8InspectorSessionImpl* session) -{ - DCHECK(m_sessions.find(session->contextGroupId()) != m_sessions.end()); - m_sessions.erase(session->contextGroupId()); -} - -InspectedContext* V8DebuggerImpl::getContext(int groupId, int contextId) const -{ - ContextsByGroupMap::const_iterator contextGroupIt = m_contexts.find(groupId); - if (contextGroupIt == m_contexts.end()) - return nullptr; - - ContextByIdMap::iterator contextIt = contextGroupIt->second->find(contextId); - if (contextIt == contextGroupIt->second->end()) - return nullptr; - - return contextIt->second.get(); -} - -void V8DebuggerImpl::contextCreated(const V8ContextInfo& info) +int V8Debugger::markContext(const V8ContextInfo& info) { DCHECK(info.context->GetIsolate() == m_isolate); - // TODO(dgozman): make s_lastContextId non-static. - int contextId = atomicIncrement(&s_lastContextId); - String16 debugData = String16::fromInteger(info.contextGroupId) + "," + String16::fromInteger(contextId) + "," + (info.isDefault ? "default" : "nondefault"); - v8::HandleScope scope(m_isolate); + int contextId = ++m_lastContextId; + String16 debugData = String16::fromInteger(info.contextGroupId) + "," + String16::fromInteger(contextId) + "," + info.auxData; v8::Context::Scope contextScope(info.context); info.context->SetEmbedderData(static_cast(v8::Context::kDebugIdIndex), toV8String(m_isolate, debugData)); - - ContextsByGroupMap::iterator contextIt = m_contexts.find(info.contextGroupId); - if (contextIt == m_contexts.end()) - contextIt = m_contexts.insert(std::make_pair(info.contextGroupId, wrapUnique(new ContextByIdMap()))).first; - - const auto& contextById = contextIt->second; - - DCHECK(contextById->find(contextId) == contextById->cend()); - InspectedContext* context = new InspectedContext(this, info, contextId); - (*contextById)[contextId] = wrapUnique(context); - SessionMap::iterator sessionIt = m_sessions.find(info.contextGroupId); - if (sessionIt != m_sessions.end()) - sessionIt->second->runtimeAgent()->reportExecutionContextCreated(context); + return contextId; } -void V8DebuggerImpl::contextDestroyed(v8::Local context) -{ - int contextId = V8DebuggerImpl::contextId(context); - int contextGroupId = getGroupId(context); - - ConsoleStorageMap::iterator storageIt = m_consoleStorageMap.find(contextGroupId); - if (storageIt != m_consoleStorageMap.end()) - storageIt->second->contextDestroyed(contextId); - - InspectedContext* inspectedContext = getContext(contextGroupId, contextId); - if (!inspectedContext) - return; - - SessionMap::iterator iter = m_sessions.find(contextGroupId); - if (iter != m_sessions.end()) - iter->second->runtimeAgent()->reportExecutionContextDestroyed(inspectedContext); - discardInspectedContext(contextGroupId, contextId); -} - -void V8DebuggerImpl::resetContextGroup(int contextGroupId) -{ - m_consoleStorageMap.erase(contextGroupId); - SessionMap::iterator session = m_sessions.find(contextGroupId); - if (session != m_sessions.end()) - session->second->reset(); - m_contexts.erase(contextGroupId); -} - -void V8DebuggerImpl::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) +void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) { if (depth <= 0) m_maxAsyncCallStackDepthMap.erase(agent); @@ -958,18 +737,12 @@ void V8DebuggerImpl::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int dept if (m_maxAsyncCallStackDepth == maxAsyncCallStackDepth) return; - - if (maxAsyncCallStackDepth && !m_maxAsyncCallStackDepth) - m_client->enableAsyncInstrumentation(); - else if (!maxAsyncCallStackDepth && m_maxAsyncCallStackDepth) - m_client->disableAsyncInstrumentation(); - m_maxAsyncCallStackDepth = maxAsyncCallStackDepth; if (!maxAsyncCallStackDepth) allAsyncTasksCanceled(); } -void V8DebuggerImpl::asyncTaskScheduled(const String16& taskName, void* task, bool recurring) +void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, bool recurring) { if (!m_maxAsyncCallStackDepth) return; @@ -983,7 +756,7 @@ void V8DebuggerImpl::asyncTaskScheduled(const String16& taskName, void* task, bo } } -void V8DebuggerImpl::asyncTaskCanceled(void* task) +void V8Debugger::asyncTaskCanceled(void* task) { if (!m_maxAsyncCallStackDepth) return; @@ -991,12 +764,10 @@ void V8DebuggerImpl::asyncTaskCanceled(void* task) m_recurringTasks.erase(task); } -void V8DebuggerImpl::asyncTaskStarted(void* task) +void V8Debugger::asyncTaskStarted(void* task) { - // Not enabled, return. if (!m_maxAsyncCallStackDepth) return; - m_currentTasks.push_back(task); AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(task); // Needs to support following order of events: @@ -1012,7 +783,7 @@ void V8DebuggerImpl::asyncTaskStarted(void* task) m_currentStacks.push_back(std::move(stack)); } -void V8DebuggerImpl::asyncTaskFinished(void* task) +void V8Debugger::asyncTaskFinished(void* task) { if (!m_maxAsyncCallStackDepth) return; @@ -1028,7 +799,7 @@ void V8DebuggerImpl::asyncTaskFinished(void* task) m_asyncTaskStacks.erase(task); } -void V8DebuggerImpl::allAsyncTasksCanceled() +void V8Debugger::allAsyncTasksCanceled() { m_asyncTaskStacks.clear(); m_recurringTasks.clear(); @@ -1036,71 +807,18 @@ void V8DebuggerImpl::allAsyncTasksCanceled() m_currentTasks.clear(); } -void V8DebuggerImpl::willExecuteScript(v8::Local context, int scriptId) -{ - if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(context)) - agent->willExecuteScript(scriptId); -} - -void V8DebuggerImpl::didExecuteScript(v8::Local context) -{ - if (V8DebuggerAgentImpl* agent = findEnabledDebuggerAgent(context)) - agent->didExecuteScript(); -} - -void V8DebuggerImpl::idleStarted() -{ - m_isolate->GetCpuProfiler()->SetIdle(true); -} - -void V8DebuggerImpl::idleFinished() -{ - m_isolate->GetCpuProfiler()->SetIdle(false); -} - -void V8DebuggerImpl::logToConsole(v8::Local context, v8::Local arg1, v8::Local arg2) -{ - int contextGroupId = getGroupId(context); - InspectedContext* inspectedContext = getContext(contextGroupId, contextId(context)); - if (!inspectedContext) - return; - std::vector> arguments; - if (!arg1.IsEmpty()) - arguments.push_back(arg1); - if (!arg2.IsEmpty()) - arguments.push_back(arg2); - ensureConsoleMessageStorage(contextGroupId)->addMessage(V8ConsoleMessage::createForConsoleAPI(m_client->currentTimeMS(), ConsoleAPIType::kLog, arguments, captureStackTrace(false), inspectedContext)); -} - -void V8DebuggerImpl::exceptionThrown(int contextGroupId, const String16& errorMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId) +void V8Debugger::muteScriptParsedEvents() { - unsigned exceptionId = ++m_lastExceptionId; - std::unique_ptr consoleMessage = V8ConsoleMessage::createForException(m_client->currentTimeMS(), errorMessage, url, lineNumber, columnNumber, std::move(stackTrace), scriptId, m_isolate, 0, v8::Local(), exceptionId); - ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage)); + ++m_ignoreScriptParsedEventsCounter; } -unsigned V8DebuggerImpl::promiseRejected(v8::Local context, const String16& errorMessage, v8::Local exception, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId) +void V8Debugger::unmuteScriptParsedEvents() { - int contextGroupId = getGroupId(context); - if (!contextGroupId) - return 0; - unsigned exceptionId = ++m_lastExceptionId; - std::unique_ptr consoleMessage = V8ConsoleMessage::createForException(m_client->currentTimeMS(), errorMessage, url, lineNumber, columnNumber, std::move(stackTrace), scriptId, m_isolate, contextId(context), exception, exceptionId); - ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage)); - return exceptionId; -} - -void V8DebuggerImpl::promiseRejectionRevoked(v8::Local context, unsigned promiseRejectionId) -{ - int contextGroupId = getGroupId(context); - if (!contextGroupId) - return; - - std::unique_ptr consoleMessage = V8ConsoleMessage::createForRevokedException(m_client->currentTimeMS(), "Handler added to rejected promise", promiseRejectionId); - ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage)); + --m_ignoreScriptParsedEventsCounter; + DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0); } -std::unique_ptr V8DebuggerImpl::captureStackTrace(bool fullStack) +std::unique_ptr V8Debugger::captureStackTrace(bool fullStack) { if (!m_isolate->InContext()) return nullptr; @@ -1111,41 +829,10 @@ std::unique_ptr V8DebuggerImpl::captureStackTrace(bool fullStack) return nullptr; size_t stackSize = fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; - SessionMap::iterator sessionIt = m_sessions.find(contextGroupId); - if (sessionIt != m_sessions.end() && sessionIt->second->runtimeAgent()->enabled()) + if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; return V8StackTraceImpl::capture(this, contextGroupId, stackSize); } -v8::Local V8DebuggerImpl::regexContext() -{ - if (m_regexContext.IsEmpty()) - m_regexContext.Reset(m_isolate, v8::Context::New(m_isolate)); - return m_regexContext.Get(m_isolate); -} - -void V8DebuggerImpl::discardInspectedContext(int contextGroupId, int contextId) -{ - if (!getContext(contextGroupId, contextId)) - return; - m_contexts[contextGroupId]->erase(contextId); - if (m_contexts[contextGroupId]->empty()) - m_contexts.erase(contextGroupId); -} - -const V8DebuggerImpl::ContextByIdMap* V8DebuggerImpl::contextGroup(int contextGroupId) -{ - ContextsByGroupMap::iterator iter = m_contexts.find(contextGroupId); - return iter == m_contexts.end() ? nullptr : iter->second.get(); -} - -V8InspectorSessionImpl* V8DebuggerImpl::sessionForContextGroup(int contextGroupId) -{ - if (!contextGroupId) - return nullptr; - SessionMap::iterator iter = m_sessions.find(contextGroupId); - return iter == m_sessions.end() ? nullptr : iter->second; -} - } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Debugger.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Debugger.h new file mode 100644 index 00000000000000..3ec68a8708bee4 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Debugger.h @@ -0,0 +1,131 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8Debugger_h +#define V8Debugger_h + +#include "platform/inspector_protocol/Allocator.h" +#include "platform/inspector_protocol/Maybe.h" +#include "platform/inspector_protocol/Platform.h" +#include "platform/v8_inspector/JavaScriptCallFrame.h" +#include "platform/v8_inspector/V8DebuggerScript.h" +#include "platform/v8_inspector/protocol/Runtime.h" +#include "platform/v8_inspector/public/V8ContextInfo.h" + +#include +#include +#include + +namespace blink { + +struct ScriptBreakpoint; +class V8DebuggerAgentImpl; +class V8InspectorImpl; +class V8StackTraceImpl; + +class V8Debugger { + PROTOCOL_DISALLOW_COPY(V8Debugger); +public: + V8Debugger(v8::Isolate*, V8InspectorImpl*); + ~V8Debugger(); + + static int contextId(v8::Local); + static int getGroupId(v8::Local); + int markContext(const V8ContextInfo&); + + bool enabled() const; + + String16 setBreakpoint(const String16& sourceID, const ScriptBreakpoint&, int* actualLineNumber, int* actualColumnNumber, bool interstatementLocation); + void removeBreakpoint(const String16& breakpointId); + void setBreakpointsActivated(bool); + bool breakpointsActivated() const { return m_breakpointsActivated; } + + enum PauseOnExceptionsState { + DontPauseOnExceptions, + PauseOnAllExceptions, + PauseOnUncaughtExceptions + }; + PauseOnExceptionsState getPauseOnExceptionsState(); + void setPauseOnExceptionsState(PauseOnExceptionsState); + void setPauseOnNextStatement(bool); + bool canBreakProgram(); + void breakProgram(); + void continueProgram(); + void stepIntoStatement(); + void stepOverStatement(); + void stepOutOfFunction(); + void clearStepping(); + + bool setScriptSource(const String16& sourceID, v8::Local newSource, bool preview, ErrorString*, protocol::Maybe*, JavaScriptCallFrames* newCallFrames, protocol::Maybe* stackChanged); + JavaScriptCallFrames currentCallFrames(int limit = 0); + + // Each script inherits debug data from v8::Context where it has been compiled. + // Only scripts whose debug data matches |contextGroupId| will be reported. + // Passing 0 will result in reporting all scripts. + void getCompiledScripts(int contextGroupId, std::vector>&); + void enable(); + void disable(); + + bool isPaused(); + v8::Local pausedContext() { return m_pausedContext; } + + int maxAsyncCallChainDepth() { return m_maxAsyncCallStackDepth; } + V8StackTraceImpl* currentAsyncCallChain(); + void setAsyncCallStackDepth(V8DebuggerAgentImpl*, int); + std::unique_ptr createStackTrace(v8::Local); + std::unique_ptr captureStackTrace(bool fullStack); + + v8::MaybeLocal functionScopes(v8::Local); + v8::MaybeLocal internalProperties(v8::Local, v8::Local); + + void asyncTaskScheduled(const String16& taskName, void* task, bool recurring); + void asyncTaskCanceled(void* task); + void asyncTaskStarted(void* task); + void asyncTaskFinished(void* task); + void allAsyncTasksCanceled(); + + void muteScriptParsedEvents(); + void unmuteScriptParsedEvents(); + +private: + void compileDebuggerScript(); + v8::MaybeLocal callDebuggerMethod(const char* functionName, int argc, v8::Local argv[]); + v8::Local debuggerContext() const; + void clearBreakpoints(); + + static void breakProgramCallback(const v8::FunctionCallbackInfo&); + void handleProgramBreak(v8::Local pausedContext, v8::Local executionState, v8::Local exception, v8::Local hitBreakpoints, bool isPromiseRejection = false); + static void v8DebugEventCallback(const v8::Debug::EventDetails&); + v8::Local callInternalGetterFunction(v8::Local, const char* functionName); + void handleV8DebugEvent(const v8::Debug::EventDetails&); + void handleV8AsyncTaskEvent(v8::Local, v8::Local executionState, v8::Local eventData); + + v8::Local collectionEntries(v8::Local, v8::Local); + v8::Local generatorObjectLocation(v8::Local); + v8::Local functionLocation(v8::Local, v8::Local); + + v8::Isolate* m_isolate; + V8InspectorImpl* m_inspector; + int m_lastContextId; + int m_enableCount; + bool m_breakpointsActivated; + v8::Global m_debuggerScript; + v8::Global m_debuggerContext; + v8::Local m_executionState; + v8::Local m_pausedContext; + bool m_runningNestedMessageLoop; + int m_ignoreScriptParsedEventsCounter; + + using AsyncTaskToStackTrace = protocol::HashMap>; + AsyncTaskToStackTrace m_asyncTaskStacks; + protocol::HashSet m_recurringTasks; + int m_maxAsyncCallStackDepth; + std::vector m_currentTasks; + std::vector> m_currentStacks; + protocol::HashMap m_maxAsyncCallStackDepthMap; +}; + +} // namespace blink + +#endif // V8Debugger_h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp index 2b232efc2e714b..584c0164e0339a 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.cpp @@ -4,6 +4,7 @@ #include "platform/v8_inspector/V8DebuggerAgentImpl.h" +#include "platform/inspector_protocol/Parser.h" #include "platform/inspector_protocol/String16.h" #include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/InjectedScript.h" @@ -11,14 +12,15 @@ #include "platform/v8_inspector/JavaScriptCallFrame.h" #include "platform/v8_inspector/RemoteObjectId.h" #include "platform/v8_inspector/ScriptBreakpoint.h" +#include "platform/v8_inspector/V8Debugger.h" +#include "platform/v8_inspector/V8DebuggerScript.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8Regex.h" #include "platform/v8_inspector/V8RuntimeAgentImpl.h" #include "platform/v8_inspector/V8StackTraceImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8ContentSearchUtil.h" -#include "platform/v8_inspector/public/V8Debugger.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" #include @@ -51,6 +53,7 @@ static const char skipAllPauses[] = "skipAllPauses"; } // namespace DebuggerAgentState; static const int maxSkipStepFrameCount = 128; +static const char backtraceObjectGroup[] = "backtrace"; static String16 breakpointIdSuffix(V8DebuggerAgentImpl::BreakpointSource source) { @@ -93,12 +96,13 @@ static std::unique_ptr buildProtocolLocation(const } V8DebuggerAgentImpl::V8DebuggerAgentImpl(V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel, protocol::DictionaryValue* state) - : m_debugger(session->debugger()) + : m_inspector(session->inspector()) + , m_debugger(m_inspector->debugger()) , m_session(session) , m_enabled(false) , m_state(state) , m_frontend(frontendChannel) - , m_isolate(m_debugger->isolate()) + , m_isolate(m_inspector->isolate()) , m_breakReason(protocol::Debugger::Paused::ReasonEnum::Other) , m_scheduledDebuggerStep(NoStep) , m_skipNextDebuggerStepOut(false) @@ -127,19 +131,19 @@ bool V8DebuggerAgentImpl::checkEnabled(ErrorString* errorString) void V8DebuggerAgentImpl::enable() { - // debugger().addListener may result in reporting all parsed scripts to + // m_inspector->addListener may result in reporting all parsed scripts to // the agent so it should already be in enabled state by then. m_enabled = true; m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true); - debugger().debuggerAgentEnabled(); + m_debugger->enable(); std::vector> compiledScripts; - debugger().getCompiledScripts(m_session->contextGroupId(), compiledScripts); + m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts); for (size_t i = 0; i < compiledScripts.size(); i++) didParseSource(std::move(compiledScripts[i]), true); // FIXME(WK44513): breakpoints activated flag should be synchronized between all front-ends - debugger().setBreakpointsActivated(true); + m_debugger->setBreakpointsActivated(true); } bool V8DebuggerAgentImpl::enabled() @@ -152,7 +156,7 @@ void V8DebuggerAgentImpl::enable(ErrorString* errorString) if (enabled()) return; - if (!m_session->client()->canExecuteScripts()) { + if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) { *errorString = "Script execution is prohibited"; return; } @@ -166,12 +170,12 @@ void V8DebuggerAgentImpl::disable(ErrorString*) return; m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, protocol::DictionaryValue::create()); - m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, V8DebuggerImpl::DontPauseOnExceptions); + m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, V8Debugger::DontPauseOnExceptions); m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0); if (!m_pausedContext.IsEmpty()) - debugger().continueProgram(); - debugger().debuggerAgentDisabled(); + m_debugger->continueProgram(); + m_debugger->disable(); m_pausedContext.Reset(); JavaScriptCallFrames emptyCallFrames; m_pausedCallFrames.swap(emptyCallFrames); @@ -200,13 +204,13 @@ void V8DebuggerAgentImpl::restore() DCHECK(!m_enabled); if (!m_state->booleanProperty(DebuggerAgentState::debuggerEnabled, false)) return; - if (!m_session->client()->canExecuteScripts()) + if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) return; enable(); ErrorString error; - int pauseState = V8DebuggerImpl::DontPauseOnExceptions; + int pauseState = V8Debugger::DontPauseOnExceptions; m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState); setPauseOnExceptionsImpl(&error, pauseState); DCHECK(error.isEmpty()); @@ -228,7 +232,7 @@ void V8DebuggerAgentImpl::setBreakpointsActive(ErrorString* errorString, bool ac { if (!checkEnabled(errorString)) return; - debugger().setBreakpointsActivated(active); + m_debugger->setBreakpointsActivated(active); } void V8DebuggerAgentImpl::setSkipAllPauses(ErrorString*, bool skipped) @@ -248,10 +252,10 @@ static std::unique_ptr buildObjectForBreakpointCookie return breakpointObject; } -static bool matches(V8DebuggerImpl* debugger, const String16& url, const String16& pattern, bool isRegex) +static bool matches(V8InspectorImpl* inspector, const String16& url, const String16& pattern, bool isRegex) { if (isRegex) { - V8Regex regex(debugger, pattern, true); + V8Regex regex(inspector, pattern, true); return regex.match(url) != -1; } return url == pattern; @@ -300,7 +304,7 @@ void V8DebuggerAgentImpl::setBreakpointByUrl(ErrorString* errorString, ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition); for (const auto& script : m_scripts) { - if (!matches(m_debugger, script.second->sourceURL(), url, isRegex)) + if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) continue; std::unique_ptr location = resolveBreakpoint(breakpointId, script.first, breakpoint, UserBreakpointSource); if (location) @@ -366,7 +370,7 @@ void V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) for (size_t i = 0; i < ids.size(); ++i) { const String16& debuggerBreakpointId = ids[i]; - debugger().removeBreakpoint(debuggerBreakpointId); + m_debugger->removeBreakpoint(debuggerBreakpointId); m_serverBreakpoints.erase(debuggerBreakpointId); } m_breakpointIdToDebuggerBreakpointIds.erase(breakpointId); @@ -379,7 +383,7 @@ void V8DebuggerAgentImpl::continueToLocation(ErrorString* errorString, if (!checkEnabled(errorString)) return; if (!m_continueToLocationBreakpointId.isEmpty()) { - debugger().removeBreakpoint(m_continueToLocationBreakpointId); + m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); m_continueToLocationBreakpointId = ""; } @@ -391,7 +395,7 @@ void V8DebuggerAgentImpl::continueToLocation(ErrorString* errorString, return; ScriptBreakpoint breakpoint(lineNumber, columnNumber, ""); - m_continueToLocationBreakpointId = debugger().setBreakpoint(scriptId, breakpoint, &lineNumber, &columnNumber, interstateLocationOpt.fromMaybe(false)); + m_continueToLocationBreakpointId = m_debugger->setBreakpoint(scriptId, breakpoint, &lineNumber, &columnNumber, interstateLocationOpt.fromMaybe(false)); resume(errorString); } @@ -399,7 +403,7 @@ void V8DebuggerAgentImpl::getBacktrace(ErrorString* errorString, std::unique_ptr { if (!assertPaused(errorString)) return; - JavaScriptCallFrames frames = debugger().currentCallFrames(); + JavaScriptCallFrames frames = m_debugger->currentCallFrames(); m_pausedCallFrames.swap(frames); *callFrames = currentCallFrames(errorString); if (!*callFrames) @@ -410,7 +414,7 @@ void V8DebuggerAgentImpl::getBacktrace(ErrorString* errorString, std::unique_ptr bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() { DCHECK(enabled()); - JavaScriptCallFrames callFrames = debugger().currentCallFrames(); + JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(); for (size_t index = 0; index < callFrames.size(); ++index) { if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index].get())) return false; @@ -498,7 +502,7 @@ std::unique_ptr V8DebuggerAgentImpl::resolveBreakp int actualLineNumber; int actualColumnNumber; - String16 debuggerBreakpointId = debugger().setBreakpoint(scriptId, breakpoint, &actualLineNumber, &actualColumnNumber, false); + String16 debuggerBreakpointId = m_debugger->setBreakpoint(scriptId, breakpoint, &actualLineNumber, &actualColumnNumber, false); if (debuggerBreakpointId.isEmpty()) return nullptr; @@ -516,10 +520,15 @@ void V8DebuggerAgentImpl::searchInContent(ErrorString* error, const String16& sc { v8::HandleScope handles(m_isolate); ScriptsMap::iterator it = m_scripts.find(scriptId); - if (it != m_scripts.end()) - *results = V8ContentSearchUtil::searchInTextByLines(m_session, toProtocolString(it->second->source(m_isolate)), query, optionalCaseSensitive.fromMaybe(false), optionalIsRegex.fromMaybe(false)); - else + if (it == m_scripts.end()) { *error = String16("No script for id: " + scriptId); + return; + } + + std::vector> matches = searchInTextByLinesImpl(m_session, toProtocolString(it->second->source(m_isolate)), query, optionalCaseSensitive.fromMaybe(false), optionalIsRegex.fromMaybe(false)); + *results = protocol::Array::create(); + for (size_t i = 0; i < matches.size(); ++i) + (*results)->addItem(std::move(matches[i])); } void V8DebuggerAgentImpl::setScriptSource(ErrorString* errorString, @@ -536,7 +545,7 @@ void V8DebuggerAgentImpl::setScriptSource(ErrorString* errorString, v8::HandleScope handles(m_isolate); v8::Local newSource = toV8String(m_isolate, newContent); - if (!debugger().setScriptSource(scriptId, newSource, preview.fromMaybe(false), errorString, optOutCompileError, &m_pausedCallFrames, stackChanged)) + if (!m_debugger->setScriptSource(scriptId, newSource, preview.fromMaybe(false), errorString, optOutCompileError, &m_pausedCallFrames, stackChanged)) return; ScriptsMap::iterator it = m_scripts.find(scriptId); @@ -557,7 +566,7 @@ void V8DebuggerAgentImpl::restartFrame(ErrorString* errorString, { if (!assertPaused(errorString)) return; - InjectedScript::CallFrameScope scope(errorString, m_debugger, m_session->contextGroupId(), callFrameId); + InjectedScript::CallFrameScope scope(errorString, m_inspector, m_session->contextGroupId(), callFrameId); if (!scope.initialize()) return; if (scope.frameOrdinal() >= m_pausedCallFrames.size()) { @@ -571,7 +580,7 @@ void V8DebuggerAgentImpl::restartFrame(ErrorString* errorString, *errorString = "Internal error"; return; } - JavaScriptCallFrames frames = debugger().currentCallFrames(); + JavaScriptCallFrames frames = m_debugger->currentCallFrames(); m_pausedCallFrames.swap(frames); *newCallFrames = currentCallFrames(errorString); @@ -595,48 +604,48 @@ void V8DebuggerAgentImpl::getScriptSource(ErrorString* error, const String16& sc void V8DebuggerAgentImpl::schedulePauseOnNextStatement(const String16& breakReason, std::unique_ptr data) { - if (!enabled() || m_scheduledDebuggerStep == StepInto || m_javaScriptPauseScheduled || debugger().isPaused() || !debugger().breakpointsActivated()) + if (!enabled() || m_scheduledDebuggerStep == StepInto || m_javaScriptPauseScheduled || m_debugger->isPaused() || !m_debugger->breakpointsActivated()) return; m_breakReason = breakReason; m_breakAuxData = std::move(data); m_pausingOnNativeEvent = true; m_skipNextDebuggerStepOut = false; - debugger().setPauseOnNextStatement(true); + m_debugger->setPauseOnNextStatement(true); } void V8DebuggerAgentImpl::schedulePauseOnNextStatementIfSteppingInto() { DCHECK(enabled()); - if (m_scheduledDebuggerStep != StepInto || m_javaScriptPauseScheduled || debugger().isPaused()) + if (m_scheduledDebuggerStep != StepInto || m_javaScriptPauseScheduled || m_debugger->isPaused()) return; clearBreakDetails(); m_pausingOnNativeEvent = false; m_skippedStepFrameCount = 0; m_recursionLevelForStepFrame = 0; - debugger().setPauseOnNextStatement(true); + m_debugger->setPauseOnNextStatement(true); } void V8DebuggerAgentImpl::cancelPauseOnNextStatement() { - if (m_javaScriptPauseScheduled || debugger().isPaused()) + if (m_javaScriptPauseScheduled || m_debugger->isPaused()) return; clearBreakDetails(); m_pausingOnNativeEvent = false; - debugger().setPauseOnNextStatement(false); + m_debugger->setPauseOnNextStatement(false); } void V8DebuggerAgentImpl::pause(ErrorString* errorString) { if (!checkEnabled(errorString)) return; - if (m_javaScriptPauseScheduled || debugger().isPaused()) + if (m_javaScriptPauseScheduled || m_debugger->isPaused()) return; clearBreakDetails(); m_javaScriptPauseScheduled = true; m_scheduledDebuggerStep = NoStep; m_skippedStepFrameCount = 0; m_steppingFromFramework = false; - debugger().setPauseOnNextStatement(true); + m_debugger->setPauseOnNextStatement(true); } void V8DebuggerAgentImpl::resume(ErrorString* errorString) @@ -645,8 +654,8 @@ void V8DebuggerAgentImpl::resume(ErrorString* errorString) return; m_scheduledDebuggerStep = NoStep; m_steppingFromFramework = false; - m_session->releaseObjectGroup(V8InspectorSession::backtraceObjectGroup); - debugger().continueProgram(); + m_session->releaseObjectGroup(backtraceObjectGroup); + m_debugger->continueProgram(); } void V8DebuggerAgentImpl::stepOver(ErrorString* errorString) @@ -661,8 +670,8 @@ void V8DebuggerAgentImpl::stepOver(ErrorString* errorString) } m_scheduledDebuggerStep = StepOver; m_steppingFromFramework = isTopPausedCallFrameBlackboxed(); - m_session->releaseObjectGroup(V8InspectorSession::backtraceObjectGroup); - debugger().stepOverStatement(); + m_session->releaseObjectGroup(backtraceObjectGroup); + m_debugger->stepOverStatement(); } void V8DebuggerAgentImpl::stepInto(ErrorString* errorString) @@ -671,8 +680,8 @@ void V8DebuggerAgentImpl::stepInto(ErrorString* errorString) return; m_scheduledDebuggerStep = StepInto; m_steppingFromFramework = isTopPausedCallFrameBlackboxed(); - m_session->releaseObjectGroup(V8InspectorSession::backtraceObjectGroup); - debugger().stepIntoStatement(); + m_session->releaseObjectGroup(backtraceObjectGroup); + m_debugger->stepIntoStatement(); } void V8DebuggerAgentImpl::stepOut(ErrorString* errorString) @@ -683,21 +692,21 @@ void V8DebuggerAgentImpl::stepOut(ErrorString* errorString) m_skipNextDebuggerStepOut = false; m_recursionLevelForStepOut = 1; m_steppingFromFramework = isTopPausedCallFrameBlackboxed(); - m_session->releaseObjectGroup(V8InspectorSession::backtraceObjectGroup); - debugger().stepOutOfFunction(); + m_session->releaseObjectGroup(backtraceObjectGroup); + m_debugger->stepOutOfFunction(); } void V8DebuggerAgentImpl::setPauseOnExceptions(ErrorString* errorString, const String16& stringPauseState) { if (!checkEnabled(errorString)) return; - V8DebuggerImpl::PauseOnExceptionsState pauseState; + V8Debugger::PauseOnExceptionsState pauseState; if (stringPauseState == "none") { - pauseState = V8DebuggerImpl::DontPauseOnExceptions; + pauseState = V8Debugger::DontPauseOnExceptions; } else if (stringPauseState == "all") { - pauseState = V8DebuggerImpl::PauseOnAllExceptions; + pauseState = V8Debugger::PauseOnAllExceptions; } else if (stringPauseState == "uncaught") { - pauseState = V8DebuggerImpl::PauseOnUncaughtExceptions; + pauseState = V8Debugger::PauseOnUncaughtExceptions; } else { *errorString = "Unknown pause on exceptions mode: " + stringPauseState; return; @@ -707,8 +716,8 @@ void V8DebuggerAgentImpl::setPauseOnExceptions(ErrorString* errorString, const S void V8DebuggerAgentImpl::setPauseOnExceptionsImpl(ErrorString* errorString, int pauseState) { - debugger().setPauseOnExceptionsState(static_cast(pauseState)); - if (debugger().getPauseOnExceptionsState() != pauseState) + m_debugger->setPauseOnExceptionsState(static_cast(pauseState)); + if (m_debugger->getPauseOnExceptionsState() != pauseState) *errorString = "Internal error. Could not change pause on exceptions state"; else m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState); @@ -728,7 +737,7 @@ void V8DebuggerAgentImpl::evaluateOnCallFrame(ErrorString* errorString, { if (!assertPaused(errorString)) return; - InjectedScript::CallFrameScope scope(errorString, m_debugger, m_session->contextGroupId(), callFrameId); + InjectedScript::CallFrameScope scope(errorString, m_inspector, m_session->contextGroupId(), callFrameId); if (!scope.initialize()) return; if (scope.frameOrdinal() >= m_pausedCallFrames.size()) { @@ -767,7 +776,7 @@ void V8DebuggerAgentImpl::setVariableValue(ErrorString* errorString, return; if (!assertPaused(errorString)) return; - InjectedScript::CallFrameScope scope(errorString, m_debugger, m_session->contextGroupId(), callFrameId); + InjectedScript::CallFrameScope scope(errorString, m_inspector, m_session->contextGroupId(), callFrameId); if (!scope.initialize()) return; @@ -818,7 +827,7 @@ void V8DebuggerAgentImpl::setBlackboxPatterns(ErrorString* errorString, std::uni bool V8DebuggerAgentImpl::setBlackboxPattern(ErrorString* errorString, const String16& pattern) { - std::unique_ptr regex(new V8Regex(m_debugger, pattern, true /** caseSensitive */, false /** multiline */)); + std::unique_ptr regex(new V8Regex(m_inspector, pattern, true /** caseSensitive */, false /** multiline */)); if (!regex->isValid()) { *errorString = "Pattern parser error: " + regex->errorMessage(); return false; @@ -873,9 +882,6 @@ void V8DebuggerAgentImpl::willExecuteScript(int scriptId) // Fast return. if (m_scheduledDebuggerStep != StepInto) return; - // Skip unknown scripts (e.g. InjectedScript). - if (m_scripts.find(String16::fromInteger(scriptId)) == m_scripts.end()) - return; schedulePauseOnNextStatementIfSteppingInto(); } @@ -886,9 +892,9 @@ void V8DebuggerAgentImpl::didExecuteScript() void V8DebuggerAgentImpl::changeJavaScriptRecursionLevel(int step) { - if (m_javaScriptPauseScheduled && !m_skipAllPauses && !debugger().isPaused()) { + if (m_javaScriptPauseScheduled && !m_skipAllPauses && !m_debugger->isPaused()) { // Do not ever loose user's pause request until we have actually paused. - debugger().setPauseOnNextStatement(true); + m_debugger->setPauseOnNextStatement(true); } if (m_scheduledDebuggerStep == StepOut) { m_recursionLevelForStepOut += step; @@ -910,7 +916,7 @@ void V8DebuggerAgentImpl::changeJavaScriptRecursionLevel(int step) // from the old StepFrame. m_skippedStepFrameCount = 0; if (m_scheduledDebuggerStep == NoStep) - debugger().clearStepping(); + m_debugger->clearStepping(); else if (m_scheduledDebuggerStep == StepOut) m_skipNextDebuggerStepOut = true; } @@ -947,12 +953,12 @@ std::unique_ptr> V8DebuggerAgentImpl::currentCallFrames(ErrorSt if (hasInternalError(errorString, !details->Get(debuggerContext, toV8StringInternalized(m_isolate, "scopeChain")).ToLocal(&scopeChain) || !scopeChain->IsArray())) return Array::create(); v8::Local scopeChainArray = scopeChain.As(); - if (!injectedScript->wrapPropertyInArray(errorString, scopeChainArray, toV8StringInternalized(m_isolate, "object"), V8InspectorSession::backtraceObjectGroup)) + if (!injectedScript->wrapPropertyInArray(errorString, scopeChainArray, toV8StringInternalized(m_isolate, "object"), backtraceObjectGroup)) return Array::create(); - if (!injectedScript->wrapObjectProperty(errorString, details, toV8StringInternalized(m_isolate, "this"), V8InspectorSession::backtraceObjectGroup)) + if (!injectedScript->wrapObjectProperty(errorString, details, toV8StringInternalized(m_isolate, "this"), backtraceObjectGroup)) return Array::create(); if (details->Has(debuggerContext, toV8StringInternalized(m_isolate, "returnValue")).FromMaybe(false)) { - if (!injectedScript->wrapObjectProperty(errorString, details, toV8StringInternalized(m_isolate, "returnValue"), V8InspectorSession::backtraceObjectGroup)) + if (!injectedScript->wrapObjectProperty(errorString, details, toV8StringInternalized(m_isolate, "returnValue"), backtraceObjectGroup)) return Array::create(); } } else { @@ -992,17 +998,19 @@ void V8DebuggerAgentImpl::didParseSource(std::unique_ptr scrip String16 scriptSource = toProtocolString(script->source(m_isolate)); bool isDeprecatedSourceURL = false; if (!success) - script->setSourceURL(V8ContentSearchUtil::findSourceURL(scriptSource, false, &isDeprecatedSourceURL)); + script->setSourceURL(findSourceURL(scriptSource, false, &isDeprecatedSourceURL)); else if (script->hasSourceURL()) - V8ContentSearchUtil::findSourceURL(scriptSource, false, &isDeprecatedSourceURL); + findSourceURL(scriptSource, false, &isDeprecatedSourceURL); bool isDeprecatedSourceMappingURL = false; if (!success) - script->setSourceMappingURL(V8ContentSearchUtil::findSourceMapURL(scriptSource, false, &isDeprecatedSourceMappingURL)); + script->setSourceMappingURL(findSourceMapURL(scriptSource, false, &isDeprecatedSourceMappingURL)); else if (!script->sourceMappingURL().isEmpty()) - V8ContentSearchUtil::findSourceMapURL(scriptSource, false, &isDeprecatedSourceMappingURL); + findSourceMapURL(scriptSource, false, &isDeprecatedSourceMappingURL); - bool isContentScript = script->isContentScript(); + std::unique_ptr executionContextAuxData; + if (!script->executionContextAuxData().isEmpty()) + executionContextAuxData = protocol::DictionaryValue::cast(parseJSON(script->executionContextAuxData())); bool isInternalScript = script->isInternalScript(); bool isLiveEdit = script->isLiveEdit(); bool hasSourceURL = script->hasSourceURL(); @@ -1011,15 +1019,15 @@ void V8DebuggerAgentImpl::didParseSource(std::unique_ptr scrip bool deprecatedCommentWasUsed = isDeprecatedSourceURL || isDeprecatedSourceMappingURL; const Maybe& sourceMapURLParam = script->sourceMappingURL(); - const bool* isContentScriptParam = isContentScript ? &isContentScript : nullptr; + const Maybe& executionContextAuxDataParam(std::move(executionContextAuxData)); const bool* isInternalScriptParam = isInternalScript ? &isInternalScript : nullptr; const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; const bool* deprecatedCommentWasUsedParam = deprecatedCommentWasUsed ? &deprecatedCommentWasUsed : nullptr; if (success) - m_frontend.scriptParsed(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), isContentScriptParam, isInternalScriptParam, isLiveEditParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); + m_frontend.scriptParsed(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), executionContextAuxDataParam, isInternalScriptParam, isLiveEditParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); else - m_frontend.scriptFailedToParse(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), isContentScriptParam, isInternalScriptParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); + m_frontend.scriptFailedToParse(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), executionContextAuxDataParam, isInternalScriptParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); m_scripts[scriptId] = std::move(script); @@ -1037,7 +1045,7 @@ void V8DebuggerAgentImpl::didParseSource(std::unique_ptr scrip breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); String16 url; breakpointObject->getString(DebuggerAgentState::url, &url); - if (!matches(m_debugger, scriptURL, url, isRegex)) + if (!matches(m_inspector, scriptURL, url, isRegex)) continue; ScriptBreakpoint breakpoint; breakpointObject->getInteger(DebuggerAgentState::lineNumber, &breakpoint.lineNumber); @@ -1051,9 +1059,16 @@ void V8DebuggerAgentImpl::didParseSource(std::unique_ptr scrip V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(v8::Local context, v8::Local exception, const std::vector& hitBreakpoints, bool isPromiseRejection) { - JavaScriptCallFrames callFrames = debugger().currentCallFrames(1); + JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1); JavaScriptCallFrame* topCallFrame = !callFrames.empty() ? callFrames.begin()->get() : nullptr; + // Skip pause in internal scripts (e.g. InjectedScriptSource.js). + if (topCallFrame) { + ScriptsMap::iterator it = m_scripts.find(String16::fromInteger(topCallFrame->sourceID())); + if (it != m_scripts.end() && it->second->isInternalScript()) + return RequestStepFrame; + } + V8DebuggerAgentImpl::SkipPauseRequest result; if (m_skipAllPauses) result = RequestContinue; @@ -1074,18 +1089,18 @@ V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(v8::LocalcurrentCallFrames(); m_pausedCallFrames.swap(frames); m_pausedContext.Reset(m_isolate, context); v8::HandleScope handles(m_isolate); if (!exception.IsEmpty()) { ErrorString ignored; - InjectedScript* injectedScript = m_session->findInjectedScript(&ignored, V8DebuggerImpl::contextId(context)); + InjectedScript* injectedScript = m_session->findInjectedScript(&ignored, V8Debugger::contextId(context)); if (injectedScript) { m_breakReason = isPromiseRejection ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection : protocol::Debugger::Paused::ReasonEnum::Exception; ErrorString errorString; - auto obj = injectedScript->wrapObject(&errorString, exception, V8InspectorSession::backtraceObjectGroup); + auto obj = injectedScript->wrapObject(&errorString, exception, backtraceObjectGroup); m_breakAuxData = obj ? obj->serialize() : nullptr; // m_breakAuxData might be null after this. } @@ -1115,7 +1130,7 @@ V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(v8::LocalremoveBreakpoint(m_continueToLocationBreakpointId); m_continueToLocationBreakpointId = ""; } return result; @@ -1132,19 +1147,19 @@ void V8DebuggerAgentImpl::didContinue() void V8DebuggerAgentImpl::breakProgram(const String16& breakReason, std::unique_ptr data) { - if (!enabled() || m_skipAllPauses || !m_pausedContext.IsEmpty() || isCurrentCallStackEmptyOrBlackboxed() || !debugger().breakpointsActivated()) + if (!enabled() || m_skipAllPauses || !m_pausedContext.IsEmpty() || isCurrentCallStackEmptyOrBlackboxed() || !m_debugger->breakpointsActivated()) return; m_breakReason = breakReason; m_breakAuxData = std::move(data); m_scheduledDebuggerStep = NoStep; m_steppingFromFramework = false; m_pausingOnNativeEvent = false; - debugger().breakProgram(); + m_debugger->breakProgram(); } void V8DebuggerAgentImpl::breakProgramOnException(const String16& breakReason, std::unique_ptr data) { - if (!enabled() || m_debugger->getPauseOnExceptionsState() == V8DebuggerImpl::DontPauseOnExceptions) + if (!enabled() || m_debugger->getPauseOnExceptionsState() == V8Debugger::DontPauseOnExceptions) return; breakProgram(breakReason, std::move(data)); } diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h index b6aea619e10318..e777f3b2cd8af4 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerAgentImpl.h @@ -7,15 +7,19 @@ #include "platform/inspector_protocol/Collections.h" #include "platform/inspector_protocol/String16.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/JavaScriptCallFrame.h" #include "platform/v8_inspector/protocol/Debugger.h" #include namespace blink { +struct ScriptBreakpoint; class JavaScriptCallFrame; class PromiseTracker; +class V8Debugger; +class V8DebuggerScript; +class V8InspectorImpl; class V8InspectorSessionImpl; class V8Regex; class V8StackTraceImpl; @@ -122,7 +126,6 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { std::unique_ptr> positions) override; bool enabled(); - V8DebuggerImpl& debugger() { return *m_debugger; } void setBreakpointAt(const String16& scriptId, int lineNumber, int columnNumber, BreakpointSource, const String16& condition = String16()); void removeBreakpointAt(const String16& scriptId, int lineNumber, int columnNumber, BreakpointSource); @@ -133,7 +136,7 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { void reset(); - // Interface for V8DebuggerImpl + // Interface for V8InspectorImpl SkipPauseRequest didPause(v8::Local, v8::Local exception, const std::vector& hitBreakpoints, bool isPromiseRejection); void didContinue(); void didParseSource(std::unique_ptr, bool success); @@ -184,7 +187,8 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend { StepOut }; - V8DebuggerImpl* m_debugger; + V8InspectorImpl* m_inspector; + V8Debugger* m_debugger; V8InspectorSessionImpl* m_session; bool m_enabled; protocol::DictionaryValue* m_state; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h deleted file mode 100644 index 0be86bfb28ae52..00000000000000 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerImpl.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2010, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef V8DebuggerImpl_h -#define V8DebuggerImpl_h - -#include "platform/inspector_protocol/Collections.h" -#include "platform/inspector_protocol/Maybe.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/v8_inspector/JavaScriptCallFrame.h" -#include "platform/v8_inspector/V8DebuggerScript.h" -#include "platform/v8_inspector/protocol/Debugger.h" -#include "platform/v8_inspector/public/V8Debugger.h" - -#include -#include -#include - -#include - -namespace blink { - -using protocol::Maybe; - -struct ScriptBreakpoint; -class InspectedContext; -class V8ConsoleMessageStorage; -class V8DebuggerAgentImpl; -class V8InspectorSessionImpl; -class V8RuntimeAgentImpl; -class V8StackTraceImpl; - -class V8DebuggerImpl : public V8Debugger { - PROTOCOL_DISALLOW_COPY(V8DebuggerImpl); -public: - V8DebuggerImpl(v8::Isolate*, V8DebuggerClient*); - ~V8DebuggerImpl() override; - - static int contextId(v8::Local); - static int getGroupId(v8::Local); - - bool enabled() const; - - String16 setBreakpoint(const String16& sourceID, const ScriptBreakpoint&, int* actualLineNumber, int* actualColumnNumber, bool interstatementLocation); - void removeBreakpoint(const String16& breakpointId); - void setBreakpointsActivated(bool); - bool breakpointsActivated() const { return m_breakpointsActivated; } - - enum PauseOnExceptionsState { - DontPauseOnExceptions, - PauseOnAllExceptions, - PauseOnUncaughtExceptions - }; - PauseOnExceptionsState getPauseOnExceptionsState(); - void setPauseOnExceptionsState(PauseOnExceptionsState); - void setPauseOnNextStatement(bool); - bool canBreakProgram(); - void breakProgram(); - void continueProgram(); - void stepIntoStatement(); - void stepOverStatement(); - void stepOutOfFunction(); - void clearStepping(); - - bool setScriptSource(const String16& sourceID, v8::Local newSource, bool preview, ErrorString*, Maybe*, JavaScriptCallFrames* newCallFrames, Maybe* stackChanged); - JavaScriptCallFrames currentCallFrames(int limit = 0); - - // Each script inherits debug data from v8::Context where it has been compiled. - // Only scripts whose debug data matches |contextGroupId| will be reported. - // Passing 0 will result in reporting all scripts. - void getCompiledScripts(int contextGroupId, std::vector>&); - void debuggerAgentEnabled(); - void debuggerAgentDisabled(); - - bool isPaused(); - v8::Local pausedContext() { return m_pausedContext; } - int maxAsyncCallChainDepth() { return m_maxAsyncCallStackDepth; } - V8StackTraceImpl* currentAsyncCallChain(); - void setAsyncCallStackDepth(V8DebuggerAgentImpl*, int); - - v8::MaybeLocal functionScopes(v8::Local); - v8::MaybeLocal internalProperties(v8::Local, v8::Local); - - v8::Isolate* isolate() const { return m_isolate; } - V8DebuggerClient* client() { return m_client; } - - v8::MaybeLocal runCompiledScript(v8::Local, v8::Local); - v8::MaybeLocal callFunction(v8::Local, v8::Local, v8::Local receiver, int argc, v8::Local info[]); - v8::MaybeLocal compileAndRunInternalScript(v8::Local, v8::Local); - v8::Local compileInternalScript(v8::Local, v8::Local, const String16& fileName); - v8::Local regexContext(); - - void enableStackCapturingIfNeeded(); - void disableStackCapturingIfNeeded(); - V8ConsoleMessageStorage* ensureConsoleMessageStorage(int contextGroupId); - - // V8Debugger implementation - std::unique_ptr connect(int contextGroupId, protocol::FrontendChannel*, V8InspectorSessionClient*, const String16* state) override; - void contextCreated(const V8ContextInfo&) override; - void contextDestroyed(v8::Local) override; - void resetContextGroup(int contextGroupId) override; - void willExecuteScript(v8::Local, int scriptId) override; - void didExecuteScript(v8::Local) override; - void idleStarted() override; - void idleFinished() override; - void logToConsole(v8::Local, v8::Local arg1, v8::Local arg2) override; - void exceptionThrown(int contextGroupId, const String16& errorMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) override; - unsigned promiseRejected(v8::Local, const String16& errorMessage, v8::Local exception, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) override; - void promiseRejectionRevoked(v8::Local, unsigned promiseRejectionId) override; - std::unique_ptr createStackTrace(v8::Local) override; - std::unique_ptr captureStackTrace(bool fullStack) override; - void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) override; - void asyncTaskCanceled(void* task) override; - void asyncTaskStarted(void* task) override; - void asyncTaskFinished(void* task) override; - void allAsyncTasksCanceled() override; - - using ContextByIdMap = protocol::HashMap>; - void discardInspectedContext(int contextGroupId, int contextId); - const ContextByIdMap* contextGroup(int contextGroupId); - void disconnect(V8InspectorSessionImpl*); - V8InspectorSessionImpl* sessionForContextGroup(int contextGroupId); - InspectedContext* getContext(int groupId, int contextId) const; - -private: - void enable(); - void disable(); - V8DebuggerAgentImpl* findEnabledDebuggerAgent(int contextGroupId); - V8DebuggerAgentImpl* findEnabledDebuggerAgent(v8::Local); - - void compileDebuggerScript(); - v8::MaybeLocal callDebuggerMethod(const char* functionName, int argc, v8::Local argv[]); - v8::Local debuggerContext() const; - void clearBreakpoints(); - - static void breakProgramCallback(const v8::FunctionCallbackInfo&); - void handleProgramBreak(v8::Local pausedContext, v8::Local executionState, v8::Local exception, v8::Local hitBreakpoints, bool isPromiseRejection = false); - static void v8DebugEventCallback(const v8::Debug::EventDetails&); - v8::Local callInternalGetterFunction(v8::Local, const char* functionName); - void handleV8DebugEvent(const v8::Debug::EventDetails&); - - v8::Local v8InternalizedString(const char*) const; - - void handleV8AsyncTaskEvent(v8::Local, v8::Local executionState, v8::Local eventData); - - using ContextsByGroupMap = protocol::HashMap>; - - v8::Local collectionEntries(v8::Local, v8::Local); - v8::Local generatorObjectLocation(v8::Local); - v8::Local functionLocation(v8::Local, v8::Local); - - v8::Isolate* m_isolate; - V8DebuggerClient* m_client; - ContextsByGroupMap m_contexts; - using SessionMap = protocol::HashMap; - SessionMap m_sessions; - using ConsoleStorageMap = protocol::HashMap>; - ConsoleStorageMap m_consoleStorageMap; - int m_capturingStackTracesCount; - unsigned m_lastExceptionId; - int m_enabledAgentsCount; - bool m_breakpointsActivated; - v8::Global m_debuggerScript; - v8::Global m_debuggerContext; - v8::Local m_executionState; - v8::Local m_pausedContext; - bool m_runningNestedMessageLoop; - v8::Global m_regexContext; - - using AsyncTaskToStackTrace = protocol::HashMap>; - AsyncTaskToStackTrace m_asyncTaskStacks; - protocol::HashSet m_recurringTasks; - int m_maxAsyncCallStackDepth; - std::vector m_currentTasks; - std::vector> m_currentStacks; - protocol::HashMap m_maxAsyncCallStackDepthMap; -}; - -} // namespace blink - - -#endif // V8DebuggerImpl_h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp index 91a060b954e023..edb2fcdc7d333d 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.cpp @@ -78,7 +78,7 @@ V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, v8::Local o m_startColumn = object->Get(toV8StringInternalized(isolate, "startColumn"))->ToInteger(isolate)->Value(); m_endLine = object->Get(toV8StringInternalized(isolate, "endLine"))->ToInteger(isolate)->Value(); m_endColumn = object->Get(toV8StringInternalized(isolate, "endColumn"))->ToInteger(isolate)->Value(); - m_isContentScript = object->Get(toV8StringInternalized(isolate, "isContentScript"))->ToBoolean(isolate)->Value(); + m_executionContextAuxData = toProtocolStringWithTypeCheck(object->Get(toV8StringInternalized(isolate, "executionContextAuxData"))); m_isInternalScript = object->Get(toV8StringInternalized(isolate, "isInternalScript"))->ToBoolean(isolate)->Value(); m_executionContextId = object->Get(toV8StringInternalized(isolate, "executionContextId"))->ToInteger(isolate)->Value(); m_isLiveEdit = isLiveEdit; @@ -92,7 +92,7 @@ V8DebuggerScript::~V8DebuggerScript() { } -String16 V8DebuggerScript::sourceURL() const +const String16& V8DebuggerScript::sourceURL() const { return m_sourceURL.isEmpty() ? m_url : m_sourceURL; } diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.h index 60d93d81986493..d3e9d8d02d5faa 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8DebuggerScript.h @@ -42,19 +42,19 @@ class V8DebuggerScript { V8DebuggerScript(v8::Isolate*, v8::Local, bool isLiveEdit); ~V8DebuggerScript(); - String16 scriptId() const { return m_id; } - String16 url() const { return m_url; } + const String16& scriptId() const { return m_id; } + const String16& url() const { return m_url; } bool hasSourceURL() const { return !m_sourceURL.isEmpty(); } - String16 sourceURL() const; - String16 sourceMappingURL() const { return m_sourceMappingURL; } + const String16& sourceURL() const; + const String16& sourceMappingURL() const { return m_sourceMappingURL; } v8::Local source(v8::Isolate*) const; - String16 hash() const { return m_hash; } + const String16& hash() const { return m_hash; } int startLine() const { return m_startLine; } int startColumn() const { return m_startColumn; } int endLine() const { return m_endLine; } int endColumn() const { return m_endColumn; } int executionContextId() const { return m_executionContextId; } - bool isContentScript() const { return m_isContentScript; } + const String16& executionContextAuxData() const { return m_executionContextAuxData; } bool isInternalScript() const { return m_isInternalScript; } bool isLiveEdit() const { return m_isLiveEdit; } @@ -74,7 +74,7 @@ class V8DebuggerScript { int m_endLine; int m_endColumn; int m_executionContextId; - bool m_isContentScript; + String16 m_executionContextAuxData; bool m_isInternalScript; bool m_isLiveEdit; }; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp index 73edc7260f0719..bed316ef35ddd5 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.cpp @@ -32,16 +32,17 @@ #include "platform/inspector_protocol/Platform.h" #include "platform/v8_inspector/V8Compat.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8Debugger.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" #include namespace blink { -V8FunctionCall::V8FunctionCall(V8DebuggerImpl* debugger, v8::Local context, v8::Local value, const String16& name) - : m_debugger(debugger) +V8FunctionCall::V8FunctionCall(V8InspectorImpl* inspector, v8::Local context, v8::Local value, const String16& name) + : m_inspector(inspector) , m_context(context) , m_name(toV8String(context->GetIsolate(), name)) , m_value(value) @@ -68,11 +69,6 @@ void V8FunctionCall::appendArgument(bool argument) m_arguments.push_back(argument ? v8::True(m_context->GetIsolate()) : v8::False(m_context->GetIsolate())); } -void V8FunctionCall::appendUndefinedArgument() -{ - m_arguments.push_back(v8::Undefined(m_context->GetIsolate())); -} - v8::Local V8FunctionCall::call(bool& hadException, bool reportExceptions) { v8::TryCatch tryCatch(m_context->GetIsolate()); @@ -85,10 +81,6 @@ v8::Local V8FunctionCall::call(bool& hadException, bool reportExcepti v8::Local V8FunctionCall::callWithoutExceptionHandling() { - // TODO(dgozman): get rid of this check. - if (!m_debugger->client()->isExecutionAllowed()) - return v8::Local(); - v8::Local thisObject = v8::Local::Cast(m_value); v8::Local value; if (!thisObject->Get(m_context, m_name).ToLocal(&value)) @@ -103,23 +95,22 @@ v8::Local V8FunctionCall::callWithoutExceptionHandling() DCHECK(!info[i].IsEmpty()); } + int contextGroupId = V8Debugger::getGroupId(m_context); + if (contextGroupId) { + m_inspector->client()->muteMetrics(contextGroupId); + m_inspector->muteExceptions(contextGroupId); + } v8::MicrotasksScope microtasksScope(m_context->GetIsolate(), v8::MicrotasksScope::kDoNotRunMicrotasks); + v8::MaybeLocal maybeResult = function->Call(m_context, thisObject, m_arguments.size(), info.get()); + if (contextGroupId) { + m_inspector->client()->unmuteMetrics(contextGroupId); + m_inspector->unmuteExceptions(contextGroupId); + } + v8::Local result; - if (!function->Call(m_context, thisObject, m_arguments.size(), info.get()).ToLocal(&result)) + if (!maybeResult.ToLocal(&result)) return v8::Local(); return result; } -v8::Local V8FunctionCall::function() -{ - v8::TryCatch tryCatch(m_context->GetIsolate()); - v8::Local thisObject = v8::Local::Cast(m_value); - v8::Local value; - if (!thisObject->Get(m_context, m_name).ToLocal(&value)) - return v8::Local(); - - DCHECK(value->IsFunction()); - return v8::Local::Cast(value); -} - } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.h index 0b9d4e2a5096f1..acb5b5c3417243 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8FunctionCall.h @@ -37,25 +37,22 @@ namespace blink { -class V8DebuggerImpl; +class V8InspectorImpl; class V8FunctionCall { public: - V8FunctionCall(V8DebuggerImpl*, v8::Local, v8::Local, const String16& name); + V8FunctionCall(V8InspectorImpl*, v8::Local, v8::Local, const String16& name); void appendArgument(v8::Local); void appendArgument(const String16&); void appendArgument(int); void appendArgument(bool); - void appendUndefinedArgument(); v8::Local call(bool& hadException, bool reportExceptions = true); - v8::Local function(); v8::Local callWithoutExceptionHandling(); - v8::Local context() { return m_context; } protected: - V8DebuggerImpl* m_debugger; + V8InspectorImpl* m_inspector; v8::Local m_context; std::vector> m_arguments; v8::Local m_name; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp index 240dc3d27492e9..d256fe1cc29efa 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp @@ -5,10 +5,11 @@ #include "platform/v8_inspector/V8HeapProfilerAgentImpl.h" #include "platform/v8_inspector/InjectedScript.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8Debugger.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" #include #include @@ -50,14 +51,10 @@ class GlobalObjectNameResolver final : public v8::HeapProfiler::ObjectNameResolv const char* GetName(v8::Local object) override { - int contextId = V8DebuggerImpl::contextId(object->CreationContext()); - if (!contextId) + InspectedContext* context = m_session->inspector()->getContext(m_session->contextGroupId(), V8Debugger::contextId(object->CreationContext())); + if (!context) return ""; - ErrorString errorString; - InjectedScript* injectedScript = m_session->findInjectedScript(&errorString, contextId); - if (!injectedScript) - return ""; - String16 name = injectedScript->context()->origin(); + String16 name = context->origin(); size_t length = name.length(); if (m_offset + length + 1 >= m_strings.size()) return ""; @@ -149,7 +146,7 @@ class HeapStatsStream final : public v8::OutputStream { V8HeapProfilerAgentImpl::V8HeapProfilerAgentImpl(V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel, protocol::DictionaryValue* state) : m_session(session) - , m_isolate(session->debugger()->isolate()) + , m_isolate(session->inspector()->isolate()) , m_frontend(frontendChannel) , m_state(state) , m_hasTimer(false) @@ -253,7 +250,7 @@ void V8HeapProfilerAgentImpl::getObjectByHeapObjectId(ErrorString* error, const return; } - if (!m_session->debugger()->client()->isInspectableHeapObject(heapObject)) { + if (!m_session->inspector()->client()->isInspectableHeapObject(heapObject)) { *error = "Object is not available"; return; } @@ -279,7 +276,7 @@ void V8HeapProfilerAgentImpl::addInspectedHeapObject(ErrorString* errorString, c return; } - if (!m_session->debugger()->client()->isInspectableHeapObject(heapObject)) { + if (!m_session->inspector()->client()->isInspectableHeapObject(heapObject)) { *errorString = "Object is not available"; return; } @@ -290,8 +287,10 @@ void V8HeapProfilerAgentImpl::addInspectedHeapObject(ErrorString* errorString, c void V8HeapProfilerAgentImpl::getHeapObjectId(ErrorString* errorString, const String16& objectId, String16* heapSnapshotObjectId) { v8::HandleScope handles(m_isolate); - v8::Local value = m_session->findObject(errorString, objectId); - if (value.IsEmpty() || value->IsUndefined()) + v8::Local value; + v8::Local context; + String16 objectGroup; + if (!m_session->unwrapObject(errorString, objectId, &value, &context, &objectGroup) || value->IsUndefined()) return; v8::SnapshotObjectId id = m_isolate->GetHeapProfiler()->GetObjectId(value); @@ -302,7 +301,7 @@ void V8HeapProfilerAgentImpl::requestHeapStatsUpdate() { HeapStatsStream stream(&m_frontend); v8::SnapshotObjectId lastSeenObjectId = m_isolate->GetHeapProfiler()->GetHeapStats(&stream); - m_frontend.lastSeenObjectId(lastSeenObjectId, m_session->debugger()->client()->currentTimeMS()); + m_frontend.lastSeenObjectId(lastSeenObjectId, m_session->inspector()->client()->currentTimeMS()); } // static @@ -316,14 +315,14 @@ void V8HeapProfilerAgentImpl::startTrackingHeapObjectsInternal(bool trackAllocat m_isolate->GetHeapProfiler()->StartTrackingHeapObjects(trackAllocations); if (!m_hasTimer) { m_hasTimer = true; - m_session->debugger()->client()->startRepeatingTimer(0.05, &V8HeapProfilerAgentImpl::onTimer, reinterpret_cast(this)); + m_session->inspector()->client()->startRepeatingTimer(0.05, &V8HeapProfilerAgentImpl::onTimer, reinterpret_cast(this)); } } void V8HeapProfilerAgentImpl::stopTrackingHeapObjectsInternal() { if (m_hasTimer) { - m_session->debugger()->client()->cancelTimer(reinterpret_cast(this)); + m_session->inspector()->client()->cancelTimer(reinterpret_cast(this)); m_hasTimer = false; } m_isolate->GetHeapProfiler()->StopTrackingHeapObjects(); diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp index afa5138f6ec245..6f9a2a05cecc8f 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.cpp @@ -7,10 +7,11 @@ #include "platform/inspector_protocol/String16.h" #include "platform/v8_inspector/InjectedScriptNative.h" #include "platform/v8_inspector/V8Compat.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8Debugger.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InternalValueType.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" namespace blink { @@ -20,38 +21,36 @@ void setFunctionProperty(v8::Local context, v8::Local o { v8::Local funcName = toV8StringInternalized(context->GetIsolate(), name); v8::Local func; - if (!v8::Function::New(context, callback, external, 0, v8::ConstructorBehavior::kThrow).ToLocal(&func)) + if (!V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, callback, external, 0).ToLocal(&func)) return; func->SetName(funcName); if (!obj->Set(context, funcName, func).FromMaybe(false)) return; } -V8DebuggerImpl* unwrapDebugger(const v8::FunctionCallbackInfo& info) +V8InspectorImpl* unwrapInspector(const v8::FunctionCallbackInfo& info) { DCHECK(!info.Data().IsEmpty()); DCHECK(info.Data()->IsExternal()); - V8DebuggerImpl* debugger = static_cast(info.Data().As()->Value()); - DCHECK(debugger); - return debugger; + V8InspectorImpl* inspector = static_cast(info.Data().As()->Value()); + DCHECK(inspector); + return inspector; } } // namespace -v8::Local V8InjectedScriptHost::create(v8::Local context, V8DebuggerImpl* debugger) +v8::Local V8InjectedScriptHost::create(v8::Local context, V8InspectorImpl* inspector) { - v8::Isolate* isolate = debugger->isolate(); + v8::Isolate* isolate = inspector->isolate(); v8::Local injectedScriptHost = v8::Object::New(isolate); - v8::Local debuggerExternal = v8::External::New(isolate, debugger); + v8::Local debuggerExternal = v8::External::New(isolate, inspector); setFunctionProperty(context, injectedScriptHost, "internalConstructorName", V8InjectedScriptHost::internalConstructorNameCallback, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "formatAccessorsAsProperties", V8InjectedScriptHost::formatAccessorsAsProperties, debuggerExternal); - setFunctionProperty(context, injectedScriptHost, "isTypedArray", V8InjectedScriptHost::isTypedArrayCallback, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "subtype", V8InjectedScriptHost::subtypeCallback, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "getInternalProperties", V8InjectedScriptHost::getInternalPropertiesCallback, debuggerExternal); - setFunctionProperty(context, injectedScriptHost, "suppressWarningsAndCallFunction", V8InjectedScriptHost::suppressWarningsAndCallFunctionCallback, debuggerExternal); + setFunctionProperty(context, injectedScriptHost, "objectHasOwnProperty", V8InjectedScriptHost::objectHasOwnPropertyCallback, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "bind", V8InjectedScriptHost::bindCallback, debuggerExternal); setFunctionProperty(context, injectedScriptHost, "proxyTargetValue", V8InjectedScriptHost::proxyTargetValueCallback, debuggerExternal); - setFunctionProperty(context, injectedScriptHost, "prototype", V8InjectedScriptHost::prototypeCallback, debuggerExternal); return injectedScriptHost; } @@ -73,15 +72,7 @@ void V8InjectedScriptHost::formatAccessorsAsProperties(const v8::FunctionCallbac // Check that function is user-defined. if (info[1].As()->ScriptId() != v8::UnboundScript::kNoScriptId) return; - info.GetReturnValue().Set(unwrapDebugger(info)->client()->formatAccessorsAsProperties(info[0])); -} - -void V8InjectedScriptHost::isTypedArrayCallback(const v8::FunctionCallbackInfo& info) -{ - if (info.Length() < 1) - return; - - info.GetReturnValue().Set(info[0]->IsTypedArray()); + info.GetReturnValue().Set(unwrapInspector(info)->client()->formatAccessorsAsProperties(info[0])); } void V8InjectedScriptHost::subtypeCallback(const v8::FunctionCallbackInfo& info) @@ -98,10 +89,14 @@ void V8InjectedScriptHost::subtypeCallback(const v8::FunctionCallbackInfoIsArray() || value->IsTypedArray() || value->IsArgumentsObject()) { + if (value->IsArray() || value->IsArgumentsObject()) { info.GetReturnValue().Set(toV8StringInternalized(isolate, "array")); return; } + if (value->IsTypedArray()) { + info.GetReturnValue().Set(toV8StringInternalized(isolate, "typedarray")); + return; + } if (value->IsDate()) { info.GetReturnValue().Set(toV8StringInternalized(isolate, "date")); return; @@ -134,7 +129,11 @@ void V8InjectedScriptHost::subtypeCallback(const v8::FunctionCallbackInfoclient()->valueSubtype(value); + if (value->IsPromise()) { + info.GetReturnValue().Set(toV8StringInternalized(isolate, "promise")); + return; + } + String16 subtype = unwrapInspector(info)->client()->valueSubtype(value); if (!subtype.isEmpty()) { info.GetReturnValue().Set(toV8String(isolate, subtype)); return; @@ -146,51 +145,16 @@ void V8InjectedScriptHost::getInternalPropertiesCallback(const v8::FunctionCallb if (info.Length() < 1) return; v8::Local properties; - if (unwrapDebugger(info)->internalProperties(info.GetIsolate()->GetCurrentContext(), info[0]).ToLocal(&properties)) + if (unwrapInspector(info)->debugger()->internalProperties(info.GetIsolate()->GetCurrentContext(), info[0]).ToLocal(&properties)) info.GetReturnValue().Set(properties); } -void V8InjectedScriptHost::suppressWarningsAndCallFunctionCallback(const v8::FunctionCallbackInfo& info) +void V8InjectedScriptHost::objectHasOwnPropertyCallback(const v8::FunctionCallbackInfo& info) { - if (info.Length() < 2 || info.Length() > 3 || !info[0]->IsFunction()) { - NOTREACHED(); + if (info.Length() < 2 || !info[0]->IsObject() || !info[1]->IsString()) return; - } - if (info.Length() > 2 && (!info[2]->IsArray() && !info[2]->IsUndefined())) { - NOTREACHED(); - return; - } - - v8::Isolate* isolate = info.GetIsolate(); - v8::Local context = isolate->GetCurrentContext(); - - v8::Local function = info[0].As(); - v8::Local receiver = info[1]; - std::unique_ptr[]> argv = nullptr; - size_t argc = 0; - - if (info.Length() > 2 && info[2]->IsArray()) { - v8::Local arguments = info[2].As(); - argc = arguments->Length(); - argv.reset(new v8::Local[argc]); - for (size_t i = 0; i < argc; ++i) { - if (!arguments->Get(context, i).ToLocal(&argv[i])) - return; - } - } - - V8DebuggerImpl* debugger = unwrapDebugger(info); - int contextGroupId = V8DebuggerImpl::getGroupId(context); - if (contextGroupId) - debugger->client()->muteWarningsAndDeprecations(contextGroupId); - - v8::MicrotasksScope microtasks(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); - v8::Local result; - if (function->Call(context, receiver, argc, argv.get()).ToLocal(&result)) - info.GetReturnValue().Set(result); - - if (contextGroupId) - debugger->client()->unmuteWarningsAndDeprecations(contextGroupId); + bool result = info[0].As()->HasOwnProperty(info.GetIsolate()->GetCurrentContext(), v8::Local::Cast(info[1])).FromMaybe(false); + info.GetReturnValue().Set(v8::Boolean::New(info.GetIsolate(), result)); } void V8InjectedScriptHost::bindCallback(const v8::FunctionCallbackInfo& info) @@ -219,10 +183,4 @@ void V8InjectedScriptHost::proxyTargetValueCallback(const v8::FunctionCallbackIn info.GetReturnValue().Set(target); } -void V8InjectedScriptHost::prototypeCallback(const v8::FunctionCallbackInfo& info) -{ - DCHECK(info.Length() > 0 && info[0]->IsObject()); - info.GetReturnValue().Set(info[0].As()->GetPrototype()); -} - } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h index bf49fa71f40cea..496b5a77f801f0 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InjectedScriptHost.h @@ -9,7 +9,7 @@ namespace blink { -class V8DebuggerImpl; +class V8InspectorImpl; // SECURITY NOTE: Although the InjectedScriptHost is intended for use solely by the inspector, // a reference to the InjectedScriptHost may be leaked to the page being inspected. Thus, the @@ -19,18 +19,16 @@ class V8DebuggerImpl; class V8InjectedScriptHost { public: // We expect that debugger outlives any JS context and thus V8InjectedScriptHost (owned by JS) - // is destroyed before debugger. - static v8::Local create(v8::Local, V8DebuggerImpl*); + // is destroyed before inspector. + static v8::Local create(v8::Local, V8InspectorImpl*); private: static void internalConstructorNameCallback(const v8::FunctionCallbackInfo&); static void formatAccessorsAsProperties(const v8::FunctionCallbackInfo&); - static void isTypedArrayCallback(const v8::FunctionCallbackInfo&); static void subtypeCallback(const v8::FunctionCallbackInfo&); static void getInternalPropertiesCallback(const v8::FunctionCallbackInfo&); - static void suppressWarningsAndCallFunctionCallback(const v8::FunctionCallbackInfo&); + static void objectHasOwnPropertyCallback(const v8::FunctionCallbackInfo&); static void bindCallback(const v8::FunctionCallbackInfo&); static void proxyTargetValueCallback(const v8::FunctionCallbackInfo&); - static void prototypeCallback(const v8::FunctionCallbackInfo&); }; } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorImpl.cpp new file mode 100644 index 00000000000000..caac2020602009 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorImpl.cpp @@ -0,0 +1,350 @@ +/* + * Copyright (c) 2010-2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "platform/v8_inspector/V8InspectorImpl.h" + +#include "platform/v8_inspector/InspectedContext.h" +#include "platform/v8_inspector/V8Compat.h" +#include "platform/v8_inspector/V8ConsoleAgentImpl.h" +#include "platform/v8_inspector/V8ConsoleMessage.h" +#include "platform/v8_inspector/V8Debugger.h" +#include "platform/v8_inspector/V8DebuggerAgentImpl.h" +#include "platform/v8_inspector/V8InspectorSessionImpl.h" +#include "platform/v8_inspector/V8RuntimeAgentImpl.h" +#include "platform/v8_inspector/V8StackTraceImpl.h" +#include "platform/v8_inspector/V8StringUtil.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" +#include + +namespace blink { + +std::unique_ptr V8Inspector::create(v8::Isolate* isolate, V8InspectorClient* client) +{ + return wrapUnique(new V8InspectorImpl(isolate, client)); +} + +V8InspectorImpl::V8InspectorImpl(v8::Isolate* isolate, V8InspectorClient* client) + : m_isolate(isolate) + , m_client(client) + , m_debugger(new V8Debugger(isolate, this)) + , m_capturingStackTracesCount(0) + , m_lastExceptionId(0) +{ +} + +V8InspectorImpl::~V8InspectorImpl() +{ +} + +V8DebuggerAgentImpl* V8InspectorImpl::enabledDebuggerAgentForGroup(int contextGroupId) +{ + V8InspectorSessionImpl* session = sessionForContextGroup(contextGroupId); + V8DebuggerAgentImpl* agent = session ? session->debuggerAgent() : nullptr; + return agent && agent->enabled() ? agent : nullptr; +} + +V8RuntimeAgentImpl* V8InspectorImpl::enabledRuntimeAgentForGroup(int contextGroupId) +{ + V8InspectorSessionImpl* session = sessionForContextGroup(contextGroupId); + V8RuntimeAgentImpl* agent = session ? session->runtimeAgent() : nullptr; + return agent && agent->enabled() ? agent : nullptr; +} + +v8::MaybeLocal V8InspectorImpl::runCompiledScript(v8::Local context, v8::Local script) +{ + v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kRunMicrotasks); + int groupId = V8Debugger::getGroupId(context); + if (V8DebuggerAgentImpl* agent = enabledDebuggerAgentForGroup(groupId)) + agent->willExecuteScript(script->GetUnboundScript()->GetId()); + v8::MaybeLocal result = script->Run(context); + // Get agent from the map again, since it could have detached during script execution. + if (V8DebuggerAgentImpl* agent = enabledDebuggerAgentForGroup(groupId)) + agent->didExecuteScript(); + return result; +} + +v8::MaybeLocal V8InspectorImpl::callFunction(v8::Local function, v8::Local context, v8::Local receiver, int argc, v8::Local info[]) +{ + v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kRunMicrotasks); + int groupId = V8Debugger::getGroupId(context); + if (V8DebuggerAgentImpl* agent = enabledDebuggerAgentForGroup(groupId)) + agent->willExecuteScript(function->ScriptId()); + v8::MaybeLocal result = function->Call(context, receiver, argc, info); + // Get agent from the map again, since it could have detached during script execution. + if (V8DebuggerAgentImpl* agent = enabledDebuggerAgentForGroup(groupId)) + agent->didExecuteScript(); + return result; +} + +v8::MaybeLocal V8InspectorImpl::compileAndRunInternalScript(v8::Local context, v8::Local source) +{ + v8::Local script = compileScript(context, source, String(), true); + if (script.IsEmpty()) + return v8::MaybeLocal(); + v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); + return script->Run(context); +} + +v8::Local V8InspectorImpl::compileScript(v8::Local context, v8::Local code, const String16& fileName, bool markAsInternal) +{ + v8::ScriptOrigin origin( + toV8String(m_isolate, fileName), + v8::Integer::New(m_isolate, 0), + v8::Integer::New(m_isolate, 0), + v8::False(m_isolate), // sharable + v8::Local(), + v8::Boolean::New(m_isolate, markAsInternal), // internal + toV8String(m_isolate, String16()), // sourceMap + v8::True(m_isolate)); // opaqueresource + v8::ScriptCompiler::Source source(code, origin); + v8::Local script; + if (!v8::ScriptCompiler::Compile(context, &source, v8::ScriptCompiler::kNoCompileOptions).ToLocal(&script)) + return v8::Local(); + return script; +} + +void V8InspectorImpl::enableStackCapturingIfNeeded() +{ + if (!m_capturingStackTracesCount) + V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate, true); + ++m_capturingStackTracesCount; +} + +void V8InspectorImpl::disableStackCapturingIfNeeded() +{ + if (!(--m_capturingStackTracesCount)) + V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(m_isolate, false); +} + +void V8InspectorImpl::muteExceptions(int contextGroupId) +{ + m_muteExceptionsMap[contextGroupId]++; +} + +void V8InspectorImpl::unmuteExceptions(int contextGroupId) +{ + m_muteExceptionsMap[contextGroupId]--; +} + +V8ConsoleMessageStorage* V8InspectorImpl::ensureConsoleMessageStorage(int contextGroupId) +{ + ConsoleStorageMap::iterator storageIt = m_consoleStorageMap.find(contextGroupId); + if (storageIt == m_consoleStorageMap.end()) + storageIt = m_consoleStorageMap.insert(std::make_pair(contextGroupId, wrapUnique(new V8ConsoleMessageStorage(this, contextGroupId)))).first; + return storageIt->second.get(); +} + +std::unique_ptr V8InspectorImpl::createStackTrace(v8::Local stackTrace) +{ + return m_debugger->createStackTrace(stackTrace); +} + +std::unique_ptr V8InspectorImpl::connect(int contextGroupId, protocol::FrontendChannel* channel, const String16* state) +{ + DCHECK(m_sessions.find(contextGroupId) == m_sessions.cend()); + std::unique_ptr session = V8InspectorSessionImpl::create(this, contextGroupId, channel, state); + m_sessions[contextGroupId] = session.get(); + return std::move(session); +} + +void V8InspectorImpl::disconnect(V8InspectorSessionImpl* session) +{ + DCHECK(m_sessions.find(session->contextGroupId()) != m_sessions.end()); + m_sessions.erase(session->contextGroupId()); +} + +InspectedContext* V8InspectorImpl::getContext(int groupId, int contextId) const +{ + if (!groupId || !contextId) + return nullptr; + + ContextsByGroupMap::const_iterator contextGroupIt = m_contexts.find(groupId); + if (contextGroupIt == m_contexts.end()) + return nullptr; + + ContextByIdMap::iterator contextIt = contextGroupIt->second->find(contextId); + if (contextIt == contextGroupIt->second->end()) + return nullptr; + + return contextIt->second.get(); +} + +void V8InspectorImpl::contextCreated(const V8ContextInfo& info) +{ + int contextId = m_debugger->markContext(info); + + ContextsByGroupMap::iterator contextIt = m_contexts.find(info.contextGroupId); + if (contextIt == m_contexts.end()) + contextIt = m_contexts.insert(std::make_pair(info.contextGroupId, wrapUnique(new ContextByIdMap()))).first; + + const auto& contextById = contextIt->second; + + DCHECK(contextById->find(contextId) == contextById->cend()); + InspectedContext* context = new InspectedContext(this, info, contextId); + (*contextById)[contextId] = wrapUnique(context); + SessionMap::iterator sessionIt = m_sessions.find(info.contextGroupId); + if (sessionIt != m_sessions.end()) + sessionIt->second->runtimeAgent()->reportExecutionContextCreated(context); +} + +void V8InspectorImpl::contextDestroyed(v8::Local context) +{ + int contextId = V8Debugger::contextId(context); + int contextGroupId = V8Debugger::getGroupId(context); + + ConsoleStorageMap::iterator storageIt = m_consoleStorageMap.find(contextGroupId); + if (storageIt != m_consoleStorageMap.end()) + storageIt->second->contextDestroyed(contextId); + + InspectedContext* inspectedContext = getContext(contextGroupId, contextId); + if (!inspectedContext) + return; + + SessionMap::iterator iter = m_sessions.find(contextGroupId); + if (iter != m_sessions.end()) + iter->second->runtimeAgent()->reportExecutionContextDestroyed(inspectedContext); + discardInspectedContext(contextGroupId, contextId); +} + +void V8InspectorImpl::resetContextGroup(int contextGroupId) +{ + m_consoleStorageMap.erase(contextGroupId); + m_muteExceptionsMap.erase(contextGroupId); + SessionMap::iterator session = m_sessions.find(contextGroupId); + if (session != m_sessions.end()) + session->second->reset(); + m_contexts.erase(contextGroupId); +} + +void V8InspectorImpl::willExecuteScript(v8::Local context, int scriptId) +{ + if (V8DebuggerAgentImpl* agent = enabledDebuggerAgentForGroup(V8Debugger::getGroupId(context))) + agent->willExecuteScript(scriptId); +} + +void V8InspectorImpl::didExecuteScript(v8::Local context) +{ + if (V8DebuggerAgentImpl* agent = enabledDebuggerAgentForGroup(V8Debugger::getGroupId(context))) + agent->didExecuteScript(); +} + +void V8InspectorImpl::idleStarted() +{ + m_isolate->GetCpuProfiler()->SetIdle(true); +} + +void V8InspectorImpl::idleFinished() +{ + m_isolate->GetCpuProfiler()->SetIdle(false); +} + +unsigned V8InspectorImpl::exceptionThrown(v8::Local context, const String16& message, v8::Local exception, const String16& detailedMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr stackTrace, int scriptId) +{ + int contextGroupId = V8Debugger::getGroupId(context); + if (!contextGroupId || m_muteExceptionsMap[contextGroupId]) + return 0; + std::unique_ptr stackTraceImpl = wrapUnique(static_cast(stackTrace.release())); + unsigned exceptionId = ++m_lastExceptionId; + std::unique_ptr consoleMessage = V8ConsoleMessage::createForException(m_client->currentTimeMS(), detailedMessage, url, lineNumber, columnNumber, std::move(stackTraceImpl), scriptId, m_isolate, message, V8Debugger::contextId(context), exception, exceptionId); + ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage)); + return exceptionId; +} + +void V8InspectorImpl::exceptionRevoked(v8::Local context, unsigned exceptionId, const String16& message) +{ + int contextGroupId = V8Debugger::getGroupId(context); + if (!contextGroupId) + return; + + std::unique_ptr consoleMessage = V8ConsoleMessage::createForRevokedException(m_client->currentTimeMS(), message, exceptionId); + ensureConsoleMessageStorage(contextGroupId)->addMessage(std::move(consoleMessage)); +} + +std::unique_ptr V8InspectorImpl::captureStackTrace(bool fullStack) +{ + return m_debugger->captureStackTrace(fullStack); +} + +void V8InspectorImpl::asyncTaskScheduled(const String16& taskName, void* task, bool recurring) +{ + m_debugger->asyncTaskScheduled(taskName, task, recurring); +} + +void V8InspectorImpl::asyncTaskCanceled(void* task) +{ + m_debugger->asyncTaskCanceled(task); +} + +void V8InspectorImpl::asyncTaskStarted(void* task) +{ + m_debugger->asyncTaskStarted(task); +} + +void V8InspectorImpl::asyncTaskFinished(void* task) +{ + m_debugger->asyncTaskFinished(task); +} + +void V8InspectorImpl::allAsyncTasksCanceled() +{ + m_debugger->allAsyncTasksCanceled(); +} + +v8::Local V8InspectorImpl::regexContext() +{ + if (m_regexContext.IsEmpty()) + m_regexContext.Reset(m_isolate, v8::Context::New(m_isolate)); + return m_regexContext.Get(m_isolate); +} + +void V8InspectorImpl::discardInspectedContext(int contextGroupId, int contextId) +{ + if (!getContext(contextGroupId, contextId)) + return; + m_contexts[contextGroupId]->erase(contextId); + if (m_contexts[contextGroupId]->empty()) + m_contexts.erase(contextGroupId); +} + +const V8InspectorImpl::ContextByIdMap* V8InspectorImpl::contextGroup(int contextGroupId) +{ + ContextsByGroupMap::iterator iter = m_contexts.find(contextGroupId); + return iter == m_contexts.end() ? nullptr : iter->second.get(); +} + +V8InspectorSessionImpl* V8InspectorImpl::sessionForContextGroup(int contextGroupId) +{ + if (!contextGroupId) + return nullptr; + SessionMap::iterator iter = m_sessions.find(contextGroupId); + return iter == m_sessions.end() ? nullptr : iter->second; +} + +} // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorImpl.h new file mode 100644 index 00000000000000..e4dad93d9c6356 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorImpl.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef V8InspectorImpl_h +#define V8InspectorImpl_h + +#include "platform/inspector_protocol/Allocator.h" +#include "platform/inspector_protocol/Collections.h" +#include "platform/inspector_protocol/Platform.h" +#include "platform/v8_inspector/public/V8Inspector.h" + +#include +#include +#include + +namespace blink { + +class InspectedContext; +class V8ConsoleMessageStorage; +class V8Debugger; +class V8DebuggerAgentImpl; +class V8InspectorSessionImpl; +class V8RuntimeAgentImpl; +class V8StackTraceImpl; + +class V8InspectorImpl : public V8Inspector { + PROTOCOL_DISALLOW_COPY(V8InspectorImpl); +public: + V8InspectorImpl(v8::Isolate*, V8InspectorClient*); + ~V8InspectorImpl() override; + + v8::Isolate* isolate() const { return m_isolate; } + V8InspectorClient* client() { return m_client; } + V8Debugger* debugger() { return m_debugger.get(); } + + v8::MaybeLocal runCompiledScript(v8::Local, v8::Local); + v8::MaybeLocal callFunction(v8::Local, v8::Local, v8::Local receiver, int argc, v8::Local info[]); + v8::MaybeLocal compileAndRunInternalScript(v8::Local, v8::Local); + v8::Local compileScript(v8::Local, v8::Local, const String16& fileName, bool markAsInternal); + v8::Local regexContext(); + + // V8Inspector implementation. + std::unique_ptr connect(int contextGroupId, protocol::FrontendChannel*, const String16* state) override; + void contextCreated(const V8ContextInfo&) override; + void contextDestroyed(v8::Local) override; + void resetContextGroup(int contextGroupId) override; + void willExecuteScript(v8::Local, int scriptId) override; + void didExecuteScript(v8::Local) override; + void idleStarted() override; + void idleFinished() override; + unsigned exceptionThrown(v8::Local, const String16& message, v8::Local exception, const String16& detailedMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) override; + void exceptionRevoked(v8::Local, unsigned exceptionId, const String16& message) override; + std::unique_ptr createStackTrace(v8::Local) override; + std::unique_ptr captureStackTrace(bool fullStack) override; + void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) override; + void asyncTaskCanceled(void* task) override; + void asyncTaskStarted(void* task) override; + void asyncTaskFinished(void* task) override; + void allAsyncTasksCanceled() override; + + void enableStackCapturingIfNeeded(); + void disableStackCapturingIfNeeded(); + void muteExceptions(int contextGroupId); + void unmuteExceptions(int contextGroupId); + V8ConsoleMessageStorage* ensureConsoleMessageStorage(int contextGroupId); + using ContextByIdMap = protocol::HashMap>; + void discardInspectedContext(int contextGroupId, int contextId); + const ContextByIdMap* contextGroup(int contextGroupId); + void disconnect(V8InspectorSessionImpl*); + V8InspectorSessionImpl* sessionForContextGroup(int contextGroupId); + InspectedContext* getContext(int groupId, int contextId) const; + V8DebuggerAgentImpl* enabledDebuggerAgentForGroup(int contextGroupId); + V8RuntimeAgentImpl* enabledRuntimeAgentForGroup(int contextGroupId); + +private: + v8::Isolate* m_isolate; + V8InspectorClient* m_client; + std::unique_ptr m_debugger; + v8::Global m_regexContext; + int m_capturingStackTracesCount; + unsigned m_lastExceptionId; + + using MuteExceptionsMap = protocol::HashMap; + MuteExceptionsMap m_muteExceptionsMap; + + using ContextsByGroupMap = protocol::HashMap>; + ContextsByGroupMap m_contexts; + + using SessionMap = protocol::HashMap; + SessionMap m_sessions; + + using ConsoleStorageMap = protocol::HashMap>; + ConsoleStorageMap m_consoleStorageMap; +}; + +} // namespace blink + + +#endif // V8InspectorImpl_h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp index 88aac8c894d41a..814b7f91ea52c4 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.cpp @@ -9,33 +9,36 @@ #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/RemoteObjectId.h" #include "platform/v8_inspector/V8ConsoleAgentImpl.h" +#include "platform/v8_inspector/V8Debugger.h" #include "platform/v8_inspector/V8DebuggerAgentImpl.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" #include "platform/v8_inspector/V8HeapProfilerAgentImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8ProfilerAgentImpl.h" #include "platform/v8_inspector/V8RuntimeAgentImpl.h" +#include "platform/v8_inspector/V8StringUtil.h" #include "platform/v8_inspector/public/V8ContextInfo.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" namespace blink { -const char V8InspectorSession::backtraceObjectGroup[] = "backtrace"; - // static -bool V8InspectorSession::isV8ProtocolMethod(const String16& method) +bool V8InspectorSession::canDispatchMethod(const String16& method) { - return method.startWith("Debugger.") || method.startWith("HeapProfiler.") || method.startWith("Profiler.") || method.startWith("Runtime.") || method.startWith("Console."); + return method.startWith(protocol::Runtime::Metainfo::commandPrefix) + || method.startWith(protocol::Debugger::Metainfo::commandPrefix) + || method.startWith(protocol::Profiler::Metainfo::commandPrefix) + || method.startWith(protocol::HeapProfiler::Metainfo::commandPrefix) + || method.startWith(protocol::Console::Metainfo::commandPrefix); } -std::unique_ptr V8InspectorSessionImpl::create(V8DebuggerImpl* debugger, int contextGroupId, protocol::FrontendChannel* channel, V8InspectorSessionClient* client, const String16* state) +std::unique_ptr V8InspectorSessionImpl::create(V8InspectorImpl* inspector, int contextGroupId, protocol::FrontendChannel* channel, const String16* state) { - return wrapUnique(new V8InspectorSessionImpl(debugger, contextGroupId, channel, client, state)); + return wrapUnique(new V8InspectorSessionImpl(inspector, contextGroupId, channel, state)); } -V8InspectorSessionImpl::V8InspectorSessionImpl(V8DebuggerImpl* debugger, int contextGroupId, protocol::FrontendChannel* channel, V8InspectorSessionClient* client, const String16* savedState) +V8InspectorSessionImpl::V8InspectorSessionImpl(V8InspectorImpl* inspector, int contextGroupId, protocol::FrontendChannel* channel, const String16* savedState) : m_contextGroupId(contextGroupId) - , m_debugger(debugger) - , m_client(client) + , m_inspector(inspector) , m_customObjectFormatterEnabled(false) , m_dispatcher(channel) , m_state(nullptr) @@ -89,7 +92,7 @@ V8InspectorSessionImpl::~V8InspectorSessionImpl() m_runtimeAgent->disable(&errorString); discardInjectedScripts(); - m_debugger->disconnect(this); + m_inspector->disconnect(this); } protocol::DictionaryValue* V8InspectorSessionImpl::agentState(const String16& name) @@ -113,7 +116,7 @@ void V8InspectorSessionImpl::reset() void V8InspectorSessionImpl::discardInjectedScripts() { m_inspectedObjects.clear(); - const V8DebuggerImpl::ContextByIdMap* contexts = m_debugger->contextGroup(m_contextGroupId); + const V8InspectorImpl::ContextByIdMap* contexts = m_inspector->contextGroup(m_contextGroupId); if (!contexts) return; @@ -122,7 +125,7 @@ void V8InspectorSessionImpl::discardInjectedScripts() for (auto& idContext : *contexts) keys.push_back(idContext.first); for (auto& key : keys) { - contexts = m_debugger->contextGroup(m_contextGroupId); + contexts = m_inspector->contextGroup(m_contextGroupId); if (!contexts) continue; auto contextIt = contexts->find(key); @@ -138,8 +141,13 @@ InjectedScript* V8InspectorSessionImpl::findInjectedScript(ErrorString* errorStr return nullptr; } - const V8DebuggerImpl::ContextByIdMap* contexts = m_debugger->contextGroup(m_contextGroupId); - auto contextsIt = contexts ? contexts->find(contextId) : contexts->end(); + const V8InspectorImpl::ContextByIdMap* contexts = m_inspector->contextGroup(m_contextGroupId); + if (!contexts) { + *errorString = "Cannot find context with specified id"; + return nullptr; + } + + auto contextsIt = contexts->find(contextId); if (contextsIt == contexts->end()) { *errorString = "Cannot find context with specified id"; return nullptr; @@ -165,7 +173,7 @@ InjectedScript* V8InspectorSessionImpl::findInjectedScript(ErrorString* errorStr void V8InspectorSessionImpl::releaseObjectGroup(const String16& objectGroup) { - const V8DebuggerImpl::ContextByIdMap* contexts = m_debugger->contextGroup(m_contextGroupId); + const V8InspectorImpl::ContextByIdMap* contexts = m_inspector->contextGroup(m_contextGroupId); if (!contexts) return; @@ -173,7 +181,7 @@ void V8InspectorSessionImpl::releaseObjectGroup(const String16& objectGroup) for (auto& idContext : *contexts) keys.push_back(idContext.first); for (auto& key : keys) { - contexts = m_debugger->contextGroup(m_contextGroupId); + contexts = m_inspector->contextGroup(m_contextGroupId); if (!contexts) continue; auto contextsIt = contexts->find(key); @@ -185,29 +193,30 @@ void V8InspectorSessionImpl::releaseObjectGroup(const String16& objectGroup) } } -v8::Local V8InspectorSessionImpl::findObject(ErrorString* errorString, const String16& objectId, v8::Local* context, String16* groupName) +bool V8InspectorSessionImpl::unwrapObject(ErrorString* errorString, const String16& objectId, v8::Local* object, v8::Local* context, String16* objectGroup) { std::unique_ptr remoteId = RemoteObjectId::parse(errorString, objectId); if (!remoteId) - return v8::Local(); + return false; InjectedScript* injectedScript = findInjectedScript(errorString, remoteId.get()); if (!injectedScript) - return v8::Local(); - v8::Local objectValue; - injectedScript->findObject(errorString, *remoteId, &objectValue); - if (objectValue.IsEmpty()) - return v8::Local(); - if (context) - *context = injectedScript->context()->context(); - if (groupName) - *groupName = injectedScript->objectGroupName(*remoteId); - return objectValue; + return false; + if (!injectedScript->findObject(errorString, *remoteId, object)) + return false; + *context = injectedScript->context()->context(); + *objectGroup = injectedScript->objectGroupName(*remoteId); + return true; +} + +std::unique_ptr V8InspectorSessionImpl::wrapObject(v8::Local context, v8::Local value, const String16& groupName) +{ + return wrapObject(context, value, groupName, false); } std::unique_ptr V8InspectorSessionImpl::wrapObject(v8::Local context, v8::Local value, const String16& groupName, bool generatePreview) { ErrorString errorString; - InjectedScript* injectedScript = findInjectedScript(&errorString, V8DebuggerImpl::contextId(context)); + InjectedScript* injectedScript = findInjectedScript(&errorString, V8Debugger::contextId(context)); if (!injectedScript) return nullptr; return injectedScript->wrapObject(&errorString, value, groupName, false, generatePreview); @@ -216,7 +225,7 @@ std::unique_ptr V8InspectorSessionImpl::wrapObj std::unique_ptr V8InspectorSessionImpl::wrapTable(v8::Local context, v8::Local table, v8::Local columns) { ErrorString errorString; - InjectedScript* injectedScript = findInjectedScript(&errorString, V8DebuggerImpl::contextId(context)); + InjectedScript* injectedScript = findInjectedScript(&errorString, V8Debugger::contextId(context)); if (!injectedScript) return nullptr; return injectedScript->wrapTable(table, columns); @@ -225,7 +234,7 @@ std::unique_ptr V8InspectorSessionImpl::wrapTab void V8InspectorSessionImpl::setCustomObjectFormatterEnabled(bool enabled) { m_customObjectFormatterEnabled = enabled; - const V8DebuggerImpl::ContextByIdMap* contexts = m_debugger->contextGroup(m_contextGroupId); + const V8InspectorImpl::ContextByIdMap* contexts = m_inspector->contextGroup(m_contextGroupId); if (!contexts) return; for (auto& idContext : *contexts) { @@ -237,7 +246,7 @@ void V8InspectorSessionImpl::setCustomObjectFormatterEnabled(bool enabled) void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) { - const V8DebuggerImpl::ContextByIdMap* contexts = m_debugger->contextGroup(m_contextGroupId); + const V8InspectorImpl::ContextByIdMap* contexts = m_inspector->contextGroup(m_contextGroupId); if (!contexts) return; for (auto& idContext : *contexts) @@ -268,9 +277,9 @@ V8InspectorSession::Inspectable* V8InspectorSessionImpl::inspectedObject(unsigne return m_inspectedObjects[num].get(); } -void V8InspectorSessionImpl::schedulePauseOnNextStatement(const String16& breakReason, std::unique_ptr data) +void V8InspectorSessionImpl::schedulePauseOnNextStatement(const String16& breakReason, const String16& breakDetails) { - m_debuggerAgent->schedulePauseOnNextStatement(breakReason, std::move(data)); + m_debuggerAgent->schedulePauseOnNextStatement(breakReason, protocol::DictionaryValue::cast(parseJSON(breakDetails))); } void V8InspectorSessionImpl::cancelPauseOnNextStatement() @@ -278,9 +287,9 @@ void V8InspectorSessionImpl::cancelPauseOnNextStatement() m_debuggerAgent->cancelPauseOnNextStatement(); } -void V8InspectorSessionImpl::breakProgram(const String16& breakReason, std::unique_ptr data) +void V8InspectorSessionImpl::breakProgram(const String16& breakReason, const String16& breakDetails) { - m_debuggerAgent->breakProgram(breakReason, std::move(data)); + m_debuggerAgent->breakProgram(breakReason, protocol::DictionaryValue::cast(parseJSON(breakDetails))); } void V8InspectorSessionImpl::setSkipAllPauses(bool skip) @@ -301,4 +310,13 @@ void V8InspectorSessionImpl::stepOver() m_debuggerAgent->stepOver(&errorString); } +std::unique_ptr> V8InspectorSessionImpl::searchInTextByLines(const String16& text, const String16& query, bool caseSensitive, bool isRegex) +{ + std::vector> matches = searchInTextByLinesImpl(this, text, query, caseSensitive, isRegex); + std::unique_ptr> result = protocol::Array::create(); + for (size_t i = 0; i < matches.size(); ++i) + result->addItem(std::move(matches[i])); + return result; +} + } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h index 21753dac21b98a..d5ee2ef75f8019 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8InspectorSessionImpl.h @@ -11,7 +11,6 @@ #include "platform/inspector_protocol/String16.h" #include "platform/v8_inspector/protocol/Runtime.h" #include "platform/v8_inspector/public/V8InspectorSession.h" -#include "platform/v8_inspector/public/V8InspectorSessionClient.h" #include @@ -23,7 +22,7 @@ class InjectedScript; class RemoteObjectIdBase; class V8ConsoleAgentImpl; class V8DebuggerAgentImpl; -class V8DebuggerImpl; +class V8InspectorImpl; class V8HeapProfilerAgentImpl; class V8ProfilerAgentImpl; class V8RuntimeAgentImpl; @@ -31,11 +30,10 @@ class V8RuntimeAgentImpl; class V8InspectorSessionImpl : public V8InspectorSession { PROTOCOL_DISALLOW_COPY(V8InspectorSessionImpl); public: - static std::unique_ptr create(V8DebuggerImpl*, int contextGroupId, protocol::FrontendChannel*, V8InspectorSessionClient*, const String16* state); + static std::unique_ptr create(V8InspectorImpl*, int contextGroupId, protocol::FrontendChannel*, const String16* state); ~V8InspectorSessionImpl(); - V8DebuggerImpl* debugger() const { return m_debugger; } - V8InspectorSessionClient* client() const { return m_client; } + V8InspectorImpl* inspector() const { return m_inspector; } V8ConsoleAgentImpl* consoleAgent() { return m_consoleAgent.get(); } V8DebuggerAgentImpl* debuggerAgent() { return m_debuggerAgent.get(); } V8ProfilerAgentImpl* profilerAgent() { return m_profilerAgent.get(); } @@ -48,32 +46,33 @@ class V8InspectorSessionImpl : public V8InspectorSession { void discardInjectedScripts(); void reportAllContexts(V8RuntimeAgentImpl*); void setCustomObjectFormatterEnabled(bool); + std::unique_ptr wrapObject(v8::Local, v8::Local, const String16& groupName, bool generatePreview); + std::unique_ptr wrapTable(v8::Local, v8::Local table, v8::Local columns); // V8InspectorSession implementation. void dispatchProtocolMessage(const String16& message) override; String16 stateJSON() override; void addInspectedObject(std::unique_ptr) override; - void schedulePauseOnNextStatement(const String16& breakReason, std::unique_ptr data) override; + void schedulePauseOnNextStatement(const String16& breakReason, const String16& breakDetails) override; void cancelPauseOnNextStatement() override; - void breakProgram(const String16& breakReason, std::unique_ptr data) override; + void breakProgram(const String16& breakReason, const String16& breakDetails) override; void setSkipAllPauses(bool) override; void resume() override; void stepOver() override; + std::unique_ptr> searchInTextByLines(const String16& text, const String16& query, bool caseSensitive, bool isRegex) override; void releaseObjectGroup(const String16& objectGroup) override; - v8::Local findObject(ErrorString*, const String16& objectId, v8::Local* = nullptr, String16* groupName = nullptr) override; - std::unique_ptr wrapObject(v8::Local, v8::Local, const String16& groupName, bool generatePreview) override; - std::unique_ptr wrapTable(v8::Local, v8::Local table, v8::Local columns); + bool unwrapObject(ErrorString*, const String16& objectId, v8::Local*, v8::Local*, String16* objectGroup) override; + std::unique_ptr wrapObject(v8::Local, v8::Local, const String16& groupName) override; V8InspectorSession::Inspectable* inspectedObject(unsigned num); static const unsigned kInspectedObjectBufferSize = 5; private: - V8InspectorSessionImpl(V8DebuggerImpl*, int contextGroupId, protocol::FrontendChannel*, V8InspectorSessionClient*, const String16* state); + V8InspectorSessionImpl(V8InspectorImpl*, int contextGroupId, protocol::FrontendChannel*, const String16* state); protocol::DictionaryValue* agentState(const String16& name); int m_contextGroupId; - V8DebuggerImpl* m_debugger; - V8InspectorSessionClient* m_client; + V8InspectorImpl* m_inspector; bool m_customObjectFormatterEnabled; protocol::UberDispatcher m_dispatcher; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp index 0761f87e0d7a26..57712a9c107439 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.cpp @@ -5,7 +5,7 @@ #include "platform/v8_inspector/V8ProfilerAgentImpl.h" #include "platform/v8_inspector/Atomics.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8StackTraceImpl.h" #include "platform/v8_inspector/V8StringUtil.h" @@ -13,6 +13,9 @@ #include +#define ENSURE_V8_VERSION(major, minor) \ + (V8_MAJOR_VERSION * 1000 + V8_MINOR_VERSION >= (major) * 1000 + (minor)) + namespace blink { namespace ProfilerAgentState { @@ -102,9 +105,9 @@ std::unique_ptr createCPUProfile(v8::Isolate* is return profile; } -std::unique_ptr currentDebugLocation(V8DebuggerImpl* debugger) +std::unique_ptr currentDebugLocation(V8InspectorImpl* inspector) { - std::unique_ptr callStack = debugger->captureStackTrace(1); + std::unique_ptr callStack = inspector->captureStackTrace(1); std::unique_ptr location = protocol::Debugger::Location::create() .setScriptId(callStack->topScriptId()) .setLineNumber(callStack->topLineNumber()).build(); @@ -127,7 +130,8 @@ class V8ProfilerAgentImpl::ProfileDescriptor { V8ProfilerAgentImpl::V8ProfilerAgentImpl(V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel, protocol::DictionaryValue* state) : m_session(session) - , m_isolate(m_session->debugger()->isolate()) + , m_isolate(m_session->inspector()->isolate()) + , m_profiler(nullptr) , m_state(state) , m_frontend(frontendChannel) , m_enabled(false) @@ -137,6 +141,10 @@ V8ProfilerAgentImpl::V8ProfilerAgentImpl(V8InspectorSessionImpl* session, protoc V8ProfilerAgentImpl::~V8ProfilerAgentImpl() { +#if ENSURE_V8_VERSION(5, 4) + if (m_profiler) + m_profiler->Dispose(); +#endif } void V8ProfilerAgentImpl::consoleProfile(const String16& title) @@ -146,7 +154,7 @@ void V8ProfilerAgentImpl::consoleProfile(const String16& title) String16 id = nextProfileId(); m_startedProfiles.push_back(ProfileDescriptor(id, title)); startProfiling(id); - m_frontend.consoleProfileStarted(id, currentDebugLocation(m_session->debugger()), title); + m_frontend.consoleProfileStarted(id, currentDebugLocation(m_session->inspector()), title); } void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) @@ -177,7 +185,7 @@ void V8ProfilerAgentImpl::consoleProfileEnd(const String16& title) std::unique_ptr profile = stopProfiling(id, true); if (!profile) return; - std::unique_ptr location = currentDebugLocation(m_session->debugger()); + std::unique_ptr location = currentDebugLocation(m_session->inspector()); m_frontend.consoleProfileFinished(id, std::move(location), std::move(profile), resolvedTitle); } @@ -186,6 +194,10 @@ void V8ProfilerAgentImpl::enable(ErrorString*) if (m_enabled) return; m_enabled = true; +#if ENSURE_V8_VERSION(5, 4) + DCHECK(!m_profiler); + m_profiler = v8::CpuProfiler::New(m_isolate); +#endif m_state->setBoolean(ProfilerAgentState::profilerEnabled, true); } @@ -197,6 +209,10 @@ void V8ProfilerAgentImpl::disable(ErrorString* errorString) stopProfiling(m_startedProfiles[i - 1].m_id, false); m_startedProfiles.clear(); stop(nullptr, nullptr); +#if ENSURE_V8_VERSION(5, 4) + m_profiler->Dispose(); + m_profiler = nullptr; +#endif m_enabled = false; m_state->setBoolean(ProfilerAgentState::profilerEnabled, false); } @@ -208,7 +224,7 @@ void V8ProfilerAgentImpl::setSamplingInterval(ErrorString* error, int interval) return; } m_state->setInteger(ProfilerAgentState::samplingInterval, interval); - m_isolate->GetCpuProfiler()->SetSamplingInterval(interval); + profiler()->SetSamplingInterval(interval); } void V8ProfilerAgentImpl::restore() @@ -217,10 +233,14 @@ void V8ProfilerAgentImpl::restore() if (!m_state->booleanProperty(ProfilerAgentState::profilerEnabled, false)) return; m_enabled = true; +#if ENSURE_V8_VERSION(5, 4) + DCHECK(!m_profiler); + m_profiler = v8::CpuProfiler::New(m_isolate); +#endif int interval = 0; m_state->getInteger(ProfilerAgentState::samplingInterval, &interval); if (interval) - m_isolate->GetCpuProfiler()->SetSamplingInterval(interval); + profiler()->SetSamplingInterval(interval); if (m_state->booleanProperty(ProfilerAgentState::userInitiatedProfiling, false)) { ErrorString error; start(&error); @@ -239,7 +259,6 @@ void V8ProfilerAgentImpl::start(ErrorString* error) m_frontendInitiatedProfileId = nextProfileId(); startProfiling(m_frontendInitiatedProfileId); m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true); - m_session->client()->profilingStarted(); } void V8ProfilerAgentImpl::stop(ErrorString* errorString, std::unique_ptr* profile) @@ -258,7 +277,6 @@ void V8ProfilerAgentImpl::stop(ErrorString* errorString, std::unique_ptrsetBoolean(ProfilerAgentState::userInitiatedProfiling, false); - m_session->client()->profilingStopped(); } String16 V8ProfilerAgentImpl::nextProfileId() @@ -269,13 +287,13 @@ String16 V8ProfilerAgentImpl::nextProfileId() void V8ProfilerAgentImpl::startProfiling(const String16& title) { v8::HandleScope handleScope(m_isolate); - m_isolate->GetCpuProfiler()->StartProfiling(toV8String(m_isolate, title), true); + profiler()->StartProfiling(toV8String(m_isolate, title), true); } std::unique_ptr V8ProfilerAgentImpl::stopProfiling(const String16& title, bool serialize) { v8::HandleScope handleScope(m_isolate); - v8::CpuProfile* profile = m_isolate->GetCpuProfiler()->StopProfiling(toV8String(m_isolate, title)); + v8::CpuProfile* profile = profiler()->StopProfiling(toV8String(m_isolate, title)); if (!profile) return nullptr; std::unique_ptr result; @@ -290,4 +308,13 @@ bool V8ProfilerAgentImpl::isRecording() const return m_recordingCPUProfile || !m_startedProfiles.empty(); } +v8::CpuProfiler* V8ProfilerAgentImpl::profiler() +{ +#if ENSURE_V8_VERSION(5, 4) + return m_profiler; +#else + return m_isolate->GetCpuProfiler(); +#endif +} + } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h index 03b8f703ae1215..4bbe00be679f9e 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8ProfilerAgentImpl.h @@ -12,6 +12,7 @@ #include namespace v8 { +class CpuProfiler; class Isolate; } @@ -39,6 +40,7 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend { private: String16 nextProfileId(); + v8::CpuProfiler* profiler(); void startProfiling(const String16& title); std::unique_ptr stopProfiling(const String16& title, bool serialize); @@ -47,6 +49,7 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend { V8InspectorSessionImpl* m_session; v8::Isolate* m_isolate; + v8::CpuProfiler* m_profiler; protocol::DictionaryValue* m_state; protocol::Profiler::Frontend m_frontend; bool m_enabled; @@ -58,5 +61,4 @@ class V8ProfilerAgentImpl : public protocol::Profiler::Backend { } // namespace blink - #endif // !defined(V8ProfilerAgentImpl_h) diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.cpp index 304b715f797b51..96cd350d814317 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.cpp @@ -5,20 +5,20 @@ #include "platform/v8_inspector/V8Regex.h" #include "platform/v8_inspector/V8Compat.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" #include namespace blink { -V8Regex::V8Regex(V8DebuggerImpl* debugger, const String16& pattern, bool caseSensitive, bool multiline) - : m_debugger(debugger) +V8Regex::V8Regex(V8InspectorImpl* inspector, const String16& pattern, bool caseSensitive, bool multiline) + : m_inspector(inspector) { - v8::Isolate* isolate = m_debugger->isolate(); + v8::Isolate* isolate = m_inspector->isolate(); v8::HandleScope handleScope(isolate); - v8::Local context = m_debugger->regexContext(); + v8::Local context = m_inspector->regexContext(); v8::Context::Scope contextScope(context); v8::TryCatch tryCatch(isolate); @@ -49,9 +49,9 @@ int V8Regex::match(const String16& string, int startFrom, int* matchLength) cons if (string.length() > INT_MAX) return -1; - v8::Isolate* isolate = m_debugger->isolate(); + v8::Isolate* isolate = m_inspector->isolate(); v8::HandleScope handleScope(isolate); - v8::Local context = m_debugger->regexContext(); + v8::Local context = m_inspector->regexContext(); v8::MicrotasksScope microtasks(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); v8::TryCatch tryCatch(isolate); diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.h index 983717d971a0bc..e4900e2d5407be 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8Regex.h @@ -11,7 +11,7 @@ namespace blink { -class V8DebuggerImpl; +class V8InspectorImpl; enum MultilineMode { MultilineDisabled, @@ -21,13 +21,13 @@ enum MultilineMode { class V8Regex { PROTOCOL_DISALLOW_COPY(V8Regex); public: - V8Regex(V8DebuggerImpl*, const String16&, bool caseSensitive, bool multiline = false); + V8Regex(V8InspectorImpl*, const String16&, bool caseSensitive, bool multiline = false); int match(const String16&, int startFrom = 0, int* matchLength = 0) const; bool isValid() const { return !m_regex.IsEmpty(); } const String16& errorMessage() const { return m_errorMessage; } private: - V8DebuggerImpl* m_debugger; + V8InspectorImpl* m_inspector; v8::Global m_regex; String16 m_errorMessage; }; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp index c9a235ae29e5fd..79d8cc9ce001ab 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.cpp @@ -30,15 +30,20 @@ #include "platform/v8_inspector/V8RuntimeAgentImpl.h" +#include "platform/inspector_protocol/Parser.h" #include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/InjectedScript.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/RemoteObjectId.h" +#include "platform/v8_inspector/V8Compat.h" #include "platform/v8_inspector/V8ConsoleMessage.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8Debugger.h" +#include "platform/v8_inspector/V8DebuggerAgentImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" +#include "platform/v8_inspector/V8StackTraceImpl.h" #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" namespace blink { @@ -57,11 +62,165 @@ static bool hasInternalError(ErrorString* errorString, bool hasError) return hasError; } +namespace { + +template +class ProtocolPromiseHandler { +public: + static void add(V8InspectorImpl* inspector, v8::Local context, v8::MaybeLocal value, const String16& notPromiseError, int contextGroupId, int executionContextId, const String16& objectGroup, bool returnByValue, bool generatePreview, std::unique_ptr callback) + { + if (value.IsEmpty()) { + callback->sendFailure("Internal error"); + return; + } + if (!value.ToLocalChecked()->IsPromise()) { + callback->sendFailure(notPromiseError); + return; + } + v8::Local promise = v8::Local::Cast(value.ToLocalChecked()); + Callback* rawCallback = callback.get(); + ProtocolPromiseHandler* handler = new ProtocolPromiseHandler(inspector, contextGroupId, executionContextId, objectGroup, returnByValue, generatePreview, std::move(callback)); + v8::Local wrapper = handler->m_wrapper.Get(inspector->isolate()); + + v8::Local thenCallbackFunction = V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, thenCallback, wrapper, 0).ToLocalChecked(); + if (promise->Then(context, thenCallbackFunction).IsEmpty()) { + rawCallback->sendFailure("Internal error"); + return; + } + v8::Local catchCallbackFunction = V8_FUNCTION_NEW_REMOVE_PROTOTYPE(context, catchCallback, wrapper, 0).ToLocalChecked(); + if (promise->Catch(context, catchCallbackFunction).IsEmpty()) { + rawCallback->sendFailure("Internal error"); + return; + } + } +private: + static void thenCallback(const v8::FunctionCallbackInfo& info) + { + ProtocolPromiseHandler* handler = static_cast*>(info.Data().As()->Value()); + DCHECK(handler); + v8::Local value = info.Length() > 0 ? info[0] : v8::Local::Cast(v8::Undefined(info.GetIsolate())); + handler->m_callback->sendSuccess(handler->wrapObject(value), Maybe(), Maybe()); + } + + static void catchCallback(const v8::FunctionCallbackInfo& info) + { + ProtocolPromiseHandler* handler = static_cast*>(info.Data().As()->Value()); + DCHECK(handler); + v8::Local value = info.Length() > 0 ? info[0] : v8::Local::Cast(v8::Undefined(info.GetIsolate())); + + std::unique_ptr exceptionDetails; + std::unique_ptr stack = handler->m_inspector->debugger()->captureStackTrace(true); + if (stack) { + exceptionDetails = protocol::Runtime::ExceptionDetails::create() + .setText("Promise was rejected") + .setLineNumber(!stack->isEmpty() ? stack->topLineNumber() : 0) + .setColumnNumber(!stack->isEmpty() ? stack->topColumnNumber() : 0) + .setScriptId(!stack->isEmpty() ? stack->topScriptId() : String16()) + .setStackTrace(stack->buildInspectorObjectImpl()) + .build(); + } + handler->m_callback->sendSuccess(handler->wrapObject(value), true, std::move(exceptionDetails)); + } + + ProtocolPromiseHandler(V8InspectorImpl* inspector, int contextGroupId, int executionContextId, const String16& objectGroup, bool returnByValue, bool generatePreview, std::unique_ptr callback) + : m_inspector(inspector) + , m_contextGroupId(contextGroupId) + , m_executionContextId(executionContextId) + , m_objectGroup(objectGroup) + , m_returnByValue(returnByValue) + , m_generatePreview(generatePreview) + , m_callback(std::move(callback)) + , m_wrapper(inspector->isolate(), v8::External::New(inspector->isolate(), this)) + { + m_wrapper.SetWeak(this, cleanup, v8::WeakCallbackType::kParameter); + } + + static void cleanup(const v8::WeakCallbackInfo>& data) + { + if (!data.GetParameter()->m_wrapper.IsEmpty()) { + data.GetParameter()->m_wrapper.Reset(); + data.SetSecondPassCallback(cleanup); + } else { + data.GetParameter()->m_callback->sendFailure("Promise was collected"); + delete data.GetParameter(); + } + } + + std::unique_ptr wrapObject(v8::Local value) + { + ErrorString errorString; + InjectedScript::ContextScope scope(&errorString, m_inspector, m_contextGroupId, m_executionContextId); + if (!scope.initialize()) { + m_callback->sendFailure(errorString); + return nullptr; + } + std::unique_ptr wrappedValue = scope.injectedScript()->wrapObject(&errorString, value, m_objectGroup, m_returnByValue, m_generatePreview); + if (!wrappedValue) { + m_callback->sendFailure(errorString); + return nullptr; + } + return wrappedValue; + } + + V8InspectorImpl* m_inspector; + int m_contextGroupId; + int m_executionContextId; + String16 m_objectGroup; + bool m_returnByValue; + bool m_generatePreview; + std::unique_ptr m_callback; + v8::Global m_wrapper; +}; + +template +bool wrapEvaluateResultAsync(InjectedScript* injectedScript, v8::MaybeLocal maybeResultValue, const v8::TryCatch& tryCatch, const String16& objectGroup, bool returnByValue, bool generatePreview, Callback* callback) +{ + std::unique_ptr result; + Maybe wasThrown; + Maybe exceptionDetails; + + ErrorString errorString; + injectedScript->wrapEvaluateResult(&errorString, + maybeResultValue, + tryCatch, + objectGroup, + returnByValue, + generatePreview, + &result, + &wasThrown, + &exceptionDetails); + if (errorString.isEmpty()) { + callback->sendSuccess(std::move(result), wasThrown, exceptionDetails); + return true; + } + callback->sendFailure(errorString); + return false; +} + +int ensureContext(ErrorString* errorString, V8InspectorImpl* inspector, int contextGroupId, const Maybe& executionContextId) +{ + int contextId; + if (executionContextId.isJust()) { + contextId = executionContextId.fromJust(); + } else { + v8::HandleScope handles(inspector->isolate()); + v8::Local defaultContext = inspector->client()->ensureDefaultContextInGroup(contextGroupId); + if (defaultContext.IsEmpty()) { + *errorString = "Cannot find default execution context"; + return 0; + } + contextId = V8Debugger::contextId(defaultContext); + } + return contextId; +} + +} // namespace + V8RuntimeAgentImpl::V8RuntimeAgentImpl(V8InspectorSessionImpl* session, protocol::FrontendChannel* FrontendChannel, protocol::DictionaryValue* state) : m_session(session) , m_state(state) , m_frontend(FrontendChannel) - , m_debugger(session->debugger()) + , m_inspector(session->inspector()) , m_enabled(false) { } @@ -71,7 +230,6 @@ V8RuntimeAgentImpl::~V8RuntimeAgentImpl() } void V8RuntimeAgentImpl::evaluate( - ErrorString* errorString, const String16& expression, const Maybe& objectGroup, const Maybe& includeCommandLineAPI, @@ -80,34 +238,31 @@ void V8RuntimeAgentImpl::evaluate( const Maybe& returnByValue, const Maybe& generatePreview, const Maybe& userGesture, - std::unique_ptr* result, - Maybe* wasThrown, - Maybe* exceptionDetails) + const Maybe& awaitPromise, + std::unique_ptr callback) { - int contextId; - if (executionContextId.isJust()) { - contextId = executionContextId.fromJust(); - } else { - v8::HandleScope handles(m_debugger->isolate()); - v8::Local defaultContext = m_debugger->client()->ensureDefaultContextInGroup(m_session->contextGroupId()); - if (defaultContext.IsEmpty()) { - *errorString = "Cannot find default execution context"; - return; - } - contextId = V8DebuggerImpl::contextId(defaultContext); + ErrorString errorString; + int contextId = ensureContext(&errorString, m_inspector, m_session->contextGroupId(), executionContextId); + if (!errorString.isEmpty()) { + callback->sendFailure(errorString); + return; } - InjectedScript::ContextScope scope(errorString, m_debugger, m_session->contextGroupId(), contextId); - if (!scope.initialize()) + InjectedScript::ContextScope scope(&errorString, m_inspector, m_session->contextGroupId(), contextId); + if (!scope.initialize()) { + callback->sendFailure(errorString); return; + } if (doNotPauseOnExceptionsAndMuteConsole.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole(); if (userGesture.fromMaybe(false)) scope.pretendUserGesture(); - if (includeCommandLineAPI.fromMaybe(false) && !scope.installCommandLineAPI()) + if (includeCommandLineAPI.fromMaybe(false) && !scope.installCommandLineAPI()) { + callback->sendFailure(errorString); return; + } bool evalIsDisabled = !scope.context()->IsCodeGenerationFromStringsAllowed(); // Temporarily enable allow evals for inspector. @@ -115,28 +270,62 @@ void V8RuntimeAgentImpl::evaluate( scope.context()->AllowCodeGenerationFromStrings(true); v8::MaybeLocal maybeResultValue; - v8::Local script = m_debugger->compileInternalScript(scope.context(), toV8String(m_debugger->isolate(), expression), String16()); + v8::Local script = m_inspector->compileScript(scope.context(), toV8String(m_inspector->isolate(), expression), String16(), false); if (!script.IsEmpty()) - maybeResultValue = m_debugger->runCompiledScript(scope.context(), script); + maybeResultValue = m_inspector->runCompiledScript(scope.context(), script); if (evalIsDisabled) scope.context()->AllowCodeGenerationFromStrings(false); // Re-initialize after running client's code, as it could have destroyed context or session. - if (!scope.initialize()) + if (!scope.initialize()) { + callback->sendFailure(errorString); return; - scope.injectedScript()->wrapEvaluateResult(errorString, + } + + if (!awaitPromise.fromMaybe(false) || scope.tryCatch().HasCaught()) { + wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""), returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), callback.get()); + return; + } + ProtocolPromiseHandler::add( + m_inspector, + scope.context(), maybeResultValue, - scope.tryCatch(), + "Result of the evaluation is not a promise", + m_session->contextGroupId(), + scope.injectedScript()->context()->contextId(), objectGroup.fromMaybe(""), returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), - result, - wasThrown, - exceptionDetails); + std::move(callback)); +} + +void V8RuntimeAgentImpl::awaitPromise( + const String16& promiseObjectId, + const Maybe& returnByValue, + const Maybe& generatePreview, + std::unique_ptr callback) +{ + ErrorString errorString; + InjectedScript::ObjectScope scope(&errorString, m_inspector, m_session->contextGroupId(), promiseObjectId); + if (!scope.initialize()) { + callback->sendFailure(errorString); + return; + } + ProtocolPromiseHandler::add( + m_inspector, + scope.context(), + scope.object(), + "Could not find promise with given id", + m_session->contextGroupId(), + scope.injectedScript()->context()->contextId(), + scope.objectGroupName(), + returnByValue.fromMaybe(false), + generatePreview.fromMaybe(false), + std::move(callback)); } -void V8RuntimeAgentImpl::callFunctionOn(ErrorString* errorString, +void V8RuntimeAgentImpl::callFunctionOn( const String16& objectId, const String16& expression, const Maybe>& optionalArguments, @@ -144,12 +333,15 @@ void V8RuntimeAgentImpl::callFunctionOn(ErrorString* errorString, const Maybe& returnByValue, const Maybe& generatePreview, const Maybe& userGesture, - std::unique_ptr* result, - Maybe* wasThrown) + const Maybe& awaitPromise, + std::unique_ptr callback) { - InjectedScript::ObjectScope scope(errorString, m_debugger, m_session->contextGroupId(), objectId); - if (!scope.initialize()) + ErrorString errorString; + InjectedScript::ObjectScope scope(&errorString, m_inspector, m_session->contextGroupId(), objectId); + if (!scope.initialize()) { + callback->sendFailure(errorString); return; + } std::unique_ptr[]> argv = nullptr; int argc = 0; @@ -159,8 +351,10 @@ void V8RuntimeAgentImpl::callFunctionOn(ErrorString* errorString, argv.reset(new v8::Local[argc]); for (int i = 0; i < argc; ++i) { v8::Local argumentValue; - if (!scope.injectedScript()->resolveCallArgument(errorString, arguments->get(i)).ToLocal(&argumentValue)) + if (!scope.injectedScript()->resolveCallArgument(&errorString, arguments->get(i)).ToLocal(&argumentValue)) { + callback->sendFailure(errorString); return; + } argv[i] = argumentValue; } } @@ -170,28 +364,47 @@ void V8RuntimeAgentImpl::callFunctionOn(ErrorString* errorString, if (userGesture.fromMaybe(false)) scope.pretendUserGesture(); - v8::MaybeLocal maybeFunctionValue = m_debugger->compileAndRunInternalScript(scope.context(), toV8String(m_debugger->isolate(), "(" + expression + ")")); + v8::MaybeLocal maybeFunctionValue = m_inspector->compileAndRunInternalScript(scope.context(), toV8String(m_inspector->isolate(), "(" + expression + ")")); // Re-initialize after running client's code, as it could have destroyed context or session. - if (!scope.initialize()) + if (!scope.initialize()) { + callback->sendFailure(errorString); return; + } if (scope.tryCatch().HasCaught()) { - scope.injectedScript()->wrapEvaluateResult(errorString, maybeFunctionValue, scope.tryCatch(), scope.objectGroupName(), false, false, result, wasThrown, nullptr); + wrapEvaluateResultAsync(scope.injectedScript(), maybeFunctionValue, scope.tryCatch(), scope.objectGroupName(), false, false, callback.get()); return; } v8::Local functionValue; if (!maybeFunctionValue.ToLocal(&functionValue) || !functionValue->IsFunction()) { - *errorString = "Given expression does not evaluate to a function"; + callback->sendFailure("Given expression does not evaluate to a function"); return; } - v8::MaybeLocal maybeResultValue = m_debugger->callFunction(functionValue.As(), scope.context(), scope.object(), argc, argv.get()); + v8::MaybeLocal maybeResultValue = m_inspector->callFunction(functionValue.As(), scope.context(), scope.object(), argc, argv.get()); // Re-initialize after running client's code, as it could have destroyed context or session. - if (!scope.initialize()) + if (!scope.initialize()) { + callback->sendFailure(errorString); + return; + } + + if (!awaitPromise.fromMaybe(false) || scope.tryCatch().HasCaught()) { + wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue, scope.tryCatch(), scope.objectGroupName(), returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), callback.get()); return; + } - scope.injectedScript()->wrapEvaluateResult(errorString, maybeResultValue, scope.tryCatch(), scope.objectGroupName(), returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result, wasThrown, nullptr); + ProtocolPromiseHandler::add( + m_inspector, + scope.context(), + maybeResultValue, + "Result of the function call is not a promise", + m_session->contextGroupId(), + scope.injectedScript()->context()->contextId(), + scope.objectGroupName(), + returnByValue.fromMaybe(false), + generatePreview.fromMaybe(false), + std::move(callback)); } void V8RuntimeAgentImpl::getProperties( @@ -206,7 +419,7 @@ void V8RuntimeAgentImpl::getProperties( { using protocol::Runtime::InternalPropertyDescriptor; - InjectedScript::ObjectScope scope(errorString, m_debugger, m_session->contextGroupId(), objectId); + InjectedScript::ObjectScope scope(errorString, m_inspector, m_session->contextGroupId(), objectId); if (!scope.initialize()) return; @@ -221,7 +434,7 @@ void V8RuntimeAgentImpl::getProperties( if (!errorString->isEmpty() || exceptionDetails->isJust() || accessorPropertiesOnly.fromMaybe(false)) return; v8::Local propertiesArray; - if (hasInternalError(errorString, !m_debugger->internalProperties(scope.context(), scope.object()).ToLocal(&propertiesArray))) + if (hasInternalError(errorString, !m_inspector->debugger()->internalProperties(scope.context(), scope.object()).ToLocal(&propertiesArray))) return; std::unique_ptr> propertiesProtocolArray = protocol::Array::create(); for (uint32_t i = 0; i < propertiesArray->Length(); i += 2) { @@ -245,7 +458,7 @@ void V8RuntimeAgentImpl::getProperties( void V8RuntimeAgentImpl::releaseObject(ErrorString* errorString, const String16& objectId) { - InjectedScript::ObjectScope scope(errorString, m_debugger, m_session->contextGroupId(), objectId); + InjectedScript::ObjectScope scope(errorString, m_inspector, m_session->contextGroupId(), objectId); if (!scope.initialize()) return; scope.injectedScript()->releaseObject(objectId); @@ -258,7 +471,7 @@ void V8RuntimeAgentImpl::releaseObjectGroup(ErrorString*, const String16& object void V8RuntimeAgentImpl::run(ErrorString* errorString) { - m_session->client()->resumeStartup(); + m_inspector->client()->resumeStartup(m_session->contextGroupId()); } void V8RuntimeAgentImpl::setCustomObjectFormatterEnabled(ErrorString*, bool enabled) @@ -269,7 +482,7 @@ void V8RuntimeAgentImpl::setCustomObjectFormatterEnabled(ErrorString*, bool enab void V8RuntimeAgentImpl::discardConsoleEntries(ErrorString*) { - V8ConsoleMessageStorage* storage = m_session->debugger()->ensureConsoleMessageStorage(m_session->contextGroupId()); + V8ConsoleMessageStorage* storage = m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId()); storage->clear(); } @@ -277,7 +490,7 @@ void V8RuntimeAgentImpl::compileScript(ErrorString* errorString, const String16& expression, const String16& sourceURL, bool persistScript, - int executionContextId, + const Maybe& executionContextId, Maybe* scriptId, Maybe* exceptionDetails) { @@ -285,11 +498,18 @@ void V8RuntimeAgentImpl::compileScript(ErrorString* errorString, *errorString = "Runtime agent is not enabled"; return; } - InjectedScript::ContextScope scope(errorString, m_debugger, m_session->contextGroupId(), executionContextId); + int contextId = ensureContext(errorString, m_inspector, m_session->contextGroupId(), executionContextId); + if (!errorString->isEmpty()) + return; + InjectedScript::ContextScope scope(errorString, m_inspector, m_session->contextGroupId(), contextId); if (!scope.initialize()) return; - v8::Local script = m_debugger->compileInternalScript(scope.context(), toV8String(m_debugger->isolate(), expression), sourceURL); + if (!persistScript) + m_inspector->debugger()->muteScriptParsedEvents(); + v8::Local script = m_inspector->compileScript(scope.context(), toV8String(m_inspector->isolate(), expression), sourceURL, false); + if (!persistScript) + m_inspector->debugger()->unmuteScriptParsedEvents(); if (script.IsEmpty()) { v8::Local message = scope.tryCatch().Message(); if (!message.IsEmpty()) @@ -303,55 +523,81 @@ void V8RuntimeAgentImpl::compileScript(ErrorString* errorString, return; String16 scriptValueId = String16::fromInteger(script->GetUnboundScript()->GetId()); - std::unique_ptr> global(new v8::Global(m_debugger->isolate(), script)); + std::unique_ptr> global(new v8::Global(m_inspector->isolate(), script)); m_compiledScripts[scriptValueId] = std::move(global); *scriptId = scriptValueId; } -void V8RuntimeAgentImpl::runScript(ErrorString* errorString, +void V8RuntimeAgentImpl::runScript( const String16& scriptId, - int executionContextId, + const Maybe& executionContextId, const Maybe& objectGroup, const Maybe& doNotPauseOnExceptionsAndMuteConsole, const Maybe& includeCommandLineAPI, - std::unique_ptr* result, - Maybe* exceptionDetails) + const Maybe& returnByValue, + const Maybe& generatePreview, + const Maybe& awaitPromise, + std::unique_ptr callback) { if (!m_enabled) { - *errorString = "Runtime agent is not enabled"; + callback->sendFailure("Runtime agent is not enabled"); return; } auto it = m_compiledScripts.find(scriptId); if (it == m_compiledScripts.end()) { - *errorString = "Script execution failed"; + callback->sendFailure("No script with given id"); return; } - InjectedScript::ContextScope scope(errorString, m_debugger, m_session->contextGroupId(), executionContextId); - if (!scope.initialize()) + ErrorString errorString; + int contextId = ensureContext(&errorString, m_inspector, m_session->contextGroupId(), executionContextId); + if (!errorString.isEmpty()) { + callback->sendFailure(errorString); return; + } + + InjectedScript::ContextScope scope(&errorString, m_inspector, m_session->contextGroupId(), contextId); + if (!scope.initialize()) { + callback->sendFailure(errorString); + return; + } if (doNotPauseOnExceptionsAndMuteConsole.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole(); std::unique_ptr> scriptWrapper = std::move(it->second); m_compiledScripts.erase(it); - v8::Local script = scriptWrapper->Get(m_debugger->isolate()); + v8::Local script = scriptWrapper->Get(m_inspector->isolate()); if (script.IsEmpty()) { - *errorString = "Script execution failed"; + callback->sendFailure("Script execution failed"); return; } if (includeCommandLineAPI.fromMaybe(false) && !scope.installCommandLineAPI()) return; - v8::MaybeLocal maybeResultValue = m_debugger->runCompiledScript(scope.context(), script); + v8::MaybeLocal maybeResultValue = m_inspector->runCompiledScript(scope.context(), script); // Re-initialize after running client's code, as it could have destroyed context or session. if (!scope.initialize()) return; - scope.injectedScript()->wrapEvaluateResult(errorString, maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""), false, false, result, nullptr, exceptionDetails); + + if (!awaitPromise.fromMaybe(false) || scope.tryCatch().HasCaught()) { + wrapEvaluateResultAsync(scope.injectedScript(), maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""), returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), callback.get()); + return; + } + ProtocolPromiseHandler::add( + m_inspector, + scope.context(), + maybeResultValue.ToLocalChecked(), + "Result of the script execution is not a promise", + m_session->contextGroupId(), + scope.injectedScript()->context()->contextId(), + objectGroup.fromMaybe(""), + returnByValue.fromMaybe(false), + generatePreview.fromMaybe(false), + std::move(callback)); } void V8RuntimeAgentImpl::restore() @@ -369,12 +615,12 @@ void V8RuntimeAgentImpl::enable(ErrorString* errorString) { if (m_enabled) return; - m_session->client()->runtimeEnabled(); + m_inspector->client()->beginEnsureAllContextsInGroup(m_session->contextGroupId()); m_enabled = true; m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, true); - m_session->debugger()->enableStackCapturingIfNeeded(); + m_inspector->enableStackCapturingIfNeeded(); m_session->reportAllContexts(this); - V8ConsoleMessageStorage* storage = m_session->debugger()->ensureConsoleMessageStorage(m_session->contextGroupId()); + V8ConsoleMessageStorage* storage = m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId()); for (const auto& message : storage->messages()) reportMessage(message.get(), false); } @@ -385,17 +631,17 @@ void V8RuntimeAgentImpl::disable(ErrorString* errorString) return; m_enabled = false; m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, false); - m_session->debugger()->disableStackCapturingIfNeeded(); + m_inspector->disableStackCapturingIfNeeded(); m_session->discardInjectedScripts(); reset(); - m_session->client()->runtimeDisabled(); + m_inspector->client()->endEnsureAllContextsInGroup(m_session->contextGroupId()); } void V8RuntimeAgentImpl::reset() { m_compiledScripts.clear(); if (m_enabled) { - if (const V8DebuggerImpl::ContextByIdMap* contexts = m_debugger->contextGroup(m_session->contextGroupId())) { + if (const V8InspectorImpl::ContextByIdMap* contexts = m_inspector->contextGroup(m_session->contextGroupId())) { for (auto& idContext : *contexts) idContext.second->setReported(false); } @@ -410,10 +656,10 @@ void V8RuntimeAgentImpl::reportExecutionContextCreated(InspectedContext* context context->setReported(true); std::unique_ptr description = protocol::Runtime::ExecutionContextDescription::create() .setId(context->contextId()) - .setIsDefault(context->isDefault()) .setName(context->humanReadableName()) - .setOrigin(context->origin()) - .setFrameId(context->frameId()).build(); + .setOrigin(context->origin()).build(); + if (!context->auxData().isEmpty()) + description->setAuxData(protocol::DictionaryValue::cast(parseJSON(context->auxData()))); m_frontend.executionContextCreated(std::move(description)); } diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h index 7b33379a0c29c0..8594ce8e2d52af 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8RuntimeAgentImpl.h @@ -43,7 +43,7 @@ class InjectedScript; class InspectedContext; class RemoteObjectIdBase; class V8ConsoleMessage; -class V8DebuggerImpl; +class V8InspectorImpl; class V8InspectorSessionImpl; namespace protocol { @@ -62,7 +62,7 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { // Part of the protocol. void enable(ErrorString*) override; void disable(ErrorString*) override; - void evaluate(ErrorString*, + void evaluate( const String16& expression, const Maybe& objectGroup, const Maybe& includeCommandLineAPI, @@ -71,10 +71,14 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { const Maybe& returnByValue, const Maybe& generatePreview, const Maybe& userGesture, - std::unique_ptr* result, - Maybe* wasThrown, - Maybe*) override; - void callFunctionOn(ErrorString*, + const Maybe& awaitPromise, + std::unique_ptr) override; + void awaitPromise( + const String16& promiseObjectId, + const Maybe& returnByValue, + const Maybe& generatePreview, + std::unique_ptr) override; + void callFunctionOn( const String16& objectId, const String16& expression, const Maybe>& optionalArguments, @@ -82,8 +86,8 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { const Maybe& returnByValue, const Maybe& generatePreview, const Maybe& userGesture, - std::unique_ptr* result, - Maybe* wasThrown) override; + const Maybe& awaitPromise, + std::unique_ptr) override; void releaseObject(ErrorString*, const String16& objectId) override; void getProperties(ErrorString*, const String16& objectId, @@ -101,17 +105,19 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { const String16& expression, const String16& sourceURL, bool persistScript, - int executionContextId, + const Maybe& executionContextId, Maybe*, Maybe*) override; - void runScript(ErrorString*, + void runScript( const String16&, - int executionContextId, + const Maybe& executionContextId, const Maybe& objectGroup, const Maybe& doNotPauseOnExceptionsAndMuteConsole, const Maybe& includeCommandLineAPI, - std::unique_ptr* result, - Maybe*) override; + const Maybe& returnByValue, + const Maybe& generatePreview, + const Maybe& awaitPromise, + std::unique_ptr) override; void reset(); void reportExecutionContextCreated(InspectedContext*); @@ -126,7 +132,7 @@ class V8RuntimeAgentImpl : public protocol::Runtime::Backend { V8InspectorSessionImpl* m_session; protocol::DictionaryValue* m_state; protocol::Runtime::Frontend m_frontend; - V8DebuggerImpl* m_debugger; + V8InspectorImpl* m_inspector; bool m_enabled; protocol::HashMap>> m_compiledScripts; }; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp index 343234c02278cc..0a8e6e1e489336 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.cpp @@ -6,7 +6,7 @@ #include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8Debugger.h" #include "platform/v8_inspector/V8StringUtil.h" #include @@ -93,7 +93,7 @@ std::unique_ptr V8StackTraceImpl::Frame::buildInsp .build(); } -V8StackTraceImpl::Frame V8StackTraceImpl::Frame::isolatedCopy() const +V8StackTraceImpl::Frame V8StackTraceImpl::Frame::clone() const { return Frame(m_functionName.isolatedCopy(), m_scriptId.isolatedCopy(), m_scriptName.isolatedCopy(), m_lineNumber, m_columnNumber); } @@ -105,7 +105,7 @@ void V8StackTraceImpl::setCaptureStackTraceForUncaughtExceptions(v8::Isolate* is } // static -std::unique_ptr V8StackTraceImpl::create(V8DebuggerImpl* debugger, int contextGroupId, v8::Local stackTrace, size_t maxStackSize, const String16& description) +std::unique_ptr V8StackTraceImpl::create(V8Debugger* debugger, int contextGroupId, v8::Local stackTrace, size_t maxStackSize, const String16& description) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::HandleScope scope(isolate); @@ -147,7 +147,7 @@ std::unique_ptr V8StackTraceImpl::create(V8DebuggerImpl* debug return result; } -std::unique_ptr V8StackTraceImpl::capture(V8DebuggerImpl* debugger, int contextGroupId, size_t maxStackSize, const String16& description) +std::unique_ptr V8StackTraceImpl::capture(V8Debugger* debugger, int contextGroupId, size_t maxStackSize, const String16& description) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::HandleScope handleScope(isolate); @@ -161,28 +161,18 @@ std::unique_ptr V8StackTraceImpl::capture(V8DebuggerImpl* debu return V8StackTraceImpl::create(debugger, contextGroupId, stackTrace, maxStackSize, description); } -std::unique_ptr V8StackTraceImpl::clone() -{ - return cloneImpl(); -} - std::unique_ptr V8StackTraceImpl::cloneImpl() { std::vector framesCopy(m_frames); return wrapUnique(new V8StackTraceImpl(m_contextGroupId, m_description, framesCopy, m_parent ? m_parent->cloneImpl() : nullptr)); } -std::unique_ptr V8StackTraceImpl::isolatedCopy() -{ - return isolatedCopyImpl(); -} - -std::unique_ptr V8StackTraceImpl::isolatedCopyImpl() +std::unique_ptr V8StackTraceImpl::clone() { std::vector frames; for (size_t i = 0; i < m_frames.size(); i++) - frames.push_back(m_frames.at(i).isolatedCopy()); - return wrapUnique(new V8StackTraceImpl(m_contextGroupId, m_description.isolatedCopy(), frames, m_parent ? m_parent->isolatedCopyImpl() : nullptr)); + frames.push_back(m_frames.at(i).clone()); + return wrapUnique(new V8StackTraceImpl(m_contextGroupId, m_description.isolatedCopy(), frames, nullptr)); } V8StackTraceImpl::V8StackTraceImpl(int contextGroupId, const String16& description, std::vector& frames, std::unique_ptr parent) @@ -227,7 +217,7 @@ String16 V8StackTraceImpl::topScriptId() const return m_frames[0].m_scriptId; } -std::unique_ptr V8StackTraceImpl::buildInspectorObject() const +std::unique_ptr V8StackTraceImpl::buildInspectorObjectImpl() const { std::unique_ptr> frames = protocol::Array::create(); for (size_t i = 0; i < m_frames.size(); i++) @@ -238,18 +228,23 @@ std::unique_ptr V8StackTraceImpl::buildInspectorO if (!m_description.isEmpty()) stackTrace->setDescription(m_description); if (m_parent) - stackTrace->setParent(m_parent->buildInspectorObject()); + stackTrace->setParent(m_parent->buildInspectorObjectImpl()); return stackTrace; } -std::unique_ptr V8StackTraceImpl::buildInspectorObjectForTail(V8DebuggerImpl* debugger) const +std::unique_ptr V8StackTraceImpl::buildInspectorObjectForTail(V8Debugger* debugger) const { v8::HandleScope handleScope(v8::Isolate::GetCurrent()); // Next call collapses possible empty stack and ensures maxAsyncCallChainDepth. std::unique_ptr fullChain = V8StackTraceImpl::create(debugger, m_contextGroupId, v8::Local(), V8StackTraceImpl::maxCallStackSizeToCapture); if (!fullChain || !fullChain->m_parent) return nullptr; - return fullChain->m_parent->buildInspectorObject(); + return fullChain->m_parent->buildInspectorObjectImpl(); +} + +std::unique_ptr V8StackTraceImpl::buildInspectorObject() const +{ + return buildInspectorObjectImpl(); } String16 V8StackTraceImpl::toString() const diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h index 63b59e8d9009b3..9d9a4892f1d2a7 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StackTraceImpl.h @@ -5,7 +5,9 @@ #ifndef V8StackTraceImpl_h #define V8StackTraceImpl_h +#include "platform/inspector_protocol/Allocator.h" #include "platform/inspector_protocol/Platform.h" +#include "platform/v8_inspector/protocol/Runtime.h" #include "platform/v8_inspector/public/V8StackTrace.h" #include @@ -13,7 +15,7 @@ namespace blink { class TracedValue; -class V8DebuggerImpl; +class V8Debugger; // Note: async stack trace may have empty top stack with non-empty tail to indicate // that current native-only state had some async story. @@ -34,7 +36,7 @@ class V8StackTraceImpl final : public V8StackTrace { const String16& sourceURL() const { return m_scriptName; } int lineNumber() const { return m_lineNumber; } int columnNumber() const { return m_columnNumber; } - Frame isolatedCopy() const; + Frame clone() const; private: friend class V8StackTraceImpl; @@ -49,14 +51,14 @@ class V8StackTraceImpl final : public V8StackTrace { }; static void setCaptureStackTraceForUncaughtExceptions(v8::Isolate*, bool capture); - static std::unique_ptr create(V8DebuggerImpl*, int contextGroupId, v8::Local, size_t maxStackSize, const String16& description = String16()); - static std::unique_ptr capture(V8DebuggerImpl*, int contextGroupId, size_t maxStackSize, const String16& description = String16()); + static std::unique_ptr create(V8Debugger*, int contextGroupId, v8::Local, size_t maxStackSize, const String16& description = String16()); + static std::unique_ptr capture(V8Debugger*, int contextGroupId, size_t maxStackSize, const String16& description = String16()); + // This method drops the async chain. Use cloneImpl() instead. std::unique_ptr clone() override; std::unique_ptr cloneImpl(); - std::unique_ptr isolatedCopy() override; - std::unique_ptr isolatedCopyImpl(); - std::unique_ptr buildInspectorObjectForTail(V8DebuggerImpl*) const; + std::unique_ptr buildInspectorObjectForTail(V8Debugger*) const; + std::unique_ptr buildInspectorObjectImpl() const; ~V8StackTraceImpl() override; // V8StackTrace implementation. @@ -66,7 +68,7 @@ class V8StackTraceImpl final : public V8StackTrace { int topColumnNumber() const override; String16 topScriptId() const override; String16 topFunctionName() const override; - std::unique_ptr buildInspectorObject() const override; + std::unique_ptr buildInspectorObject() const override; String16 toString() const override; private: diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.cpp index 4ba7898bc58162..037d91036cfde8 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.cpp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.cpp @@ -5,10 +5,9 @@ #include "platform/v8_inspector/V8StringUtil.h" #include "platform/inspector_protocol/String16.h" -#include "platform/v8_inspector/V8DebuggerImpl.h" +#include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8Regex.h" -#include "platform/v8_inspector/public/V8ContentSearchUtil.h" namespace blink { @@ -144,10 +143,10 @@ std::unique_ptr buildObjectForSearchMatch(int l .build(); } -std::unique_ptr createSearchRegex(V8DebuggerImpl* debugger, const String16& query, bool caseSensitive, bool isRegex) +std::unique_ptr createSearchRegex(V8InspectorImpl* inspector, const String16& query, bool caseSensitive, bool isRegex) { String16 regexSource = isRegex ? query : createSearchRegexSource(query); - return wrapUnique(new V8Regex(debugger, regexSource, caseSensitive)); + return wrapUnique(new V8Regex(inspector, regexSource, caseSensitive)); } } // namespace @@ -166,6 +165,11 @@ v8::Local toV8StringInternalized(v8::Isolate* isolate, const String1 return v8::String::NewFromTwoByte(isolate, reinterpret_cast(string.characters16()), v8::NewStringType::kInternalized, string.length()).ToLocalChecked(); } +v8::Local toV8StringInternalized(v8::Isolate* isolate, const char* str) +{ + return v8::String::NewFromUtf8(isolate, str, v8::NewStringType::kInternalized).ToLocalChecked(); +} + String16 toProtocolString(v8::Local value) { if (value.IsEmpty() || value->IsNull() || value->IsUndefined()) @@ -182,7 +186,16 @@ String16 toProtocolStringWithTypeCheck(v8::Local value) return toProtocolString(value.As()); } -namespace V8ContentSearchUtil { +std::vector> searchInTextByLinesImpl(V8InspectorSession* session, const String16& text, const String16& query, const bool caseSensitive, const bool isRegex) +{ + std::unique_ptr regex = createSearchRegex(static_cast(session)->inspector(), query, caseSensitive, isRegex); + std::vector> matches = scriptRegexpMatchesByLines(*regex.get(), text); + + std::vector> result; + for (const auto& match : matches) + result.push_back(buildObjectForSearchMatch(match.first, match.second)); + return result; +} String16 findSourceURL(const String16& content, bool multiline, bool* deprecated) { @@ -194,20 +207,6 @@ String16 findSourceMapURL(const String16& content, bool multiline, bool* depreca return findMagicComment(content, "sourceMappingURL", multiline, deprecated); } -std::unique_ptr> searchInTextByLines(V8InspectorSession* session, const String16& text, const String16& query, const bool caseSensitive, const bool isRegex) -{ - std::unique_ptr> result = protocol::Array::create(); - std::unique_ptr regex = createSearchRegex(static_cast(session)->debugger(), query, caseSensitive, isRegex); - std::vector> matches = scriptRegexpMatchesByLines(*regex.get(), text); - - for (const auto& match : matches) - result->addItem(buildObjectForSearchMatch(match.first, match.second)); - - return result; -} - -} // namespace V8ContentSearchUtil - std::unique_ptr toProtocolValue(v8::Local context, v8::Local value, int maxDepth) { if (value.IsEmpty()) { diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.h index 2d42613d41614d..029ed5661a9e29 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/V8StringUtil.h @@ -7,18 +7,26 @@ #include "platform/inspector_protocol/String16.h" #include "platform/inspector_protocol/Values.h" +#include "platform/v8_inspector/protocol/Debugger.h" #include namespace blink { +class V8InspectorSession; + std::unique_ptr toProtocolValue(v8::Local, v8::Local, int maxDepth = protocol::Value::maxDepth); v8::Local toV8String(v8::Isolate*, const String16&); v8::Local toV8StringInternalized(v8::Isolate*, const String16&); +v8::Local toV8StringInternalized(v8::Isolate*, const char*); String16 toProtocolString(v8::Local); String16 toProtocolStringWithTypeCheck(v8::Local); +String16 findSourceURL(const String16& content, bool multiline, bool* deprecated = nullptr); +String16 findSourceMapURL(const String16& content, bool multiline, bool* deprecated = nullptr); +std::vector> searchInTextByLinesImpl(V8InspectorSession*, const String16& text, const String16& query, bool caseSensitive, bool isRegex); + } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/debugger_script_externs.js b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/debugger_script_externs.js index cf2a0457c4c1b3..dddc709a57a471 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/debugger_script_externs.js +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/debugger_script_externs.js @@ -29,7 +29,7 @@ var RawLocation; startColumn: number, endColumn: number, executionContextId: number, - isContentScript: boolean, + executionContextAuxData: string, isInternalScript: boolean }} */ var FormattedScript; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/injected_script_externs.js b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/injected_script_externs.js index 5fba025caab2b8..03455614f32f1f 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/injected_script_externs.js +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/injected_script_externs.js @@ -39,12 +39,11 @@ InjectedScriptHostClass.prototype.isTypedArray = function(obj) {} InjectedScriptHostClass.prototype.getInternalProperties = function(obj) {} /** - * @param {!Function} fn - * @param {*} receiver - * @param {!Array.<*>=} argv - * @return {*} + * @param {!Object} object + * @param {string} propertyName + * @return {boolean} */ -InjectedScriptHostClass.prototype.suppressWarningsAndCallFunction = function(fn, receiver, argv) {} +InjectedScriptHostClass.prototype.objectHasOwnProperty = function(object, propertyName) {} /** * @param {*} value @@ -59,12 +58,6 @@ InjectedScriptHostClass.prototype.bind = function(value, groupName) {} */ InjectedScriptHostClass.prototype.proxyTargetValue = function(object) {} -/** - * @param {!Object} object - * @return {Object|undefined} - */ -InjectedScriptHostClass.prototype.prototype = function(object) {} - /** @type {!InjectedScriptHostClass} */ var InjectedScriptHost; /** @type {!Window} */ diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/js_protocol.json b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/js_protocol.json index 78548bc8402aeb..161cdb89e17f8c 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/js_protocol.json +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/js_protocol.json @@ -14,25 +14,33 @@ "type": "string", "description": "Unique object identifier." }, + { + "id": "UnserializableValue", + "type": "string", + "enum": ["Infinity", "NaN", "-Infinity", "-0"], + "description": "Primitive value which cannot be JSON-stringified." + }, { "id": "RemoteObject", "type": "object", "description": "Mirror object referencing original JavaScript object.", + "exported": true, "properties": [ { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol"], "description": "Object type." }, - { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "map", "set", "iterator", "generator", "error"], "description": "Object subtype hint. Specified for object type values only." }, + { "name": "subtype", "type": "string", "optional": true, "enum": ["array", "null", "node", "regexp", "date", "map", "set", "iterator", "generator", "error", "proxy", "promise", "typedarray"], "description": "Object subtype hint. Specified for object type values only." }, { "name": "className", "type": "string", "optional": true, "description": "Object class (constructor) name. Specified for object type values only." }, - { "name": "value", "type": "any", "optional": true, "description": "Remote object value in case of primitive values or JSON values (if it was requested), or description string if the value can not be JSON-stringified (like NaN, Infinity, -Infinity, -0)." }, + { "name": "value", "type": "any", "optional": true, "description": "Remote object value in case of primitive values or JSON values (if it was requested)." }, + { "name": "unserializableValue", "$ref": "UnserializableValue", "optional": true, "experimental": true, "description": "Primitive value which can not be JSON-stringified does not have value, but gets this property." }, { "name": "description", "type": "string", "optional": true, "description": "String representation of the object." }, { "name": "objectId", "$ref": "RemoteObjectId", "optional": true, "description": "Unique object identifier (for non-primitive values)." }, - { "name": "preview", "$ref": "ObjectPreview", "optional": true, "description": "Preview containing abbreviated property values. Specified for object type values only.", "hidden": true }, - { "name": "customPreview", "$ref": "CustomPreview", "optional": true, "hidden": true} + { "name": "preview", "$ref": "ObjectPreview", "optional": true, "description": "Preview containing abbreviated property values. Specified for object type values only.", "experimental": true }, + { "name": "customPreview", "$ref": "CustomPreview", "optional": true, "experimental": true} ] }, { "id": "CustomPreview", "type": "object", - "hidden": true, + "experimental": true, "properties": [ { "name": "header", "type": "string"}, { "name": "hasBody", "type": "boolean"}, @@ -44,7 +52,7 @@ { "id": "ObjectPreview", "type": "object", - "hidden": true, + "experimental": true, "description": "Object containing abbreviated remote object value.", "properties": [ { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol"], "description": "Object type." }, @@ -58,7 +66,7 @@ { "id": "PropertyPreview", "type": "object", - "hidden": true, + "experimental": true, "properties": [ { "name": "name", "type": "string", "description": "Property name." }, { "name": "type", "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol", "accessor"], "description": "Object type. Accessor means that the property itself is an accessor property." }, @@ -70,7 +78,7 @@ { "id": "EntryPreview", "type": "object", - "hidden": true, + "experimental": true, "properties": [ { "name": "key", "$ref": "ObjectPreview", "optional": true, "description": "Preview of the key. Specified for map-like collection entries." }, { "name": "value", "$ref": "ObjectPreview", "description": "Preview of the value." } @@ -89,8 +97,8 @@ { "name": "configurable", "type": "boolean", "description": "True if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object." }, { "name": "enumerable", "type": "boolean", "description": "True if this property shows up during enumeration of the properties on the corresponding object." }, { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }, - { "name": "isOwn", "optional": true, "type": "boolean", "description": "True if the property is owned for the object.", "hidden": true }, - { "name": "symbol", "$ref": "RemoteObject", "optional": true, "description": "Property symbol object, if the property is of the symbol type.", "hidden": true } + { "name": "isOwn", "optional": true, "type": "boolean", "description": "True if the property is owned for the object.", "experimental": true }, + { "name": "symbol", "$ref": "RemoteObject", "optional": true, "description": "Property symbol object, if the property is of the symbol type.", "experimental": true } ] }, { @@ -101,16 +109,16 @@ { "name": "name", "type": "string", "description": "Conventional property name." }, { "name": "value", "$ref": "RemoteObject", "optional": true, "description": "The value associated with the property." } ], - "hidden": true + "experimental": true }, { "id": "CallArgument", "type": "object", - "description": "Represents function call argument. Either remote object id objectId or primitive value or neither of (for undefined) them should be specified.", + "description": "Represents function call argument. Either remote object id objectId, primitive value, unserializable primitive value or neither of (for undefined) them should be specified.", "properties": [ - { "name": "value", "type": "any", "optional": true, "description": "Primitive value, or description string if the value can not be JSON-stringified (like NaN, Infinity, -Infinity, -0)." }, - { "name": "objectId", "$ref": "RemoteObjectId", "optional": true, "description": "Remote object handle." }, - { "name": "type", "optional": true, "hidden": true, "type": "string", "enum": ["object", "function", "undefined", "string", "number", "boolean", "symbol"], "description": "Object type." } + { "name": "value", "type": "any", "optional": true, "description": "Primitive value." }, + { "name": "unserializableValue", "$ref": "UnserializableValue", "optional": true, "experimental": true, "description": "Primitive value which can not be JSON-stringified." }, + { "name": "objectId", "$ref": "RemoteObjectId", "optional": true, "description": "Remote object handle." } ] }, { @@ -124,16 +132,15 @@ "description": "Description of an isolated world.", "properties": [ { "name": "id", "$ref": "ExecutionContextId", "description": "Unique id of the execution context. It can be used to specify in which execution context script evaluation should be performed." }, - { "name": "isDefault", "type": "boolean", "description": "Whether context is the default page context (as opposite to e.g. context of content script).", "hidden": true }, - { "name": "origin", "type": "string", "description": "Execution context origin.", "hidden": true}, - { "name": "name", "type": "string", "description": "Human readable name describing given context.", "hidden": true}, - { "name": "frameId", "type": "string", "description": "Id of the owning frame. May be an empty string if the context is not associated with a frame." } + { "name": "origin", "type": "string", "description": "Execution context origin.", "experimental": true }, + { "name": "name", "type": "string", "description": "Human readable name describing given context.", "experimental": true }, + { "name": "auxData", "type": "object", "optional": true, "description": "Embedder-specific auxiliary data.", "experimental": true } ] }, { "id": "ExceptionDetails", "type": "object", - "hidden": true, + "experimental": true, "description": "Detailed information about exception (or error) that was thrown during script compilation or execution.", "properties": [ { "name": "text", "type": "string", "description": "Exception text." }, @@ -148,7 +155,7 @@ "id": "Timestamp", "type": "number", "description": "Number of milliseconds since epoch.", - "hidden": true + "experimental": true }, { "id": "CallFrame", @@ -166,47 +173,69 @@ "id": "StackTrace", "type": "object", "description": "Call frames for assertions or error messages.", + "exported": true, "properties": [ { "name": "description", "type": "string", "optional": true, "description": "String label of this stack trace. For async traces this may be a name of the function that initiated the async call." }, { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "JavaScript function name." }, - { "name": "parent", "$ref": "StackTrace", "optional": true, "hidden": true, "description": "Asynchronous JavaScript stack trace that preceded this stack, if available." } + { "name": "parent", "$ref": "StackTrace", "optional": true, "experimental": true, "description": "Asynchronous JavaScript stack trace that preceded this stack, if available." } ] } ], "commands": [ { "name": "evaluate", + "async": true, "parameters": [ { "name": "expression", "type": "string", "description": "Expression to evaluate." }, { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." }, - { "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Determines whether Command Line API should be available during the evaluation.", "hidden": true }, - { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether evaluation should stop on exceptions and mute console. Overrides setPauseOnException state.", "hidden": true }, - { "name": "contextId", "$ref": "ExecutionContextId", "optional": true, "description": "Specifies in which isolated context to perform evaluation. Each content script lives in an isolated context and this parameter may be used to specify one of those contexts. If the parameter is omitted or 0 the evaluation will be performed in the context of the inspected page." }, + { "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Determines whether Command Line API should be available during the evaluation.", "experimental": true }, + { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether evaluation should stop on exceptions and mute console. Overrides setPauseOnException state.", "experimental": true }, + { "name": "contextId", "$ref": "ExecutionContextId", "optional": true, "description": "Specifies in which execution context to perform evaluation. If the parameter is omitted the evaluation will be performed in the context of the inspected page." }, { "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object that should be sent by value." }, - { "name": "generatePreview", "type": "boolean", "optional": true, "hidden": true, "description": "Whether preview should be generated for the result." }, - { "name": "userGesture", "type": "boolean", "optional": true, "hidden": true, "description": "Whether execution should be treated as initiated by user in the UI." } + { "name": "generatePreview", "type": "boolean", "optional": true, "experimental": true, "description": "Whether preview should be generated for the result." }, + { "name": "userGesture", "type": "boolean", "optional": true, "experimental": true, "description": "Whether execution should be treated as initiated by user in the UI." }, + { "name": "awaitPromise", "type": "boolean", "optional":true, "experimental": true, "description": "Whether execution should wait for promise to be resolved. If the result of evaluation is not a Promise, it's considered to be an error." } ], "returns": [ { "name": "result", "$ref": "RemoteObject", "description": "Evaluation result." }, { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }, - { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "hidden": true, "description": "Exception details."} + { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "experimental": true, "description": "Exception details."} ], "description": "Evaluates expression on global object." }, + { + "name": "awaitPromise", + "experimental": true, + "async": true, + "parameters": [ + { "name": "promiseObjectId", "$ref": "RemoteObjectId", "description": "Identifier of the promise." }, + { "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object that should be sent by value." }, + { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for the result." } + ], + "returns": [ + { "name": "result", "$ref": "RemoteObject", "description": "Promise result. Will contain rejected value if promise was rejected." }, + { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the promise was rejected." }, + { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "description": "Exception details if stack strace is available."} + ], + "description": "Add handler to promise with given promise object id." + }, { "name": "callFunctionOn", + "async": true, "parameters": [ { "name": "objectId", "$ref": "RemoteObjectId", "description": "Identifier of the object to call function on." }, { "name": "functionDeclaration", "type": "string", "description": "Declaration of the function to call." }, { "name": "arguments", "type": "array", "items": { "$ref": "CallArgument", "description": "Call argument." }, "optional": true, "description": "Call arguments. All call arguments must belong to the same JavaScript world as the target object." }, - { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether function call should stop on exceptions and mute console. Overrides setPauseOnException state.", "hidden": true }, + { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether function call should stop on exceptions and mute console. Overrides setPauseOnException state.", "experimental": true }, { "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object which should be sent by value." }, - { "name": "generatePreview", "type": "boolean", "optional": true, "hidden": true, "description": "Whether preview should be generated for the result." }, - { "name": "userGesture", "type": "boolean", "optional": true, "hidden": true, "description": "Whether execution should be treated as initiated by user in the UI." } + { "name": "generatePreview", "type": "boolean", "optional": true, "experimental": true, "description": "Whether preview should be generated for the result." }, + { "name": "userGesture", "type": "boolean", "optional": true, "experimental": true, "description": "Whether execution should be treated as initiated by user in the UI." }, + { "name": "awaitPromise", "type": "boolean", "optional":true, "experimental": true, "description": "Whether execution should wait for promise to be resolved. If the result of evaluation is not a Promise, it's considered to be an error." } ], "returns": [ { "name": "result", "$ref": "RemoteObject", "description": "Call result." }, - { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." } + { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }, + { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "experimental": true, "description": "Exception details."} ], "description": "Calls function with given declaration on the given object. Object group of the result is inherited from the target object." }, @@ -215,13 +244,13 @@ "parameters": [ { "name": "objectId", "$ref": "RemoteObjectId", "description": "Identifier of the object to return properties for." }, { "name": "ownProperties", "optional": true, "type": "boolean", "description": "If true, returns properties belonging only to the element itself, not to its prototype chain." }, - { "name": "accessorPropertiesOnly", "optional": true, "type": "boolean", "description": "If true, returns accessor properties (with getter/setter) only; internal properties are not returned either.", "hidden": true }, - { "name": "generatePreview", "type": "boolean", "optional": true, "hidden": true, "description": "Whether preview should be generated for the results." } + { "name": "accessorPropertiesOnly", "optional": true, "type": "boolean", "description": "If true, returns accessor properties (with getter/setter) only; internal properties are not returned either.", "experimental": true }, + { "name": "generatePreview", "type": "boolean", "optional": true, "experimental": true, "description": "Whether preview should be generated for the results." } ], "returns": [ { "name": "result", "type": "array", "items": { "$ref": "PropertyDescriptor" }, "description": "Object properties." }, - { "name": "internalProperties", "optional": true, "type": "array", "items": { "$ref": "InternalPropertyDescriptor" }, "description": "Internal object properties (only of the element itself).", "hidden": true }, - { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "hidden": true, "description": "Exception details."} + { "name": "internalProperties", "optional": true, "type": "array", "items": { "$ref": "InternalPropertyDescriptor" }, "description": "Internal object properties (only of the element itself).", "experimental": true }, + { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "experimental": true, "description": "Exception details."} ], "description": "Returns properties of a given object. Object group of the result is inherited from the target object." }, @@ -241,7 +270,7 @@ }, { "name": "run", - "hidden": true, + "experimental": true, "description": "Tells inspected instance(worker or page) that it can run in case it was started paused." }, { @@ -250,12 +279,12 @@ }, { "name": "disable", - "hidden": true, + "experimental": true, "description": "Disables reporting of execution contexts creation." }, { "name": "discardConsoleEntries", - "hidden": true, + "experimental": true, "description": "Discards collected exceptions and console API calls." }, { @@ -266,16 +295,16 @@ "type": "boolean" } ], - "hidden": true + "experimental": true }, { "name": "compileScript", - "hidden": true, + "experimental": true, "parameters": [ { "name": "expression", "type": "string", "description": "Expression to compile." }, { "name": "sourceURL", "type": "string", "description": "Source url to be set for the script." }, { "name": "persistScript", "type": "boolean", "description": "Specifies whether the compiled script should be persisted." }, - { "name": "executionContextId", "$ref": "ExecutionContextId", "description": "Specifies in which isolated context to perform script run. Each content script lives in an isolated context and this parameter is used to specify one of those contexts." } + { "name": "executionContextId", "$ref": "ExecutionContextId", "optional": true, "description": "Specifies in which execution context to perform script run. If the parameter is omitted the evaluation will be performed in the context of the inspected page." } ], "returns": [ { "name": "scriptId", "$ref": "ScriptId", "optional": true, "description": "Id of the script." }, @@ -285,16 +314,21 @@ }, { "name": "runScript", - "hidden": true, + "experimental": true, + "async": true, "parameters": [ { "name": "scriptId", "$ref": "ScriptId", "description": "Id of the script to run." }, - { "name": "executionContextId", "$ref": "ExecutionContextId", "description": "Specifies in which isolated context to perform script run. Each content script lives in an isolated context and this parameter is used to specify one of those contexts." }, + { "name": "executionContextId", "$ref": "ExecutionContextId", "optional": true, "description": "Specifies in which execution context to perform script run. If the parameter is omitted the evaluation will be performed in the context of the inspected page." }, { "name": "objectGroup", "type": "string", "optional": true, "description": "Symbolic group name that can be used to release multiple objects." }, { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether script run should stop on exceptions and mute console. Overrides setPauseOnException state." }, - { "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Determines whether Command Line API should be available during the evaluation." } + { "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Determines whether Command Line API should be available during the evaluation." }, + { "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object which should be sent by value." }, + { "name": "generatePreview", "type": "boolean", "optional": true, "description": "Whether preview should be generated for the result." }, + { "name": "awaitPromise", "type": "boolean", "optional": true, "description": "Whether execution should wait for promise to be resolved. If the result of evaluation is not a Promise, it's considered to be an error." } ], "returns": [ { "name": "result", "$ref": "RemoteObject", "description": "Run result." }, + { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the execution." }, { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "description": "Exception details."} ], "description": "Runs script with given id in a given context." @@ -329,7 +363,7 @@ { "name": "exception", "$ref": "RemoteObject", "optional": true, "description": "Exception object." }, { "name": "executionContextId", "$ref": "ExecutionContextId", "optional": true, "description": "Identifier of the context where exception happened." } ], - "hidden": true + "experimental": true }, { "name": "exceptionRevoked", @@ -338,7 +372,7 @@ { "name": "message", "type": "string", "description": "Message describing why exception was revoked." }, { "name": "exceptionId", "type": "integer", "description": "The id of revoked exception, as reported in exceptionUnhandled." } ], - "hidden": true + "experimental": true }, { "name": "consoleAPICalled", @@ -350,7 +384,7 @@ { "name": "timestamp", "$ref": "Timestamp", "description": "Call timestamp." }, { "name": "stackTrace", "$ref": "StackTrace", "optional": true, "description": "Stack trace captured when the call was made." } ], - "hidden": true + "experimental": true }, { "name": "inspectRequested", @@ -358,7 +392,7 @@ { "name": "object", "$ref": "RemoteObject" }, { "name": "hints", "type": "object" } ], - "hidden": true + "experimental": true } ] }, @@ -389,7 +423,7 @@ }, { "id": "ScriptPosition", - "hidden": true, + "experimental": true, "type": "object", "properties": [ { "name": "lineNumber", "type": "integer" }, @@ -403,11 +437,11 @@ "properties": [ { "name": "callFrameId", "$ref": "CallFrameId", "description": "Call frame identifier. This identifier is only valid while the virtual machine is paused." }, { "name": "functionName", "type": "string", "description": "Name of the JavaScript function called on this call frame." }, - { "name": "functionLocation", "$ref": "Location", "optional": true, "hidden": true, "description": "Location in the source code." }, + { "name": "functionLocation", "$ref": "Location", "optional": true, "experimental": true, "description": "Location in the source code." }, { "name": "location", "$ref": "Location", "description": "Location in the source code." }, { "name": "scopeChain", "type": "array", "items": { "$ref": "Scope" }, "description": "Scope chain for this call frame." }, { "name": "this", "$ref": "Runtime.RemoteObject", "description": "this object for this call frame." }, - { "name": "returnValue", "$ref": "Runtime.RemoteObject", "optional": true, "hidden": true, "description": "The value being returned, if the function is at return point." } + { "name": "returnValue", "$ref": "Runtime.RemoteObject", "optional": true, "experimental": true, "description": "The value being returned, if the function is at return point." } ], "description": "JavaScript call frame. Array of call frames form the call stack." }, @@ -417,9 +451,9 @@ "properties": [ { "name": "type", "type": "string", "enum": ["global", "local", "with", "closure", "catch", "block", "script"], "description": "Scope type." }, { "name": "object", "$ref": "Runtime.RemoteObject", "description": "Object representing the scope. For global and with scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties." }, - { "name": "name", "type": "string", "optional": true, "hidden": true }, - { "name": "startLocation", "$ref": "Location", "optional": true, "hidden": true, "description": "Location in the source code where scope starts" }, - { "name": "endLocation", "$ref": "Location", "optional": true, "hidden": true, "description": "Location in the source code where scope ends" } + { "name": "name", "type": "string", "optional": true, "experimental": true }, + { "name": "startLocation", "$ref": "Location", "optional": true, "experimental": true, "description": "Location in the source code where scope starts" }, + { "name": "endLocation", "$ref": "Location", "optional": true, "experimental": true, "description": "Location in the source code where scope ends" } ], "description": "Scope description." }, @@ -427,11 +461,12 @@ "id": "SearchMatch", "type": "object", "description": "Search match for resource.", + "exported": true, "properties": [ { "name": "lineNumber", "type": "number", "description": "Line number in resource content." }, { "name": "lineContent", "type": "string", "description": "Line with match content." } ], - "hidden": true + "experimental": true } ], "commands": [ @@ -452,7 +487,7 @@ }, { "name": "setSkipAllPauses", - "hidden": true, + "experimental": true, "parameters": [ { "name": "skipped", "type": "boolean", "description": "New value for skip pauses state." } ], @@ -496,7 +531,7 @@ "name": "continueToLocation", "parameters": [ { "name": "location", "$ref": "Location", "description": "Location to continue to." }, - { "name": "interstatementLocation", "type": "boolean", "optional": true, "hidden": true, "description": "Allows breakpoints at the intemediate positions inside statements." } + { "name": "interstatementLocation", "type": "boolean", "optional": true, "experimental": true, "description": "Allows breakpoints at the intemediate positions inside statements." } ], "description": "Continues execution until specific location is reached." }, @@ -545,12 +580,12 @@ "parameters": [ { "name": "scriptId", "$ref": "Runtime.ScriptId", "description": "Id of the script to edit." }, { "name": "scriptSource", "type": "string", "description": "New content of the script." }, - { "name": "preview", "type": "boolean", "optional": true, "description": " If true the change will not actually be applied. Preview mode may be used to get result description without actually modifying the code.", "hidden": true } + { "name": "preview", "type": "boolean", "optional": true, "description": " If true the change will not actually be applied. Preview mode may be used to get result description without actually modifying the code.", "experimental": true } ], "returns": [ { "name": "callFrames", "type": "array", "optional": true, "items": { "$ref": "CallFrame" }, "description": "New stack trace in case editing has happened while VM was stopped." }, - { "name": "stackChanged", "type": "boolean", "optional": true, "description": "Whether current call stack was modified after applying the changes.", "hidden": true }, - { "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any.", "hidden": true }, + { "name": "stackChanged", "type": "boolean", "optional": true, "description": "Whether current call stack was modified after applying the changes.", "experimental": true }, + { "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any.", "experimental": true }, { "name": "compileError", "optional": true, "$ref": "Runtime.ExceptionDetails", "description": "Error data if any." } ], "description": "Edits JavaScript source live." @@ -564,7 +599,7 @@ { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "New stack trace." }, { "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any." } ], - "hidden": true, + "experimental": true, "description": "Restarts particular call frame from the beginning." }, { @@ -590,15 +625,15 @@ { "name": "callFrameId", "$ref": "CallFrameId", "description": "Call frame identifier to evaluate on." }, { "name": "expression", "type": "string", "description": "Expression to evaluate." }, { "name": "objectGroup", "type": "string", "optional": true, "description": "String object group name to put result into (allows rapid releasing resulting object handles using releaseObjectGroup)." }, - { "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Specifies whether command line API should be available to the evaluated expression, defaults to false.", "hidden": true }, - { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether evaluation should stop on exceptions and mute console. Overrides setPauseOnException state.", "hidden": true }, + { "name": "includeCommandLineAPI", "type": "boolean", "optional": true, "description": "Specifies whether command line API should be available to the evaluated expression, defaults to false.", "experimental": true }, + { "name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true, "description": "Specifies whether evaluation should stop on exceptions and mute console. Overrides setPauseOnException state.", "experimental": true }, { "name": "returnByValue", "type": "boolean", "optional": true, "description": "Whether the result is expected to be a JSON object that should be sent by value." }, - { "name": "generatePreview", "type": "boolean", "optional": true, "hidden": true, "description": "Whether preview should be generated for the result." } + { "name": "generatePreview", "type": "boolean", "optional": true, "experimental": true, "description": "Whether preview should be generated for the result." } ], "returns": [ { "name": "result", "$ref": "Runtime.RemoteObject", "description": "Object wrapper for the evaluation result." }, { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }, - { "name": "exceptionDetails", "$ref": "Runtime.ExceptionDetails", "optional": true, "hidden": true, "description": "Exception details."} + { "name": "exceptionDetails", "$ref": "Runtime.ExceptionDetails", "optional": true, "experimental": true, "description": "Exception details."} ], "description": "Evaluates expression on a given call frame." }, @@ -610,7 +645,7 @@ { "name": "newValue", "$ref": "Runtime.CallArgument", "description": "New variable value." }, { "name": "callFrameId", "$ref": "CallFrameId", "description": "Id of callframe that holds variable." } ], - "hidden": true, + "experimental": true, "description": "Changes value of variable in a callframe. Object-based scopes are not supported and must be mutated manually." }, { @@ -619,7 +654,7 @@ { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." }, { "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any." } ], - "hidden": true, + "experimental": true, "description": "Returns call stack including variables changed since VM was paused. VM must be paused." }, { @@ -627,7 +662,7 @@ "parameters": [ { "name": "maxDepth", "type": "integer", "description": "Maximum depth of async call stacks. Setting to 0 will effectively disable collecting async call stacks (default)." } ], - "hidden": true, + "experimental": true, "description": "Enables or disables async call stacks tracking." }, { @@ -635,7 +670,7 @@ "parameters": [ { "name": "patterns", "type": "array", "items": { "type": "string" }, "description": "Array of regexps that will be used to check script url for blackbox state." } ], - "hidden": true, + "experimental": true, "description": "Replace previous blackbox patterns with passed ones. Forces backend to skip stepping/pausing in scripts with url matching one of the patterns. VM will try to leave blackboxed script by performing 'step in' several times, finally resorting to 'step out' if unsuccessful." }, { @@ -644,7 +679,7 @@ { "name": "scriptId", "$ref": "Runtime.ScriptId", "description": "Id of the script." }, { "name": "positions", "type": "array", "items": { "$ref": "ScriptPosition" } } ], - "hidden": true, + "experimental": true, "description": "Makes backend skip steps in the script in blackboxed ranges. VM will try leave blacklisted scripts by performing 'step in' several times, finally resorting to 'step out' if unsuccessful. Positions array contains positions where blackbox state is changed. First interval isn't blackboxed. Array should be sorted." } ], @@ -658,14 +693,14 @@ { "name": "startColumn", "type": "integer", "description": "Column offset of the script within the resource with given URL." }, { "name": "endLine", "type": "integer", "description": "Last line of the script." }, { "name": "endColumn", "type": "integer", "description": "Length of the last line of the script." }, - { "name": "executionContextId", "$ref": "Runtime.ExecutionContextId", "description": "Specifies script creation context.", "hidden": true }, - { "name": "hash", "type": "string", "hidden": true, "description": "Content hash of the script."}, - { "name": "isContentScript", "type": "boolean", "optional": true, "description": "Determines whether this script is a user extension script." }, - { "name": "isInternalScript", "type": "boolean", "optional": true, "description": "Determines whether this script is an internal script.", "hidden": true }, - { "name": "isLiveEdit", "type": "boolean", "optional": true, "description": "True, if this script is generated as a result of the live edit operation.", "hidden": true }, + { "name": "executionContextId", "$ref": "Runtime.ExecutionContextId", "description": "Specifies script creation context.", "experimental": true }, + { "name": "hash", "type": "string", "experimental": true, "description": "Content hash of the script."}, + { "name": "executionContextAuxData", "type": "object", "optional": true, "description": "Embedder-specific auxiliary data.", "experimental": true }, + { "name": "isInternalScript", "type": "boolean", "optional": true, "description": "Determines whether this script is an internal script.", "experimental": true }, + { "name": "isLiveEdit", "type": "boolean", "optional": true, "description": "True, if this script is generated as a result of the live edit operation.", "experimental": true }, { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with script (if any)." }, - { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "hidden": true }, - { "name": "deprecatedCommentWasUsed", "type": "boolean", "optional": true, "hidden": true, "description": "True, if '//@ sourceURL' or '//@ sourceMappingURL' was used."} + { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "experimental": true }, + { "name": "deprecatedCommentWasUsed", "type": "boolean", "optional": true, "experimental": true, "description": "True, if '//@ sourceURL' or '//@ sourceMappingURL' was used."} ], "description": "Fired when virtual machine parses script. This event is also fired for all known and uncollected scripts upon enabling debugger." }, @@ -678,13 +713,13 @@ { "name": "startColumn", "type": "integer", "description": "Column offset of the script within the resource with given URL." }, { "name": "endLine", "type": "integer", "description": "Last line of the script." }, { "name": "endColumn", "type": "integer", "description": "Length of the last line of the script." }, - { "name": "executionContextId", "$ref": "Runtime.ExecutionContextId", "description": "Specifies script creation context.", "hidden": true }, - { "name": "hash", "type": "string", "hidden": true, "description": "Content hash of the script."}, - { "name": "isContentScript", "type": "boolean", "optional": true, "description": "Determines whether this script is a user extension script." }, - { "name": "isInternalScript", "type": "boolean", "optional": true, "description": "Determines whether this script is an internal script.", "hidden": true }, + { "name": "executionContextId", "$ref": "Runtime.ExecutionContextId", "description": "Specifies script creation context.", "experimental": true }, + { "name": "hash", "type": "string", "experimental": true, "description": "Content hash of the script."}, + { "name": "executionContextAuxData", "type": "object", "optional": true, "description": "Embedder-specific auxiliary data.", "experimental": true }, + { "name": "isInternalScript", "type": "boolean", "optional": true, "description": "Determines whether this script is an internal script.", "experimental": true }, { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with script (if any)." }, - { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "hidden": true }, - { "name": "deprecatedCommentWasUsed", "type": "boolean", "optional": true, "hidden": true, "description": "True, if '//@ sourceURL' or '//@ sourceMappingURL' was used."} + { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "experimental": true }, + { "name": "deprecatedCommentWasUsed", "type": "boolean", "optional": true, "experimental": true, "description": "True, if '//@ sourceURL' or '//@ sourceMappingURL' was used."} ], "description": "Fired when virtual machine fails to parse the script." }, @@ -700,10 +735,10 @@ "name": "paused", "parameters": [ { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." }, - { "name": "reason", "type": "string", "enum": [ "XHR", "DOM", "EventListener", "exception", "assert", "debugCommand", "promiseRejection", "other" ], "description": "Pause reason." }, + { "name": "reason", "type": "string", "enum": [ "XHR", "DOM", "EventListener", "exception", "assert", "debugCommand", "promiseRejection", "other" ], "description": "Pause reason.", "exported": true }, { "name": "data", "type": "object", "optional": true, "description": "Object containing break-specific auxiliary properties." }, - { "name": "hitBreakpoints", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Hit breakpoints IDs", "hidden": true }, - { "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any.", "hidden": true } + { "name": "hitBreakpoints", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Hit breakpoints IDs", "experimental": true }, + { "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any.", "experimental": true } ], "description": "Fired when the virtual machine stopped on breakpoint or exception or any other stop criteria." }, @@ -759,7 +794,7 @@ "name": "messageRepeatCountUpdated", "parameters": [ { "name": "count", "type": "integer", "description": "New repeat count value." }, - { "name": "timestamp", "$ref": "Runtime.Timestamp", "description": "Timestamp of most recent message in batch.", "hidden": true } + { "name": "timestamp", "$ref": "Runtime.Timestamp", "description": "Timestamp of most recent message in batch.", "experimental": true } ], "description": "Not issued.", "deprecated": true @@ -774,7 +809,7 @@ { "domain": "Profiler", "dependencies": ["Runtime", "Debugger"], - "hidden": true, + "experimental": true, "types": [ { "id": "CPUProfileNode", @@ -859,7 +894,7 @@ { "domain": "HeapProfiler", "dependencies": ["Runtime"], - "hidden": true, + "experimental": true, "types": [ { "id": "HeapSnapshotObjectId", diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/InspectorVersion.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/InspectorVersion.h new file mode 100644 index 00000000000000..aff7b1519fb8e7 --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/InspectorVersion.h @@ -0,0 +1,6 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file is automatically generated. Do not modify. +#define V8_INSPECTOR_REVISION "62cd277117e6f8ec53e31b1be58290a6f7ab42ef" diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ConsoleTypes.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ConsoleTypes.h deleted file mode 100644 index 73c1878e9e3d84..00000000000000 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ConsoleTypes.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8ConsoleTypes_h -#define V8ConsoleTypes_h - -namespace blink { - -enum MessageLevel { - DebugMessageLevel = 4, - LogMessageLevel = 1, - InfoMessageLevel = 5, - WarningMessageLevel = 2, - ErrorMessageLevel = 3 -}; - -} - -#endif // !defined(V8ConsoleTypes_h) diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h deleted file mode 100644 index a932b7a4664c92..00000000000000 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContentSearchUtil.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8ContentSearchUtil_h -#define V8ContentSearchUtil_h - -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" -#include "platform/v8_inspector/protocol/Debugger.h" - -namespace blink { - -class V8InspectorSession; - -namespace V8ContentSearchUtil { - -PLATFORM_EXPORT String16 findSourceURL(const String16& content, bool multiline, bool* deprecated = nullptr); -PLATFORM_EXPORT String16 findSourceMapURL(const String16& content, bool multiline, bool* deprecated = nullptr); -PLATFORM_EXPORT std::unique_ptr> searchInTextByLines(V8InspectorSession*, const String16& text, const String16& query, const bool caseSensitive, const bool isRegex); - -} - -} - -#endif // !defined(V8ContentSearchUtil_h) diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h index 0dc1de29da75e5..81a98e6c520198 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8ContextInfo.h @@ -13,14 +13,11 @@ namespace blink { class V8ContextInfo { public: - V8ContextInfo(v8::Local context, int contextGroupId, bool isDefault, const String16& origin, const String16& humanReadableName, const String16& frameId, bool hasMemoryOnConsole) + V8ContextInfo(v8::Local context, int contextGroupId, const String16& humanReadableName) : context(context) , contextGroupId(contextGroupId) - , isDefault(isDefault) - , origin(origin) , humanReadableName(humanReadableName) - , frameId(frameId) - , hasMemoryOnConsole(hasMemoryOnConsole) + , hasMemoryOnConsole(false) { } @@ -29,11 +26,9 @@ class V8ContextInfo { // V8DebuggerAgent to notify about events in the context. // |contextGroupId| must be non-0. int contextGroupId; - bool isDefault; - const String16 origin; - const String16 humanReadableName; - // TODO(dgozman): aux data? - const String16 frameId; + String16 humanReadableName; + String16 origin; + String16 auxData; bool hasMemoryOnConsole; }; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Debugger.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Debugger.h deleted file mode 100644 index da3dcacf555b15..00000000000000 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Debugger.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8Debugger_h -#define V8Debugger_h - -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" -#include "platform/v8_inspector/public/V8ConsoleTypes.h" - -#include - -namespace blink { - -class V8ContextInfo; -class V8DebuggerClient; -class V8InspectorSession; -class V8InspectorSessionClient; -class V8StackTrace; - -namespace protocol { -class FrontendChannel; -} - -class PLATFORM_EXPORT V8Debugger { -public: - static std::unique_ptr create(v8::Isolate*, V8DebuggerClient*); - virtual ~V8Debugger() { } - - // Contexts instrumentation. - virtual void contextCreated(const V8ContextInfo&) = 0; - virtual void contextDestroyed(v8::Local) = 0; - virtual void resetContextGroup(int contextGroupId) = 0; - - // Various instrumentation. - virtual void willExecuteScript(v8::Local, int scriptId) = 0; - virtual void didExecuteScript(v8::Local) = 0; - virtual void idleStarted() = 0; - virtual void idleFinished() = 0; - - // Async call stacks instrumentation. - virtual void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) = 0; - virtual void asyncTaskCanceled(void* task) = 0; - virtual void asyncTaskStarted(void* task) = 0; - virtual void asyncTaskFinished(void* task) = 0; - virtual void allAsyncTasksCanceled() = 0; - - // Runtime instrumentation. - // TODO(dgozman): can we pass exception object? - virtual void exceptionThrown(int contextGroupId, const String16& errorMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) = 0; - virtual unsigned promiseRejected(v8::Local, const String16& errorMessage, v8::Local exception, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) = 0; - virtual void promiseRejectionRevoked(v8::Local, unsigned promiseRejectionId) = 0; - - // TODO(dgozman): can we remove this method? - virtual void logToConsole(v8::Local, v8::Local arg1, v8::Local arg2) = 0; - - // API methods. - virtual std::unique_ptr connect(int contextGroupId, protocol::FrontendChannel*, V8InspectorSessionClient*, const String16* state) = 0; - virtual std::unique_ptr createStackTrace(v8::Local) = 0; - virtual std::unique_ptr captureStackTrace(bool fullStack) = 0; -}; - -} // namespace blink - - -#endif // V8Debugger_h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h deleted file mode 100644 index 3747f66707d051..00000000000000 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8DebuggerClient.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8DebuggerClient_h -#define V8DebuggerClient_h - -#include "platform/inspector_protocol/Platform.h" -#include "platform/v8_inspector/public/V8ConsoleTypes.h" -#include "platform/v8_inspector/public/V8ContextInfo.h" - -#include - -namespace blink { - -class V8StackTrace; - -class PLATFORM_EXPORT V8DebuggerClient { -public: - virtual ~V8DebuggerClient() { } - virtual void runMessageLoopOnPause(int contextGroupId) = 0; - virtual void quitMessageLoopOnPause() = 0; - virtual void muteWarningsAndDeprecations(int contextGroupId) = 0; - virtual void unmuteWarningsAndDeprecations(int contextGroupId) = 0; - virtual void beginUserGesture() = 0; - virtual void endUserGesture() = 0; - virtual bool callingContextCanAccessContext(v8::Local calling, v8::Local target) = 0; - virtual String16 valueSubtype(v8::Local) = 0; - virtual bool formatAccessorsAsProperties(v8::Local) = 0; - virtual bool isExecutionAllowed() = 0; - virtual double currentTimeMS() = 0; - virtual v8::Local ensureDefaultContextInGroup(int contextGroupId) = 0; - virtual bool isInspectableHeapObject(v8::Local) = 0; - virtual void enableAsyncInstrumentation() = 0; - virtual void disableAsyncInstrumentation() = 0; - - virtual void installAdditionalCommandLineAPI(v8::Local, v8::Local) = 0; - - virtual void consoleTime(const String16& title) = 0; - virtual void consoleTimeEnd(const String16& title) = 0; - virtual void consoleTimeStamp(const String16& title) = 0; - virtual void consoleAPIMessage(int contextGroupId, MessageLevel, const String16& message, const String16& url, unsigned lineNumber, unsigned columnNumber, V8StackTrace*) = 0; - - virtual v8::MaybeLocal memoryInfo(v8::Isolate*, v8::Local) = 0; - - typedef void (*TimerCallback)(void*); - virtual void startRepeatingTimer(double, TimerCallback, void* data) = 0; - virtual void cancelTimer(void* data) = 0; -}; - -} // namespace blink - - -#endif // V8DebuggerClient_h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp deleted file mode 100644 index f118dcacf3ce5a..00000000000000 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - - -#include "platform/v8_inspector/public/V8Inspector.h" - -#include "platform/inspector_protocol/DispatcherBase.h" -#include "platform/v8_inspector/V8StringUtil.h" -#include "platform/v8_inspector/public/V8Debugger.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" - -namespace blink { - -V8Inspector::V8Inspector(v8::Isolate* isolate, v8::Local context) - : m_context(context) -{ - m_debugger = V8Debugger::create(isolate, this); - m_debugger->contextCreated(V8ContextInfo(context, 1, true, "", - "NodeJS Main Context", "", false)); -} - -V8Inspector::~V8Inspector() -{ - disconnectFrontend(); -} - -bool V8Inspector::callingContextCanAccessContext(v8::Local calling, v8::Local target) -{ - return true; -} - -String16 V8Inspector::valueSubtype(v8::Local value) -{ - return String16(); -} - -bool V8Inspector::formatAccessorsAsProperties(v8::Local value) -{ - return false; -} - -void V8Inspector::connectFrontend(protocol::FrontendChannel* channel) -{ - m_session = m_debugger->connect(1, channel, this, &m_state); -} - -void V8Inspector::disconnectFrontend() -{ - m_session.reset(); -} - -void V8Inspector::dispatchMessageFromFrontend(const String16& message) -{ - if (m_session) - m_session->dispatchProtocolMessage(message); -} - -v8::Local V8Inspector::ensureDefaultContextInGroup(int) -{ - return m_context; -} - -bool V8Inspector::isExecutionAllowed() -{ - return true; -} - -bool V8Inspector::canExecuteScripts() -{ - return true; -} - -} // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.h index 4dbb797d50935f..a62f0c8b3a078d 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8Inspector.h @@ -1,4 +1,4 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,76 +6,55 @@ #define V8Inspector_h #include "platform/inspector_protocol/Platform.h" -#include "platform/v8_inspector/public/V8DebuggerClient.h" -#include "platform/v8_inspector/public/V8InspectorSession.h" -#include "platform/v8_inspector/public/V8InspectorSessionClient.h" +#include "platform/inspector_protocol/String16.h" +#include "platform/v8_inspector/public/V8ContextInfo.h" #include namespace blink { +class V8InspectorClient; +class V8InspectorSession; +class V8StackTrace; + namespace protocol { -class Dispatcher; -class Frontend; class FrontendChannel; } -class V8Debugger; -class V8HeapProfilerAgent; -class V8ProfilerAgent; - -class V8Inspector : public V8DebuggerClient, V8InspectorSessionClient { +class PLATFORM_EXPORT V8Inspector { public: - V8Inspector(v8::Isolate*, v8::Local); - ~V8Inspector(); - - // Transport interface. - void connectFrontend(protocol::FrontendChannel*); - void disconnectFrontend(); - void dispatchMessageFromFrontend(const String16& message); - -private: - bool callingContextCanAccessContext(v8::Local calling, v8::Local target) override; - String16 valueSubtype(v8::Local) override; - bool formatAccessorsAsProperties(v8::Local) override; - void muteWarningsAndDeprecations(int) override { } - void unmuteWarningsAndDeprecations(int) override { } - double currentTimeMS() override { return 0; }; - - bool isExecutionAllowed() override; - v8::Local ensureDefaultContextInGroup(int contextGroupId) override; - void beginUserGesture() override { } - void endUserGesture() override { } - bool isInspectableHeapObject(v8::Local) override { return true; } - void consoleTime(const String16& title) override { } - void consoleTimeEnd(const String16& title) override { } - void consoleTimeStamp(const String16& title) override { } - void consoleAPIMessage(int contextGroupId, MessageLevel, const String16& message, const String16& url, unsigned lineNumber, unsigned columnNumber, V8StackTrace*) override { } - v8::MaybeLocal memoryInfo(v8::Isolate*, v8::Local) override - { - return v8::MaybeLocal(); - } - void installAdditionalCommandLineAPI(v8::Local, v8::Local) override { } - void enableAsyncInstrumentation() override { } - void disableAsyncInstrumentation() override { } - void startRepeatingTimer(double, TimerCallback, void* data) override { } - void cancelTimer(void* data) override { } - - // V8InspectorSessionClient - void runtimeEnabled() override { }; - void runtimeDisabled() override { }; - void resumeStartup() override { }; - bool canExecuteScripts() override; - void profilingStarted() override { }; - void profilingStopped() override { }; - void consoleCleared() override { }; - - std::unique_ptr m_debugger; - std::unique_ptr m_session; - String16 m_state; - v8::Local m_context; + static std::unique_ptr create(v8::Isolate*, V8InspectorClient*); + virtual ~V8Inspector() { } + + // Contexts instrumentation. + virtual void contextCreated(const V8ContextInfo&) = 0; + virtual void contextDestroyed(v8::Local) = 0; + virtual void resetContextGroup(int contextGroupId) = 0; + + // Various instrumentation. + virtual void willExecuteScript(v8::Local, int scriptId) = 0; + virtual void didExecuteScript(v8::Local) = 0; + virtual void idleStarted() = 0; + virtual void idleFinished() = 0; + + // Async stack traces instrumentation. + virtual void asyncTaskScheduled(const String16& taskName, void* task, bool recurring) = 0; + virtual void asyncTaskCanceled(void* task) = 0; + virtual void asyncTaskStarted(void* task) = 0; + virtual void asyncTaskFinished(void* task) = 0; + virtual void allAsyncTasksCanceled() = 0; + + // Exceptions instrumentation. + virtual unsigned exceptionThrown(v8::Local, const String16& message, v8::Local exception, const String16& detailedMessage, const String16& url, unsigned lineNumber, unsigned columnNumber, std::unique_ptr, int scriptId) = 0; + virtual void exceptionRevoked(v8::Local, unsigned exceptionId, const String16& message) = 0; + + // API methods. + virtual std::unique_ptr connect(int contextGroupId, protocol::FrontendChannel*, const String16* state) = 0; + virtual std::unique_ptr createStackTrace(v8::Local) = 0; + virtual std::unique_ptr captureStackTrace(bool fullStack) = 0; }; -} +} // namespace blink + #endif // V8Inspector_h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorClient.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorClient.h new file mode 100644 index 00000000000000..27495ae9884b0b --- /dev/null +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorClient.h @@ -0,0 +1,60 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8InspectorClient_h +#define V8InspectorClient_h + +#include "platform/inspector_protocol/Platform.h" +#include "platform/inspector_protocol/String16.h" + +#include + +namespace blink { + +class V8StackTrace; + +enum class V8ConsoleAPIType { kClear, kDebug, kLog, kInfo, kWarning, kError }; + +class PLATFORM_EXPORT V8InspectorClient { +public: + virtual ~V8InspectorClient() { } + + virtual void runMessageLoopOnPause(int contextGroupId) { } + virtual void quitMessageLoopOnPause() { } + virtual void resumeStartup(int contextGroupId) { } + + virtual void muteMetrics(int contextGroupId) { } + virtual void unmuteMetrics(int contextGroupId) { } + + virtual void beginUserGesture() { } + virtual void endUserGesture() { } + + virtual String16 valueSubtype(v8::Local) { return String16(); } + virtual bool formatAccessorsAsProperties(v8::Local) { return false; } + virtual bool isInspectableHeapObject(v8::Local) { return true; } + + virtual v8::Local ensureDefaultContextInGroup(int contextGroupId) { return v8::Local(); } + virtual void beginEnsureAllContextsInGroup(int contextGroupId) { } + virtual void endEnsureAllContextsInGroup(int contextGroupId) { } + + virtual void installAdditionalCommandLineAPI(v8::Local, v8::Local) { } + virtual void consoleAPIMessage(int contextGroupId, V8ConsoleAPIType, const String16& message, const String16& url, unsigned lineNumber, unsigned columnNumber, V8StackTrace*) { } + virtual v8::MaybeLocal memoryInfo(v8::Isolate*, v8::Local) { return v8::MaybeLocal(); } + + virtual void consoleTime(const String16& title) { } + virtual void consoleTimeEnd(const String16& title) { } + virtual void consoleTimeStamp(const String16& title) { } + virtual double currentTimeMS() { return 0; } + typedef void (*TimerCallback)(void*); + virtual void startRepeatingTimer(double, TimerCallback, void* data) { } + virtual void cancelTimer(void* data) { } + + // TODO(dgozman): this was added to support service worker shadow page. We should not connect at all. + virtual bool canExecuteScripts(int contextGroupId) { return true; } +}; + +} // namespace blink + + +#endif // V8InspectorClient_h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h index 2103467e44087b..365ab86432ba1f 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSession.h @@ -5,8 +5,10 @@ #ifndef V8InspectorSession_h #define V8InspectorSession_h +#include "platform/inspector_protocol/Array.h" #include "platform/inspector_protocol/Platform.h" -#include "platform/v8_inspector/protocol/Runtime.h" +#include "platform/v8_inspector/public/protocol/Debugger.h" +#include "platform/v8_inspector/public/protocol/Runtime.h" #include @@ -25,23 +27,22 @@ class PLATFORM_EXPORT V8InspectorSession { virtual void addInspectedObject(std::unique_ptr) = 0; // Dispatching protocol messages. - // TODO(dgozman): generate this one. - static bool isV8ProtocolMethod(const String16& method); + static bool canDispatchMethod(const String16& method); virtual void dispatchProtocolMessage(const String16& message) = 0; virtual String16 stateJSON() = 0; // Debugger actions. - virtual void schedulePauseOnNextStatement(const String16& breakReason, std::unique_ptr data) = 0; + virtual void schedulePauseOnNextStatement(const String16& breakReason, const String16& breakDetails) = 0; virtual void cancelPauseOnNextStatement() = 0; - virtual void breakProgram(const String16& breakReason, std::unique_ptr data) = 0; + virtual void breakProgram(const String16& breakReason, const String16& breakDetails) = 0; virtual void setSkipAllPauses(bool) = 0; virtual void resume() = 0; virtual void stepOver() = 0; + virtual std::unique_ptr> searchInTextByLines(const String16& text, const String16& query, bool caseSensitive, bool isRegex) = 0; // Remote objects. - static const char backtraceObjectGroup[]; - virtual std::unique_ptr wrapObject(v8::Local, v8::Local, const String16& groupName, bool generatePreview) = 0; - virtual v8::Local findObject(ErrorString*, const String16& objectId, v8::Local* = nullptr, String16* objectGroup = nullptr) = 0; + virtual std::unique_ptr wrapObject(v8::Local, v8::Local, const String16& groupName) = 0; + virtual bool unwrapObject(ErrorString*, const String16& objectId, v8::Local*, v8::Local*, String16* objectGroup) = 0; virtual void releaseObjectGroup(const String16&) = 0; }; diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h deleted file mode 100644 index e9e7c33ea83fd2..00000000000000 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8InspectorSessionClient.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8InspectorSessionClient_h -#define V8InspectorSessionClient_h - -#include "platform/inspector_protocol/Platform.h" - -#include - -namespace blink { - -class PLATFORM_EXPORT V8InspectorSessionClient { -public: - virtual ~V8InspectorSessionClient() { } - virtual void runtimeEnabled() = 0; - virtual void runtimeDisabled() = 0; - virtual void resumeStartup() = 0; - // TODO(dgozman): this was added to support service worker shadow page. We should not connect at all. - virtual bool canExecuteScripts() = 0; - virtual void profilingStarted() = 0; - virtual void profilingStopped() = 0; - virtual void consoleCleared() = 0; -}; - -} // namespace blink - -#endif // V8InspectorSessionClient_h diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8StackTrace.h b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8StackTrace.h index beee1155f6e87f..1913554a20e141 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8StackTrace.h +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/public/V8StackTrace.h @@ -7,13 +7,12 @@ #include "platform/inspector_protocol/Platform.h" #include "platform/inspector_protocol/String16.h" -#include "platform/v8_inspector/protocol/Runtime.h" +#include "platform/v8_inspector/public/protocol/Runtime.h" #include namespace blink { -// TODO(dgozman): migrate to V8SourceLocation. class V8StackTrace { public: virtual bool isEmpty() const = 0; @@ -24,10 +23,11 @@ class V8StackTrace { virtual String16 topFunctionName() const = 0; virtual ~V8StackTrace() { } - virtual std::unique_ptr buildInspectorObject() const = 0; + virtual std::unique_ptr buildInspectorObject() const = 0; virtual String16 toString() const = 0; + + // Safe to pass between threads, drops async chain. virtual std::unique_ptr clone() = 0; - virtual std::unique_ptr isolatedCopy() = 0; // Safe to pass between threads. }; } // namespace blink diff --git a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/v8_inspector.gyp b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/v8_inspector.gyp index 6de6017c6931af..ebfc91a66d4b19 100644 --- a/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/v8_inspector.gyp +++ b/deps/v8_inspector/third_party/v8_inspector/platform/v8_inspector/v8_inspector.gyp @@ -79,6 +79,8 @@ # Source code templates. '../inspector_protocol/TypeBuilder_h.template', '../inspector_protocol/TypeBuilder_cpp.template', + '../inspector_protocol/Exported_h.template', + '../inspector_protocol/Imported_h.template', # Protocol definitions 'js_protocol.json', ], @@ -93,6 +95,8 @@ '<(blink_platform_output_dir)/v8_inspector/protocol/Profiler.h', '<(blink_platform_output_dir)/v8_inspector/protocol/Runtime.cpp', '<(blink_platform_output_dir)/v8_inspector/protocol/Runtime.h', + '<(blink_platform_output_dir)/v8_inspector/public/protocol/Runtime.h', + '<(blink_platform_output_dir)/v8_inspector/public/protocol/Debugger.h', ], 'action': [ 'python', @@ -102,6 +106,8 @@ '--export_macro', 'PLATFORM_EXPORT', '--output_dir', '<(blink_platform_output_dir)/v8_inspector/protocol', '--output_package', 'platform/v8_inspector/protocol', + '--exported_dir', '<(blink_platform_output_dir)/v8_inspector/public/protocol', + '--exported_package', 'platform/v8_inspector/public/protocol', ], 'message': 'Generating protocol backend sources from json definitions.', }, @@ -177,11 +183,9 @@ '../inspector_protocol/String16STL.h', '../inspector_protocol/Values.cpp', '../inspector_protocol/Values.h', - '../inspector_protocol/ValueConversions.cpp', '../inspector_protocol/ValueConversions.h', 'Atomics.h', - 'IgnoreExceptionsScope.h', 'InjectedScript.cpp', 'InjectedScript.h', 'InjectedScriptNative.cpp', @@ -200,10 +204,12 @@ 'V8ConsoleAgentImpl.h', 'V8ConsoleMessage.cpp', 'V8ConsoleMessage.h', + 'V8Debugger.cpp', + 'V8Debugger.h', 'V8DebuggerAgentImpl.cpp', 'V8DebuggerAgentImpl.h', - 'V8DebuggerImpl.cpp', - 'V8DebuggerImpl.h', + 'V8InspectorImpl.cpp', + 'V8InspectorImpl.h', 'V8DebuggerScript.cpp', 'V8DebuggerScript.h', 'V8FunctionCall.cpp', @@ -227,13 +233,10 @@ 'V8StringUtil.cpp', 'V8StringUtil.h', 'public/V8EventListenerInfo.h', - 'public/V8ContentSearchUtil.h', 'public/V8ContextInfo.h', - 'public/V8Debugger.h', - 'public/V8DebuggerClient.h', - 'public/V8HeapProfilerAgent.h', - 'public/V8Inspector.cpp', 'public/V8Inspector.h', + 'public/V8InspectorClient.h', + 'public/V8HeapProfilerAgent.h', 'public/V8InspectorSession.h', 'public/V8StackTrace.h', diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index 5a870aa91ca0f4..6bcc195e77535c 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -9,7 +9,10 @@ #include "v8-platform.h" #include "util.h" +#include "platform/v8_inspector/public/InspectorVersion.h" #include "platform/v8_inspector/public/V8Inspector.h" +#include "platform/v8_inspector/public/V8InspectorClient.h" +#include "platform/v8_inspector/public/V8InspectorSession.h" #include "platform/inspector_protocol/FrontendChannel.h" #include "platform/inspector_protocol/String16.h" #include "platform/inspector_protocol/Values.h" @@ -36,7 +39,7 @@ const char TAG_CONNECT[] = "#connect"; const char TAG_DISCONNECT[] = "#disconnect"; const char DEVTOOLS_PATH[] = "/node"; -const char DEVTOOLS_HASH[] = "851972d6da7463c353d712d2cb6c1ec23fa6c4fe"; +const char DEVTOOLS_HASH[] = V8_INSPECTOR_REVISION; void PrintDebuggerReadyMessage(int port) { fprintf(stderr, "Debugger listening on port %d.\n" @@ -156,6 +159,8 @@ bool RespondToGet(inspector_socket_t* socket, const std::string& path, namespace inspector { +class V8NodeInspector; + class AgentImpl { public: explicit AgentImpl(node::Environment* env); @@ -211,7 +216,7 @@ class AgentImpl { uv_async_t* data_written_; uv_async_t io_thread_req_; inspector_socket_t* client_socket_; - blink::V8Inspector* inspector_; + V8NodeInspector* inspector_; v8::Platform* platform_; MessageQueue incoming_message_queue_; MessageQueue outgoing_message_queue_; @@ -271,16 +276,20 @@ class ChannelImpl final : public blink::protocol::FrontendChannel { AgentImpl* const agent_; }; -class V8NodeInspector : public blink::V8Inspector { +class V8NodeInspector : public blink::V8InspectorClient { public: V8NodeInspector(AgentImpl* agent, node::Environment* env, v8::Platform* platform) - : blink::V8Inspector(env->isolate(), env->context()), - agent_(agent), + : agent_(agent), isolate_(env->isolate()), platform_(platform), terminated_(false), - running_nested_loop_(false) {} + running_nested_loop_(false), + inspector_( + blink::V8Inspector::create(env->isolate(), this)) { + inspector_->contextCreated( + blink::V8ContextInfo(env->context(), 1, "NodeJS Main Context")); + } void runMessageLoopOnPause(int context_group_id) override { if (running_nested_loop_) @@ -303,12 +312,27 @@ class V8NodeInspector : public blink::V8Inspector { terminated_ = true; } + void connectFrontend() { + session_ = inspector_->connect(1, new ChannelImpl(agent_), nullptr); + } + + void disconnectFrontend() { + session_.reset(); + } + + void dispatchMessageFromFrontend(const String16& message) { + CHECK(session_); + session_->dispatchProtocolMessage(message); + } + private: AgentImpl* agent_; v8::Isolate* isolate_; v8::Platform* platform_; bool terminated_; bool running_nested_loop_; + std::unique_ptr inspector_; + std::unique_ptr session_; }; AgentImpl::AgentImpl(Environment* env) : port_(0), @@ -546,7 +570,7 @@ void AgentImpl::DispatchMessages() { backend_session_id_++; state_ = State::kConnected; fprintf(stderr, "Debugger attached.\n"); - inspector_->connectFrontend(new ChannelImpl(this)); + inspector_->connectFrontend(); } else if (message == TAG_DISCONNECT) { CHECK_EQ(State::kConnected, state_); if (shutting_down_) { From 60d6e048f0f912882c80a088aeb5828a9ecf639b Mon Sep 17 00:00:00 2001 From: Aleksei Koziatinskii Date: Fri, 5 Aug 2016 13:45:08 -0700 Subject: [PATCH 133/144] deps: v8_inspector: console support When node is running with --inspect flag, default console.log, console.warn and other methods call inspector console methods in addition to current behaviour (dump formatted message to stderr and stdout). Inspector console methods forward message to DevTools and show up in DevTools Console with DevTools formatters. Inspector console methods not present on Node console will be added into it. Only own methods on global.console object will be changed while in a debugging session. User are still able to redefine it, use console.Console or change original methods on Console.prototype. PR-URL: https://github.com/nodejs/node/pull/7988 Reviewed-By: bnoordhuis - Ben Noordhuis Reviewed-By: jasnell - James M Snell Reviewed-By: ofrobots - Ali Ijaz Sheikh --- lib/internal/bootstrap_node.js | 39 +++++++++++++- src/inspector_agent.cc | 92 ++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index 22c72bc8120cf5..140816aac08cc1 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -238,15 +238,52 @@ } function setupGlobalConsole() { + var inspectorConsole; + var wrapConsoleCall; + if (process.inspector) { + inspectorConsole = global.console; + wrapConsoleCall = process.inspector.wrapConsoleCall; + delete process.inspector; + } + var console; Object.defineProperty(global, 'console', { configurable: true, enumerable: true, get: function() { - return NativeModule.require('console'); + if (!console) { + console = NativeModule.require('console'); + installInspectorConsoleIfNeeded(console, + inspectorConsole, + wrapConsoleCall); + } + return console; } }); } + function installInspectorConsoleIfNeeded(console, + inspectorConsole, + wrapConsoleCall) { + if (!inspectorConsole) + return; + var config = {}; + for (const key of Object.keys(console)) { + if (!inspectorConsole.hasOwnProperty(key)) + continue; + // If node console has the same method as inspector console, + // then wrap these two methods into one. Native wrapper will preserve + // the original stack. + console[key] = wrapConsoleCall(inspectorConsole[key], + console[key], + config); + } + for (const key of Object.keys(inspectorConsole)) { + if (console.hasOwnProperty(key)) + continue; + console[key] = inspectorConsole[key]; + } + } + function setupProcessFatal() { process._fatalException = function(er) { diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index 6bcc195e77535c..78fc3719a6972f 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -186,6 +186,8 @@ class AgentImpl { const std::string& path); static void WriteCbIO(uv_async_t* async); + void InstallInspectorOnProcess(); + void WorkerRunIO(); void OnInspectorConnectionIO(inspector_socket_t* socket); void OnRemoteDataIO(inspector_socket_t* stream, ssize_t read, @@ -276,6 +278,9 @@ class ChannelImpl final : public blink::protocol::FrontendChannel { AgentImpl* const agent_; }; +// Used in V8NodeInspector::currentTimeMS() below. +#define NANOS_PER_MSEC 1000000 + class V8NodeInspector : public blink::V8InspectorClient { public: V8NodeInspector(AgentImpl* agent, node::Environment* env, @@ -308,6 +313,10 @@ class V8NodeInspector : public blink::V8InspectorClient { running_nested_loop_ = false; } + double currentTimeMS() override { + return uv_hrtime() * 1.0 / NANOS_PER_MSEC; + } + void quitMessageLoopOnPause() override { terminated_ = true; } @@ -361,11 +370,78 @@ AgentImpl::~AgentImpl() { data_written_ = nullptr; } +void InspectorConsoleCall(const v8::FunctionCallbackInfo& info) { + v8::Isolate* isolate = info.GetIsolate(); + v8::Local context = isolate->GetCurrentContext(); + + CHECK(info.Data()->IsArray()); + v8::Local args = info.Data().As(); + CHECK_EQ(args->Length(), 3); + + v8::Local inspector_method = + args->Get(context, 0).ToLocalChecked(); + CHECK(inspector_method->IsFunction()); + v8::Local node_method = + args->Get(context, 1).ToLocalChecked(); + CHECK(node_method->IsFunction()); + v8::Local config_value = + args->Get(context, 2).ToLocalChecked(); + CHECK(config_value->IsObject()); + v8::Local config_object = config_value.As(); + + std::vector> call_args(info.Length()); + for (int i = 0; i < info.Length(); ++i) { + call_args[i] = info[i]; + } + + v8::Local in_call_key = OneByteString(isolate, "in_call"); + bool in_call = config_object->Has(context, in_call_key).FromMaybe(false); + if (!in_call) { + CHECK(config_object->Set(context, + in_call_key, + v8::True(isolate)).FromJust()); + CHECK(!inspector_method.As()->Call( + context, + info.Holder(), + call_args.size(), + call_args.data()).IsEmpty()); + } + + v8::TryCatch try_catch(info.GetIsolate()); + node_method.As()->Call(context, + info.Holder(), + call_args.size(), + call_args.data()); + CHECK(config_object->Delete(context, in_call_key).FromJust()); + if (try_catch.HasCaught()) + try_catch.ReThrow(); +} + +void InspectorWrapConsoleCall(const v8::FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + + if (args.Length() != 3 || !args[0]->IsFunction() || + !args[1]->IsFunction() || !args[2]->IsObject()) { + return env->ThrowError("inspector.wrapConsoleCall takes exactly 3 " + "arguments: two functions and an object."); + } + + v8::Local array = v8::Array::New(env->isolate(), args.Length()); + CHECK(array->Set(env->context(), 0, args[0]).FromJust()); + CHECK(array->Set(env->context(), 1, args[1]).FromJust()); + CHECK(array->Set(env->context(), 2, args[2]).FromJust()); + args.GetReturnValue().Set(v8::Function::New(env->context(), + InspectorConsoleCall, + array).ToLocalChecked()); +} + bool AgentImpl::Start(v8::Platform* platform, int port, bool wait) { auto env = parent_env_; inspector_ = new V8NodeInspector(this, env, platform); platform_ = platform; + InstallInspectorOnProcess(); + int err = uv_loop_init(&child_loop_); CHECK_EQ(err, 0); @@ -403,6 +479,22 @@ void AgentImpl::WaitForDisconnect() { inspector_->runMessageLoopOnPause(0); } +#define READONLY_PROPERTY(obj, str, var) \ + do { \ + obj->DefineOwnProperty(env->context(), \ + OneByteString(env->isolate(), str), \ + var, \ + v8::ReadOnly).FromJust(); \ + } while (0) + +void AgentImpl::InstallInspectorOnProcess() { + auto env = parent_env_; + v8::Local process = env->process_object(); + v8::Local inspector = v8::Object::New(env->isolate()); + READONLY_PROPERTY(process, "inspector", inspector); + env->SetMethod(inspector, "wrapConsoleCall", InspectorWrapConsoleCall); +} + // static void AgentImpl::ThreadCbIO(void* agent) { static_cast(agent)->WorkerRunIO(); From 18a30649377923a6abb0e36d0f25879d0792a71a Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Wed, 27 Jul 2016 00:18:35 +0200 Subject: [PATCH 134/144] fs: restore JS implementation of realpath This reverts parts of https://github.com/nodejs/node/commit/b488b19eaf2b2e7a3ca5eccd2445e245847a5f76 restoring javascript implementation of realpath and realpathSync. Fixes: https://github.com/nodejs/node/issues/7175 Fixes: https://github.com/nodejs/node/issues/6861 Fixes: https://github.com/nodejs/node/issues/7294 Fixes: https://github.com/nodejs/node/issues/7192 Fixes: https://github.com/nodejs/node/issues/7044 Fixes: https://github.com/nodejs/node/issues/6624 Fixes: https://github.com/nodejs/node/issues/6978 PR-URL: https://github.com/nodejs/node/pull/7899 Reviewed-By: James M Snell Reviewed-By: Anna Henningsen --- doc/api/fs.md | 8 +- lib/fs.js | 225 +++++++++++++++++- .../test-fs-realpath-buffer-encoding.js | 88 +++++++ .../test-fs-realpath-on-substed-drive.js | 53 +++++ 4 files changed, 360 insertions(+), 14 deletions(-) create mode 100644 test/parallel/test-fs-realpath-buffer-encoding.js create mode 100644 test/parallel/test-fs-realpath-on-substed-drive.js diff --git a/doc/api/fs.md b/doc/api/fs.md index ab8c8a92bdfc99..40b8a990631271 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1222,6 +1222,8 @@ added: v0.1.31 Asynchronous realpath(3). The `callback` gets two arguments `(err, resolvedPath)`. May use `process.cwd` to resolve relative paths. +Only paths that can be converted to UTF8 strings are supported. + The optional `options` argument can be a string specifying an encoding, or an object with an `encoding` property specifying the character encoding to use for the path passed to the callback. If the `encoding` is set to `'buffer'`, @@ -1238,10 +1240,12 @@ added: v0.1.31 Synchronous realpath(3). Returns the resolved path. +Only paths that can be converted to UTF8 strings are supported. + The optional `options` argument can be a string specifying an encoding, or an object with an `encoding` property specifying the character encoding to use for -the path passed to the callback. If the `encoding` is set to `'buffer'`, -the path returned will be passed as a `Buffer` object. +the returned value. If the `encoding` is set to `'buffer'`, the path returned +will be passed as a `Buffer` object. ## fs.rename(oldPath, newPath, callback) When set to `1`, writes to `stdout` and `stderr` will be non-blocking and diff --git a/doc/api/fs.md b/doc/api/fs.md index 40b8a990631271..d3f42f89903c2d 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -183,7 +183,7 @@ using the `fs.close()` method. ### readStream.bytesRead The number of bytes read so far. diff --git a/doc/api/process.md b/doc/api/process.md index df8dc095ea8ec6..ee329f268ebd09 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -489,7 +489,7 @@ Would generate the output: ## process.argv0 The `process.argv0` property stores a read-only copy of the original value of diff --git a/doc/changelogs/CHANGELOG_V6.md b/doc/changelogs/CHANGELOG_V6.md index fbc0e2b62319cd..53da68c2bc4402 100644 --- a/doc/changelogs/CHANGELOG_V6.md +++ b/doc/changelogs/CHANGELOG_V6.md @@ -6,6 +6,7 @@ +6.4.0
6.3.1
6.3.0
6.2.2
@@ -29,6 +30,179 @@ [Node.js Long Term Support plan](https://github.com/nodejs/LTS) starting in October 2016. + +## 2016-08-15, Version 6.4.0 (Current), @cjihrig + +### Notable changes + +* **build**: zlib symbols and additional OpenSSL symbols are now exposed on Windows platforms. (Alex Hultman) [#7983](https://github.com/nodejs/node/pull/7983) and [#7576](https://github.com/nodejs/node/pull/7576) +* **child_process**, **cluster**: Forked child processes and cluster workers now support stdio configuration. (Colin Ihrig) [#7811](https://github.com/nodejs/node/pull/7811) and [#7838](https://github.com/nodejs/node/pull/7838) +* **child_process**: `argv[0]` can now be set to arbitrary values in spawned processes. (Pat Pannuto) [#7696](https://github.com/nodejs/node/pull/7696) +* **fs**: `fs.ReadStream` now exposes the number of bytes it has read so far. (Linus Unnebäck) [#7942](https://github.com/nodejs/node/pull/7942) +* **repl**: The REPL now supports editor mode. (Prince J Wesley) [#7275](https://github.com/nodejs/node/pull/7275) +* **util**: `inspect()` can now be configured globally using `util.inspect.defaultOptions`. (Roman Reiss) [#8013](https://github.com/nodejs/node/pull/8013) + +### Commits + +* [[`06a0a053ea`](https://github.com/nodejs/node/commit/06a0a053ea)] - 2016-08-15, Version 6.4.0 (Current) (cjihrig) [#8070](https://github.com/nodejs/node/pull/8070) +* [[`342a85b1a7`](https://github.com/nodejs/node/commit/342a85b1a7)] - Working on v6.3.2 (Evan Lucas) [#7782](https://github.com/nodejs/node/pull/7782) +* [[`f135a4c3d1`](https://github.com/nodejs/node/commit/f135a4c3d1)] - 2016-07-21, Version 6.3.1 (Current) (Evan Lucas) [#7782](https://github.com/nodejs/node/pull/7782) +* [[`57043aad33`](https://github.com/nodejs/node/commit/57043aad33)] - **assert**: fix deepEqual/deepStrictEqual on equivalent typed arrays (Feross Aboukhadijeh) [#8002](https://github.com/nodejs/node/pull/8002) +* [[`f6713bfabd`](https://github.com/nodejs/node/commit/f6713bfabd)] - **bench**: add bench for fs.realpath() fix (Trevor Norris) [#7899](https://github.com/nodejs/node/pull/7899) +* [[`0d4b04659f`](https://github.com/nodejs/node/commit/0d4b04659f)] - **benchmark**: favor === over == (Rich Trott) [#8000](https://github.com/nodejs/node/pull/8000) +* [[`98f51ffeb6`](https://github.com/nodejs/node/commit/98f51ffeb6)] - **buffer**: fix unintended unsigned overflow (Fedor Indutny) [#7494](https://github.com/nodejs/node/pull/7494) +* [[`28071a130e`](https://github.com/nodejs/node/commit/28071a130e)] - **buffer**: introduce latin1 encoding term (Trevor Norris) [#7111](https://github.com/nodejs/node/pull/7111) +* [[`b0a557eef7`](https://github.com/nodejs/node/commit/b0a557eef7)] - **build**: add correct shared library naming on OS X (Stewart Addison) [#7687](https://github.com/nodejs/node/pull/7687) +* [[`6ed4ea8fd6`](https://github.com/nodejs/node/commit/6ed4ea8fd6)] - **build**: turn on thin static archives (Ben Noordhuis) [#7957](https://github.com/nodejs/node/pull/7957) +* [[`c843e58914`](https://github.com/nodejs/node/commit/c843e58914)] - **(SEMVER-MINOR)** **build**: export zlib symbols on Windows (Alex Hultman) [#7983](https://github.com/nodejs/node/pull/7983) +* [[`889c62fec1`](https://github.com/nodejs/node/commit/889c62fec1)] - **build**: fix dependency on missing header file (Ben Noordhuis) [#7945](https://github.com/nodejs/node/pull/7945) +* [[`a4394b8745`](https://github.com/nodejs/node/commit/a4394b8745)] - **build**: fix typo in non-essential source file name (Ben Noordhuis) [#7945](https://github.com/nodejs/node/pull/7945) +* [[`636cf2236a`](https://github.com/nodejs/node/commit/636cf2236a)] - **build**: adding config.gypi dep to addons/.buildstamp (Daniel Bevenius) [#7893](https://github.com/nodejs/node/pull/7893) +* [[`ddf292fc32`](https://github.com/nodejs/node/commit/ddf292fc32)] - **build**: don't link against liblog on host system (Ben Noordhuis) [#7762](https://github.com/nodejs/node/pull/7762) +* [[`f0312e6560`](https://github.com/nodejs/node/commit/f0312e6560)] - **(SEMVER-MINOR)** **build**: export more openssl symbols on Windows (Alex Hultman) [#7576](https://github.com/nodejs/node/pull/7576) +* [[`e561895275`](https://github.com/nodejs/node/commit/e561895275)] - **(SEMVER-MINOR)** **child_process**: control argv0 for spawned processes (Pat Pannuto) [#7696](https://github.com/nodejs/node/pull/7696) +* [[`da481c634f`](https://github.com/nodejs/node/commit/da481c634f)] - **(SEMVER-MINOR)** **child_process**: support stdio option in fork() (cjihrig) [#7811](https://github.com/nodejs/node/pull/7811) +* [[`a4f0b13e2b`](https://github.com/nodejs/node/commit/a4f0b13e2b)] - **(SEMVER-MINOR)** **cluster**: support stdio option for workers (cjihrig) [#7838](https://github.com/nodejs/node/pull/7838) +* [[`5f3ab3ffd1`](https://github.com/nodejs/node/commit/5f3ab3ffd1)] - **(SEMVER-MINOR)** **crypto**: fix undefined behavior in ParseExtension (Fedor Indutny) [#7494](https://github.com/nodejs/node/pull/7494) +* [[`60d6e048f0`](https://github.com/nodejs/node/commit/60d6e048f0)] - **(SEMVER-MINOR)** **deps**: v8_inspector: console support (Aleksei Koziatinskii) [#7988](https://github.com/nodejs/node/pull/7988) +* [[`a9fe85ee9c`](https://github.com/nodejs/node/commit/a9fe85ee9c)] - **deps**: v8_inspector update (Ali Ijaz Sheikh) [#8014](https://github.com/nodejs/node/pull/8014) +* [[`4d81362b99`](https://github.com/nodejs/node/commit/4d81362b99)] - **deps**: v8_inspector: remove jinja2 tests (Ali Ijaz Sheikh) [#7796](https://github.com/nodejs/node/pull/7796) +* [[`57312fc0c5`](https://github.com/nodejs/node/commit/57312fc0c5)] - **deps**: remove jinja.el from deps/v8_inspector (Ali Ijaz Sheikh) [#7796](https://github.com/nodejs/node/pull/7796) +* [[`507c65d94a`](https://github.com/nodejs/node/commit/507c65d94a)] - **deps**: update v8_inspector (Ali Ijaz Sheikh) [#7796](https://github.com/nodejs/node/pull/7796) +* [[`3f46b5c18e`](https://github.com/nodejs/node/commit/3f46b5c18e)] - **deps**: float gyp patch for long filenames (Anna Henningsen) [#7963](https://github.com/nodejs/node/pull/7963) +* [[`e6887e2ceb`](https://github.com/nodejs/node/commit/e6887e2ceb)] - **deps**: cherry-pick a76d133 from v8 upstream (Matt Loring) [#7689](https://github.com/nodejs/node/pull/7689) +* [[`a03e3d3cff`](https://github.com/nodejs/node/commit/a03e3d3cff)] - **deps**: cherry-pick b93c80a from v8 upstream (Matt Loring) [#7689](https://github.com/nodejs/node/pull/7689) +* [[`75b37a6bac`](https://github.com/nodejs/node/commit/75b37a6bac)] - **deps**: cherry-pick 43547df from V8 upstream (Franziska Hinkelmann) [#7863](https://github.com/nodejs/node/pull/7863) +* [[`af63871593`](https://github.com/nodejs/node/commit/af63871593)] - **deps**: cherry-pick a51f429 from V8 upstream (Franziska Hinkelmann) [#7834](https://github.com/nodejs/node/pull/7834) +* [[`e82e80417b`](https://github.com/nodejs/node/commit/e82e80417b)] - **deps**: backport 2bcbe2f from V8 upstream (ofrobots) [#7814](https://github.com/nodejs/node/pull/7814) +* [[`51a2041b90`](https://github.com/nodejs/node/commit/51a2041b90)] - **(SEMVER-MINOR)** **dgram**: generalized send queue to handle close (Matteo Collina) [#7066](https://github.com/nodejs/node/pull/7066) +* [[`7eb95f6faa`](https://github.com/nodejs/node/commit/7eb95f6faa)] - **doc**: minor updates to onboarding doc (Rich Trott) [#8060](https://github.com/nodejs/node/pull/8060) +* [[`5259322e62`](https://github.com/nodejs/node/commit/5259322e62)] - **doc**: add POST_STATUS_TO_PR info to onboarding doc (Rich Trott) [#8059](https://github.com/nodejs/node/pull/8059) +* [[`1903275963`](https://github.com/nodejs/node/commit/1903275963)] - **doc**: update windows prerequisites (Ben Noordhuis) [#8049](https://github.com/nodejs/node/pull/8049) +* [[`3fe122f57e`](https://github.com/nodejs/node/commit/3fe122f57e)] - **doc**: update licenses (Ali Ijaz Sheikh) [#7796](https://github.com/nodejs/node/pull/7796) +* [[`14b762f81f`](https://github.com/nodejs/node/commit/14b762f81f)] - **doc**: move orangemocha to collaborators list (Rich Trott) [#8062](https://github.com/nodejs/node/pull/8062) +* [[`ffbead92a0`](https://github.com/nodejs/node/commit/ffbead92a0)] - **doc**: Add fhinkel to collaborators (Franziska Hinkelmann) [#8052](https://github.com/nodejs/node/pull/8052) +* [[`96d15e2f3c`](https://github.com/nodejs/node/commit/96d15e2f3c)] - **doc**: fix cluster message event docs (Zach Bjornson) [#8017](https://github.com/nodejs/node/pull/8017) +* [[`4a8b8048f2`](https://github.com/nodejs/node/commit/4a8b8048f2)] - **doc**: add `added:` information for cluster (Anna Henningsen) [#7640](https://github.com/nodejs/node/pull/7640) +* [[`38255080db`](https://github.com/nodejs/node/commit/38255080db)] - **doc**: remove spurious new line in CHANGELOG_V6.md (Luigi Pinca) [#8009](https://github.com/nodejs/node/pull/8009) +* [[`9f78c3f64f`](https://github.com/nodejs/node/commit/9f78c3f64f)] - **doc**: fix typo in vm.runInNewContext() description (Luigi Pinca) [#8005](https://github.com/nodejs/node/pull/8005) +* [[`c4765a1b66`](https://github.com/nodejs/node/commit/c4765a1b66)] - **doc**: Clean up roff source in manpage (Alhadis) [#7819](https://github.com/nodejs/node/pull/7819) +* [[`cbcd03c912`](https://github.com/nodejs/node/commit/cbcd03c912)] - **doc**: add CTC meeting minutes 2016-08-03 (Josh Gavant) [#7980](https://github.com/nodejs/node/pull/7980) +* [[`7d0e5a0622`](https://github.com/nodejs/node/commit/7d0e5a0622)] - **doc**: clarify collaborators & ctc members relationships (yorkie) [#7996](https://github.com/nodejs/node/pull/7996) +* [[`dedfcb7858`](https://github.com/nodejs/node/commit/dedfcb7858)] - **doc**: clarify fd closing by `fs.readFile` etc. (kibertoad) [#7561](https://github.com/nodejs/node/pull/7561) +* [[`ce776d22f9`](https://github.com/nodejs/node/commit/ce776d22f9)] - **doc**: fix a markdown error in CTC meeting minutes (Сковорода Никита Андреевич) [#7729](https://github.com/nodejs/node/pull/7729) +* [[`b20518a013`](https://github.com/nodejs/node/commit/b20518a013)] - **doc**: add `added:` information for events (Luigi Pinca) [#7822](https://github.com/nodejs/node/pull/7822) +* [[`7fa4be0f87`](https://github.com/nodejs/node/commit/7fa4be0f87)] - **doc**: improve server.listen() random port (Phillip Johnsen) [#7976](https://github.com/nodejs/node/pull/7976) +* [[`7c427bdccc`](https://github.com/nodejs/node/commit/7c427bdccc)] - **doc**: clarify "Reviewed-By" iff "LGTM" (Bryan English) [#7183](https://github.com/nodejs/node/pull/7183) +* [[`cdbeae9adc`](https://github.com/nodejs/node/commit/cdbeae9adc)] - **doc**: add CTC meeting minutes 2016-07-13 (Josh Gavant) [#7968](https://github.com/nodejs/node/pull/7968) +* [[`2245e843cc`](https://github.com/nodejs/node/commit/2245e843cc)] - **doc**: add CTC meeting minutes 2016-07-20 (Josh Gavant) [#7970](https://github.com/nodejs/node/pull/7970) +* [[`cb0baca982`](https://github.com/nodejs/node/commit/cb0baca982)] - **doc**: use consistent markdown in README (Rich Trott) [#7971](https://github.com/nodejs/node/pull/7971) +* [[`3d1a06451a`](https://github.com/nodejs/node/commit/3d1a06451a)] - **doc**: use `git-secure-tag` for release tags (Fedor Indutny) [#7603](https://github.com/nodejs/node/pull/7603) +* [[`e116cf96a0`](https://github.com/nodejs/node/commit/e116cf96a0)] - **doc**: use blockquotes for Stability: markers (Anna Henningsen) [#7757](https://github.com/nodejs/node/pull/7757) +* [[`c934f51aa4`](https://github.com/nodejs/node/commit/c934f51aa4)] - **doc**: fix default encoding mention in crypto.md (hugnosis) [#7805](https://github.com/nodejs/node/pull/7805) +* [[`df35ae6246`](https://github.com/nodejs/node/commit/df35ae6246)] - **doc**: fix minor formatting issue in 0.10 changelog (Сковорода Никита Андреевич) [#7727](https://github.com/nodejs/node/pull/7727) +* [[`5f12807c46`](https://github.com/nodejs/node/commit/5f12807c46)] - **doc**: remove extra indentation in iojs changelog (Сковорода Никита Андреевич) [#7727](https://github.com/nodejs/node/pull/7727) +* [[`abd0bc0523`](https://github.com/nodejs/node/commit/abd0bc0523)] - **doc**: *.md formatting fixes in the top-level dir (Сковорода Никита Андреевич) [#7727](https://github.com/nodejs/node/pull/7727) +* [[`c72019b75a`](https://github.com/nodejs/node/commit/c72019b75a)] - **doc**: convert tabs to spaces (Сковорода Никита Андреевич) [#7727](https://github.com/nodejs/node/pull/7727) +* [[`0fbb83a67b`](https://github.com/nodejs/node/commit/0fbb83a67b)] - **doc**: piscisaureus has stepped-down from the CTC (James M Snell) [#7969](https://github.com/nodejs/node/pull/7969) +* [[`48422c240a`](https://github.com/nodejs/node/commit/48422c240a)] - **doc**: add @addaleax to the CTC (Anna Henningsen) [#7966](https://github.com/nodejs/node/pull/7966) +* [[`0094adc0b2`](https://github.com/nodejs/node/commit/0094adc0b2)] - **doc**: add CTC meeting minutes 2016-06-22 (Josh Gavant) [#7390](https://github.com/nodejs/node/pull/7390) +* [[`fd9b7b4c5a`](https://github.com/nodejs/node/commit/fd9b7b4c5a)] - **doc**: add CTC meeting minutes 2016-07-06 (Josh Gavant) [#7570](https://github.com/nodejs/node/pull/7570) +* [[`4616261110`](https://github.com/nodejs/node/commit/4616261110)] - **doc**: add CTC meeting minutes 2016-06-29 (Josh Gavant) [#7571](https://github.com/nodejs/node/pull/7571) +* [[`bb90867339`](https://github.com/nodejs/node/commit/bb90867339)] - **doc**: add CTC meeting minutes 2016-07-27 (William Kapke) [#7900](https://github.com/nodejs/node/pull/7900) +* [[`7d0c1bf781`](https://github.com/nodejs/node/commit/7d0c1bf781)] - **doc**: fix path markdown formatting (Joey Cozza) [#7817](https://github.com/nodejs/node/pull/7817) +* [[`04ec64aacc`](https://github.com/nodejs/node/commit/04ec64aacc)] - **doc**: add missing semicolon (Ravindra barthwal) [#7915](https://github.com/nodejs/node/pull/7915) +* [[`8d8d70d826`](https://github.com/nodejs/node/commit/8d8d70d826)] - **doc**: fill in missing V8 version (Timothy Gu) [#7878](https://github.com/nodejs/node/pull/7878) +* [[`6ce9c80ccb`](https://github.com/nodejs/node/commit/6ce9c80ccb)] - **doc**: remove extra spaces and concats in examples (Joe Esposito) [#7885](https://github.com/nodejs/node/pull/7885) +* [[`23b6468667`](https://github.com/nodejs/node/commit/23b6468667)] - **doc**: add information about CTC quorum rules (Rich Trott) [#7813](https://github.com/nodejs/node/pull/7813) +* [[`0645c3d0c4`](https://github.com/nodejs/node/commit/0645c3d0c4)] - **doc**: align breakEvalOnSigint - repl option (Prince J Wesley) [#7849](https://github.com/nodejs/node/pull/7849) +* [[`14a0c3181c`](https://github.com/nodejs/node/commit/14a0c3181c)] - **doc**: remove platform assumption from CONTRIBUTING (Bethany N Griggs) [#7783](https://github.com/nodejs/node/pull/7783) +* [[`5c4b938665`](https://github.com/nodejs/node/commit/5c4b938665)] - **doc**: minor typo fixes in stream docs (Alex Perkins) [#7763](https://github.com/nodejs/node/pull/7763) +* [[`57fb0d2ee2`](https://github.com/nodejs/node/commit/57fb0d2ee2)] - **doc**: add/fix version metadata for Buffer methods (Brian White) [#7784](https://github.com/nodejs/node/pull/7784) +* [[`49a669bcda`](https://github.com/nodejs/node/commit/49a669bcda)] - **doc**: improve function parameter descriptions (Brian White) [#7784](https://github.com/nodejs/node/pull/7784) +* [[`bdc8690610`](https://github.com/nodejs/node/commit/bdc8690610)] - **doc**: add missing properties in Buffer docs (Brian White) [#7784](https://github.com/nodejs/node/pull/7784) +* [[`a8e7c7f2bf`](https://github.com/nodejs/node/commit/a8e7c7f2bf)] - **doc**: improve wording and style of Buffer docs (Brian White) [#7784](https://github.com/nodejs/node/pull/7784) +* [[`9a4a00bcdb`](https://github.com/nodejs/node/commit/9a4a00bcdb)] - **doc**: improve links in Buffer docs (Brian White) [#7784](https://github.com/nodejs/node/pull/7784) +* [[`0103d9dcea`](https://github.com/nodejs/node/commit/0103d9dcea)] - **doc**: reorganize Buffer link references (Brian White) [#7784](https://github.com/nodejs/node/pull/7784) +* [[`17ae49a055`](https://github.com/nodejs/node/commit/17ae49a055)] - **doc**: improve Buffer code examples (Brian White) [#7784](https://github.com/nodejs/node/pull/7784) +* [[`0ffeddb5b4`](https://github.com/nodejs/node/commit/0ffeddb5b4)] - **doc**: various documentation formatting fixes (Сковорода Никита Андреевич) [#7637](https://github.com/nodejs/node/pull/7637) +* [[`1fa9330ac6`](https://github.com/nodejs/node/commit/1fa9330ac6)] - **doc**: add princejwesley to collaborators (Prince J Wesley) [#7877](https://github.com/nodejs/node/pull/7877) +* [[`715ac62670`](https://github.com/nodejs/node/commit/715ac62670)] - **doc**: clarify that the node.js irc channel is not under tsc oversight (James M Snell) [#7810](https://github.com/nodejs/node/pull/7810) +* [[`edb877da65`](https://github.com/nodejs/node/commit/edb877da65)] - **doc**: fix `added:` date for `NODE_REPL_HISTORY` (Anna Henningsen) [#7775](https://github.com/nodejs/node/pull/7775) +* [[`27f92efaee`](https://github.com/nodejs/node/commit/27f92efaee)] - **doctool**: improve the title of pages in doc (yorkie) [#7939](https://github.com/nodejs/node/pull/7939) +* [[`18a3064937`](https://github.com/nodejs/node/commit/18a3064937)] - **fs**: restore JS implementation of realpath (Bartosz Sosnowski) [#7899](https://github.com/nodejs/node/pull/7899) +* [[`0bb9d21f0e`](https://github.com/nodejs/node/commit/0bb9d21f0e)] - **(SEMVER-MINOR)** **fs**: add bytesRead to ReadStream (Linus Unnebäck) [#7942](https://github.com/nodejs/node/pull/7942) +* [[`db3a7e83eb`](https://github.com/nodejs/node/commit/db3a7e83eb)] - **http**: specify \_implicitHeader in OutgoingMessage (yorkie) [#7949](https://github.com/nodejs/node/pull/7949) +* [[`b75ca50c90`](https://github.com/nodejs/node/commit/b75ca50c90)] - **inspector**: Do not crash if the port is n/a (Eugene Ostroukhov) [#7874](https://github.com/nodejs/node/pull/7874) +* [[`7dc66f82e3`](https://github.com/nodejs/node/commit/7dc66f82e3)] - **lib**: remove double check of string type (Franziska Hinkelmann) [#7985](https://github.com/nodejs/node/pull/7985) +* [[`5cc4b0ed15`](https://github.com/nodejs/node/commit/5cc4b0ed15)] - **meta**: clarify process for breaking changes (Rich Trott) [#7955](https://github.com/nodejs/node/pull/7955) +* [[`79ecfb5183`](https://github.com/nodejs/node/commit/79ecfb5183)] - **meta**: include a minimal CTC removal policy (Rich Trott) [#7720](https://github.com/nodejs/node/pull/7720) +* [[`376d73b3b9`](https://github.com/nodejs/node/commit/376d73b3b9)] - **meta**: provide example activities (Rich Trott) [#7744](https://github.com/nodejs/node/pull/7744) +* [[`ccbb46378f`](https://github.com/nodejs/node/commit/ccbb46378f)] - **module**: fix node_modules search path in edge case (hefangshi) [#6670](https://github.com/nodejs/node/pull/6670) +* [[`2f32191686`](https://github.com/nodejs/node/commit/2f32191686)] - **(SEMVER-MINOR)** **process**: save original argv\[0\] (Pat Pannuto) [#7696](https://github.com/nodejs/node/pull/7696) +* [[`d9c9e46780`](https://github.com/nodejs/node/commit/d9c9e46780)] - **repl**: disable Ctrl+C support on win32 for now (Anna Henningsen) [#7977](https://github.com/nodejs/node/pull/7977) +* [[`61e57e06a6`](https://github.com/nodejs/node/commit/61e57e06a6)] - **repl**: don't override all internal repl defaults (cjihrig) [#7826](https://github.com/nodejs/node/pull/7826) +* [[`4875aa2aa2`](https://github.com/nodejs/node/commit/4875aa2aa2)] - **(SEMVER-MINOR)** **repl**: Add editor mode support (Prince J Wesley) [#7275](https://github.com/nodejs/node/pull/7275) +* [[`fc3ba2ff4f`](https://github.com/nodejs/node/commit/fc3ba2ff4f)] - **(SEMVER-MINOR)** **repl**: Use displayErrors for SyntaxError (Prince J Wesley) [#7589](https://github.com/nodejs/node/pull/7589) +* [[`b3164ae22e`](https://github.com/nodejs/node/commit/b3164ae22e)] - **(SEMVER-MINOR)** **repl**: add support for custom completions (Diosney Sarmiento) [#7527](https://github.com/nodejs/node/pull/7527) +* [[`980f4da8c4`](https://github.com/nodejs/node/commit/980f4da8c4)] - **repl**: prevent undefined ref in completion (Evan Lucas) [#7718](https://github.com/nodejs/node/pull/7718) +* [[`6e6cf36761`](https://github.com/nodejs/node/commit/6e6cf36761)] - **repl**: default useGlobal to true (cjihrig) [#7795](https://github.com/nodejs/node/pull/7795) +* [[`08e6eeee70`](https://github.com/nodejs/node/commit/08e6eeee70)] - **repl,util**: insert carriage returns in output (JungMinu) [#8028](https://github.com/nodejs/node/pull/8028) +* [[`fb8840cac2`](https://github.com/nodejs/node/commit/fb8840cac2)] - **src**: use RAII for mutexes in node_watchdog.cc (Anna Henningsen) [#7933](https://github.com/nodejs/node/pull/7933) +* [[`780395ffca`](https://github.com/nodejs/node/commit/780395ffca)] - **src**: fix use-after-free in inspector agent (Ben Noordhuis) [#7907](https://github.com/nodejs/node/pull/7907) +* [[`9d45569ed4`](https://github.com/nodejs/node/commit/9d45569ed4)] - **src**: avoid manual memory management in inspector (Ben Noordhuis) [#7906](https://github.com/nodejs/node/pull/7906) +* [[`a20336e708`](https://github.com/nodejs/node/commit/a20336e708)] - **src**: remove unused using decls (Haojian Wu) [#7990](https://github.com/nodejs/node/pull/7990) +* [[`317ae96c33`](https://github.com/nodejs/node/commit/317ae96c33)] - **src**: make EnvDelete behave like the delete operator (Franziska Hinkelmann) [#7975](https://github.com/nodejs/node/pull/7975) +* [[`1ab796fa96`](https://github.com/nodejs/node/commit/1ab796fa96)] - **src**: do not copy on failing setProperty() (Franziska Hinkelmann) [#7908](https://github.com/nodejs/node/pull/7908) +* [[`cf65a7ce9e`](https://github.com/nodejs/node/commit/cf65a7ce9e)] - **src**: unifying PipeConnectWrap and TCPConnectWrap (Daniel Bevenius) [#7501](https://github.com/nodejs/node/pull/7501) +* [[`63c62cce35`](https://github.com/nodejs/node/commit/63c62cce35)] - **src**: Only use TR1 type_traits on OSX<10.9 (Ehsan Akhgari) [#7778](https://github.com/nodejs/node/pull/7778) +* [[`d7143095cb`](https://github.com/nodejs/node/commit/d7143095cb)] - **src**: fix build on CentOS (Rich Trott) [#7873](https://github.com/nodejs/node/pull/7873) +* [[`303f4102d3`](https://github.com/nodejs/node/commit/303f4102d3)] - **src**: pull OnConnection from pipe_wrap and tcp_wrap (Daniel Bevenius) [#7547](https://github.com/nodejs/node/pull/7547) +* [[`c967af8c07`](https://github.com/nodejs/node/commit/c967af8c07)] - **src**: suppress coverity message (cjihrig) [#7587](https://github.com/nodejs/node/pull/7587) +* [[`f3e5b39696`](https://github.com/nodejs/node/commit/f3e5b39696)] - **src**: guard against overflow in ParseArrayIndex() (Ben Noordhuis) [#7497](https://github.com/nodejs/node/pull/7497) +* [[`c730a5d026`](https://github.com/nodejs/node/commit/c730a5d026)] - **src**: move ParseArrayIndex() to src/node_buffer.cc (Ben Noordhuis) [#7497](https://github.com/nodejs/node/pull/7497) +* [[`da9bd2fc48`](https://github.com/nodejs/node/commit/da9bd2fc48)] - **src**: alias BINARY to LATIN1 (Ben Noordhuis) [#7284](https://github.com/nodejs/node/pull/7284) +* [[`7ba0f860a6`](https://github.com/nodejs/node/commit/7ba0f860a6)] - **src**: fix erroneous fallthrough in ParseEncoding() (Ben Noordhuis) [#7262](https://github.com/nodejs/node/pull/7262) +* [[`a059aea9a2`](https://github.com/nodejs/node/commit/a059aea9a2)] - **src**: remove final trace of raw encoding (Trevor Norris) [#7111](https://github.com/nodejs/node/pull/7111) +* [[`2db26cb165`](https://github.com/nodejs/node/commit/2db26cb165)] - **test**: add test for debug usage message (Rich Trott) [#8061](https://github.com/nodejs/node/pull/8061) +* [[`2e435998eb`](https://github.com/nodejs/node/commit/2e435998eb)] - **test**: mark test failing on AIX as flaky (Michael Dawson) [#8065](https://github.com/nodejs/node/pull/8065) +* [[`554b0f9d91`](https://github.com/nodejs/node/commit/554b0f9d91)] - **test**: fix failing inspector cctest (Eugene Ostroukhov) [#8019](https://github.com/nodejs/node/pull/8019) +* [[`c565c17636`](https://github.com/nodejs/node/commit/c565c17636)] - **test**: fix memory leaks in inspector tests (Ben Noordhuis) [#7906](https://github.com/nodejs/node/pull/7906) +* [[`5d68e4ba9b`](https://github.com/nodejs/node/commit/5d68e4ba9b)] - **test**: console constructor missing new keyword (Rich Trott) [#8003](https://github.com/nodejs/node/pull/8003) +* [[`9735accd3e`](https://github.com/nodejs/node/commit/9735accd3e)] - **test**: allow globals to be whitelisted (cjihrig) [#7826](https://github.com/nodejs/node/pull/7826) +* [[`a385277eb5`](https://github.com/nodejs/node/commit/a385277eb5)] - **test**: fix flaky test-vm-sigint-existing-handler (Anna Henningsen) [#7982](https://github.com/nodejs/node/pull/7982) +* [[`b5beae2529`](https://github.com/nodejs/node/commit/b5beae2529)] - **test**: remove internal headers from addons (Gibson Fahnestock) [#7947](https://github.com/nodejs/node/pull/7947) +* [[`02b12fe880`](https://github.com/nodejs/node/commit/02b12fe880)] - **test**: improve chained property readability (Rich Trott) [#7920](https://github.com/nodejs/node/pull/7920) +* [[`d94063a22b`](https://github.com/nodejs/node/commit/d94063a22b)] - **test**: fix test-vm-sigint flakiness (Santiago Gimeno) [#7854](https://github.com/nodejs/node/pull/7854) +* [[`facd7dade1`](https://github.com/nodejs/node/commit/facd7dade1)] - **test**: don't hard code deprecation count (Prince J Wesley) [#7927](https://github.com/nodejs/node/pull/7927) +* [[`4aee970d92`](https://github.com/nodejs/node/commit/4aee970d92)] - **test**: decrease inconsistency in the common.js (Vse Mozhet Byt) [#7758](https://github.com/nodejs/node/pull/7758) +* [[`10f0c94c35`](https://github.com/nodejs/node/commit/10f0c94c35)] - **test**: fix flaky test-tls-wrap-timeout (Rich Trott) [#7857](https://github.com/nodejs/node/pull/7857) +* [[`ccfa6bf4d4`](https://github.com/nodejs/node/commit/ccfa6bf4d4)] - **test**: speed up test-net-reconnect-error (Rich Trott) [#7886](https://github.com/nodejs/node/pull/7886) +* [[`577adc74cd`](https://github.com/nodejs/node/commit/577adc74cd)] - **test**: ensure stream preprocessing order (Vse Mozhet Byt) [#7741](https://github.com/nodejs/node/pull/7741) +* [[`8f51e36898`](https://github.com/nodejs/node/commit/8f51e36898)] - **test**: use common platform helpers everywhere (Santiago Gimeno) [#7845](https://github.com/nodejs/node/pull/7845) +* [[`2f45941807`](https://github.com/nodejs/node/commit/2f45941807)] - **test**: handle IPv6 localhost issues within tests (Rich Trott) [#7766](https://github.com/nodejs/node/pull/7766) +* [[`e56db1477c`](https://github.com/nodejs/node/commit/e56db1477c)] - **test**: fix flaky test-*-connect-address-family (Rich Trott) [#7605](https://github.com/nodejs/node/pull/7605) +* [[`1ab6df6b04`](https://github.com/nodejs/node/commit/1ab6df6b04)] - **test**: make import common as the first line (Sakthipriyan Vairamani) [#7786](https://github.com/nodejs/node/pull/7786) +* [[`0daceffd38`](https://github.com/nodejs/node/commit/0daceffd38)] - **test,assert**: add deepEqual/deepStrictEqual tests for typed arrays (Feross Aboukhadijeh) [#8002](https://github.com/nodejs/node/pull/8002) +* [[`4416ffab8a`](https://github.com/nodejs/node/commit/4416ffab8a)] - **test,util**: fix flaky test-util-sigint-watchdog (Anna Henningsen) [#7933](https://github.com/nodejs/node/pull/7933) +* [[`4535149794`](https://github.com/nodejs/node/commit/4535149794)] - **timers**: remove unused repeat param in timer_wrap (Jan Schär) [#7994](https://github.com/nodejs/node/pull/7994) +* [[`381aef8145`](https://github.com/nodejs/node/commit/381aef8145)] - **timers**: fix cleanup of nested same-timeout timers (Erin Spiceland) [#7827](https://github.com/nodejs/node/pull/7827) +* [[`e611c293bb`](https://github.com/nodejs/node/commit/e611c293bb)] - **tools**: enable rest-spread-spacing (Rich Trott) [#8073](https://github.com/nodejs/node/pull/8073) +* [[`7eb0e7a479`](https://github.com/nodejs/node/commit/7eb0e7a479)] - **tools**: favor === over == in license2rtf.js (Rich Trott) +* [[`583a2515da`](https://github.com/nodejs/node/commit/583a2515da)] - **tools**: update license-builder.sh for v8_inspector (Ali Ijaz Sheikh) [#7796](https://github.com/nodejs/node/pull/7796) +* [[`97934f99bb`](https://github.com/nodejs/node/commit/97934f99bb)] - **tools**: enable linting for chained properties (Rich Trott) [#7999](https://github.com/nodejs/node/pull/7999) +* [[`60ff991c09`](https://github.com/nodejs/node/commit/60ff991c09)] - **tools**: update to ESLint 3.2.2 (Rich Trott) [#7999](https://github.com/nodejs/node/pull/7999) +* [[`d37a17ec5f`](https://github.com/nodejs/node/commit/d37a17ec5f)] - **tools**: add remark-lint configuration in .remarkrc (Сковорода Никита Андреевич) [#7729](https://github.com/nodejs/node/pull/7729) +* [[`cb16e97e9f`](https://github.com/nodejs/node/commit/cb16e97e9f)] - **tools**: add .vscode folder to .gitignore (Josh Gavant) [#7967](https://github.com/nodejs/node/pull/7967) +* [[`fecf611ca8`](https://github.com/nodejs/node/commit/fecf611ca8)] - **tools,test**: show signal code when test crashes (Santiago Gimeno) [#7859](https://github.com/nodejs/node/pull/7859) +* [[`2f20910e24`](https://github.com/nodejs/node/commit/2f20910e24)] - **tty**: set the handle to blocking mode (Jeremiah Senkpiel) [#6816](https://github.com/nodejs/node/pull/6816) +* [[`cfec3ae5fd`](https://github.com/nodejs/node/commit/cfec3ae5fd)] - **(SEMVER-MINOR)** **util**: add inspect.defaultOptions (Roman Reiss) [#8013](https://github.com/nodejs/node/pull/8013) +* [[`295d1ea016`](https://github.com/nodejs/node/commit/295d1ea016)] - **util**: support classes in util.deprecate() (vladimir) [#7690](https://github.com/nodejs/node/pull/7690) +* [[`0a07201ca1`](https://github.com/nodejs/node/commit/0a07201ca1)] - **util**: fix formatting of objects with SIMD enabled (Anna Henningsen) [#7864](https://github.com/nodejs/node/pull/7864) +* [[`f1c50a8c5e`](https://github.com/nodejs/node/commit/f1c50a8c5e)] - **win,msi**: fix inclusion of translations (João Reis) [#7798](https://github.com/nodejs/node/pull/7798) +* [[`dbbcb9dbd9`](https://github.com/nodejs/node/commit/dbbcb9dbd9)] - **win,msi**: Added Italian translation (Matteo Collina) [#4647](https://github.com/nodejs/node/pull/4647) +* [[`909254c901`](https://github.com/nodejs/node/commit/909254c901)] - **zlib**: remove unneeded property (Jan Schär) [#7987](https://github.com/nodejs/node/pull/7987) + ## 2016-07-21, Version 6.3.1 (Current), @evanlucas diff --git a/src/node_version.h b/src/node_version.h index da553fdd2e9330..768c3b6e31bc9c 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -2,10 +2,10 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 6 -#define NODE_MINOR_VERSION 3 -#define NODE_PATCH_VERSION 2 +#define NODE_MINOR_VERSION 4 +#define NODE_PATCH_VERSION 0 -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) From 5cff1476b24e0a4abc0b380b65cb1e6751198ea5 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Mon, 15 Aug 2016 13:14:09 -0400 Subject: [PATCH 144/144] Working on v6.4.1 PR-URL: https://github.com/nodejs/node/pull/8070 --- src/node_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_version.h b/src/node_version.h index 768c3b6e31bc9c..e867454e9d86b6 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -3,9 +3,9 @@ #define NODE_MAJOR_VERSION 6 #define NODE_MINOR_VERSION 4 -#define NODE_PATCH_VERSION 0 +#define NODE_PATCH_VERSION 1 -#define NODE_VERSION_IS_RELEASE 1 +#define NODE_VERSION_IS_RELEASE 0 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)