Bug 632347 - Expanding a property in the Object Inspector whose type is Generator causes lockup; f=rcampbell r=sdwilsh

This commit is contained in:
Mihai Sucan 2011-03-25 13:42:09 -03:00
Родитель 77510fcb7b
Коммит 64f9c0a5b9
5 изменённых файлов: 233 добавлений и 1 удалений

Просмотреть файл

@ -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>