Skip to content

Commit 68ac71e

Browse files
committed
� Conflicts: � __tests__/index-test.js � package.json � src/index.js � yarn.lock
2 parents f0ff8a4 + d6bfa5a commit 68ac71e

6 files changed

Lines changed: 474 additions & 596 deletions

File tree

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## v3.2.1 (2021-01-15)
2+
3+
#### :bug: Bug Fix
4+
* [#170](https://github.com/ember-cli/babel-plugin-ember-modules-api-polyfill/pull/170) Ensure decorators are transpiled properly when the decorator identifier is aliased within the decorated method ([@dwickern](https://github.com/dwickern))
5+
6+
#### :house: Internal
7+
* [#172](https://github.com/ember-cli/babel-plugin-ember-modules-api-polyfill/pull/172) Update eslint related packages. ([@rwjblue](https://github.com/rwjblue))
8+
* [#171](https://github.com/ember-cli/babel-plugin-ember-modules-api-polyfill/pull/171) Update release automation setup. ([@rwjblue](https://github.com/rwjblue))
9+
* [#171](https://github.com/ember-cli/babel-plugin-ember-modules-api-polyfill/pull/171) Update release automation setup. ([@rwjblue](https://github.com/rwjblue))
10+
11+
#### Committers: 3
12+
- Derek Wickern ([@dwickern](https://github.com/dwickern))
13+
- Robert Jackson ([@rwjblue](https://github.com/rwjblue))
14+
- [@dependabot-preview[bot]](https://github.com/apps/dependabot-preview)
15+
16+
117
## v3.2.0 (2020-10-02)
218

319
#### :rocket: Enhancement

RELEASE.md

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
# Release
1+
# Release Process
22

33
Releases are mostly automated using
44
[release-it](https://github.com/release-it/release-it/) and
55
[lerna-changelog](https://github.com/lerna/lerna-changelog/).
66

7-
87
## Preparation
98

109
Since the majority of the actual release process is automated, the primary
@@ -25,39 +24,33 @@ When reviewing merged PR's the labels to be used are:
2524
* internal - Used for internal changes that still require a mention in the
2625
changelog/release notes.
2726

28-
2927
## Release
3028

3129
Once the prep work is completed, the actual release is straight forward:
3230

33-
* First ensure that you have `release-it` installed globally, generally done by
34-
using one of the following commands:
31+
* First, ensure that you have installed your projects dependencies:
3532

33+
```sh
34+
yarn install
3635
```
37-
# using https://volta.sh
38-
volta install release-it
3936

40-
# using Yarn
41-
yarn global add release-it
37+
* Second, ensure that you have obtained a
38+
[GitHub personal access token][generate-token] with the `repo` scope (no
39+
other permissions are needed). Make sure the token is available as the
40+
`GITHUB_AUTH` environment variable.
4241

43-
# using npm
44-
npm install --global release-it
45-
```
42+
For instance:
4643

47-
* Second, ensure that you have installed your projects dependencies:
44+
```bash
45+
export GITHUB_AUTH=abc123def456
46+
```
4847

49-
```
50-
yarn install
51-
```
48+
[generate-token]: https://github.com/settings/tokens/new?scopes=repo&description=GITHUB_AUTH+env+variable
5249

53-
* And last (but not least 😁) do your release. It requires a
54-
[GitHub personal access token](https://github.com/settings/tokens) as
55-
`$GITHUB_AUTH` environment variable. Only "repo" access is needed; no "admin"
56-
or other scopes are required.
50+
* And last (but not least 😁) do your release.
5751

58-
```
59-
export GITHUB_AUTH="f941e0..."
60-
release-it
52+
```sh
53+
npx release-it
6154
```
6255

6356
[release-it](https://github.com/release-it/release-it/) manages the actual

__tests__/index-test.js

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ function transform7(source, _plugins) {
2323
return result.code;
2424
}
2525

26-
function transformWithPresetEnv(source) {
26+
function transformWithPresetEnv(source, _plugins) {
27+
let plugins = [].concat([[Plugin]], _plugins || []);
2728
let result = babel7.transformSync(source, {
28-
plugins: [[Plugin]],
29+
plugins,
30+
2931
presets: [['@babel/preset-env', { targets: { ie: '8' }, modules: false }]],
3032
});
3133

@@ -423,6 +425,39 @@ describe('when used with typescript', () => {
423425
});
424426
});
425427

428+
describe('when used with native classes and decorators', () => {
429+
it('allows "action" to be used as a variable name', () => {
430+
let source = `
431+
import { action } from '@ember/object';
432+
import Controller from '@ember/controller';
433+
434+
export default class MyController extends Controller {
435+
@action
436+
addAction(action) {
437+
this.actions.pushObject(action);
438+
}
439+
}
440+
`;
441+
442+
let actual = transform7(source, [
443+
[Plugin],
444+
['@babel/plugin-proposal-decorators', { legacy: true }],
445+
]);
446+
447+
expect(actual).toEqual(`var _dec, _class;
448+
449+
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object.keys(descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object.defineProperty(target, property, desc); desc = null; } return desc; }
450+
451+
let MyController = (_dec = Ember._action, (_class = class MyController extends Ember.Controller {
452+
addAction(action) {
453+
this.actions.pushObject(action);
454+
}
455+
456+
}, (_applyDecoratedDescriptor(_class.prototype, "addAction", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "addAction"), _class.prototype)), _class));
457+
export { MyController as default };`);
458+
});
459+
});
460+
426461
describe('when used with babel-plugin-istanbul', () => {
427462
// babel-plugin-istanbul won't run on <= Node 6
428463
const majorVersion = parseInt(process.version.match(/^v(\d+)\./)[1], 10);

package.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "babel-plugin-ember-modules-api-polyfill",
3-
"version": "3.2.0",
3+
"version": "3.2.1",
44
"description": "Polyfill for Ember JS API.",
55
"keywords": [
66
"babel-plugin"
@@ -31,19 +31,20 @@
3131
"ember-rfc176-data": "^0.3.16"
3232
},
3333
"devDependencies": {
34-
"@babel/core": "^7.12.9",
34+
"@babel/core": "^7.12.10",
35+
"@babel/plugin-proposal-decorators": "^7.12.12",
3536
"@babel/plugin-transform-typescript": "^7.12.1",
36-
"@babel/preset-env": "^7.12.7",
37+
"@babel/preset-env": "^7.12.11",
3738
"babel-core": "^6.25.0",
39+
"eslint": "^7.19.0",
40+
"eslint-config-prettier": "^7.2.0",
3841
"babel-plugin-istanbul": "^6.0.0",
39-
"eslint": "^7.14.0",
40-
"eslint-config-prettier": "^6.15.0",
4142
"eslint-plugin-node": "^11.1.0",
42-
"eslint-plugin-prettier": "^3.1.4",
43+
"eslint-plugin-prettier": "^3.3.1",
4344
"jest": "^24.9.0",
4445
"prettier": "^2.2.1",
4546
"release-it": "^14.2.2",
46-
"release-it-lerna-changelog": "^2.4.0"
47+
"release-it-lerna-changelog": "^3.1.0"
4748
},
4849
"engines": {
4950
"node": "6.* || 8.* || >= 10.*"

src/index.js

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ function isIgnored(ignore, importPath, exportName) {
1313
}
1414
}
1515

16+
function isDecorator(moduleName, importName) {
17+
switch (moduleName) {
18+
case '@ember/service':
19+
return importName === 'inject';
20+
case '@ember/controller':
21+
return importName === 'inject';
22+
case '@glimmer/tracking':
23+
return importName === 'tracked';
24+
case '@ember/object/compat':
25+
return importName === 'dependentKeyCompat';
26+
case '@ember/object':
27+
return ['action', 'computed'].includes(importName);
28+
case '@ember/object/computed':
29+
// only the default import of this module is not a decorator
30+
return importName !== 'default';
31+
}
32+
}
33+
1634
module.exports = function (babel) {
1735
const t = babel.types;
1836

@@ -169,8 +187,35 @@ module.exports = function (babel) {
169187

170188
// Replace the occurences of the imported name with the global name.
171189
let binding = path.scope.getBinding(local.name);
190+
let referencePaths = binding.referencePaths;
191+
192+
if (isDecorator(importPath, importName)) {
193+
// tldr; decorator paths are not always included in `path.scope.getBinding(local.name)`
194+
//
195+
// In some circumstances, decorators are not included in the
196+
// reference paths for a local binding when the decorator
197+
// identifier name is also defined _within_ the method being
198+
// decorated. This is likely a bug in Babel, that should be
199+
// reported and fixed.
200+
//
201+
// in order to fix that, we have to manually traverse to gather
202+
// the decorator references **before** the
203+
// @babel/plugin-proposal-decorators runs (because it removes
204+
// them)
205+
path.parentPath.traverse({
206+
Decorator(decoratorPath) {
207+
if (
208+
decoratorPath.node.expression.type === 'Identifier' &&
209+
decoratorPath.node.expression.name === local.name
210+
) {
211+
referencePaths.push(decoratorPath.get('expression'));
212+
}
213+
},
214+
});
215+
}
172216

173-
binding.referencePaths.forEach((referencePath) => {
217+
// Replace the occurences of the imported name with the global name.
218+
referencePaths.forEach((referencePath) => {
174219
if (!isTypescriptNode(referencePath.parentPath)) {
175220
referencePath.replaceWith(getMemberExpressionFor(global));
176221
}

0 commit comments

Comments
 (0)