Skip to content

Commit

Permalink
Merge pull request #17540 from pzuraq/refactor-alias-method
Browse files Browse the repository at this point in the history
[DEPRECATE] Deprecates aliasMethod
  • Loading branch information
rwjblue committed Feb 2, 2019
2 parents 39d0d8d + 1f5438b commit 310c0db
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 109 deletions.
100 changes: 60 additions & 40 deletions packages/@ember/-internals/metal/lib/mixin.ts
Expand Up @@ -12,7 +12,8 @@ import {
setObservers,
wrap,
} from '@ember/-internals/utils';
import { assert } from '@ember/debug';
import { assert, deprecate } from '@ember/debug';
import { ALIAS_METHOD } from '@ember/deprecated-features';
import { assign } from '@ember/polyfills';
import { DEBUG } from '@glimmer/env';
import { ComputedProperty, ComputedPropertyGetter, ComputedPropertySetter } from './computed';
Expand Down Expand Up @@ -301,28 +302,37 @@ function mergeMixins(
}
}

function followMethodAlias(
let followMethodAlias: (
obj: object,
_desc: Alias,
alias: Alias,
descs: { [key: string]: any },
values: { [key: string]: any }
) {
let altKey = _desc.methodName;
let possibleDesc;
let desc = descs[altKey];
let value = values[altKey];

if (desc !== undefined || value !== undefined) {
// do nothing
} else if ((possibleDesc = descriptorFor(obj, altKey)) !== undefined) {
desc = possibleDesc;
value = undefined;
} else {
desc = undefined;
value = obj[altKey];
}
) => { desc: any; value: any };

if (ALIAS_METHOD) {
followMethodAlias = function(
obj: object,
alias: Alias,
descs: { [key: string]: any },
values: { [key: string]: any }
) {
let altKey = alias.methodName;
let possibleDesc;
let desc = descs[altKey];
let value = values[altKey];

if (desc !== undefined || value !== undefined) {
// do nothing
} else if ((possibleDesc = descriptorFor(obj, altKey)) !== undefined) {
desc = possibleDesc;
value = undefined;
} else {
desc = undefined;
value = obj[altKey];
}

return { desc, value };
return { desc, value };
};
}

function updateObserversAndListeners(
Expand Down Expand Up @@ -387,10 +397,12 @@ export function applyMixin(obj: { [key: string]: any }, mixins: Mixin[]) {
desc = descs[key];
value = values[key];

while (desc && desc instanceof Alias) {
let followed = followMethodAlias(obj, desc, descs, values);
desc = followed.desc;
value = followed.value;
if (ALIAS_METHOD) {
while (value && value instanceof AliasImpl) {
let followed = followMethodAlias(obj, value, descs, values);
desc = followed.desc;
value = followed.value;
}
}

if (desc === undefined && value === undefined) {
Expand Down Expand Up @@ -703,23 +715,17 @@ function _keys(mixin: Mixin, ret = new Set(), seen = new Set()) {
return ret;
}

class Alias extends Descriptor {
methodName: string;
declare class Alias {
public methodName: string;
constructor(methodName: string);
}

constructor(methodName: string) {
super();
this.methodName = methodName;
}
let AliasImpl: typeof Alias;

teardown(_obj: object, _keyName: string, _meta: Meta): void {
throw new Error('Method not implemented.');
}
get(_obj: object, _keyName: string) {
throw new Error('Method not implemented.');
}
set(_obj: object, _keyName: string, _value: any) {
throw new Error('Method not implemented.');
}
if (ALIAS_METHOD) {
AliasImpl = class AliasImpl {
constructor(public methodName: string) {}
} as typeof Alias;
}

/**
Expand Down Expand Up @@ -747,12 +753,26 @@ class Alias extends Descriptor {
@method aliasMethod
@static
@deprecated Use a shared utility method instead
@for @ember/object
@param {String} methodName name of the method to alias
@public
*/
export function aliasMethod(methodName: string): Alias {
return new Alias(methodName);
export let aliasMethod: (methodName: string) => any;

if (ALIAS_METHOD) {
aliasMethod = function aliasMethod(methodName: string): Alias {
deprecate(
`You attempted to alias '${methodName}, but aliasMethod has been deprecated. Consider extracting the method into a shared utility function.`,
false,
{
id: 'object.alias-method',
until: '4.0.0',
url: 'https://emberjs.com/deprecations/v3.x#toc_object-alias-method',
}
);
return new AliasImpl(methodName);
};
}

// ..........................................................
Expand Down
138 changes: 74 additions & 64 deletions packages/@ember/-internals/metal/tests/mixin/alias_method_test.js
Expand Up @@ -10,82 +10,92 @@ moduleFor(
'aliasMethod',
class extends AbstractTestCase {
['@test methods of another name are aliased when the mixin is applied'](assert) {
let MyMixin = Mixin.create({
fooMethod() {
return 'FOO';
},
barMethod: aliasMethod('fooMethod'),
});

let obj = MyMixin.apply({});
validateAliasMethod(assert, obj);
expectDeprecation(() => {
let MyMixin = Mixin.create({
fooMethod() {
return 'FOO';
},
barMethod: aliasMethod('fooMethod'),
});

let obj = MyMixin.apply({});
validateAliasMethod(assert, obj);
}, /aliasMethod has been deprecated. Consider extracting the method into a shared utility function/);
}

['@test should follow aliasMethods all the way down'](assert) {
let MyMixin = Mixin.create({
bar: aliasMethod('foo'), // put first to break ordered iteration
baz() {
return 'baz';
},
foo: aliasMethod('baz'),
});

let obj = MyMixin.apply({});
assert.equal(get(obj, 'bar')(), 'baz', 'should have followed aliasMethods');
expectDeprecation(() => {
let MyMixin = Mixin.create({
bar: aliasMethod('foo'), // put first to break ordered iteration
baz() {
return 'baz';
},
foo: aliasMethod('baz'),
});

let obj = MyMixin.apply({});
assert.equal(get(obj, 'bar')(), 'baz', 'should have followed aliasMethods');
}, /aliasMethod has been deprecated. Consider extracting the method into a shared utility function/);
}

['@test should alias methods from other dependent mixins'](assert) {
let BaseMixin = Mixin.create({
fooMethod() {
return 'FOO';
},
});

let MyMixin = Mixin.create(BaseMixin, {
barMethod: aliasMethod('fooMethod'),
});

let obj = MyMixin.apply({});
validateAliasMethod(assert, obj);
expectDeprecation(() => {
let BaseMixin = Mixin.create({
fooMethod() {
return 'FOO';
},
});

let MyMixin = Mixin.create(BaseMixin, {
barMethod: aliasMethod('fooMethod'),
});

let obj = MyMixin.apply({});
validateAliasMethod(assert, obj);
}, /aliasMethod has been deprecated. Consider extracting the method into a shared utility function/);
}

['@test should alias methods from other mixins applied at same time'](assert) {
let BaseMixin = Mixin.create({
fooMethod() {
return 'FOO';
},
});

let MyMixin = Mixin.create({
barMethod: aliasMethod('fooMethod'),
});

let obj = mixin({}, BaseMixin, MyMixin);
validateAliasMethod(assert, obj);
expectDeprecation(() => {
let BaseMixin = Mixin.create({
fooMethod() {
return 'FOO';
},
});

let MyMixin = Mixin.create({
barMethod: aliasMethod('fooMethod'),
});

let obj = mixin({}, BaseMixin, MyMixin);
validateAliasMethod(assert, obj);
}, /aliasMethod has been deprecated. Consider extracting the method into a shared utility function/);
}

['@test should alias methods from mixins already applied on object'](assert) {
let BaseMixin = Mixin.create({
quxMethod() {
return 'qux';
},
});

let MyMixin = Mixin.create({
bar: aliasMethod('foo'),
barMethod: aliasMethod('fooMethod'),
});

let obj = {
fooMethod() {
return 'FOO';
},
};

BaseMixin.apply(obj);
MyMixin.apply(obj);

validateAliasMethod(assert, obj);
expectDeprecation(() => {
let BaseMixin = Mixin.create({
quxMethod() {
return 'qux';
},
});

let MyMixin = Mixin.create({
bar: aliasMethod('foo'),
barMethod: aliasMethod('fooMethod'),
});

let obj = {
fooMethod() {
return 'FOO';
},
};

BaseMixin.apply(obj);
MyMixin.apply(obj);

validateAliasMethod(assert, obj);
}, /aliasMethod has been deprecated. Consider extracting the method into a shared utility function/);
}
}
);
11 changes: 6 additions & 5 deletions packages/@ember/-internals/runtime/lib/mixins/array.js
Expand Up @@ -11,7 +11,6 @@ import {
replaceInNativeArray,
replace,
computed,
aliasMethod,
Mixin,
hasListeners,
beginPropertyChanges,
Expand Down Expand Up @@ -180,6 +179,10 @@ function nonEnumerableComputed() {
return property;
}

function mapBy(key) {
return this.map(next => get(next, key));
}

// ..........................................................
// ARRAY
//
Expand Down Expand Up @@ -572,7 +575,7 @@ const ArrayMixin = Mixin.create(Enumerable, {
@return {Array} The mapped array.
@public
*/
getEach: aliasMethod('mapBy'),
getEach: mapBy,

/**
Sets the value on the named property for each member. This is more
Expand Down Expand Up @@ -636,9 +639,7 @@ const ArrayMixin = Mixin.create(Enumerable, {
@return {Array} The mapped array.
@public
*/
mapBy(key) {
return this.map(next => get(next, key));
},
mapBy,

/**
Returns an array with all of the items in the enumeration that the passed
Expand Down
4 changes: 4 additions & 0 deletions packages/@ember/deprecated-features/index.ts
@@ -1,5 +1,8 @@
/* eslint-disable no-implicit-coercion */

// These versions should be the version that the deprecation was _introduced_,
// not the version that the feature will be removed.

export const SEND_ACTION = !!'3.4.0';
export const EMBER_EXTEND_PROTOTYPES = !!'3.2.0-beta.5';
export const RUN_SYNC = !!'3.0.0-beta.4';
Expand All @@ -10,3 +13,4 @@ export const ROUTER_EVENTS = !!'3.9.0';
export const TRANSITION_STATE = !!'3.9.0';
export const COMPONENT_MANAGER_STRING_LOOKUP = !!'4.0.0';
export const JQUERY_INTEGRATION = !!'3.9.0';
export const ALIAS_METHOD = !!'3.9.0';

0 comments on commit 310c0db

Please sign in to comment.