зеркало из https://github.com/mozilla/gecko-dev.git
Bug 632347 - Expanding a property in the Object Inspector whose type is Generator causes lockup; f=rcampbell r=sdwilsh
This commit is contained in:
Родитель
77510fcb7b
Коммит
64f9c0a5b9
|
@ -3760,6 +3760,11 @@ function JSPropertyProvider(aScope, aInputValue)
|
|||
return null;
|
||||
}
|
||||
|
||||
// Skip Iterators and Generators.
|
||||
if (isIteratorOrGenerator(obj)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let matches = [];
|
||||
for (var prop in obj) {
|
||||
matches.push(prop);
|
||||
|
@ -3775,6 +3780,24 @@ function JSPropertyProvider(aScope, aInputValue)
|
|||
};
|
||||
}
|
||||
|
||||
function isIteratorOrGenerator(aObject)
|
||||
{
|
||||
if (typeof aObject == "object") {
|
||||
if (typeof aObject.__iterator__ == "function" ||
|
||||
aObject.constructor && aObject.constructor.name == "Iterator") {
|
||||
return true;
|
||||
}
|
||||
|
||||
let str = aObject.toString();
|
||||
if (typeof aObject.next == "function" &&
|
||||
str.indexOf("[object Generator") == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// JSTerm
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -4365,6 +4388,11 @@ JSTerm.prototype = {
|
|||
{
|
||||
let isEnumerable = false;
|
||||
|
||||
// Skip Iterators and Generators.
|
||||
if (isIteratorOrGenerator(aResult)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let p in aResult) {
|
||||
isEnumerable = true;
|
||||
break;
|
||||
|
|
|
@ -95,6 +95,12 @@ function presentableValueFor(aObject)
|
|||
display: aObject
|
||||
};
|
||||
|
||||
case "Iterator":
|
||||
return {
|
||||
type: TYPE_OTHER,
|
||||
display: "Iterator"
|
||||
};
|
||||
|
||||
case "Function":
|
||||
presentable = aObject.toString();
|
||||
return {
|
||||
|
@ -105,7 +111,21 @@ function presentableValueFor(aObject)
|
|||
default:
|
||||
presentable = aObject.toString();
|
||||
let m = /^\[object (\S+)\]/.exec(presentable);
|
||||
let display;
|
||||
|
||||
if (typeof aObject == "object" && typeof aObject.next == "function" &&
|
||||
m && m[1] == "Generator") {
|
||||
return {
|
||||
type: TYPE_OTHER,
|
||||
display: m[1]
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof aObject == "object" && typeof aObject.__iterator__ == "function") {
|
||||
return {
|
||||
type: TYPE_OTHER,
|
||||
display: "Iterator"
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
type: TYPE_OBJECT,
|
||||
|
|
|
@ -128,6 +128,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_webconsole_bug_611795.js \
|
||||
browser_webconsole_bug_618311_close_panels.js \
|
||||
browser_webconsole_bug_618311_private_browsing.js \
|
||||
browser_webconsole_bug_632347_iterators_generators.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -195,6 +196,7 @@ _BROWSER_TEST_PAGES = \
|
|||
test-bug-618078-network-exceptions.html \
|
||||
test-bug-630733-response-redirect-headers.sjs \
|
||||
test-bug-621644-jsterm-dollar.html \
|
||||
test-bug-632347-iterators-generators.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Web Console test suite.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mihai Sucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-bug-632347-iterators-generators.html";
|
||||
|
||||
function test() {
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", tabLoaded, true);
|
||||
}
|
||||
|
||||
function tabLoaded() {
|
||||
browser.removeEventListener("load", tabLoaded, true);
|
||||
openConsole();
|
||||
|
||||
let hudId = HUDService.getHudIdByWindow(content);
|
||||
let HUD = HUDService.hudReferences[hudId];
|
||||
let jsterm = HUD.jsterm;
|
||||
|
||||
let win = content.wrappedJSObject;
|
||||
|
||||
// Make sure autocomplete does not walk through iterators and generators.
|
||||
let result = win.gen1.next();
|
||||
let completion = jsterm.propertyProvider(win, "gen1.");
|
||||
is(completion, null, "no matchees for gen1");
|
||||
ok(!jsterm.isResultInspectable(win.gen1),
|
||||
"gen1 is not inspectable");
|
||||
|
||||
is(result+1, win.gen1.next(), "gen1.next() did not execute");
|
||||
|
||||
result = win.gen2.next();
|
||||
|
||||
completion = jsterm.propertyProvider(win, "gen2.");
|
||||
is(completion, null, "no matchees for gen2");
|
||||
ok(!jsterm.isResultInspectable(win.gen2),
|
||||
"gen2 is not inspectable");
|
||||
|
||||
is((result/2+1)*2, win.gen2.next(),
|
||||
"gen2.next() did not execute");
|
||||
|
||||
result = win.iter1.next();
|
||||
is(result[0], "foo", "iter1.next() [0] is correct");
|
||||
is(result[1], "bar", "iter1.next() [1] is correct");
|
||||
|
||||
completion = jsterm.propertyProvider(win, "iter1.");
|
||||
is(completion, null, "no matchees for iter1");
|
||||
ok(!jsterm.isResultInspectable(win.iter1),
|
||||
"iter1 is not inspectable");
|
||||
|
||||
result = win.iter1.next();
|
||||
is(result[0], "baz", "iter1.next() [0] is correct");
|
||||
is(result[1], "baaz", "iter1.next() [1] is correct");
|
||||
|
||||
completion = jsterm.propertyProvider(content, "iter2.");
|
||||
is(completion, null, "no matchees for iter2");
|
||||
ok(!jsterm.isResultInspectable(win.iter2),
|
||||
"iter2 is not inspectable");
|
||||
|
||||
completion = jsterm.propertyProvider(win, "window.");
|
||||
ok(completion, "matches available for window");
|
||||
ok(completion.matches.length, "matches available for window (length)");
|
||||
ok(jsterm.isResultInspectable(win),
|
||||
"window is inspectable");
|
||||
|
||||
let panel = jsterm.openPropertyPanel("Test", win);
|
||||
ok(panel, "opened the Property Panel");
|
||||
let rows = panel.treeView._rows;
|
||||
ok(rows.length, "Property Panel rows are available");
|
||||
|
||||
let find = function(display, children) {
|
||||
return rows.some(function(row) {
|
||||
return row.display == display &&
|
||||
row.children == children;
|
||||
});
|
||||
};
|
||||
|
||||
ok(find("gen1: Generator", false),
|
||||
"gen1 is correctly displayed in the Property Panel");
|
||||
|
||||
ok(find("gen2: Generator", false),
|
||||
"gen2 is correctly displayed in the Property Panel");
|
||||
|
||||
ok(find("iter1: Iterator", false),
|
||||
"iter1 is correctly displayed in the Property Panel");
|
||||
|
||||
ok(find("iter2: Iterator", false),
|
||||
"iter2 is correctly displayed in the Property Panel");
|
||||
|
||||
ok(find("parent: Window", true),
|
||||
"window.parent is correctly displayed in the Property Panel");
|
||||
|
||||
panel.destroy();
|
||||
|
||||
finishTest();
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Web Console test for bug 632347 - iterators and generators</title>
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<script type="application/javascript;version=1.8">
|
||||
(function(){
|
||||
function genFunc() {
|
||||
var a = 5;
|
||||
while (a < 10) {
|
||||
yield a++;
|
||||
}
|
||||
}
|
||||
|
||||
window.gen1 = genFunc();
|
||||
gen1.next();
|
||||
|
||||
var obj = { foo: "bar", baz: "baaz", hay: "stack" };
|
||||
window.iter1 = Iterator(obj);
|
||||
|
||||
function Range(low, high) {
|
||||
this.low = low;
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
function RangeIterator(range) {
|
||||
this.range = range;
|
||||
this.current = this.range.low;
|
||||
}
|
||||
|
||||
RangeIterator.prototype.next = function() {
|
||||
if (this.current > this.range.high) {
|
||||
throw StopIteration;
|
||||
} else {
|
||||
return this.current++;
|
||||
}
|
||||
}
|
||||
|
||||
Range.prototype.__iterator__ = function() {
|
||||
return new RangeIterator(this);
|
||||
}
|
||||
|
||||
window.iter2 = new Range(3, 15);
|
||||
|
||||
window.gen2 = (i * 2 for (i in iter2));
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Web Console test for bug 632347 - iterators and generators.</p>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче