Skip to content

Commit

Permalink
[BUGFIX release] Fix descriptorFor to support fallback
Browse files Browse the repository at this point in the history
Ensure all fallback cases are deprecated.

Fixes #16427 and add test for `notifyPropertyChange` not working for plain obj.
  • Loading branch information
bekzod authored and krisselden committed May 18, 2018
1 parent e52f85e commit 26ea077
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 47 deletions.
1 change: 1 addition & 0 deletions packages/ember-meta/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export {
meta,
MetaCounters,
peekMeta,
PROXY_CONTENT,
setMeta,
UNDEFINED,
} from './lib/meta';
41 changes: 35 additions & 6 deletions packages/ember-meta/lib/meta.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { assert } from '@ember/debug';
import { assert, deprecate } from '@ember/debug';
import { DEBUG } from '@glimmer/env';
import { Tag } from '@glimmer/reference';
import { ENV } from 'ember-environment';
import { lookupDescriptor, symbol, toString } from 'ember-utils';
import { HAS_NATIVE_PROXY, lookupDescriptor, symbol, toString } from 'ember-utils';

export const PROXY_CONTENT = symbol('PROXY_CONTENT');

export interface MetaCounters {
peekCalls: number;
Expand Down Expand Up @@ -787,10 +789,33 @@ export function descriptorFor(obj: object, keyName: string, _meta?: Meta) {
);

let meta = _meta === undefined ? peekMeta(obj) : _meta;

let descriptor;
if (meta !== undefined) {
return meta.peekDescriptors(keyName);
descriptor = meta.peekDescriptors(keyName);
}
if (descriptor === undefined) {
let possibleDesc;
if (DEBUG && HAS_NATIVE_PROXY && obj[PROXY_CONTENT] !== undefined) {
possibleDesc = obj[PROXY_CONTENT][keyName];
} else {
possibleDesc = obj[keyName];
}
if (isDescriptor(possibleDesc)) {
deprecate(
`[DEPRECATED] computed property '${keyName}' was not set on object '${obj &&
toString(obj)}' via 'defineProperty'`,
false,
{
id: 'ember-meta.descriptor-on-object',
until: '3.5.0',
url:
'https://emberjs.com/deprecations/v3.x#toc_use-defineProperty-to-define-computed-properties',
}
);
descriptor = possibleDesc;
}
}
return descriptor;
}

/**
Expand All @@ -802,8 +827,12 @@ export function descriptorFor(obj: object, keyName: string, _meta?: Meta) {
@private
*/
export function isDescriptor(possibleDesc: any | undefined | null): boolean {
// TODO make this return possibleDesc is Descriptor
return possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor;
return (
possibleDesc !== undefined &&
possibleDesc !== null &&
typeof possibleDesc === 'object' &&
possibleDesc.isDescriptor === true
);
}

