Bug 807001 - Change Map and Set size() methods to accessor properties. r=Waldo.

--HG--
extra : rebase_source : bf2809aa1d943caa6349d7b44621cd1b0bb85742
This commit is contained in:
Jason Orendorff 2012-11-02 10:12:36 -05:00
parent 4171f7df7d
commit f0ddf7bbd5
50 changed files with 121 additions and 91 deletions

View File

@ -61,7 +61,7 @@ VariablesView.prototype = {
*/
empty: function VV_empty(aTimeout = LAZY_EMPTY_DELAY) {
// If there are no items in this container, emptying is useless.
if (!this._store.size()) {
if (!this._store.size) {
return;
}
// Check if this empty operation may be executed lazily.
@ -110,7 +110,7 @@ VariablesView.prototype = {
this._parent.removeChild(prevList);
this._parent.appendChild(currList);
if (!this._store.size()) {
if (!this._store.size) {
this._appendEmptyNotice();
}
}.bind(this), aTimeout);

View File

@ -812,7 +812,7 @@ create({ constructor: GlobalSearchView, proto: MenuContainer.prototype }, {
*/
_fetchSources: function DVGS__fetchSources(aFetchCallback, aFetchedCallback, aLocations) {
// If all the sources were already fetched, then don't do anything.
if (this._cache.size() == aLocations.length) {
if (this._cache.size == aLocations.length) {
aFetchedCallback();
return;
}
@ -840,7 +840,7 @@ create({ constructor: GlobalSearchView, proto: MenuContainer.prototype }, {
this._cache.set(aLocation, aContents);
// Check if all sources were fetched and stored in the cache.
if (this._cache.size() == this._sourcesCount) {
if (this._cache.size == this._sourcesCount) {
this._onFetchSourcesFinished();
}
},
@ -1151,7 +1151,7 @@ GlobalResults.prototype = {
/**
* Gets the number of source results in this store.
*/
get itemCount() this._store.size(),
get itemCount() this._store.size,
_store: null
};

View File

@ -134,7 +134,7 @@ function testLocationChange()
window.addEventListener("Debugger:GlobalSearch:CacheCleared", function _onCacheCleared(aEvent) {
window.removeEventListener(aEvent.type, _onCacheCleared);
is(gSearchView._cache.size(), 0,
is(gSearchView._cache.size, 0,
"The scripts sources cache for global searching should be cleared after a page navigation.")
cacheCleared = true;

View File

@ -947,8 +947,12 @@ Class MapObject::class_ = {
mark
};
JSPropertySpec MapObject::properties[] = {
JS_PSG("size", size, 0),
JS_PS_END
};
JSFunctionSpec MapObject::methods[] = {
JS_FN("size", size, 0, 0),
JS_FN("get", get, 1, 0),
JS_FN("has", has, 1, 0),
JS_FN("set", set, 2, 0),
@ -960,7 +964,7 @@ JSFunctionSpec MapObject::methods[] = {
static JSObject *
InitClass(JSContext *cx, Handle<GlobalObject*> global, Class *clasp, JSProtoKey key, Native construct,
JSFunctionSpec *methods)
JSPropertySpec *properties, JSFunctionSpec *methods)
{
Rooted<JSObject*> proto(cx, global->createBlankPrototype(cx, clasp));
if (!proto)
@ -970,7 +974,7 @@ InitClass(JSContext *cx, Handle<GlobalObject*> global, Class *clasp, JSProtoKey
Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(key, cx), 1));
if (!ctor ||
!LinkConstructorAndPrototype(cx, ctor, proto) ||
!DefinePropertiesAndBrand(cx, proto, NULL, methods) ||
!DefinePropertiesAndBrand(cx, proto, properties, methods) ||
!DefineConstructorAndPrototype(cx, global, key, ctor, proto))
{
return NULL;
@ -982,7 +986,7 @@ JSObject *
MapObject::initClass(JSContext *cx, JSObject *obj)
{
Rooted<GlobalObject*> global(cx, &obj->asGlobal());
return InitClass(cx, global, &class_, JSProto_Map, construct, methods);
return InitClass(cx, global, &class_, JSProto_Map, construct, properties, methods);
}
template <class Range>
@ -1410,8 +1414,12 @@ Class SetObject::class_ = {
mark
};
JSPropertySpec SetObject::properties[] = {
JS_PSG("size", size, 0),
JS_PS_END
};
JSFunctionSpec SetObject::methods[] = {
JS_FN("size", size, 0, 0),
JS_FN("has", has, 1, 0),
JS_FN("add", add, 1, 0),
JS_FN("delete", delete_, 1, 0),
@ -1424,7 +1432,7 @@ JSObject *
SetObject::initClass(JSContext *cx, JSObject *obj)
{
Rooted<GlobalObject*> global(cx, &obj->asGlobal());
return InitClass(cx, global, &class_, JSProto_Set, construct, methods);
return InitClass(cx, global, &class_, JSProto_Set, construct, properties, methods);
}
void

View File

@ -84,6 +84,7 @@ class MapObject : public JSObject {
static JSObject *initClass(JSContext *cx, JSObject *obj);
static Class class_;
private:
static JSPropertySpec properties[];
static JSFunctionSpec methods[];
ValueMap *getData() { return static_cast<ValueMap *>(getPrivate()); }
static ValueMap & extract(CallReceiver call);
@ -114,6 +115,7 @@ class SetObject : public JSObject {
static JSObject *initClass(JSContext *cx, JSObject *obj);
static Class class_;
private:
static JSPropertySpec properties[];
static JSFunctionSpec methods[];
ValueSet *getData() { return static_cast<ValueSet *>(getPrivate()); }
static ValueSet & extract(CallReceiver call);

View File

@ -3,6 +3,6 @@
var m = Map();
for (var i = 0; i < 2; i++) {
m.clear();
assertEq(m.size(), 0);
assertEq(m.size, 0);
assertEq(m.has(undefined), false);
}

View File

@ -1,9 +1,9 @@
// Clearing a Map removes its entries; the Map remains usable afterwards.
var m = Map([["a", "b"], ["b", "c"]]);
assertEq(m.size(), 2);
assertEq(m.size, 2);
m.clear();
assertEq(m.size(), 0);
assertEq(m.size, 0);
assertEq(m.has("a"), false);
assertEq(m.get("a"), undefined);
assertEq(m.delete("a"), false);
@ -12,6 +12,6 @@ for (var pair of m)
throw "FAIL"; // shouldn't be any pairs
m.set("c", "d");
assertEq(m.size(), 1);
assertEq(m.size, 1);
assertEq(m.has("a"), false);
assertEq(m.has("b"), false);

View File

@ -3,8 +3,8 @@
var m = Map();
for (var i = 0; i < 100; i++)
m.set(i, i);
assertEq(m.size(), i);
assertEq(m.size, i);
m.clear();
assertEq(m.size(), 0);
assertEq(m.size, 0);
m.set("a", 1);
assertEq(m.get("a"), 1);

View File

@ -5,6 +5,6 @@ for (var [k, v] of m)
if (k !== "c")
m.delete(k);
m.clear();
assertEq(m.size(), 0);
assertEq(m.size, 0);
assertEq(m.has("c"), false);
assertEq(m.has("d"), false);

View File

@ -6,9 +6,9 @@ var m1 = Map(data), m2 = Map(data);
delete Map.prototype.delete;
delete Map.prototype.iterator;
m1.clear();
assertEq(m1.size(), 0);
assertEq(m1.size, 0);
Map.prototype.delete = function () { throw "FAIL"; };
Map.prototype.iterator = function () { throw "FAIL"; };
m2.clear();
assertEq(m2.size(), 0);
assertEq(m2.size, 0);

View File

@ -1,6 +1,6 @@
// The Map constructor creates an empty Map by default.
assertEq(Map().size(), 0);
assertEq((new Map).size(), 0);
assertEq(Map(undefined).size(), 0);
assertEq(new Map(undefined).size(), 0);
assertEq(Map().size, 0);
assertEq((new Map).size, 0);
assertEq(Map(undefined).size, 0);
assertEq(new Map(undefined).size, 0);

View File

@ -2,7 +2,7 @@
var arr = [["a"], ["b"], ["c"]];
var m = Map(arr);
assertEq(m.size(), 3);
assertEq(m.size, 3);
for (var [k, _] of arr) {
assertEq(m.has(k), true);
assertEq(m.get(k), undefined);

View File

@ -5,4 +5,4 @@ var m = Map(arg);
assertEq(m.get("zero"), 0);
assertEq(m.get("one"), 1);
assertEq(m.get("two"), 2);
assertEq(m.size(), 3);
assertEq(m.size, 3);

View File

@ -12,7 +12,7 @@ function data(n) {
var m = Map(data(50));
assertEq(done, true); // the constructor consumes the argument
assertEq(m.size(), 50);
assertEq(m.size, 50);
assertEq(m.get(""), 0);
assertEq(m.get("....."), 5);
assertEq(m.get(Array(49+1).join(".")), 49);

View File

@ -2,7 +2,7 @@
var arr = [1, 2, "green", "red"];
var m = Map([v, v] for (v of arr));
assertEq(m.size(), 4);
assertEq(m.size, 4);
for (var i = 0; i < 4; i++)
assertEq(m.get(arr[i]), arr[i]);

View File

@ -1,8 +1,8 @@
// The argument to Map may be a generator-iterator that produces no values.
assertEq(Map(x for (x of [])).size(), 0);
assertEq(Map(x for (x of [])).size, 0);
function none() {
if (0) yield 0;
}
assertEq(Map(none()).size(), 0);
assertEq(Map(none()).size, 0);

View File

@ -2,13 +2,13 @@
var m = Map();
m.delete(3);
assertEq(m.size(), 0);
assertEq(m.size, 0);
m.set({}, 'ok');
m.set(Math, 'ok');
assertEq(m.size(), 2);
assertEq(m.size, 2);
m.delete({});
assertEq(m.size(), 2);
assertEq(m.size, 2);
m.delete(Math);
assertEq(m.size(), 1);
assertEq(m.size, 1);
m.delete(Math);
assertEq(m.size(), 1);
assertEq(m.size, 1);

View File

@ -12,4 +12,4 @@ for (let [k, v] of map) {
force(v);
}
assertEq(log, '5;4;3;2;1;0;');
assertEq(map.size(), 6);
assertEq(map.size, 6);

View File

@ -5,7 +5,7 @@ load(libdir + "eqArrayHelper.js");
var map = Map();
for (var i = 7; i !== 1; i = i * 7 % 1117)
map.set("" + i, i);
assertEq(map.size(), 557);
assertEq(map.size, 557);
i = 7;
for (var pair of map) {

View File

@ -9,4 +9,4 @@ assertEq(pair[0], 'b');
assertEq(pair[1], 2);
assertEq(map.get('a'), 1);
assertEq(map.has('b'), false);
assertEq(map.size(), 1);
assertEq(map.size, 1);

View File

@ -18,5 +18,5 @@ for (var [k, v] of map) {
}
}
assertEq(log, 'ABCDEFGHIJKLMNOPQRST');
assertEq(map.size(), 1); // Only the last entry remains.
assertEq(map.size, 1); // Only the last entry remains.
assertEq(map.get('T'), 19);

View File

@ -11,7 +11,7 @@ var iter = map.iterator();
assertEq(iter.next()[0], 0);
for (var i = 0; i < 30; i++)
map.delete(i);
assertEq(map.size(), 2);
assertEq(map.size, 2);
for (var i = 32; i < 100; i++)
map.set(i, i); // eventually triggers compaction

View File

@ -2,13 +2,13 @@
var m = Map();
m.set('a', 0);
assertEq(m.size(), 1);
assertEq(m.size, 1);
m.set('a', 0);
assertEq(m.size(), 1);
assertEq(m.size, 1);
m.set('a', undefined);
assertEq(m.size(), 1);
assertEq(m.size, 1);
m.set('b', 2);
assertEq(m.size(), 2);
assertEq(m.size, 2);
m.set('a', 1);
assertEq(m.size(), 2);
assertEq(m.size, 2);

View File

@ -2,5 +2,5 @@
var m1 = Map(), m2 = Map();
m1.set("x", 3);
assertEq(m1.size(), 1);
assertEq(m2.size(), 0);
assertEq(m1.size, 1);
assertEq(m2.size, 0);

View File

@ -27,9 +27,15 @@ function checkMethod(name, arity) {
assertEq(desc.value.length, arity);
}
checkMethod("size", 0);
checkMethod("get", 1);
checkMethod("has", 1);
checkMethod("set", 2);
checkMethod("delete", 1);
var desc = Object.getOwnPropertyDescriptor(Map.prototype, "size");
assertEq(desc.enumerable, false);
assertEq(desc.configurable, true);
assertEq(typeof desc.get, 'function');
assertEq(desc.get.length, 0);
assertEq(desc.set, undefined);
checkMethod("clear", 0);

View File

@ -8,13 +8,15 @@ function testcase(obj, fn) {
assertThrowsInstanceOf(function () { fn.apply(obj, args); }, TypeError);
}
var Map_size_getter = Object.getOwnPropertyDescriptor(Map.prototype, "size").get;
function test(obj) {
testcase(obj, Map.prototype.size);
testcase(obj, Map.prototype.get, "x");
testcase(obj, Map.prototype.has, "x");
testcase(obj, Map.prototype.set, "x", 1);
testcase(obj, Map.prototype.delete, "x");
testcase(obj, Map.prototype.clear);
testcase(obj, Map_size_getter);
}
test(Map.prototype);

View File

@ -1,11 +1,11 @@
// set.add(v) increments set.size() iff the set did not already contain v.
// set.add(v) increments set.size iff the set did not already contain v.
var s = Set();
for (var i = 0; i < 10; i++) {
assertEq(s.size(), i);
assertEq(s.size, i);
s.add(i);
}
for (var i = 0; i < 10; i++) {
assertEq(s.size(), 10);
assertEq(s.size, 10);
s.add(i);
}

View File

@ -3,6 +3,6 @@
var s = Set();
for (var i = 0; i < 2; i++) {
s.clear();
assertEq(s.size(), 0);
assertEq(s.size, 0);
assertEq(s.has(undefined), false);
}

View File

@ -1,9 +1,9 @@
// Clearing a Set removes its elements; the Set remains usable afterwards.
var s = Set(["x", "y", "z", "z", "y"]);
assertEq(s.size(), 3);
assertEq(s.size, 3);
s.clear();
assertEq(s.size(), 0);
assertEq(s.size, 0);
assertEq(s.has("x"), false);
assertEq(s.delete("x"), false);
assertEq(s.has("z"), false);
@ -11,6 +11,6 @@ for (var v of s)
throw "FAIL"; // shouldn't be any elements
s.add("y");
assertEq(s.size(), 1);
assertEq(s.size, 1);
assertEq(s.has("x"), false);
assertEq(s.has("z"), false);

View File

@ -3,8 +3,8 @@
var s = Set();
for (var i = 0; i < 100; i++)
s.add(i);
assertEq(s.size(), i);
assertEq(s.size, i);
s.clear();
assertEq(s.size(), 0);
assertEq(s.size, 0);
s.add(12);
assertEq(s.has(12), true);

View File

@ -5,6 +5,6 @@ for (var v of s)
if (v !== "c")
s.delete(v);
s.clear();
assertEq(s.size(), 0);
assertEq(s.size, 0);
assertEq(s.has("c"), false);
assertEq(s.has("d"), false);

View File

@ -6,9 +6,9 @@ var s1 = Set(data), s2 = Set(data);
delete Set.prototype.delete;
delete Set.prototype.iterator;
s1.clear();
assertEq(s1.size(), 0);
assertEq(s1.size, 0);
Set.prototype.delete = function () { throw "FAIL"; };
Set.prototype.iterator = function () { throw "FAIL"; };
s2.clear();
assertEq(s2.size(), 0);
assertEq(s2.size, 0);

View File

@ -1,6 +1,6 @@
// The Set constructor creates an empty Set by default.
assertEq(Set().size(), 0);
assertEq((new Set).size(), 0);
assertEq(Set(undefined).size(), 0);
assertEq(new Set(undefined).size(), 0);
assertEq(Set().size, 0);
assertEq((new Set).size, 0);
assertEq(Set(undefined).size, 0);
assertEq(new Set(undefined).size, 0);

View File

@ -1,17 +1,17 @@
// The Set constructor can take an argument that is an array.
var s = Set([]);
assertEq(s.size(), 0);
assertEq(s.size, 0);
assertEq(s.has(undefined), false);
s = Set(["one", "two", "three"]);
assertEq(s.size(), 3);
assertEq(s.size, 3);
assertEq(s.has("one"), true);
assertEq(s.has("eleventeen"), false);
var a = [{}, {}, {}];
s = Set(a);
assertEq(s.size(), 3);
assertEq(s.size, 3);
for (let obj of a)
assertEq(s.has(obj), true);
assertEq(s.has({}), false);

View File

@ -1,11 +1,11 @@
// The argument to Set may contain a value multiple times. Duplicates are discarded.
assertEq(Set(["testing", "testing", 123]).size(), 2);
assertEq(Set(["testing", "testing", 123]).size, 2);
var values = [undefined, null, false, NaN, 0, -0, 6.022e23, -Infinity, "", "xyzzy", {}, Math.sin];
for (let v of values) {
var a = [v, {}, {}, {}, v, {}, v, v];
var s = Set(a);
assertEq(s.size(), 5);
assertEq(s.size, 5);
assertEq(s.has(v), true);
}

View File

@ -6,7 +6,7 @@ function hexData(n) {
}
var s = Set(hexData(256));
assertEq(s.size(), 256);
assertEq(s.size, 256);
assertEq(s.has("0"), true);
assertEq(s.has(0), false);
assertEq(s.has("ff"), true);

View File

@ -1,7 +1,7 @@
// The argument to Set can be a generator-expression.
var s = Set(k * k for (k of [1, 2, 3, 4]));
assertEq(s.size(), 4);
assertEq(s.size, 4);
assertEq(s.has(1), true);
assertEq(s.has(4), true);
assertEq(s.has(9), true);

View File

@ -1,15 +1,15 @@
// set.delete(v) decrements set.size() iff the set contained v.
// set.delete(v) decrements set.size iff the set contained v.
var s = Set();
for (var i = 0; i < 10; i++)
s.add(i);
for (var i = 10; i > 0; i--) {
assertEq(s.size(), i);
assertEq(s.size, i);
assertEq(s.delete(i), false);
assertEq(s.size(), i);
assertEq(s.size, i);
assertEq(s.delete(i - 1), true);
assertEq(s.size(), i - 1);
assertEq(s.size, i - 1);
assertEq(s.delete(i - 1), false);
assertEq(s.size(), i - 1);
assertEq(s.size, i - 1);
}

View File

@ -2,7 +2,7 @@
var arr = [{}, {}, {}, [], /xyz/, new Date];
var set = Set(arr);
assertEq(set.size(), arr.length);
assertEq(set.size, arr.length);
var i = 0;
for (var x of set)

View File

@ -8,4 +8,4 @@ for (let x of set) {
set.add(x - 1);
}
assertEq(log, '5;4;3;2;1;0;');
assertEq(set.size(), 6);
assertEq(set.size, 6);

View File

@ -4,7 +4,7 @@ var set = Set();
var i;
for (i = 7; i !== 1; i = i * 7 % 1117)
set.add(i);
assertEq(set.size(), 557);
assertEq(set.size, 557);
i = 7;
for (var v of set) {

View File

@ -18,5 +18,5 @@ for (var x of set) {
}
}
assertEq(log, str);
assertEq(set.size(), 1); // Elements 0 to 24 are removed, leaving only 25 (Z).
assertEq(set.size, 1); // Elements 0 to 24 are removed, leaving only 25 (Z).
assertEq(set.has('Z'), true);

View File

@ -11,7 +11,7 @@ var iter = set.iterator();
assertEq(iter.next(), 0);
for (var i = 0; i < 30; i++)
set.delete(i);
assertEq(set.size(), 2);
assertEq(set.size, 2);
for (var i = 32; i < 100; i++)
set.add(i); // eventually triggers compaction

View File

@ -3,5 +3,5 @@
var s1 = Set(), s2 = Set();
for (var i = 0; i < 30; i++)
s1.add(i);
assertEq(s1.size(), 30);
assertEq(s2.size(), 0);
assertEq(s1.size, 30);
assertEq(s2.size, 0);

View File

@ -30,4 +30,11 @@ function checkMethod(name, arity) {
checkMethod("has", 1);
checkMethod("add", 1);
checkMethod("delete", 1);
var desc = Object.getOwnPropertyDescriptor(Set.prototype, "size");
assertEq(desc.enumerable, false);
assertEq(desc.configurable, true);
assertEq(typeof desc.get, 'function');
assertEq(desc.get.length, 0);
assertEq(desc.set, undefined);
checkMethod("clear", 0);

View File

@ -8,11 +8,14 @@ function testcase(obj, fn) {
assertThrowsInstanceOf(function () { fn.apply(obj, args); }, TypeError);
}
var Set_size_getter = Object.getOwnPropertyDescriptor(Set.prototype, "size").get;
function test(obj) {
testcase(obj, Set.prototype.has, 12);
testcase(obj, Set.prototype.add, 12);
testcase(obj, Set.prototype.delete, 12);
testcase(obj, Set.prototype.clear);
testcase(obj, Set_size_getter);
}
test(Set.prototype);

View File

@ -1,5 +1,7 @@
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
assertThrowsInstanceOf(function () { Map.prototype.size.apply(g, []); }, g.TypeError);
assertThrowsInstanceOf(function () { Set.prototype.size.apply(g, []); }, g.TypeError);
for (var cls of [Map, Set]) {
var getter = Object.getOwnPropertyDescriptor(cls.prototype, "size").get;
assertThrowsInstanceOf(function () { getter.apply(g, []); }, g.TypeError);
}

View File

@ -158,7 +158,7 @@ add_test(function test_invalid_request_method() {
allowed.add(method);
}
do_check_eq(allowed.size(), 3);
do_check_eq(allowed.size, 3);
for (let method of ["GET", "PUT", "DELETE"]) {
do_check_true(allowed.has(method));
}

View File

@ -131,7 +131,7 @@ var inMemoryPrefsProto = {
if (this._prefCache[aGroup].has(aName)) {
this._prefCache[aGroup].delete(aName);
if (this._prefCache[aGroup].size() == 0) {
if (this._prefCache[aGroup].size == 0) {
// remove empty group
delete this._prefCache[aGroup];
}

View File

@ -78,9 +78,9 @@ nsPluginInstallerWizard.prototype.pluginInfoReceived = function (aPluginRequestI
progressMeter.setAttribute("mode", "determined");
progressMeter.setAttribute("value",
((this.WSPluginCounter / this.mPluginRequests.size()) * 100) + "%");
((this.WSPluginCounter / this.mPluginRequests.size) * 100) + "%");
if (this.WSPluginCounter == this.mPluginRequests.size()) {
if (this.WSPluginCounter == this.mPluginRequests.size) {
// check if no plugins were found
if (this.mPluginInfoArrayLength == 0) {
this.advancePage("lastpage");