Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Commit

Permalink
bug 1092231 - fix traits to work with Symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
zombie committed Nov 4, 2014
1 parent 54417b4 commit 5533dc4
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 41 deletions.
15 changes: 7 additions & 8 deletions lib/sdk/deprecated/traits.js
@@ -1,7 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

module.metadata = {
Expand All @@ -17,9 +16,10 @@ const {
required,
} = require('./traits/core');

const defineProperties = Object.defineProperties,
freeze = Object.freeze,
create = Object.create;
const { getOwnPropertyIdentifiers } = require('../util/object');
const defineProperties = Object.defineProperties;
const freeze = Object.freeze;
const create = Object.create;

/**
* Work around bug 608959 by defining the _create function here instead of
Expand All @@ -31,7 +31,7 @@ const defineProperties = Object.defineProperties,
*/
function _create(proto, trait) {
let properties = {},
keys = Object.getOwnPropertyNames(trait);
keys = getOwnPropertyIdentifiers(trait);
for (let key of keys) {
let descriptor = trait[key];
if (descriptor.required &&
Expand Down Expand Up @@ -72,9 +72,9 @@ function TraitDescriptor(object)

function Public(instance, trait) {
let result = {},
keys = Object.getOwnPropertyNames(trait);
keys = getOwnPropertyIdentifiers(trait);
for (let key of keys) {
if ('_' === key.charAt(0) && '__iterator__' !== key )
if (typeof key === 'string' && '_' === key.charAt(0) && '__iterator__' !== key )
continue;
let property = trait[key],
descriptor = {
Expand Down Expand Up @@ -184,4 +184,3 @@ const Trait = Composition({
});
TraitProto = Trait.prototype;
exports.Trait = Trait;

35 changes: 16 additions & 19 deletions lib/sdk/deprecated/traits/core.js
@@ -1,7 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

module.metadata = {
Expand All @@ -10,11 +9,10 @@ module.metadata = {

// Design inspired by: http://www.traitsjs.org/

// shortcuts
const getOwnPropertyNames = Object.getOwnPropertyNames,
getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor,
hasOwn = Object.prototype.hasOwnProperty,
_create = Object.create;
const { getOwnPropertyIdentifiers } = require('../../util/object');
const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
const hasOwn = Object.prototype.hasOwnProperty;
const _create = Object.create;

function doPropertiesMatch(object1, object2, name) {
// If `object1` has property with the given `name`
Expand Down Expand Up @@ -114,12 +112,12 @@ function Conflict(name) {
*/
function trait(properties) {
let result = {},
keys = getOwnPropertyNames(properties);
for (let key of keys) {
let descriptor = getOwnPropertyDescriptor(properties, key);
result[key] = (required === descriptor.value) ? Required(key) : descriptor;
}
return result;
keys = getOwnPropertyIdentifiers(properties);
for (let key of keys) {
let descriptor = getOwnPropertyDescriptor(properties, key);
result[key] = (required === descriptor.value) ? Required(key) : descriptor;
}
return result;
}
exports.Trait = exports.trait = trait;

Expand All @@ -140,7 +138,7 @@ function compose(trait1, trait2) {
let traits = Array.slice(arguments, 0),
result = {};
for (let trait of traits) {
let keys = getOwnPropertyNames(trait);
let keys = getOwnPropertyIdentifiers(trait);
for (let key of keys) {
let descriptor = trait[key];
// if property already exists and it's not a requirement
Expand Down Expand Up @@ -174,7 +172,7 @@ function exclude(keys, trait) {
let exclusions = Map(keys),
result = {};

keys = getOwnPropertyNames(trait);
keys = getOwnPropertyIdentifiers(trait);

for (let key of keys) {
if (!hasOwn.call(exclusions, key) || trait[key].required)
Expand Down Expand Up @@ -210,7 +208,7 @@ function override() {
let traits = Array.slice(arguments, 0),
result = {};
for (let trait of traits) {
let keys = getOwnPropertyNames(trait);
let keys = getOwnPropertyIdentifiers(trait);
for (let key of keys) {
let descriptor = trait[key];
if (!hasOwn.call(result, key) || result[key].required)
Expand All @@ -236,7 +234,7 @@ exports.override = override;
*/
function rename(map, trait) {
let result = {},
keys = getOwnPropertyNames(trait);
keys = getOwnPropertyIdentifiers(trait);
for (let key of keys) {
// must be renamed & it's not requirement
if (hasOwn.call(map, key) && !trait[key].required) {
Expand Down Expand Up @@ -281,7 +279,7 @@ function rename(map, trait) {
function resolve(resolutions, trait) {
let renames = {},
exclusions = [],
keys = getOwnPropertyNames(resolutions);
keys = getOwnPropertyIdentifiers(resolutions);
for (let key of keys) { // pre-process renamed and excluded properties
if (resolutions[key]) // old name -> new name
renames[key] = resolutions[key];
Expand All @@ -306,7 +304,7 @@ exports.resolve = resolve;
*/
function create(proto, trait) {
let properties = {},
keys = getOwnPropertyNames(trait);
keys = getOwnPropertyIdentifiers(trait);
for (let key of keys) {
let descriptor = trait[key];
if (descriptor.required && !hasOwn.call(proto, key))
Expand All @@ -319,4 +317,3 @@ function create(proto, trait) {
return _create(proto, properties);
}
exports.create = create;

19 changes: 6 additions & 13 deletions lib/sdk/util/iteration.js
Expand Up @@ -7,20 +7,13 @@ module.metadata = {
"stability": "experimental"
};

// This is known as @@iterator in the ES6 spec. Until it is bound to
// some well-known name, find the @@iterator object by expecting it as
// the first property accessed on a for-of iterable.
const iteratorSymbol = (function() {
try {
for (var _ of Proxy.create({get: function(_, name) { throw name; } }))
break;
} catch (name) {
return name;
}
throw new TypeError;
})();
// test if JS has Symbols and uses them for iteration
const JS_USE_SYMBOLS = typeof Symbol === "function" &&
Symbol.iterator in Array.prototype;

exports.iteratorSymbol = iteratorSymbol;
// This is known as @@iterator in the ES6 spec. In builds that have and use
// it for iteration, return that; otherwise return the legacy method name.
exports.iteratorSymbol = JS_USE_SYMBOLS ? Symbol.iterator : "@@iterator";

// An adaptor that, given an object that is iterable with for-of, is
// suitable for being bound to __iterator__ in order to make the object
Expand Down
12 changes: 11 additions & 1 deletion lib/sdk/util/object.js
@@ -1,7 +1,6 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

module.metadata = {
Expand Down Expand Up @@ -90,3 +89,14 @@ function omit(source, ...values) {
return copy;
}
exports.omit = omit;

// get object's own property Symbols and/or Names, including nonEnumerables by default
function getOwnPropertyIdentifiers(object, options = { names: true, symbols: true, nonEnumerables: true }) {
const symbols = !options.symbols ? [] :
Object.getOwnPropertySymbols(object);
const names = !options.names ? [] :
options.nonEnumerables ? Object.getOwnPropertyNames(object) :
Object.keys(object);
return [...names, ...symbols];
}
exports.getOwnPropertyIdentifiers = getOwnPropertyIdentifiers;

0 comments on commit 5533dc4

Please sign in to comment.