export { counters };
Expand Down
2 changes: 1 addition & 1 deletion packages/ember-metal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export { default as computed, ComputedProperty, _globalsComputed } from './lib/c
export { getCacheFor, getCachedValueFor, peekCacheFor } from './lib/computed_cache';
export { default as alias } from './lib/alias';
export { deprecateProperty } from './lib/deprecate_property';
export { PROXY_CONTENT, _getPath, get, getWithDefault } from './lib/property_get';
export { _getPath, get, getWithDefault } from './lib/property_get';
export { set, trySet } from './lib/property_set';
export {
objectAt,
Expand Down
3 changes: 1 addition & 2 deletions packages/ember-metal/lib/property_events.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ function notifyPropertyChange(obj, keyName, _meta) {

let possibleDesc = descriptorFor(obj, keyName, meta);

// shouldn't this mean that we're watching this key?
if (possibleDesc !== undefined && possibleDesc.didChange) {
if (possibleDesc !== undefined && typeof possibleDesc.didChange === 'function') {
possibleDesc.didChange(obj, keyName);
}

Expand Down
39 changes: 9 additions & 30 deletions packages/ember-metal/lib/property_get.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
@module @ember/object
*/
import { DEBUG } from '@glimmer/env';
import { assert, deprecate } from '@ember/debug';
import { HAS_NATIVE_PROXY, symbol } from 'ember-utils';
import { assert } from '@ember/debug';
import { HAS_NATIVE_PROXY } from 'ember-utils';
import { EMBER_METAL_TRACKED_PROPERTIES } from '@ember/canary-features';
import { isPath } from './path_cache';
import { isDescriptor, descriptorFor } from 'ember-meta';
import { descriptorFor, PROXY_CONTENT } from 'ember-meta';
import { getCurrentTracker } from './tracked';
import { tagForProperty } from './tags';

Expand All @@ -16,8 +16,6 @@ const ALLOWABLE_TYPES = {
string: true,
};

export const PROXY_CONTENT = symbol('PROXY_CONTENT');

export let getPossibleMandatoryProxyValue;

if (DEBUG && HAS_NATIVE_PROXY) {
Expand Down Expand Up @@ -105,34 +103,15 @@ export function get(obj, keyName) {
}

descriptor = descriptorFor(obj, keyName);

if (descriptor === undefined) {
if (DEBUG && HAS_NATIVE_PROXY) {
value = getPossibleMandatoryProxyValue(obj, keyName);
} else {
value = obj[keyName];
}

if (isDescriptor(value)) {
deprecate(
`[DEPRECATED] computed property '${keyName}' was not set on object '${obj &&
obj.toString &&
obj.toString()}' via 'defineProperty'`,
false,
{
id: 'ember-meta.descriptor-on-object',
until: '3.5.0',
url:
'https://emberjs.com/deprecations/v3.x#toc_use-defineProperty-to-define-computed-properties',
}
);
descriptor = value;
}
}

if (descriptor !== undefined) {
return descriptor.get(obj, keyName);
}

if (DEBUG && HAS_NATIVE_PROXY) {
value = getPossibleMandatoryProxyValue(obj, keyName);
} else {
value = obj[keyName];
}
} else {
value = obj[keyName];
}
Expand Down
7 changes: 2 additions & 5 deletions packages/ember-metal/lib/property_set.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getPossibleMandatoryProxyValue, _getPath as getPath } from './property_
import { notifyPropertyChange } from './property_events';

import { isPath } from './path_cache';
import { isDescriptor, peekMeta, descriptorFor } from 'ember-meta';
import { peekMeta, descriptorFor } from 'ember-meta';

/**
@module @ember/object
Expand Down Expand Up @@ -78,10 +78,7 @@ export function set(obj, keyName, value, tolerant) {
currentValue = obj[keyName];
}

if (isDescriptor(currentValue)) {
/* computed property */
currentValue.set(obj, keyName, value);
} else if (
if (
currentValue === undefined &&
'object' === typeof obj &&
!(keyName in obj) &&
Expand Down
23 changes: 23 additions & 0 deletions packages/ember-metal/tests/computed_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
set,
isWatching,
addObserver,
notifyPropertyChange,
} from '..';
import { meta as metaFor } from 'ember-meta';
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';
Expand Down Expand Up @@ -60,6 +61,28 @@ moduleFor(
assert.equal(count, 1, 'should have invoked computed property');
}

['@test `notifyPropertyChange` works for plain objects #GH16427'](assert) {
let obj = {
a: 50,
b: computed(function() {
return this.a / 5;
}),
};

expectDeprecation(function() {
assert.equal(get(obj, 'b'), 10);
});

obj.a = 10;
expectDeprecation(function() {
notifyPropertyChange(obj, 'b');
});

expectDeprecation(function() {
assert.equal(get(obj, 'b'), 2);
});
}

['@test defining computed property should invoke property on get'](assert) {
let obj = {};
let count = 0;
Expand Down
3 changes: 1 addition & 2 deletions packages/ember-runtime/lib/system/core_object.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import {
isInternalSymbol,
} from 'ember-utils';
import { schedule } from '@ember/runloop';
import { descriptorFor, meta, peekMeta, deleteMeta } from 'ember-meta';
import { descriptorFor, meta, peekMeta, deleteMeta, PROXY_CONTENT } from 'ember-meta';
import {
PROXY_CONTENT,
finishChains,
sendEvent,
Mixin,
Expand Down
3 changes: 2 additions & 1 deletion packages/ember-runtime/lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DEBUG } from '@glimmer/env';
import { PROXY_CONTENT, get } from 'ember-metal';
import { get } from 'ember-metal';
import { PROXY_CONTENT } from 'ember-meta';
import { HAS_NATIVE_PROXY } from 'ember-utils';
import EmberArray, { A } from './mixins/array';
import EmberObject from './system/object';
Expand Down

0 comments on commit 26ea077

Please sign in to comment.