Skip to content

Commit 9a387d5

Browse files
author
Suchita Doshi
committed
Fix the removal of computed decorators
1 parent 70740a7 commit 9a387d5

File tree

8 files changed

+56
-41
lines changed

8 files changed

+56
-41
lines changed

transforms/tracked-properties/README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export default class Foo extends Component {
141141
return `Name: ${get(this, 'firstName')} ${get(this, 'lastName')}`;
142142
}
143143

144-
@computed('areaCode')
144+
@computed('areaCode', 'phone')
145145
get phoneNumber() {
146146
return `(${get(this, 'areaCode')}) ${get(this, 'phone')}`;
147147
}
@@ -190,15 +190,17 @@ export default class Foo extends Component {
190190
@tracked foo = 'bar';
191191
baz;
192192

193+
@computed('foo')
193194
get fooBar() {
194195
return `Foo: ${get(this, 'foo')}`;
195196
}
196197

198+
@computed('fooBar')
197199
get fooBarDetail() {
198200
return `Foo bar detail: ${get(this, 'fooBar')}`;
199201
}
200202

201-
@computed('bang')
203+
@computed('fooBarDetail', 'bang')
202204
get fooBarDetailWithBaz() {
203205
return `(${get(this, 'fooBarDetail')}) ${get(this, 'baz')}`;
204206
}
@@ -252,7 +254,7 @@ export default class AddTeamComponent extends Component {
252254
@tracked teamName;
253255
@tracked noOfHackers;
254256

255-
@computed('fooBar')
257+
@computed('fooBar', 'noOfHackers')
256258
get isMaxExceeded() {
257259
return this.noOfHackers > 10;
258260
}
@@ -316,12 +318,12 @@ export default class Foo extends Component {
316318
@alias('model.isFoo')
317319
isFoo;
318320

319-
@computed('isFoo')
321+
@computed('baz', 'isFoo')
320322
get bazInfo() {
321323
return get(this, 'isFoo') ? `Name: ${get(this, 'baz')}` : 'Baz';
322324
}
323325

324-
@(computed('isFoo').readOnly())
326+
@computed('bar', 'isFoo').readOnly()
325327
get barInfo() {
326328
return get(this, 'isFoo') ? `Name: ${get(this, 'bar')}` : 'Bar';
327329
}
@@ -385,7 +387,7 @@ export default class Foo extends Component {
385387
return `Bar: ${get(this, 'bar')}, Baz: ${get(this, 'baz')}`;
386388
}
387389

388-
@(computed('isFoo').readOnly())
390+
@(computed('bar', 'isFoo').readOnly())
389391
get barInfo() {
390392
return get(this, 'isFoo') ? `Name: ${get(this, 'bar')}` : 'Bar';
391393
}

transforms/tracked-properties/__testfixtures__/chained-complex-computed.output.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default class AddTeamComponent extends Component {
88
@tracked teamName;
99
@tracked noOfHackers;
1010

11-
@computed('fooBar')
11+
@computed('fooBar', 'noOfHackers')
1212
get isMaxExceeded() {
1313
return this.noOfHackers > 10;
1414
}

transforms/tracked-properties/__testfixtures__/chained-computed.output.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ export default class Foo extends Component {
66
@tracked foo = 'bar';
77
baz;
88

9+
@computed('foo')
910
get fooBar() {
1011
return `Foo: ${get(this, 'foo')}`;
1112
}
1213

14+
@computed('fooBar')
1315
get fooBarDetail() {
1416
return `Foo bar detail: ${get(this, 'fooBar')}`;
1517
}
1618

17-
@computed('bang')
19+
@computed('fooBarDetail', 'bang')
1820
get fooBarDetailWithBaz() {
1921
return `(${get(this, 'fooBarDetail')}) ${get(this, 'baz')}`;
2022
}

transforms/tracked-properties/__testfixtures__/complex.output.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export default class Foo extends Component {
1212
return `Name: ${get(this, 'firstName')} ${get(this, 'lastName')}`;
1313
}
1414

15-
@computed('areaCode')
15+
@computed('areaCode', 'phone')
1616
get phoneNumber() {
1717
return `(${get(this, 'areaCode')}) ${get(this, 'phone')}`;
1818
}

transforms/tracked-properties/__testfixtures__/non-computed-decorators.output.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ export default class Foo extends Component {
1111
@alias('model.isFoo')
1212
isFoo;
1313

14-
@computed('isFoo')
14+
@computed('baz', 'isFoo')
1515
get bazInfo() {
1616
return get(this, 'isFoo') ? `Name: ${get(this, 'baz')}` : 'Baz';
1717
}
1818

19-
@computed('isFoo').readOnly()
19+
@computed('bar', 'isFoo').readOnly()
2020
get barInfo() {
2121
return get(this, 'isFoo') ? `Name: ${get(this, 'bar')}` : 'Bar';
2222
}

transforms/tracked-properties/__testfixtures__/read-only-computed-decorators.output.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default class Foo extends Component {
1515
return `Bar: ${get(this, 'bar')}, Baz: ${get(this, 'baz')}`;
1616
}
1717

18-
@(computed('isFoo').readOnly())
18+
@(computed('bar', 'isFoo').readOnly())
1919
get barInfo() {
2020
return get(this, 'isFoo') ? `Name: ${get(this, 'bar')}` : 'Bar';
2121
}

transforms/tracked-properties/index.js

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -119,38 +119,49 @@ module.exports = function transformer(file, api) {
119119
trackedConvertedSource = reformatTrackedDecorators(trackedConvertedSource);
120120
}
121121

122-
// Iterate on all the `computed` decorators and for each node, check if
123-
// all the arguments are a part of the `classProps` array, if so, then
124-
// remove the `@computed` decorator, else remove the arguments that are
125-
// defined locally in the class.
122+
/**
123+
* Iterate on all the class items, if the class item has decorators and it is not a dependent
124+
* key of some other property, then go ahead and check if the `computed` decorator can be safely removed.
125+
*/
126126
const convertedResult = j(trackedConvertedSource)
127-
.find(j.Decorator)
128-
.filter(path => {
129-
return (
130-
path.node.expression.type === 'CallExpression' &&
131-
_isComputedProperty(path.node)
132-
);
133-
})
127+
.find(j.ClassBody)
134128
.forEach(path => {
135-
const isReadOnlyProperty = _isReadOnlyComputedProperty(path.node);
136-
const computedPropArguments = isReadOnlyProperty
137-
? path.node.expression.callee.object.arguments
138-
: path.node.expression.arguments;
129+
path.node.body.forEach(classItem => {
130+
const propName = classItem.key.name;
131+
// Check if the class item is not a dependent key of any other computed properties in the class
132+
// and if the item has any decorators.
133+
if (
134+
!Object.keys(computedPropsMap).some(item =>
135+
computedPropsMap[item].includes(propName)
136+
) &&
137+
classItem.decorators
138+
) {
139+
classItem.decorators.forEach((decoratorItem, i) => {
140+
if (
141+
decoratorItem.expression.type === 'CallExpression' &&
142+
_isComputedProperty(decoratorItem)
143+
) {
144+
const isReadOnlyProperty = _isReadOnlyComputedProperty(
145+
decoratorItem
146+
);
147+
const computedPropArguments = isReadOnlyProperty
148+
? decoratorItem.expression.callee.object.arguments
149+
: decoratorItem.expression.arguments;
139150

140-
const dependentKeys = getDependentKeys(
141-
computedPropArguments,
142-
computedPropsMap,
143-
classProps
144-
);
145-
if (!dependentKeys.length) {
146-
path.replace();
147-
} else {
148-
if (isReadOnlyProperty) {
149-
path.node.expression.callee.object.arguments = dependentKeys;
150-
} else {
151-
path.node.expression.arguments = dependentKeys;
151+
const dependentKeys = getDependentKeys(
152+
computedPropArguments,
153+
computedPropsMap,
154+
classProps
155+
);
156+
// If all the arguments of the decorator are class properties, then remove the decorator completely
157+
// from the item.
158+
if (!dependentKeys.length) {
159+
classItem.decorators.splice(i, 1);
160+
}
161+
}
162+
});
152163
}
153-
}
164+
});
154165
});
155166

156167
return shouldImportBeAdded

transforms/tracked-properties/utils/helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ function _doesContainNonLocalArgs(argItem, computedMap, classProperties) {
6363

6464
// If currItem is not a class property and
6565
// if it is not a computed property with dependent keys, return true.
66-
if (!classProperties.includes(currItem) && !dependentKeys) {
66+
if ((!classProperties.includes(currItem) && !dependentKeys) || Object.keys(computedMap).includes(currItem)) {
6767
return true;
6868
}
6969
// If currItem itself is a computed property, then it would have dependent keys.

0 commit comments

Comments
 (0)