Skip to content

Commit c1a0eff

Browse files
Robert JacksonChris Garrett
authored andcommitted
Remove remaining traces of wrapComputed. (#152)
* Remove remaining traces of wrapComputed. * Moves `setRuntimeData` _before_ `setDecorators` so that we can more easily setup local state in `setDecorators` * Removes remaining references to `wrapComputed` * Adds `.isComputed` boolean to `EOProp` class to allow us to track when the runtime data indicates that a given property was a computed property. * Update decorator building code to avoid creating a call expression for decorators that are returning computed properties without arguments (e.g. use `@someComputedMacro` vs `@someComputedMacro()`) * add/correct tests, fix bug where all objects/functions get turned into computeds * Ensure @service('something') works properly. * Process all functions but only object expressions for computed * Get things working again, fixup some tests
1 parent 0f7e0df commit c1a0eff

11 files changed

Lines changed: 140 additions & 80 deletions

File tree

test/fixtures/output/app/components/test-component.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@ function fullNameMacro() {
1010

1111
@classic
1212
export default class TestComponentComponent extends Component {
13-
@fullNameMacro
13+
@fullNameMacro()
1414
fullName;
1515
}
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"runtime.input": {
3-
"computedProperties": ["computedMacro", "numPlusOne", "numPlusPlus"],
3+
"computedProperties": ["computedMacro", "anotherMacro", "numPlusOne", "numPlusPlus", "error", "errorService"],
44
"observedProperties": [],
55
"observerProperties": {},
66
"offProperties": { "offProp": ["prop1", "prop2"] },
@@ -9,5 +9,16 @@
99
"ownProperties": [],
1010
"type": "EmberObject",
1111
"unobservedProperties": { "unobservedProp": ["prop3", "prop4"] }
12+
},
13+
"injecting-service.input": {
14+
"computedProperties": ["something", "otherThing"],
15+
"observedProperties": [],
16+
"observerProperties": {},
17+
"offProperties": {},
18+
"overriddenActions": [],
19+
"overriddenProperties": [],
20+
"ownProperties": [],
21+
"type": "Service",
22+
"unobservedProperties": {}
1223
}
1324
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import Service, { service as injectService } from '@ember/service';
2+
3+
export default Service.extend({
4+
something: injectService(),
5+
otherThing: injectService('some-thing'),
6+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import classic from 'ember-classic-decorator';
2+
import Service, { service as injectService } from '@ember/service';
3+
4+
@classic
5+
export default class InjectingServiceInputService extends Service {
6+
@injectService()
7+
something;
8+
9+
@injectService('some-thing')
10+
otherThing;
11+
}

transforms/ember-object/__testfixtures__/runtime.input.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import RuntimeInput from 'common/runtime/input';
22
import { alias } from '@ember/object/computed';
33
import { computed } from '@ember/object';
4+
import { service } from '@ember/service';
45

56
/**
67
* Program comments
@@ -15,6 +16,9 @@ export default RuntimeInput.extend(MyMixin, {
1516
[MY_VAL]: 'val',
1617
queryParams: {},
1718

19+
error: service(),
20+
errorService: service('error'),
21+
1822
unobservedProp: null,
1923
offProp: null,
2024

@@ -26,6 +30,11 @@ export default RuntimeInput.extend(MyMixin, {
2630

2731
computedMacro: customMacro(),
2832

33+
anotherMacro: customMacroWithInput({
34+
foo: 123,
35+
bar: 'baz'
36+
}),
37+
2938
/**
3039
* Method comments
3140
*/

transforms/ember-object/__testfixtures__/runtime.output.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { off, unobserves } from '@ember-decorators/object';
33
import { action, computed } from '@ember/object';
44
import { alias } from '@ember/object/computed';
55
import RuntimeInput from 'common/runtime/input';
6+
import { service } from '@ember/service';
67

78
/**
89
* Program comments
@@ -19,6 +20,12 @@ export default class RuntimeInputEmberObject extends RuntimeInput.extend(MyMixin
1920
[MY_VAL] = 'val';
2021
queryParams = {};
2122

23+
@service
24+
error;
25+
26+
@service('error')
27+
errorService;
28+
2229
@unobserves('prop3', 'prop4')
2330
unobservedProp;
2431

@@ -33,9 +40,15 @@ export default class RuntimeInputEmberObject extends RuntimeInput.extend(MyMixin
3340
@alias('numPlusOne')
3441
numPlusPlus;
3542

36-
@customMacro
43+
@customMacro()
3744
computedMacro;
3845

46+
@customMacroWithInput({
47+
foo: 123,
48+
bar: 'baz'
49+
})
50+
anotherMacro;
51+
3952
/**
4053
* Method comments
4154
*/

transforms/helpers/EOProp.js

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const {
1616
class EOProp {
1717
constructor(eoProp) {
1818
this._prop = eoProp;
19-
this.decoratorNames = [];
19+
this.decorators = [];
2020
this.modifiers = [];
2121
this.decoratorArgs = {};
2222
}
@@ -27,9 +27,20 @@ class EOProp {
2727

2828
get kind() {
2929
let kind = get(this._prop, 'kind');
30-
if (kind === 'init' && this.hasDecorators && !this.hasMethodDecorator) {
30+
let method = get(this._prop, 'method');
31+
32+
if (
33+
kind === 'init' &&
34+
this.hasDecorators &&
35+
this.decorators.find(d => d.importedName === 'computed')
36+
) {
3137
kind = 'get';
3238
}
39+
40+
if (method || this.hasMethodDecorator) {
41+
kind = 'method';
42+
}
43+
3344
return kind;
3445
}
3546

@@ -61,6 +72,10 @@ class EOProp {
6172
return isClassDecoratorProp(this.name);
6273
}
6374

75+
get decoratorNames() {
76+
return this.decorators.map(d => d.name);
77+
}
78+
6479
get classDecoratorName() {
6580
if (this.name === LAYOUT_DECORATOR_NAME && this.value.name === LAYOUT_DECORATOR_NAME) {
6681
return LAYOUT_DECORATOR_LOCAL_NAME;
@@ -81,20 +96,15 @@ class EOProp {
8196
}
8297

8398
get hasDecorators() {
84-
return this.decoratorNames.length;
99+
return this.decorators.length;
85100
}
86101

87102
get callExprArgs() {
88103
return get(this.calleeObject, 'arguments') || [];
89104
}
90105

91106
get shouldRemoveLastArg() {
92-
const lastArg = this.callExprArgs.slice(-1) || [];
93-
94-
return (
95-
lastArg.length > 0 &&
96-
(lastArg[0].type === 'FunctionExpression' || lastArg[0].type === 'ObjectExpression')
97-
);
107+
return this.kind === 'method' || this.kind === 'get';
98108
}
99109

100110
get hasModifierWithArgs() {
@@ -141,14 +151,18 @@ class EOProp {
141151
return this.decoratorNames.includes('off');
142152
}
143153

144-
get hasWrapComputedDecorator() {
145-
return this.decoratorNames.includes('wrapComputed');
146-
}
147-
148154
get hasRuntimeData() {
149155
return !!this.runtimeType;
150156
}
151157

158+
get hasMethodDecorator() {
159+
return this.decorators.find(d => d.isMethodDecorator);
160+
}
161+
162+
get hasMetaDecorator() {
163+
return this.decorators.find(d => d.isMetaDecorator);
164+
}
165+
152166
setCallExpressionProps() {
153167
let calleeObject = get(this._prop, 'value');
154168
const modifiers = [getModifier(calleeObject)];
@@ -164,25 +178,21 @@ class EOProp {
164178
setDecorators(importedDecoratedProps) {
165179
if (this.isCallExpression) {
166180
this.setCallExpressionProps();
167-
const { decoratorName, isMethodDecorator, isMetaDecorator, importedName } =
168-
importedDecoratedProps[this.calleeName] || {};
169-
if (decoratorName) {
170-
this.hasMapDecorator = importedName === 'map';
171-
this.hasFilterDecorator = importedName === 'filter';
172-
this.hasComputedDecorator = importedName === 'computed';
173-
this.hasMethodDecorator = isMethodDecorator;
174-
this.hasMetaDecorator = isMetaDecorator;
175-
this.decoratorNames.push(decoratorName);
181+
182+
if (importedDecoratedProps[this.calleeName]) {
183+
this.decorators.push(importedDecoratedProps[this.calleeName]);
184+
} else if (this.isComputed) {
185+
this.decorators.push({ name: this.calleeName });
176186
}
177187
}
178188
}
179189

180190
addBindingProps(attributeBindingsProps, classNameBindingsProps) {
181191
if (attributeBindingsProps[this.name]) {
182-
this.decoratorNames.push('attribute');
192+
this.decorators.push({ name: 'attribute' });
183193
this.propList = attributeBindingsProps[this.name];
184194
} else if (classNameBindingsProps[this.name]) {
185-
this.decoratorNames.push('className');
195+
this.decorators.push({ name: 'className' });
186196
this.propList = classNameBindingsProps[this.name];
187197
}
188198
}
@@ -201,17 +211,18 @@ class EOProp {
201211
if (!type) {
202212
return;
203213
}
214+
204215
const name = this.name;
205216
if (Object.keys(unobservedProperties).includes(name)) {
206-
this.decoratorNames.push('unobserves');
217+
this.decorators.push({ name: 'unobserves' });
207218
this.decoratorArgs['unobserves'] = unobservedProperties[name];
208219
}
209220
if (Object.keys(offProperties).includes(name)) {
210-
this.decoratorNames.push('off');
221+
this.decorators.push({ name: 'off' });
211222
this.decoratorArgs['off'] = offProperties[name];
212223
}
213-
if (computedProperties.includes(name) && !this.hasComputedDecorator && !this.hasMetaDecorator) {
214-
this.decoratorNames.push('wrapComputed');
224+
if (computedProperties.includes(name)) {
225+
this.isComputed = true;
215226
}
216227
if (this.isAction) {
217228
this.overriddenActions = overriddenActions;

transforms/helpers/decorator-helper.js

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,30 +46,28 @@ function createCallExpressionDecorators(j, decoratorName, instanceProp) {
4646
return [];
4747
}
4848

49-
if (instanceProp.hasWrapComputedDecorator) {
50-
return j.decorator(j.identifier(instanceProp.calleeName));
51-
}
49+
const decoratorArgs = instanceProp.shouldRemoveLastArg
50+
? instanceProp.callExprArgs.slice(0, -1)
51+
: instanceProp.callExprArgs.slice(0);
5252

53-
const decoratorArgs =
54-
!instanceProp.hasMapDecorator &&
55-
!instanceProp.hasFilterDecorator &&
56-
instanceProp.shouldRemoveLastArg
57-
? instanceProp.callExprArgs.slice(0, -1)
58-
: instanceProp.callExprArgs.slice(0);
53+
let decoratorExpression =
54+
['computed', 'service', 'controller'].includes(decoratorName) && decoratorArgs.length === 0
55+
? j.identifier(decoratorName)
56+
: j.callExpression(j.identifier(decoratorName), decoratorArgs);
5957

60-
const decoratorExpr = instanceProp.modifiers.reduce(
58+
decoratorExpression = instanceProp.modifiers.reduce(
6159
(callExpr, modifier) =>
6260
j.callExpression(j.memberExpression(callExpr, modifier.prop), modifier.args),
63-
j.callExpression(j.identifier(decoratorName), decoratorArgs)
61+
decoratorExpression
6462
);
6563

6664
if (!instanceProp.modifiers.length) {
67-
return j.decorator(decoratorExpr);
65+
return j.decorator(decoratorExpression);
6866
}
6967

7068
// If has modifiers wrap decorators in anonymous call expression
7169
// it transforms @computed('').readOnly() => @(computed('').readOnly())
72-
return j.decorator(j.callExpression(j.identifier(''), [decoratorExpr]));
70+
return j.decorator(j.callExpression(j.identifier(''), [decoratorExpression]));
7371
}
7472

7573
/**

transforms/helpers/import-helper.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,20 @@ function getDecoratorInfo(specifier, importPropDecoratorMap) {
2121
const importedName = get(specifier, 'imported.name');
2222
const isImportedAs = importedName !== localName;
2323
const isMetaDecorator = !importPropDecoratorMap;
24-
let decoratorName;
24+
let name;
2525
if (isImportedAs) {
26-
decoratorName = localName;
26+
name = localName;
2727
} else {
2828
if (isMetaDecorator) {
29-
decoratorName = localName;
29+
name = localName;
3030
} else {
31-
decoratorName = importPropDecoratorMap[importedName];
31+
name = importPropDecoratorMap[importedName];
3232
}
3333
}
3434

3535
const isMethodDecorator = METHOD_DECORATORS.includes(importedName);
3636
return {
37-
decoratorName,
37+
name,
3838
importedName,
3939
isImportedAs,
4040
isMetaDecorator,

transforms/helpers/parse-helper.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ function getEmberObjectProps(j, eoExpression, importedDecoratedProps = {}, runti
3535
} else if (prop.name === 'attributeBindings') {
3636
Object.assign(attributeBindingsProps, parseBindingProps(prop.value.elements));
3737
} else {
38-
prop.setDecorators(importedDecoratedProps);
3938
prop.setRuntimeData(runtimeData);
39+
prop.setDecorators(importedDecoratedProps);
4040
instanceProps.push(prop);
4141
}
4242
});
@@ -83,7 +83,6 @@ function getDecoratorsToImportMap(instanceProps, decoratorsMap = {}) {
8383
return instanceProps.reduce((specs, prop) => {
8484
return {
8585
action: specs.action || prop.isAction,
86-
wrapComputed: specs.wrapComputed || prop.hasWrapComputedDecorator,
8786
attribute: specs.attribute || prop.hasAttributeDecorator,
8887
className: specs.className || prop.hasClassNameDecorator,
8988
classNames: specs.classNames || prop.isClassNames,

0 commit comments

Comments
 (0)