Skip to content

Commit

Permalink
Merge pull request #12423 from emberjs/cleanup-meta
Browse files Browse the repository at this point in the history
Cleanup meta
  • Loading branch information
stefanpenner committed Oct 7, 2015
2 parents c0b010e + e46e056 commit d462156
Show file tree
Hide file tree
Showing 12 changed files with 80 additions and 55 deletions.
8 changes: 4 additions & 4 deletions packages/ember-metal/lib/chains.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { warn } from 'ember-metal/debug';
import { get, normalizeTuple } from 'ember-metal/property_get';
import { meta as metaFor } from 'ember-metal/meta';
import { meta as metaFor, peekMeta } from 'ember-metal/meta';
import { watchKey, unwatchKey } from 'ember-metal/watch_key';
import EmptyObject from 'ember-metal/empty_object';

Expand Down Expand Up @@ -147,7 +147,7 @@ function removeChainWatcher(obj, keyName, node) {
return;
}

let m = obj.__ember_meta__;
let m = peekMeta(obj);

if (!m || !m.readableChainWatchers()) {
return;
Expand Down Expand Up @@ -195,7 +195,7 @@ function lazyGet(obj, key) {
return;
}

var meta = obj['__ember_meta__'];
var meta = peekMeta(obj);

// check if object meant only to be a prototype
if (meta && meta.proto === obj) {
Expand Down Expand Up @@ -401,7 +401,7 @@ ChainNode.prototype = {

export function finishChains(obj) {
// We only create meta if we really have to
let m = obj.__ember_meta__;
let m = peekMeta(obj);
if (m) {
m = metaFor(obj);

Expand Down
6 changes: 3 additions & 3 deletions packages/ember-metal/lib/computed.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { assert } from 'ember-metal/debug';
import { set } from 'ember-metal/property_set';
import { inspect } from 'ember-metal/utils';
import { meta as metaFor } from 'ember-metal/meta';
import { meta as metaFor, peekMeta } from 'ember-metal/meta';
import expandProperties from 'ember-metal/expand_properties';
import EmberError from 'ember-metal/error';
import {
Expand Down Expand Up @@ -313,7 +313,7 @@ ComputedPropertyPrototype.didChange = function(obj, keyName) {
}

// don't create objects just to invalidate
let meta = obj.__ember_meta__;
let meta = peekMeta(obj);
if (!meta || meta.source !== obj) {
return;
}
Expand Down Expand Up @@ -620,7 +620,7 @@ export default function computed(func) {
@public
*/
function cacheFor(obj, key) {
var meta = obj.__ember_meta__;
var meta = peekMeta(obj);
var cache = meta && meta.source === obj && meta.readableCache();
var ret = cache && cache[key];

Expand Down
10 changes: 5 additions & 5 deletions packages/ember-metal/lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
apply,
applyStr
} from 'ember-metal/utils';
import { meta as metaFor } from 'ember-metal/meta';
import { meta as metaFor, peekMeta } from 'ember-metal/meta';

import { ONCE, SUSPENDED } from 'ember-metal/meta_listeners';

Expand Down Expand Up @@ -49,7 +49,7 @@ function indexOf(array, target, method) {
}

export function accumulateListeners(obj, eventName, otherActions) {
var meta = obj['__ember_meta__'];
var meta = peekMeta(obj);
if (!meta) { return; }
var actions = meta.matchingListeners(eventName);
var newActions = [];
Expand Down Expand Up @@ -201,7 +201,7 @@ export function watchedEvents(obj) {
*/
export function sendEvent(obj, eventName, params, actions) {
if (!actions) {
var meta = obj['__ember_meta__'];
var meta = peekMeta(obj);
actions = meta && meta.matchingListeners(eventName);
}

Expand Down Expand Up @@ -241,7 +241,7 @@ export function sendEvent(obj, eventName, params, actions) {
@param {String} eventName
*/
export function hasListeners(obj, eventName) {
var meta = obj['__ember_meta__'];
var meta = peekMeta(obj);
if (!meta) { return false; }
return meta.matchingListeners(eventName).length > 0;
}
Expand All @@ -255,7 +255,7 @@ export function hasListeners(obj, eventName) {
*/
export function listenersFor(obj, eventName) {
var ret = [];
var meta = obj['__ember_meta__'];
var meta = peekMeta(obj);
var actions = meta && meta.matchingListeners(eventName);

if (!actions) { return ret; }
Expand Down
3 changes: 1 addition & 2 deletions packages/ember-metal/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
wrap
} from 'ember-metal/utils';
import {
EMPTY_META,
META_DESC,
meta
} from 'ember-metal/meta';
Expand Down Expand Up @@ -210,9 +209,9 @@ Ember.platform = {
Ember.Error = EmberError;
Ember.guidFor = guidFor;
Ember.META_DESC = META_DESC;
Ember.EMPTY_META = EMPTY_META;
Ember.meta = meta;
Ember.inspect = inspect;

Ember.tryCatchFinally = deprecatedTryCatchFinally;
Ember.makeArray = makeArray;
Ember.canInvoke = canInvoke;
Expand Down
63 changes: 37 additions & 26 deletions packages/ember-metal/lib/meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ let members = {
};

let memberNames = Object.keys(members);
const META_FIELD = '__ember_meta__';

function Meta(obj, parentMeta) {
this._cache = undefined;
Expand Down Expand Up @@ -292,12 +293,24 @@ export var META_DESC = {
};

var EMBER_META_PROPERTY = {
name: '__ember_meta__',
name: META_FIELD,
descriptor: META_DESC
};

// Placeholder for non-writable metas.
export var EMPTY_META = new Meta(null);
// choose the one appropriate for given platform
let setMeta = function(obj, meta) {
// if `null` already, just set it to the new value
// otherwise define property first
if (obj[META_FIELD] !== null) {
if (obj.__defineNonEnumerable) {
obj.__defineNonEnumerable(EMBER_META_PROPERTY);
} else {
Object.defineProperty(obj, META_FIELD, META_DESC);
}
}

obj[META_FIELD] = meta;
};

/**
Retrieves the meta hash for an object. If `writable` is true ensures the
Expand All @@ -317,32 +330,30 @@ export var EMPTY_META = new Meta(null);
the meta hash, allowing the method to avoid making an unnecessary copy.
@return {Object} the meta hash for an object
*/
export function meta(obj, writable) {
var ret = obj.__ember_meta__;
if (writable === false) {
return ret || EMPTY_META;
export function meta(obj) {
let maybeMeta = peekMeta(obj);
let parent;

// remove this code, in-favor of explicit parent
if (maybeMeta) {
if (maybeMeta.source === obj) {
return maybeMeta;
}
parent = maybeMeta;
}

if (ret && ret.source === obj) {
return ret;
}
let newMeta = new Meta(obj, parent);
setMeta(obj, newMeta);
return newMeta;
}

if (!ret) {
ret = new Meta(obj);
} else {
ret = new Meta(obj, ret);
}
export function peekMeta(obj) {
return obj[META_FIELD];
}

// if `null` already, just set it to the new value
// otherwise define property first
if (obj.__ember_meta__ !== null) {
if (obj.__defineNonEnumerable) {
obj.__defineNonEnumerable(EMBER_META_PROPERTY);
} else {
Object.defineProperty(obj, '__ember_meta__', META_DESC);
}
export function deleteMeta(obj) {
if (typeof obj[META_FIELD] !== 'object') {
return;
}
obj.__ember_meta__ = ret;

return ret;
obj[META_FIELD] = null;
}
6 changes: 3 additions & 3 deletions packages/ember-metal/lib/mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
wrap,
makeArray
} from 'ember-metal/utils';
import { meta as metaFor } from 'ember-metal/meta';
import { meta as metaFor, peekMeta } from 'ember-metal/meta';
import expandProperties from 'ember-metal/expand_properties';
import {
Descriptor,
Expand Down Expand Up @@ -604,7 +604,7 @@ function _detect(curMixin, targetMixin, seen) {
MixinPrototype.detect = function(obj) {
if (!obj) { return false; }
if (obj instanceof Mixin) { return _detect(obj, this, {}); }
var m = obj.__ember_meta__;
var m = peekMeta(obj);
if (!m) { return false; }
return !!m.peekMixins(guidFor(this));
};
Expand Down Expand Up @@ -645,7 +645,7 @@ MixinPrototype.keys = function() {
// returns the mixins currently applied to the specified object
// TODO: Make Ember.mixin
Mixin.mixins = function(obj) {
var m = obj['__ember_meta__'];
var m = peekMeta(obj);
var ret = [];
if (!m) { return ret; }

Expand Down
9 changes: 6 additions & 3 deletions packages/ember-metal/lib/property_events.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import {
guidFor
guidFor,
} from 'ember-metal/utils';
import {
peekMeta
} from 'ember-metal/meta';
import {
sendEvent,
accumulateListeners
Expand Down Expand Up @@ -35,7 +38,7 @@ var deferred = 0;
@private
*/
function propertyWillChange(obj, keyName) {
var m = obj['__ember_meta__'];
var m = peekMeta(obj);
var watching = (m && m.peekWatching(keyName) > 0) || keyName === 'length';
var proto = m && m.proto;
var possibleDesc = obj[keyName];
Expand Down Expand Up @@ -75,7 +78,7 @@ function propertyWillChange(obj, keyName) {
@private
*/
function propertyDidChange(obj, keyName) {
var m = obj['__ember_meta__'];
var m = peekMeta(obj);
var watching = (m && m.peekWatching(keyName) > 0) || keyName === 'length';
var proto = m && m.proto;
var possibleDesc = obj[keyName];
Expand Down
5 changes: 4 additions & 1 deletion packages/ember-metal/lib/property_get.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import {
isPath,
hasThis as pathHasThis
} from 'ember-metal/path_cache';
import {
peekMeta
} from 'ember-metal/meta';

var FIRST_KEY = /^([^\.]+)/;

Expand Down Expand Up @@ -57,7 +60,7 @@ export function get(obj, keyName) {
return obj;
}

var meta = obj['__ember_meta__'];
var meta = peekMeta(obj);
var possibleDesc = obj[keyName];
var desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined;
var ret;
Expand Down
5 changes: 4 additions & 1 deletion packages/ember-metal/lib/property_set.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import {
isPath,
hasThis as pathHasThis
} from 'ember-metal/path_cache';
import {
peekMeta
} from 'ember-metal/meta';

/**
Sets the value of a property on an object, respecting computed properties
Expand All @@ -38,7 +41,7 @@ export function set(obj, keyName, value, tolerant) {

var meta, possibleDesc, desc;
if (obj) {
meta = obj['__ember_meta__'];
meta = peekMeta(obj);
possibleDesc = obj[keyName];
desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined;
}
Expand Down
10 changes: 7 additions & 3 deletions packages/ember-metal/lib/watching.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import {
import {
isPath
} from 'ember-metal/path_cache';
import {
peekMeta,
deleteMeta
} from 'ember-metal/meta';

/**
Starts watching a property on an object. Whenever the property changes,
Expand Down Expand Up @@ -45,7 +49,7 @@ function watch(obj, _keyPath, m) {
export { watch };

export function isWatching(obj, key) {
var meta = obj['__ember_meta__'];
var meta = peekMeta(obj);
return (meta && meta.peekWatching(key)) > 0;
}

Expand Down Expand Up @@ -75,11 +79,11 @@ var NODE_STACK = [];
@private
*/
export function destroy(obj) {
var meta = obj['__ember_meta__'];
var meta = peekMeta(obj);
var node, nodes, key, nodeObject;

if (meta) {
obj['__ember_meta__'] = null;
deleteMeta(obj);
// remove chainWatchers to remove circular references that would prevent GC
node = meta.readableChains();
if (node) {
Expand Down
4 changes: 3 additions & 1 deletion packages/ember-metal/tests/chains_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { finishChains } from 'ember-metal/chains';
import { defineProperty } from 'ember-metal/properties';
import computed from 'ember-metal/computed';
import { propertyDidChange } from 'ember-metal/property_events';
import { peekMeta } from 'ember-metal/meta';

QUnit.module('Chains');

QUnit.test('finishChains should properly copy chains from prototypes to instances', function() {
Expand All @@ -14,7 +16,7 @@ QUnit.test('finishChains should properly copy chains from prototypes to instance

var childObj = Object.create(obj);
finishChains(childObj);
ok(obj['__ember_meta__'].readableChains() !== childObj['__ember_meta__'].readableChains(), 'The chains object is copied');
ok(peekMeta(obj) !== peekMeta(childObj).readableChains(), 'The chains object is copied');
});


Expand Down
6 changes: 3 additions & 3 deletions packages/ember-runtime/tests/system/object/destroy_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from 'ember-metal/property_events';
import { testBoth } from 'ember-metal/tests/props_helper';
import EmberObject from 'ember-runtime/system/object';

import { peekMeta } from 'ember-metal/meta';
QUnit.module('ember-runtime/system/object/destroy_test');

testBoth('should schedule objects to be destroyed at the end of the run loop', function(get, set) {
Expand All @@ -18,13 +18,13 @@ testBoth('should schedule objects to be destroyed at the end of the run loop', f

run(function() {
obj.destroy();
meta = obj['__ember_meta__'];
meta = peekMeta(obj);
ok(meta, 'meta is not destroyed immediately');
ok(get(obj, 'isDestroying'), 'object is marked as destroying immediately');
ok(!get(obj, 'isDestroyed'), 'object is not destroyed immediately');
});

meta = obj['__ember_meta__'];
meta = peekMeta(obj);
ok(!meta, 'meta is destroyed after run loop finishes');
ok(get(obj, 'isDestroyed'), 'object is destroyed after run loop finishes');
});
Expand Down

0 comments on commit d462156

Please sign in to comment.