├── transforms
├── .gitkeep
└── no-implicit-this
│ ├── __testfixtures__
│ ├── paths.input.hbs
│ ├── custom-helpers.input.hbs
│ ├── custom-helpers.output.hbs
│ ├── paths.output.hbs
│ ├── -helpers.json
│ ├── custom-helpers.options.json
│ ├── angle-brackets-without-params.input.hbs
│ ├── angle-brackets-without-params.output.hbs
│ ├── comments.input.hbs
│ ├── comments.output.hbs
│ ├── handlebars-without-params.input.hbs
│ ├── handlebars-without-params.output.hbs
│ ├── batman.input.hbs
│ ├── batman.output.hbs
│ ├── -mock-telemetry.d.json.ts
│ ├── void-elements.input.hbs
│ ├── void-elements.output.hbs
│ ├── angle-brackets-with-block-params.input.hbs
│ ├── angle-brackets-with-block-params.output.hbs
│ ├── has-block.input.hbs
│ ├── has-block.output.hbs
│ ├── handlebars-with-wall-street-syntax.input.hbs
│ ├── handlebars-with-positional-params.input.hbs
│ ├── handlebars-with-positional-params.output.hbs
│ ├── handlebars-with-wall-street-syntax.output.hbs
│ ├── handlebars-with-hash-params.input.hbs
│ ├── handlebars-with-block-params.input.hbs
│ ├── handlebars-with-block-params.output.hbs
│ ├── tagged-templates-ts.input.ts
│ ├── handlebars-with-hash-params.output.hbs
│ ├── tagged-templates-js.input.js
│ ├── tagged-templates-ts.output.ts
│ ├── tagged-templates-js.output.js
│ ├── -mock-telemetry.json
│ ├── built-in-helpers.input.hbs
│ ├── built-in-helpers.output.hbs
│ ├── angle-brackets-with-hash-params.input.hbs
│ └── angle-brackets-with-hash-params.output.hbs
│ ├── test.ts
│ ├── test-helpers.ts
│ ├── helpers
│ ├── known-helpers.ts
│ ├── parse.ts
│ ├── telemetry.ts
│ ├── tagged-templates.ts
│ ├── options.ts
│ └── plugin.ts
│ ├── index.ts
│ └── README.md
├── test
├── fixtures
│ ├── 3.10
│ │ ├── input
│ │ │ ├── app
│ │ │ │ ├── styles
│ │ │ │ │ └── app.css
│ │ │ │ ├── components
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── helpers
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── models
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── routes
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── controllers
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── templates
│ │ │ │ │ ├── components
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ │ └── application.hbs
│ │ │ │ ├── resolver.js
│ │ │ │ ├── router.js
│ │ │ │ ├── app.js
│ │ │ │ └── index.html
│ │ │ ├── vendor
│ │ │ │ └── .gitkeep
│ │ │ ├── tests
│ │ │ │ ├── helpers
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── unit
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── integration
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── test-helper.js
│ │ │ │ └── index.html
│ │ │ ├── .watchmanconfig
│ │ │ ├── config
│ │ │ │ ├── optional-features.json
│ │ │ │ ├── targets.js
│ │ │ │ └── environment.js
│ │ │ ├── public
│ │ │ │ └── robots.txt
│ │ │ ├── .template-lintrc.js
│ │ │ ├── .ember-cli
│ │ │ ├── .eslintignore
│ │ │ ├── .travis.yml
│ │ │ ├── .editorconfig
│ │ │ ├── .gitignore
│ │ │ ├── testem.js
│ │ │ ├── ember-cli-build.js
│ │ │ ├── .eslintrc.js
│ │ │ ├── README.md
│ │ │ └── package.json
│ │ └── output
│ │ │ ├── vendor
│ │ │ └── .gitkeep
│ │ │ ├── app
│ │ │ ├── helpers
│ │ │ │ └── .gitkeep
│ │ │ ├── models
│ │ │ │ └── .gitkeep
│ │ │ ├── routes
│ │ │ │ └── .gitkeep
│ │ │ ├── styles
│ │ │ │ └── app.css
│ │ │ ├── components
│ │ │ │ └── .gitkeep
│ │ │ ├── controllers
│ │ │ │ └── .gitkeep
│ │ │ ├── templates
│ │ │ │ ├── components
│ │ │ │ │ └── .gitkeep
│ │ │ │ └── application.hbs
│ │ │ ├── resolver.js
│ │ │ ├── router.js
│ │ │ ├── app.js
│ │ │ └── index.html
│ │ │ ├── tests
│ │ │ ├── helpers
│ │ │ │ └── .gitkeep
│ │ │ ├── unit
│ │ │ │ └── .gitkeep
│ │ │ ├── integration
│ │ │ │ └── .gitkeep
│ │ │ ├── test-helper.js
│ │ │ └── index.html
│ │ │ ├── .watchmanconfig
│ │ │ ├── config
│ │ │ ├── optional-features.json
│ │ │ ├── targets.js
│ │ │ └── environment.js
│ │ │ ├── public
│ │ │ └── robots.txt
│ │ │ ├── .template-lintrc.js
│ │ │ ├── .ember-cli
│ │ │ ├── .eslintignore
│ │ │ ├── .travis.yml
│ │ │ ├── .editorconfig
│ │ │ ├── .gitignore
│ │ │ ├── testem.js
│ │ │ ├── ember-cli-build.js
│ │ │ ├── .eslintrc.js
│ │ │ ├── README.md
│ │ │ └── package.json
│ └── 3.13
│ │ ├── input
│ │ ├── app
│ │ │ ├── styles
│ │ │ │ └── app.css
│ │ │ ├── components
│ │ │ │ └── .gitkeep
│ │ │ ├── helpers
│ │ │ │ └── .gitkeep
│ │ │ ├── models
│ │ │ │ └── .gitkeep
│ │ │ ├── routes
│ │ │ │ └── .gitkeep
│ │ │ ├── controllers
│ │ │ │ ├── .gitkeep
│ │ │ │ └── application.js
│ │ │ ├── templates
│ │ │ │ ├── components
│ │ │ │ │ └── .gitkeep
│ │ │ │ └── application.hbs
│ │ │ ├── resolver.js
│ │ │ ├── router.js
│ │ │ ├── app.js
│ │ │ └── index.html
│ │ ├── vendor
│ │ │ └── .gitkeep
│ │ ├── tests
│ │ │ ├── helpers
│ │ │ │ └── .gitkeep
│ │ │ ├── unit
│ │ │ │ ├── .gitkeep
│ │ │ │ └── controllers
│ │ │ │ │ └── application-test.js
│ │ │ ├── integration
│ │ │ │ └── .gitkeep
│ │ │ ├── test-helper.js
│ │ │ └── index.html
│ │ ├── .watchmanconfig
│ │ ├── config
│ │ │ ├── optional-features.json
│ │ │ ├── targets.js
│ │ │ └── environment.js
│ │ ├── public
│ │ │ └── robots.txt
│ │ ├── .template-lintrc.js
│ │ ├── .ember-cli
│ │ ├── .eslintignore
│ │ ├── .travis.yml
│ │ ├── .editorconfig
│ │ ├── .gitignore
│ │ ├── testem.js
│ │ ├── ember-cli-build.js
│ │ ├── .eslintrc.js
│ │ ├── README.md
│ │ └── package.json
│ │ └── output
│ │ ├── vendor
│ │ └── .gitkeep
│ │ ├── app
│ │ ├── helpers
│ │ │ └── .gitkeep
│ │ ├── models
│ │ │ └── .gitkeep
│ │ ├── routes
│ │ │ └── .gitkeep
│ │ ├── styles
│ │ │ └── app.css
│ │ ├── components
│ │ │ └── .gitkeep
│ │ ├── controllers
│ │ │ ├── .gitkeep
│ │ │ └── application.js
│ │ ├── templates
│ │ │ ├── components
│ │ │ │ └── .gitkeep
│ │ │ └── application.hbs
│ │ ├── resolver.js
│ │ ├── router.js
│ │ ├── app.js
│ │ └── index.html
│ │ ├── tests
│ │ ├── helpers
│ │ │ └── .gitkeep
│ │ ├── unit
│ │ │ ├── .gitkeep
│ │ │ └── controllers
│ │ │ │ └── application-test.js
│ │ ├── integration
│ │ │ └── .gitkeep
│ │ ├── test-helper.js
│ │ └── index.html
│ │ ├── .watchmanconfig
│ │ ├── config
│ │ ├── optional-features.json
│ │ ├── targets.js
│ │ └── environment.js
│ │ ├── public
│ │ └── robots.txt
│ │ ├── .template-lintrc.js
│ │ ├── .ember-cli
│ │ ├── .eslintignore
│ │ ├── .travis.yml
│ │ ├── .editorconfig
│ │ ├── .gitignore
│ │ ├── testem.js
│ │ ├── ember-cli-build.js
│ │ ├── .eslintrc.js
│ │ ├── README.md
│ │ └── package.json
├── helpers
│ ├── sequence.ts
│ ├── utils.ts
│ └── test-runner.ts
└── run-test.ts
├── .eslintignore
├── .editorconfig
├── .prettierrc.js
├── bin
├── telemetry.js
└── cli.js
├── types
├── codemod-cli.d.ts
└── ember-codemods-telemetry-helpers.d.ts
├── .gitignore
├── helpers
└── types.ts
├── .github
├── dependabot.yml
└── workflows
│ ├── tests.yml
│ ├── publish.yml
│ └── plan-release.yml
├── tsconfig.json
├── .eslintrc.js
├── tsconfig.node16-strictest.json
├── README.md
├── LICENSE
├── RELEASE.md
├── .release-plan.json
├── package.json
└── CHANGELOG.md
/transforms/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/styles/app.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/vendor/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/vendor/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/styles/app.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/vendor/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/vendor/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/models/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/routes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/tests/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/models/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/routes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/styles/app.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/tests/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/models/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/routes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/tests/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/models/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/routes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/styles/app.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/tests/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/controllers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/tests/integration/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/controllers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/tests/integration/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/controllers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/tests/integration/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/controllers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/tests/integration/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/templates/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/templates/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/__testfixtures__/**/*.js
2 | **/fixtures/**
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/templates/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/templates/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {
2 | "ignore_dirs": ["tmp", "dist"]
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {
2 | "ignore_dirs": ["tmp", "dist"]
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {
2 | "ignore_dirs": ["tmp", "dist"]
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {
2 | "ignore_dirs": ["tmp", "dist"]
3 | }
4 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/paths.input.hbs:
--------------------------------------------------------------------------------
1 | {{foo-bar-baz}}
2 | {{baz}}
3 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/custom-helpers.input.hbs:
--------------------------------------------------------------------------------
1 | {{biz}}
2 | {{bang}}
3 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/custom-helpers.output.hbs:
--------------------------------------------------------------------------------
1 | {{biz}}
2 | {{bang}}
3 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/paths.output.hbs:
--------------------------------------------------------------------------------
1 | {{foo-bar-baz}}
2 | {{this.baz}}
3 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | indent_size = 2
6 | indent_style = space
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/config/optional-features.json:
--------------------------------------------------------------------------------
1 | {
2 | "jquery-integration": true
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/config/optional-features.json:
--------------------------------------------------------------------------------
1 | {
2 | "jquery-integration": true
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/config/optional-features.json:
--------------------------------------------------------------------------------
1 | {
2 | "jquery-integration": true
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/config/optional-features.json:
--------------------------------------------------------------------------------
1 | {
2 | "jquery-integration": true
3 | }
4 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/-helpers.json:
--------------------------------------------------------------------------------
1 | {
2 | "helpers": ["biz", "bang"]
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from 'ember-resolver';
2 |
3 | export default Resolver;
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from 'ember-resolver';
2 |
3 | export default Resolver;
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from 'ember-resolver';
2 |
3 | export default Resolver;
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from 'ember-resolver';
2 |
3 | export default Resolver;
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/.template-lintrc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | extends: 'recommended'
5 | };
6 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/.template-lintrc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | extends: 'recommended'
5 | };
6 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/.template-lintrc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | extends: 'recommended'
5 | };
6 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/.template-lintrc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | extends: 'recommended'
5 | };
6 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | singleQuote: true,
5 | trailingComma: 'es5',
6 | printWidth: 100,
7 | };
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/templates/application.hbs:
--------------------------------------------------------------------------------
1 | {{not false}}
2 |
3 | {{#if (not foo)}}
4 | {{foo}}
5 | {{/if}}
6 |
7 | {{outlet}}
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/templates/application.hbs:
--------------------------------------------------------------------------------
1 | {{not false}}
2 |
3 | {{#if (not this.foo)}}
4 | {{this.foo}}
5 | {{/if}}
6 |
7 | {{outlet}}
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/custom-helpers.options.json:
--------------------------------------------------------------------------------
1 | {
2 | "config": "./transforms/no-implicit-this/__testfixtures__/-helpers.json"
3 | }
4 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/controllers/application.js:
--------------------------------------------------------------------------------
1 | import Controller from '@ember/controller';
2 |
3 | export default Controller.extend({
4 | foo: 'foo',
5 | });
6 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/angle-brackets-without-params.input.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/angle-brackets-without-params.output.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/controllers/application.js:
--------------------------------------------------------------------------------
1 | import Controller from '@ember/controller';
2 |
3 | export default Controller.extend({
4 | foo: 'foo',
5 | });
6 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/comments.input.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{!-- foo bar --}}
4 | {{!-- {{foo-bar}} --}}
5 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/comments.output.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{!-- foo bar --}}
4 | {{!-- {{foo-bar}} --}}
5 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-without-params.input.hbs:
--------------------------------------------------------------------------------
1 | {{my-component}}
2 | {{a-helper}}
3 | {{foo}}
4 | {{property}}
5 | {{namespace/foo}}
6 | {{someGetter}}
7 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-without-params.output.hbs:
--------------------------------------------------------------------------------
1 | {{my-component}}
2 | {{a-helper}}
3 | {{foo}}
4 | {{this.property}}
5 | {{namespace/foo}}
6 | {{this.someGetter}}
7 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/batman.input.hbs:
--------------------------------------------------------------------------------
1 | {{addon-name$helper-name}}
2 | {{addon-name$component-name}}
3 |
4 |
5 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/batman.output.hbs:
--------------------------------------------------------------------------------
1 | {{addon-name$helper-name}}
2 | {{addon-name$component-name}}
3 |
4 |
5 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/templates/application.hbs:
--------------------------------------------------------------------------------
1 | {{!-- The following component displays Ember's default welcome message. --}}
2 |
3 | {{!-- Feel free to remove this! --}}
4 |
5 | {{outlet}}
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/templates/application.hbs:
--------------------------------------------------------------------------------
1 | {{!-- The following component displays Ember's default welcome message. --}}
2 |
3 | {{!-- Feel free to remove this! --}}
4 |
5 | {{outlet}}
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/-mock-telemetry.d.json.ts:
--------------------------------------------------------------------------------
1 | export type Telemetry = Record>;
2 |
3 | declare const telemetry: Telemetry;
4 |
5 | export default telemetry;
--------------------------------------------------------------------------------
/bin/telemetry.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict';
3 |
4 | const { gatherTelemetryForUrl, analyzeEmberObject } = require('ember-codemods-telemetry-helpers');
5 |
6 | gatherTelemetryForUrl(process.argv[2], analyzeEmberObject);
7 |
--------------------------------------------------------------------------------
/types/codemod-cli.d.ts:
--------------------------------------------------------------------------------
1 | import { JSCodeshift } from 'jscodeshift';
2 |
3 | declare module 'codemod-cli' {
4 | export function getOptions(): unknown;
5 | export function runTransformTest(options: Record): unknown;
6 | }
7 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/void-elements.input.hbs:
--------------------------------------------------------------------------------
1 |
6 |
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | coverage/
2 | node_modules
3 | tmp
4 | *.log
5 | test/**/yarn.lock
6 | test/**/*.js
7 | test/**/*.js.map
8 | transforms/**/*.js
9 | transforms/**/*.js.map
10 | helpers/**/*.js
11 | helpers/**/*.js.map
12 | !**/__testfixtures__/**/*
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/void-elements.output.hbs:
--------------------------------------------------------------------------------
1 |
6 |
7 |
--------------------------------------------------------------------------------
/helpers/types.ts:
--------------------------------------------------------------------------------
1 | /** Type predicate. Checks if the given value is a `Record`. */
2 | export function isRecord>(
3 | value: unknown
4 | ): value is R {
5 | return value !== null && typeof value === 'object';
6 | }
--------------------------------------------------------------------------------
/types/ember-codemods-telemetry-helpers.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'ember-codemods-telemetry-helpers' {
2 | export function getTelemetry(): unknown;
3 | export function getTelemetryFor(filePath: string): unknown;
4 | export function setTelemetry(telemetry: unknown): void;
5 | }
6 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/test.ts:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import { runTransformTest } from 'codemod-cli';
4 | import { setupTelemetry } from './test-helpers';
5 |
6 | setupTelemetry();
7 |
8 | runTransformTest({
9 | type: 'jscodeshift',
10 | name: 'no-implicit-this',
11 | });
12 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import Application from '../app';
2 | import config from '../config/environment';
3 | import { setApplication } from '@ember/test-helpers';
4 | import { start } from 'ember-qunit';
5 |
6 | setApplication(Application.create(config.APP));
7 |
8 | start();
9 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import Application from '../app';
2 | import config from '../config/environment';
3 | import { setApplication } from '@ember/test-helpers';
4 | import { start } from 'ember-qunit';
5 |
6 | setApplication(Application.create(config.APP));
7 |
8 | start();
9 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import Application from '../app';
2 | import config from '../config/environment';
3 | import { setApplication } from '@ember/test-helpers';
4 | import { start } from 'ember-qunit';
5 |
6 | setApplication(Application.create(config.APP));
7 |
8 | start();
9 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import Application from '../app';
2 | import config from '../config/environment';
3 | import { setApplication } from '@ember/test-helpers';
4 | import { start } from 'ember-qunit';
5 |
6 | setApplication(Application.create(config.APP));
7 |
8 | start();
9 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/angle-brackets-with-block-params.input.hbs:
--------------------------------------------------------------------------------
1 |
2 | {{foo}}
3 | {{hash.property}}
4 |
5 |
6 | {{property}}
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/angle-brackets-with-block-params.output.hbs:
--------------------------------------------------------------------------------
1 |
2 | {{foo}}
3 | {{hash.property}}
4 |
5 |
6 | {{property}}
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/router.js:
--------------------------------------------------------------------------------
1 | import EmberRouter from '@ember/routing/router';
2 | import config from './config/environment';
3 |
4 | const Router = EmberRouter.extend({
5 | location: config.locationType,
6 | rootURL: config.rootURL
7 | });
8 |
9 | Router.map(function() {
10 | });
11 |
12 | export default Router;
13 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/router.js:
--------------------------------------------------------------------------------
1 | import EmberRouter from '@ember/routing/router';
2 | import config from './config/environment';
3 |
4 | const Router = EmberRouter.extend({
5 | location: config.locationType,
6 | rootURL: config.rootURL
7 | });
8 |
9 | Router.map(function() {
10 | });
11 |
12 | export default Router;
13 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/router.js:
--------------------------------------------------------------------------------
1 | import EmberRouter from '@ember/routing/router';
2 | import config from './config/environment';
3 |
4 | const Router = EmberRouter.extend({
5 | location: config.locationType,
6 | rootURL: config.rootURL
7 | });
8 |
9 | Router.map(function() {
10 | });
11 |
12 | export default Router;
13 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/router.js:
--------------------------------------------------------------------------------
1 | import EmberRouter from '@ember/routing/router';
2 | import config from './config/environment';
3 |
4 | const Router = EmberRouter.extend({
5 | location: config.locationType,
6 | rootURL: config.rootURL
7 | });
8 |
9 | Router.map(function() {
10 | });
11 |
12 | export default Router;
13 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/.ember-cli:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | Ember CLI sends analytics information by default. The data is completely
4 | anonymous, but there are times when you might want to disable this behavior.
5 |
6 | Setting `disableAnalytics` to true will prevent any data from being sent.
7 | */
8 | "disableAnalytics": false
9 | }
10 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/.ember-cli:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | Ember CLI sends analytics information by default. The data is completely
4 | anonymous, but there are times when you might want to disable this behavior.
5 |
6 | Setting `disableAnalytics` to true will prevent any data from being sent.
7 | */
8 | "disableAnalytics": false
9 | }
10 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/.ember-cli:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | Ember CLI sends analytics information by default. The data is completely
4 | anonymous, but there are times when you might want to disable this behavior.
5 |
6 | Setting `disableAnalytics` to true will prevent any data from being sent.
7 | */
8 | "disableAnalytics": false
9 | }
10 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/.ember-cli:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | Ember CLI sends analytics information by default. The data is completely
4 | anonymous, but there are times when you might want to disable this behavior.
5 |
6 | Setting `disableAnalytics` to true will prevent any data from being sent.
7 | */
8 | "disableAnalytics": false
9 | }
10 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/has-block.input.hbs:
--------------------------------------------------------------------------------
1 | {{if hasBlock "block"}}
2 | {{#if hasBlock}}block{{/if}}
3 | {{if (has-block) "block"}}
4 | {{#if (has-block)}}block{{/if}}
5 | {{if (has-block "main") "block"}}
6 | {{#if (has-block "main")}}block{{/if}}
7 | {{if (has-block-params "main") "block"}}
8 | {{#if (has-block-params "main")}}block{{/if}}
9 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/has-block.output.hbs:
--------------------------------------------------------------------------------
1 | {{if hasBlock "block"}}
2 | {{#if hasBlock}}block{{/if}}
3 | {{if (has-block) "block"}}
4 | {{#if (has-block)}}block{{/if}}
5 | {{if (has-block "main") "block"}}
6 | {{#if (has-block "main")}}block{{/if}}
7 | {{if (has-block-params "main") "block"}}
8 | {{#if (has-block-params "main")}}block{{/if}}
9 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/.eslintignore:
--------------------------------------------------------------------------------
1 | # unconventional js
2 | /blueprints/*/files/
3 | /vendor/
4 |
5 | # compiled app
6 | /dist/
7 | /tmp/
8 |
9 | # dependencies
10 | /bower_components/
11 | /node_modules/
12 |
13 | # misc
14 | /coverage/
15 | !.*
16 |
17 | # ember-try
18 | /.node_modules.ember-try/
19 | /bower.json.ember-try
20 | /package.json.ember-try
21 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/.eslintignore:
--------------------------------------------------------------------------------
1 | # unconventional js
2 | /blueprints/*/files/
3 | /vendor/
4 |
5 | # compiled app
6 | /dist/
7 | /tmp/
8 |
9 | # dependencies
10 | /bower_components/
11 | /node_modules/
12 |
13 | # misc
14 | /coverage/
15 | !.*
16 |
17 | # ember-try
18 | /.node_modules.ember-try/
19 | /bower.json.ember-try
20 | /package.json.ember-try
21 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-with-wall-street-syntax.input.hbs:
--------------------------------------------------------------------------------
1 | {{my-addon$my-component foo}}
2 | {{my-addon$namespace::my-component @foo}}
3 | {{my-addon$namespace::my-component property}}
4 | {{my-addon$my-component (my-helper property)}}
5 | {{my-addon$my-component (my-helper "string")}}
6 | {{my-addon$namespace::my-component (my-helper 1)}}
7 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/.eslintignore:
--------------------------------------------------------------------------------
1 | # unconventional js
2 | /blueprints/*/files/
3 | /vendor/
4 |
5 | # compiled output
6 | /dist/
7 | /tmp/
8 |
9 | # dependencies
10 | /bower_components/
11 | /node_modules/
12 |
13 | # misc
14 | /coverage/
15 | !.*
16 |
17 | # ember-try
18 | /.node_modules.ember-try/
19 | /bower.json.ember-try
20 | /package.json.ember-try
21 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/.eslintignore:
--------------------------------------------------------------------------------
1 | # unconventional js
2 | /blueprints/*/files/
3 | /vendor/
4 |
5 | # compiled output
6 | /dist/
7 | /tmp/
8 |
9 | # dependencies
10 | /bower_components/
11 | /node_modules/
12 |
13 | # misc
14 | /coverage/
15 | !.*
16 |
17 | # ember-try
18 | /.node_modules.ember-try/
19 | /bower.json.ember-try
20 | /package.json.ember-try
21 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-with-positional-params.input.hbs:
--------------------------------------------------------------------------------
1 | {{my-component "string"}}
2 | {{my-component 1}}
3 | {{my-component foo}}
4 | {{my-component @foo}}
5 | {{my-component property}}
6 | {{my-component (my-helper property)}}
7 | {{my-component (my-helper "string")}}
8 | {{my-component (my-helper 1)}}
9 | {{get this 'key'}}
10 |
11 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-with-positional-params.output.hbs:
--------------------------------------------------------------------------------
1 | {{my-component "string"}}
2 | {{my-component 1}}
3 | {{my-component this.foo}}
4 | {{my-component @foo}}
5 | {{my-component this.property}}
6 | {{my-component (my-helper this.property)}}
7 | {{my-component (my-helper "string")}}
8 | {{my-component (my-helper 1)}}
9 | {{get this 'key'}}
10 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-with-wall-street-syntax.output.hbs:
--------------------------------------------------------------------------------
1 | {{my-addon$my-component this.foo}}
2 | {{my-addon$namespace::my-component @foo}}
3 | {{my-addon$namespace::my-component this.property}}
4 | {{my-addon$my-component (my-helper this.property)}}
5 | {{my-addon$my-component (my-helper "string")}}
6 | {{my-addon$namespace::my-component (my-helper 1)}}
7 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 | node_js:
4 | - "8"
5 |
6 | sudo: false
7 | dist: trusty
8 |
9 | addons:
10 | chrome: stable
11 |
12 | cache:
13 | directories:
14 | - $HOME/.npm
15 |
16 | env:
17 | global:
18 | # See https://git.io/vdao3 for details.
19 | - JOBS=1
20 |
21 | script:
22 | - npm run lint:hbs
23 | - npm run lint:js
24 | - npm test
25 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 | node_js:
4 | - "8"
5 |
6 | sudo: false
7 | dist: trusty
8 |
9 | addons:
10 | chrome: stable
11 |
12 | cache:
13 | directories:
14 | - $HOME/.npm
15 |
16 | env:
17 | global:
18 | # See https://git.io/vdao3 for details.
19 | - JOBS=1
20 |
21 | script:
22 | - npm run lint:hbs
23 | - npm run lint:js
24 | - npm test
25 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 | node_js:
4 | - "8"
5 |
6 | sudo: false
7 | dist: trusty
8 |
9 | addons:
10 | chrome: stable
11 |
12 | cache:
13 | directories:
14 | - $HOME/.npm
15 |
16 | env:
17 | global:
18 | # See https://git.io/vdao3 for details.
19 | - JOBS=1
20 |
21 | script:
22 | - npm run lint:hbs
23 | - npm run lint:js
24 | - npm test
25 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 | node_js:
4 | - "8"
5 |
6 | sudo: false
7 | dist: trusty
8 |
9 | addons:
10 | chrome: stable
11 |
12 | cache:
13 | directories:
14 | - $HOME/.npm
15 |
16 | env:
17 | global:
18 | # See https://git.io/vdao3 for details.
19 | - JOBS=1
20 |
21 | script:
22 | - npm run lint:hbs
23 | - npm run lint:js
24 | - npm test
25 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-with-hash-params.input.hbs:
--------------------------------------------------------------------------------
1 | {{my-component arg="string"}}
2 | {{my-component arg=2}}
3 | {{my-component arg=foo}}
4 | {{my-component arg=property}}
5 | {{my-component arg=(my-helper property)}}
6 | {{my-component arg=(my-helper (fn myAction property) foo)}}
7 | {{my-component arg=property arg2=foo}}
8 | {{my-component arg=property arg2=(fn myAction foo)}}
9 |
10 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/config/targets.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const browsers = [
4 | 'last 1 Chrome versions',
5 | 'last 1 Firefox versions',
6 | 'last 1 Safari versions'
7 | ];
8 |
9 | const isCI = !!process.env.CI;
10 | const isProduction = process.env.EMBER_ENV === 'production';
11 |
12 | if (isCI || isProduction) {
13 | browsers.push('ie 11');
14 | }
15 |
16 | module.exports = {
17 | browsers
18 | };
19 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/config/targets.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const browsers = [
4 | 'last 1 Chrome versions',
5 | 'last 1 Firefox versions',
6 | 'last 1 Safari versions'
7 | ];
8 |
9 | const isCI = !!process.env.CI;
10 | const isProduction = process.env.EMBER_ENV === 'production';
11 |
12 | if (isCI || isProduction) {
13 | browsers.push('ie 11');
14 | }
15 |
16 | module.exports = {
17 | browsers
18 | };
19 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/config/targets.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const browsers = [
4 | 'last 1 Chrome versions',
5 | 'last 1 Firefox versions',
6 | 'last 1 Safari versions'
7 | ];
8 |
9 | const isCI = !!process.env.CI;
10 | const isProduction = process.env.EMBER_ENV === 'production';
11 |
12 | if (isCI || isProduction) {
13 | browsers.push('ie 11');
14 | }
15 |
16 | module.exports = {
17 | browsers
18 | };
19 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/config/targets.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const browsers = [
4 | 'last 1 Chrome versions',
5 | 'last 1 Firefox versions',
6 | 'last 1 Safari versions'
7 | ];
8 |
9 | const isCI = !!process.env.CI;
10 | const isProduction = process.env.EMBER_ENV === 'production';
11 |
12 | if (isCI || isProduction) {
13 | browsers.push('ie 11');
14 | }
15 |
16 | module.exports = {
17 | browsers
18 | };
19 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-with-block-params.input.hbs:
--------------------------------------------------------------------------------
1 | {{#my-component as |foo myAction hash components|}}
2 | {{foo}} {{myAction}}
3 | {{hash.property}} {{hash.foo}}
4 |
5 | {{components.foo}}
6 |
7 | {{#components.my-component}}
8 |
9 | {{/components.my-component}}
10 |
11 | {{#components.block as |block|}}
12 | {{block}}
13 | {{/components.block}}
14 | {{/my-component}}
15 |
16 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-with-block-params.output.hbs:
--------------------------------------------------------------------------------
1 | {{#my-component as |foo myAction hash components|}}
2 | {{foo}} {{myAction}}
3 | {{hash.property}} {{hash.foo}}
4 |
5 | {{components.foo}}
6 |
7 | {{#components.my-component}}
8 |
9 | {{/components.my-component}}
10 |
11 | {{#components.block as |block|}}
12 | {{block}}
13 | {{/components.block}}
14 | {{/my-component}}
15 |
16 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/tests/unit/controllers/application-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Controller | application', function(hooks) {
5 | setupTest(hooks);
6 |
7 | // Replace this with your real tests.
8 | test('it exists', function(assert) {
9 | let controller = this.owner.lookup('controller:application');
10 | assert.ok(controller);
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/tests/unit/controllers/application-test.js:
--------------------------------------------------------------------------------
1 | import { module, test } from 'qunit';
2 | import { setupTest } from 'ember-qunit';
3 |
4 | module('Unit | Controller | application', function(hooks) {
5 | setupTest(hooks);
6 |
7 | // Replace this with your real tests.
8 | test('it exists', function(assert) {
9 | let controller = this.owner.lookup('controller:application');
10 | assert.ok(controller);
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/tagged-templates-ts.input.ts:
--------------------------------------------------------------------------------
1 | import { hbs as echHBS } from 'ember-cli-htmlbars';
2 | import hipHBS from 'htmlbars-inline-precompile';
3 | import echipHBS from 'ember-cli-htmlbars-inline-precompile';
4 |
5 | declare const hbs: unknown;
6 |
7 | echHBS`
8 | Hello,
9 | {{target}}!
10 | \n
11 | `;
12 |
13 | hipHBS`Hello, {{target}}!`;
14 |
15 | echipHBS`Hello, {{target}}!`;
16 |
17 | hbs`Hello, {{target}}!`;
18 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/app.js:
--------------------------------------------------------------------------------
1 | import Application from '@ember/application';
2 | import Resolver from './resolver';
3 | import loadInitializers from 'ember-load-initializers';
4 | import config from './config/environment';
5 |
6 | const App = Application.extend({
7 | modulePrefix: config.modulePrefix,
8 | podModulePrefix: config.podModulePrefix,
9 | Resolver
10 | });
11 |
12 | loadInitializers(App, config.modulePrefix);
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/app.js:
--------------------------------------------------------------------------------
1 | import Application from '@ember/application';
2 | import Resolver from './resolver';
3 | import loadInitializers from 'ember-load-initializers';
4 | import config from './config/environment';
5 |
6 | const App = Application.extend({
7 | modulePrefix: config.modulePrefix,
8 | podModulePrefix: config.podModulePrefix,
9 | Resolver
10 | });
11 |
12 | loadInitializers(App, config.modulePrefix);
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/app.js:
--------------------------------------------------------------------------------
1 | import Application from '@ember/application';
2 | import Resolver from './resolver';
3 | import loadInitializers from 'ember-load-initializers';
4 | import config from './config/environment';
5 |
6 | const App = Application.extend({
7 | modulePrefix: config.modulePrefix,
8 | podModulePrefix: config.podModulePrefix,
9 | Resolver
10 | });
11 |
12 | loadInitializers(App, config.modulePrefix);
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/app.js:
--------------------------------------------------------------------------------
1 | import Application from '@ember/application';
2 | import Resolver from './resolver';
3 | import loadInitializers from 'ember-load-initializers';
4 | import config from './config/environment';
5 |
6 | const App = Application.extend({
7 | modulePrefix: config.modulePrefix,
8 | podModulePrefix: config.podModulePrefix,
9 | Resolver
10 | });
11 |
12 | loadInitializers(App, config.modulePrefix);
13 |
14 | export default App;
15 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/handlebars-with-hash-params.output.hbs:
--------------------------------------------------------------------------------
1 | {{my-component arg="string"}}
2 | {{my-component arg=2}}
3 | {{my-component arg=this.foo}}
4 | {{my-component arg=this.property}}
5 | {{my-component arg=(my-helper this.property)}}
6 | {{my-component arg=(my-helper (fn this.myAction this.property) this.foo)}}
7 | {{my-component arg=this.property arg2=this.foo}}
8 | {{my-component arg=this.property arg2=(fn this.myAction this.foo)}}
9 |
10 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/tagged-templates-js.input.js:
--------------------------------------------------------------------------------
1 | import { hbs as echHBS } from 'ember-cli-htmlbars';
2 | import hipHBS from 'htmlbars-inline-precompile';
3 | import echipHBS from 'ember-cli-htmlbars-inline-precompile';
4 | import { hbs } from 'unknown-tag-source';
5 |
6 | echHBS`
7 | Hello,
8 | {{target}}!
9 | \n
10 | `;
11 |
12 | hipHBS`Hello, {{target}}!`;
13 |
14 | echipHBS`Hello, {{target}}!`;
15 |
16 | hbs`Hello, {{target}}!`;
17 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/tagged-templates-ts.output.ts:
--------------------------------------------------------------------------------
1 | import { hbs as echHBS } from 'ember-cli-htmlbars';
2 | import hipHBS from 'htmlbars-inline-precompile';
3 | import echipHBS from 'ember-cli-htmlbars-inline-precompile';
4 |
5 | declare const hbs: unknown;
6 |
7 | echHBS`
8 | Hello,
9 | {{this.target}}!
10 | \n
11 | `;
12 |
13 | hipHBS`Hello, {{this.target}}!`;
14 |
15 | echipHBS`Hello, {{this.target}}!`;
16 |
17 | hbs`Hello, {{target}}!`;
18 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/tagged-templates-js.output.js:
--------------------------------------------------------------------------------
1 | import { hbs as echHBS } from 'ember-cli-htmlbars';
2 | import hipHBS from 'htmlbars-inline-precompile';
3 | import echipHBS from 'ember-cli-htmlbars-inline-precompile';
4 | import { hbs } from 'unknown-tag-source';
5 |
6 | echHBS`
7 | Hello,
8 | {{this.target}}!
9 | \n
10 | `;
11 |
12 | hipHBS`Hello, {{this.target}}!`;
13 |
14 | echipHBS`Hello, {{this.target}}!`;
15 |
16 | hbs`Hello, {{target}}!`;
17 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 | indent_style = space
14 | indent_size = 2
15 |
16 | [*.hbs]
17 | insert_final_newline = false
18 |
19 | [*.{diff,md}]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 | indent_style = space
14 | indent_size = 2
15 |
16 | [*.hbs]
17 | insert_final_newline = false
18 |
19 | [*.{diff,md}]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 | indent_style = space
14 | indent_size = 2
15 |
16 | [*.hbs]
17 | insert_final_newline = false
18 |
19 | [*.{diff,md}]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 | indent_style = space
14 | indent_size = 2
15 |
16 | [*.hbs]
17 | insert_final_newline = false
18 |
19 | [*.{diff,md}]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/-mock-telemetry.json:
--------------------------------------------------------------------------------
1 | {
2 | "some-component": { "type": "Component" },
3 | "my-component": { "type": "Component" },
4 | "namespace/my-component": { "type": "Component" },
5 | "block-component": { "type": "Component" },
6 | "foo": { "type": "Component" },
7 | "namespace/foo": { "type": "Component" },
8 | "my-helper": { "type": "Helper" },
9 | "a-helper": { "type": "Helper" },
10 | "foo-bar-baz": { "type": "Component" }
11 | }
12 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: npm
4 | directory: "/"
5 | groups:
6 | dev-dependencies:
7 | dependency-type: "development"
8 | update-types:
9 | - "minor"
10 | - "patch"
11 | schedule:
12 | interval: weekly
13 | open-pull-requests-limit: 10
14 | versioning-strategy: increase
15 | - package-ecosystem: github-actions
16 | directory: "/"
17 | schedule:
18 | interval: weekly
19 | open-pull-requests-limit: 10
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/built-in-helpers.input.hbs:
--------------------------------------------------------------------------------
1 | {{debugger}}
2 | {{has-block}}
3 | {{hasBlock}}
4 | {{input}}
5 | {{outlet}}
6 | {{textarea}}
7 | {{yield}}
8 |
9 | {{#let (concat "a" "b") as |ab|}}
10 | {{ab}}
11 | {{/let}}
12 |
13 | {{#each records as |record|}}
14 | {{record.property}}
15 | {{/each}}
16 |
17 |
18 |
19 |
20 |
21 | {{link-to 'name' 'route'}}
22 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled app
4 | /dist/
5 | /tmp/
6 |
7 | # dependencies
8 | /bower_components/
9 | /node_modules/
10 |
11 | # misc
12 | /.env*
13 | /.pnp*
14 | /.sass-cache
15 | /connect.lock
16 | /coverage/
17 | /libpeerconnection.log
18 | /npm-debug.log*
19 | /testem.log
20 | /yarn-error.log
21 |
22 | # ember-try
23 | /.node_modules.ember-try/
24 | /bower.json.ember-try
25 | /package.json.ember-try
26 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled app
4 | /dist/
5 | /tmp/
6 |
7 | # dependencies
8 | /bower_components/
9 | /node_modules/
10 |
11 | # misc
12 | /.env*
13 | /.pnp*
14 | /.sass-cache
15 | /connect.lock
16 | /coverage/
17 | /libpeerconnection.log
18 | /npm-debug.log*
19 | /testem.log
20 | /yarn-error.log
21 |
22 | # ember-try
23 | /.node_modules.ember-try/
24 | /bower.json.ember-try
25 | /package.json.ember-try
26 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist/
5 | /tmp/
6 |
7 | # dependencies
8 | /bower_components/
9 | /node_modules/
10 |
11 | # misc
12 | /.env*
13 | /.pnp*
14 | /.sass-cache
15 | /connect.lock
16 | /coverage/
17 | /libpeerconnection.log
18 | /npm-debug.log*
19 | /testem.log
20 | /yarn-error.log
21 |
22 | # ember-try
23 | /.node_modules.ember-try/
24 | /bower.json.ember-try
25 | /package.json.ember-try
26 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist/
5 | /tmp/
6 |
7 | # dependencies
8 | /bower_components/
9 | /node_modules/
10 |
11 | # misc
12 | /.env*
13 | /.pnp*
14 | /.sass-cache
15 | /connect.lock
16 | /coverage/
17 | /libpeerconnection.log
18 | /npm-debug.log*
19 | /testem.log
20 | /yarn-error.log
21 |
22 | # ember-try
23 | /.node_modules.ember-try/
24 | /bower.json.ember-try
25 | /package.json.ember-try
26 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/built-in-helpers.output.hbs:
--------------------------------------------------------------------------------
1 | {{debugger}}
2 | {{has-block}}
3 | {{hasBlock}}
4 | {{input}}
5 | {{outlet}}
6 | {{textarea}}
7 | {{yield}}
8 |
9 | {{#let (concat "a" "b") as |ab|}}
10 | {{ab}}
11 | {{/let}}
12 |
13 | {{#each this.records as |record|}}
14 | {{record.property}}
15 | {{/each}}
16 |
17 |
18 |
19 |
20 |
21 | {{link-to 'name' 'route'}}
22 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/test-helpers.ts:
--------------------------------------------------------------------------------
1 | import { setTelemetry } from 'ember-codemods-telemetry-helpers';
2 | import path from 'node:path';
3 | import mockTelemetryData, { type Telemetry } from './__testfixtures__/-mock-telemetry.json';
4 |
5 | export function setupTelemetry() {
6 | let mockTelemetry: Telemetry = {};
7 |
8 | Object.keys(mockTelemetryData).forEach(key => {
9 | let value = mockTelemetryData[key] || {};
10 | let mockPath = path.resolve(__dirname, `./__testfixtures__/${key}`);
11 |
12 | mockTelemetry[mockPath] = value;
13 | });
14 |
15 | setTelemetry(mockTelemetry);
16 | }
17 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/angle-brackets-with-hash-params.input.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
17 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/__testfixtures__/angle-brackets-with-hash-params.output.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
17 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // TODO: Can use an array once ts-node is updated with https://github.com/TypeStrong/ts-node/pull/1958
3 | // "extends": ["@tsconfig/node16/tsconfig.json", "@tsconfig/strictest/tsconfig.json"],
4 | "extends": "./tsconfig.node16-strictest.json",
5 | "compilerOptions": {
6 | "sourceMap": true,
7 | "resolveJsonModule": true,
8 | "allowArbitraryExtensions": true,
9 | // FIXME: "skipLibCheck": false,
10 | "baseUrl": ".",
11 | "paths": {
12 | "*": ["types/*"]
13 | }
14 | },
15 | "include": ["transforms/**/*", "test/**/*", "helpers/**/*"],
16 | "exclude": ["**/__testfixtures__/**/*", "test/fixtures/**/*"]
17 | }
18 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/testem.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | test_page: 'tests/index.html?hidepassed',
3 | disable_watching: true,
4 | launch_in_ci: [
5 | 'Chrome'
6 | ],
7 | launch_in_dev: [
8 | 'Chrome'
9 | ],
10 | browser_args: {
11 | Chrome: {
12 | ci: [
13 | // --no-sandbox is needed when running Chrome inside a container
14 | process.env.CI ? '--no-sandbox' : null,
15 | '--headless',
16 | '--disable-gpu',
17 | '--disable-dev-shm-usage',
18 | '--disable-software-rasterizer',
19 | '--mute-audio',
20 | '--remote-debugging-port=0',
21 | '--window-size=1440,900'
22 | ].filter(Boolean)
23 | }
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/testem.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | test_page: 'tests/index.html?hidepassed',
3 | disable_watching: true,
4 | launch_in_ci: [
5 | 'Chrome'
6 | ],
7 | launch_in_dev: [
8 | 'Chrome'
9 | ],
10 | browser_args: {
11 | Chrome: {
12 | ci: [
13 | // --no-sandbox is needed when running Chrome inside a container
14 | process.env.CI ? '--no-sandbox' : null,
15 | '--headless',
16 | '--disable-gpu',
17 | '--disable-dev-shm-usage',
18 | '--disable-software-rasterizer',
19 | '--mute-audio',
20 | '--remote-debugging-port=0',
21 | '--window-size=1440,900'
22 | ].filter(Boolean)
23 | }
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/testem.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | test_page: 'tests/index.html?hidepassed',
3 | disable_watching: true,
4 | launch_in_ci: [
5 | 'Chrome'
6 | ],
7 | launch_in_dev: [
8 | 'Chrome'
9 | ],
10 | browser_args: {
11 | Chrome: {
12 | ci: [
13 | // --no-sandbox is needed when running Chrome inside a container
14 | process.env.CI ? '--no-sandbox' : null,
15 | '--headless',
16 | '--disable-gpu',
17 | '--disable-dev-shm-usage',
18 | '--disable-software-rasterizer',
19 | '--mute-audio',
20 | '--remote-debugging-port=0',
21 | '--window-size=1440,900'
22 | ].filter(Boolean)
23 | }
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/testem.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | test_page: 'tests/index.html?hidepassed',
3 | disable_watching: true,
4 | launch_in_ci: [
5 | 'Chrome'
6 | ],
7 | launch_in_dev: [
8 | 'Chrome'
9 | ],
10 | browser_args: {
11 | Chrome: {
12 | ci: [
13 | // --no-sandbox is needed when running Chrome inside a container
14 | process.env.CI ? '--no-sandbox' : null,
15 | '--headless',
16 | '--disable-gpu',
17 | '--disable-dev-shm-usage',
18 | '--disable-software-rasterizer',
19 | '--mute-audio',
20 | '--remote-debugging-port=0',
21 | '--window-size=1440,900'
22 | ].filter(Boolean)
23 | }
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/bin/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict';
3 |
4 | const debug = require('debug')('ember-no-implicit-this-codemod');
5 | const {
6 | gatherTelemetryForUrl,
7 | analyzeEmberObject,
8 | getTelemetry,
9 | } = require('ember-codemods-telemetry-helpers');
10 | const appLocation = process.argv[2];
11 | const args = process.argv.slice(3);
12 |
13 | (async () => {
14 | debug('Gathering telemetry data from %s ...', appLocation);
15 | await gatherTelemetryForUrl(appLocation, analyzeEmberObject);
16 |
17 | let telemetry = getTelemetry();
18 | debug('Gathered telemetry on %d modules', Object.keys(telemetry).length);
19 |
20 | require('codemod-cli').runTransform(__dirname, 'no-implicit-this', args, 'hbs');
21 | })();
22 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | App
7 |
8 |
9 |
10 | {{content-for "head"}}
11 |
12 |
13 |
14 |
15 | {{content-for "head-footer"}}
16 |
17 |
18 | {{content-for "body"}}
19 |
20 |
21 |
22 |
23 | {{content-for "body-footer"}}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | App
7 |
8 |
9 |
10 | {{content-for "head"}}
11 |
12 |
13 |
14 |
15 | {{content-for "head-footer"}}
16 |
17 |
18 | {{content-for "body"}}
19 |
20 |
21 |
22 |
23 | {{content-for "body-footer"}}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | App
7 |
8 |
9 |
10 | {{content-for "head"}}
11 |
12 |
13 |
14 |
15 | {{content-for "head-footer"}}
16 |
17 |
18 | {{content-for "body"}}
19 |
20 |
21 |
22 |
23 | {{content-for "body-footer"}}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | App
7 |
8 |
9 |
10 | {{content-for "head"}}
11 |
12 |
13 |
14 |
15 | {{content-for "head-footer"}}
16 |
17 |
18 | {{content-for "body"}}
19 |
20 |
21 |
22 |
23 | {{content-for "body-footer"}}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/test/helpers/sequence.ts:
--------------------------------------------------------------------------------
1 | import { TestRunner } from './test-runner';
2 | import { log } from './utils';
3 |
4 | export async function runTestIntegrationSequence(version: string) {
5 | const runner = new TestRunner(version);
6 |
7 | log(`Running Integration Test for Ember ${version}`);
8 | log(`Installing Dependencies`);
9 | await runner.installDeps();
10 |
11 | try {
12 | log(`Starting the Ember Dev Server`);
13 | await runner.startEmber();
14 | log(`Running Codemod`);
15 | await runner.runCodemod();
16 | log(`Stopping the Ember Dev Server`);
17 | await runner.stopEmber();
18 | } catch (e) {
19 | log(`Stopping the Ember Dev Server`);
20 | await runner.stopEmber();
21 | throw e;
22 | }
23 |
24 | log(`Comparing Results`);
25 | await runner.compare();
26 | log(`Success`);
27 | }
28 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/helpers/known-helpers.ts:
--------------------------------------------------------------------------------
1 | const KNOWN_HELPERS = [
2 | // Ember.js
3 | 'action',
4 | 'array',
5 | 'component',
6 | 'concat',
7 | 'debugger',
8 | 'each',
9 | 'each-in',
10 | 'else',
11 | 'fn',
12 | 'get',
13 | 'hash',
14 | 'has-block',
15 | 'has-block-params',
16 | 'if',
17 | 'if-unless',
18 | 'in-element',
19 | '-in-element',
20 | 'input',
21 | 'textarea',
22 | 'let',
23 | 'link-to',
24 | 'loc',
25 | 'log',
26 | 'mut',
27 | 'on',
28 | 'outlet',
29 | 'partial',
30 | 'query-params',
31 | 'readonly',
32 | 'unbound',
33 | 'unless',
34 | 'with',
35 | 'yield',
36 |
37 | // Glimmer VM
38 | 'identity', // glimmer blocks
39 | 'render-inverse', // glimmer blocks
40 | '-get-dynamic-var', // glimmer internal helper
41 | ];
42 |
43 | export default KNOWN_HELPERS;
44 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | ecmaVersion: 2017
5 | },
6 | env: {
7 | node: true,
8 | es6: true
9 | },
10 | extends: ["eslint:recommended", "prettier"],
11 | plugins: ["prettier"],
12 | rules: {
13 | "prettier/prettier": "error"
14 | },
15 | overrides: [
16 | {
17 | files: ['**/*.ts'],
18 | parser: '@typescript-eslint/parser',
19 | plugins: ['prettier', '@typescript-eslint'],
20 | extends: [
21 | 'eslint:recommended',
22 | 'plugin:@typescript-eslint/recommended',
23 | 'prettier',
24 | 'prettier/@typescript-eslint',
25 | ],
26 | },
27 | {
28 | files: ['**/*.test.js'],
29 | env: {
30 | jest: true
31 | }
32 | }
33 | ]
34 | };
35 |
--------------------------------------------------------------------------------
/tsconfig.node16-strictest.json:
--------------------------------------------------------------------------------
1 | // TODO: Can remove this once ts-node is updated with https://github.com/TypeStrong/ts-node/pull/1958
2 | {
3 | "extends": "@tsconfig/node16/tsconfig.json",
4 | "compilerOptions": {
5 | // The following are copied from @tsconfig/strictest/tsconfig.json
6 | "strict": true,
7 | "allowUnusedLabels": false,
8 | "allowUnreachableCode": false,
9 | "exactOptionalPropertyTypes": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "noImplicitOverride": true,
12 | "noImplicitReturns": true,
13 | "noPropertyAccessFromIndexSignature": true,
14 | "noUncheckedIndexedAccess": true,
15 | "noUnusedLocals": true,
16 | "noUnusedParameters": true,
17 | "checkJs": true,
18 | "esModuleInterop": true,
19 | "skipLibCheck": true,
20 | "forceConsistentCasingInFileNames": true
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/ember-cli-build.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const EmberApp = require('ember-cli/lib/broccoli/ember-app');
4 |
5 | module.exports = function(defaults) {
6 | let app = new EmberApp(defaults, {
7 | // Add options here
8 | });
9 |
10 | // Use `app.import` to add additional libraries to the generated
11 | // output files.
12 | //
13 | // If you need to use different assets in different
14 | // environments, specify an object as the first parameter. That
15 | // object's keys should be the environment name and the values
16 | // should be the asset to use in that environment.
17 | //
18 | // If the library that you are including contains AMD or ES6
19 | // modules that you would like to import into your application
20 | // please specify an object with the list of modules as keys
21 | // along with the exports of each module as its value.
22 |
23 | return app.toTree();
24 | };
25 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/ember-cli-build.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const EmberApp = require('ember-cli/lib/broccoli/ember-app');
4 |
5 | module.exports = function(defaults) {
6 | let app = new EmberApp(defaults, {
7 | // Add options here
8 | });
9 |
10 | // Use `app.import` to add additional libraries to the generated
11 | // app files.
12 | //
13 | // If you need to use different assets in different
14 | // environments, specify an object as the first parameter. That
15 | // object's keys should be the environment name and the values
16 | // should be the asset to use in that environment.
17 | //
18 | // If the library that you are including contains AMD or ES6
19 | // modules that you would like to import into your application
20 | // please specify an object with the list of modules as keys
21 | // along with the exports of each module as its value.
22 |
23 | return app.toTree();
24 | };
25 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/ember-cli-build.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const EmberApp = require('ember-cli/lib/broccoli/ember-app');
4 |
5 | module.exports = function(defaults) {
6 | let app = new EmberApp(defaults, {
7 | // Add options here
8 | });
9 |
10 | // Use `app.import` to add additional libraries to the generated
11 | // output files.
12 | //
13 | // If you need to use different assets in different
14 | // environments, specify an object as the first parameter. That
15 | // object's keys should be the environment name and the values
16 | // should be the asset to use in that environment.
17 | //
18 | // If the library that you are including contains AMD or ES6
19 | // modules that you would like to import into your application
20 | // please specify an object with the list of modules as keys
21 | // along with the exports of each module as its value.
22 |
23 | return app.toTree();
24 | };
25 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/ember-cli-build.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const EmberApp = require('ember-cli/lib/broccoli/ember-app');
4 |
5 | module.exports = function(defaults) {
6 | let app = new EmberApp(defaults, {
7 | // Add options here
8 | });
9 |
10 | // Use `app.import` to add additional libraries to the generated
11 | // app files.
12 | //
13 | // If you need to use different assets in different
14 | // environments, specify an object as the first parameter. That
15 | // object's keys should be the environment name and the values
16 | // should be the asset to use in that environment.
17 | //
18 | // If the library that you are including contains AMD or ES6
19 | // modules that you would like to import into your application
20 | // please specify an object with the list of modules as keys
21 | // along with the exports of each module as its value.
22 |
23 | return app.toTree();
24 | };
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ember-no-implicit-this-codemod
2 |
3 | [](https://travis-ci.com/ember-codemods/ember-no-implicit-this-codemod)
4 |
5 | [](https://www.npmjs.com/package/ember-no-implicit-this-codemod)
6 |
7 |
8 | ## Usage
9 |
10 | 1. Start your ember development server
11 | 2. Run Codemod, pointing it at the address of the development server
12 | ```
13 | npx ember-no-implicit-this-codemod http://localhost:4200 path/of/files/ or/some**/*glob.hbs
14 | ```
15 |
16 | ## Contributing
17 |
18 | ### Installation
19 |
20 | * clone the repo
21 | * change into the repo directory
22 | * `yarn`
23 |
24 | ### Running tests
25 |
26 | * `yarn test`
27 |
28 | #### Running a single test
29 |
30 | * `yarn test --runInBand --testNamePattern=void-elements`
31 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/helpers/parse.ts:
--------------------------------------------------------------------------------
1 | import type { ParserOptions } from '@babel/core';
2 | import { parse } from '@babel/parser';
3 | import type { Parser } from 'jscodeshift';
4 |
5 | // Inspired by https://github.com/ember-codemods/ember-component-template-colocation-migrator/blob/50c37e5ab8710ced7815dd6c968af97cade23aa4/lib/utils/js-parser.js#L7
6 |
7 | const options: ParserOptions = {
8 | sourceType: 'module',
9 | allowImportExportEverywhere: true,
10 | tokens: true,
11 | plugins: [
12 | // Without this, our @classic decorators cause this error:
13 | // > Using the export keyword between a decorator and a class is not allowed.
14 | // > Please use `export @dec class` instead.
15 | // Additionally, we have some users using legacy decorator features, such
16 | // as decorators in object literals
17 | 'decorators-legacy',
18 | 'exportDefaultFrom',
19 | 'typescript',
20 | ],
21 | };
22 |
23 | const parser: Parser = {
24 | parse(code) {
25 | return parse(code, options);
26 | },
27 | };
28 |
29 | export default parser;
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 ember-codemods
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | App Tests
7 |
8 |
9 |
10 | {{content-for "head"}}
11 | {{content-for "test-head"}}
12 |
13 |
14 |
15 |
16 |
17 | {{content-for "head-footer"}}
18 | {{content-for "test-head-footer"}}
19 |
20 |
21 | {{content-for "body"}}
22 | {{content-for "test-body"}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{content-for "body-footer"}}
31 | {{content-for "test-body-footer"}}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | App Tests
7 |
8 |
9 |
10 | {{content-for "head"}}
11 | {{content-for "test-head"}}
12 |
13 |
14 |
15 |
16 |
17 | {{content-for "head-footer"}}
18 | {{content-for "test-head-footer"}}
19 |
20 |
21 | {{content-for "body"}}
22 | {{content-for "test-body"}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{content-for "body-footer"}}
31 | {{content-for "test-body-footer"}}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | App Tests
7 |
8 |
9 |
10 | {{content-for "head"}}
11 | {{content-for "test-head"}}
12 |
13 |
14 |
15 |
16 |
17 | {{content-for "head-footer"}}
18 | {{content-for "test-head-footer"}}
19 |
20 |
21 | {{content-for "body"}}
22 | {{content-for "test-body"}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{content-for "body-footer"}}
31 | {{content-for "test-body-footer"}}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | App Tests
7 |
8 |
9 |
10 | {{content-for "head"}}
11 | {{content-for "test-head"}}
12 |
13 |
14 |
15 |
16 |
17 | {{content-for "head-footer"}}
18 | {{content-for "test-head-footer"}}
19 |
20 |
21 | {{content-for "body"}}
22 | {{content-for "test-body"}}
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{content-for "body-footer"}}
31 | {{content-for "test-body-footer"}}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 | on:
3 | pull_request:
4 | branches:
5 | - main
6 | - master
7 |
8 | jobs:
9 | tests:
10 | name: Unit Tests
11 | runs-on: ubuntu-latest
12 | timeout-minutes: 15
13 |
14 | steps:
15 | - uses: actions/checkout@v4
16 | - uses: pnpm/action-setup@v2
17 | with:
18 | version: 8
19 | - uses: actions/setup-node@v4
20 | with:
21 | node-version: '16.x'
22 | - name: Install
23 | run: pnpm install
24 | - name: Linting
25 | run: pnpm lint:js
26 | - name: Test
27 | run: pnpm run test --coverage
28 |
29 | integration_tests:
30 | name: Integration Tests
31 | strategy:
32 | matrix:
33 | ember_version: ['3.10', '3.13']
34 | runs-on: ubuntu-latest
35 | timeout-minutes: 15
36 |
37 | steps:
38 | - uses: actions/checkout@v4
39 | - uses: pnpm/action-setup@v2
40 | with:
41 | version: 8
42 | - uses: actions/setup-node@v4
43 | with:
44 | node-version: '16.x'
45 | - name: Install
46 | run: pnpm install
47 | - run: pnpm build
48 | - name: Test
49 | env:
50 | EMBER_VERSION: ${{ matrix.ember_version }}
51 | run: pnpm run test:integration
52 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | ecmaVersion: 2018,
5 | sourceType: 'module'
6 | },
7 | plugins: [
8 | 'ember'
9 | ],
10 | extends: [
11 | 'eslint:recommended',
12 | 'plugin:ember/recommended'
13 | ],
14 | env: {
15 | browser: true
16 | },
17 | rules: {
18 | },
19 | overrides: [
20 | // node files
21 | {
22 | files: [
23 | '.eslintrc.js',
24 | '.template-lintrc.js',
25 | 'ember-cli-build.js',
26 | 'testem.js',
27 | 'blueprints/*/index.js',
28 | 'config/**/*.js',
29 | 'lib/*/index.js',
30 | 'server/**/*.js'
31 | ],
32 | parserOptions: {
33 | sourceType: 'script',
34 | ecmaVersion: 2015
35 | },
36 | env: {
37 | browser: false,
38 | node: true
39 | },
40 | plugins: ['node'],
41 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, {
42 | // add your custom rules and overrides for node files here
43 |
44 | // this can be removed once the following is fixed
45 | // https://github.com/mysticatea/eslint-plugin-node/issues/77
46 | 'node/no-unpublished-require': 'off'
47 | })
48 | }
49 | ]
50 | };
51 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | ecmaVersion: 2018,
5 | sourceType: 'module'
6 | },
7 | plugins: [
8 | 'ember'
9 | ],
10 | extends: [
11 | 'eslint:recommended',
12 | 'plugin:ember/recommended'
13 | ],
14 | env: {
15 | browser: true
16 | },
17 | rules: {
18 | },
19 | overrides: [
20 | // node files
21 | {
22 | files: [
23 | '.eslintrc.js',
24 | '.template-lintrc.js',
25 | 'ember-cli-build.js',
26 | 'testem.js',
27 | 'blueprints/*/index.js',
28 | 'config/**/*.js',
29 | 'lib/*/index.js',
30 | 'server/**/*.js'
31 | ],
32 | parserOptions: {
33 | sourceType: 'script',
34 | ecmaVersion: 2015
35 | },
36 | env: {
37 | browser: false,
38 | node: true
39 | },
40 | plugins: ['node'],
41 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, {
42 | // add your custom rules and overrides for node files here
43 |
44 | // this can be removed once the following is fixed
45 | // https://github.com/mysticatea/eslint-plugin-node/issues/77
46 | 'node/no-unpublished-require': 'off'
47 | })
48 | }
49 | ]
50 | };
51 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | ecmaVersion: 2018,
5 | sourceType: 'module'
6 | },
7 | plugins: [
8 | 'ember'
9 | ],
10 | extends: [
11 | 'eslint:recommended',
12 | 'plugin:ember/recommended'
13 | ],
14 | env: {
15 | browser: true
16 | },
17 | rules: {
18 | },
19 | overrides: [
20 | // node files
21 | {
22 | files: [
23 | '.eslintrc.js',
24 | '.template-lintrc.js',
25 | 'ember-cli-build.js',
26 | 'testem.js',
27 | 'blueprints/*/index.js',
28 | 'config/**/*.js',
29 | 'lib/*/index.js',
30 | 'server/**/*.js'
31 | ],
32 | parserOptions: {
33 | sourceType: 'script',
34 | ecmaVersion: 2015
35 | },
36 | env: {
37 | browser: false,
38 | node: true
39 | },
40 | plugins: ['node'],
41 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, {
42 | // add your custom rules and overrides for node files here
43 |
44 | // this can be removed once the following is fixed
45 | // https://github.com/mysticatea/eslint-plugin-node/issues/77
46 | 'node/no-unpublished-require': 'off'
47 | })
48 | }
49 | ]
50 | };
51 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parserOptions: {
4 | ecmaVersion: 2018,
5 | sourceType: 'module'
6 | },
7 | plugins: [
8 | 'ember'
9 | ],
10 | extends: [
11 | 'eslint:recommended',
12 | 'plugin:ember/recommended'
13 | ],
14 | env: {
15 | browser: true
16 | },
17 | rules: {
18 | },
19 | overrides: [
20 | // node files
21 | {
22 | files: [
23 | '.eslintrc.js',
24 | '.template-lintrc.js',
25 | 'ember-cli-build.js',
26 | 'testem.js',
27 | 'blueprints/*/index.js',
28 | 'config/**/*.js',
29 | 'lib/*/index.js',
30 | 'server/**/*.js'
31 | ],
32 | parserOptions: {
33 | sourceType: 'script',
34 | ecmaVersion: 2015
35 | },
36 | env: {
37 | browser: false,
38 | node: true
39 | },
40 | plugins: ['node'],
41 | rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, {
42 | // add your custom rules and overrides for node files here
43 |
44 | // this can be removed once the following is fixed
45 | // https://github.com/mysticatea/eslint-plugin-node/issues/77
46 | 'node/no-unpublished-require': 'off'
47 | })
48 | }
49 | ]
50 | };
51 |
--------------------------------------------------------------------------------
/test/helpers/utils.ts:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk';
2 | import execa from 'execa';
3 | import { isRecord } from '../../helpers/types';
4 |
5 | export function log(msg: unknown): void {
6 | console.log(chalk.yellowBright(msg));
7 | }
8 |
9 | export function error(msg: unknown): void {
10 | console.error(chalk.redBright(msg));
11 | }
12 |
13 | export function timeoutAfter(ms: number, promise: Promise) {
14 | const timeout = new Promise((_, reject) => {
15 | const id = setTimeout(() => {
16 | clearTimeout(id);
17 | reject(`Timed out after ${ms}ms`);
18 | }, ms);
19 | });
20 |
21 | return Promise.race([promise, timeout]);
22 | }
23 |
24 | export async function kill(subprocess: execa.ExecaChildProcess): Promise {
25 | if (!subprocess || !subprocess.pid) {
26 | throw new Error('Cannot kill non-running process');
27 | }
28 |
29 | try {
30 | console.log(`Requesting SIGTERM of ember serve: (PID) ${subprocess.pid}`);
31 |
32 | process.kill(subprocess.pid);
33 | } catch (e) {
34 | console.log(`PID ${subprocess.pid} has stopped.`);
35 | console.log(`\tKilled: ${subprocess.killed}`);
36 | console.log(`\tCancelled: ${isRecord(e) ? e['isCanceled']: 'unknown'}`);
37 | }
38 |
39 | return new Promise(resolve => {
40 | setTimeout(() => resolve(), 3000);
41 | });
42 | }
43 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/config/environment.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(environment) {
4 | let ENV = {
5 | modulePrefix: 'app',
6 | environment,
7 | rootURL: '/',
8 | locationType: 'auto',
9 | EmberENV: {
10 | FEATURES: {
11 | // Here you can enable experimental features on an ember canary build
12 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
13 | },
14 | EXTEND_PROTOTYPES: {
15 | // Prevent Ember Data from overriding Date.parse.
16 | Date: false
17 | }
18 | },
19 |
20 | APP: {
21 | // Here you can pass flags/options to your application instance
22 | // when it is created
23 | }
24 | };
25 |
26 | if (environment === 'development') {
27 | // ENV.APP.LOG_RESOLVER = true;
28 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
29 | // ENV.APP.LOG_TRANSITIONS = true;
30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
31 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
32 | }
33 |
34 | if (environment === 'test') {
35 | // Testem prefers this...
36 | ENV.locationType = 'none';
37 |
38 | // keep test console output quieter
39 | ENV.APP.LOG_ACTIVE_GENERATION = false;
40 | ENV.APP.LOG_VIEW_LOOKUPS = false;
41 |
42 | ENV.APP.rootElement = '#ember-testing';
43 | ENV.APP.autoboot = false;
44 | }
45 |
46 | if (environment === 'production') {
47 | // here you can enable a production-specific feature
48 | }
49 |
50 | return ENV;
51 | };
52 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/config/environment.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(environment) {
4 | let ENV = {
5 | modulePrefix: 'app',
6 | environment,
7 | rootURL: '/',
8 | locationType: 'auto',
9 | EmberENV: {
10 | FEATURES: {
11 | // Here you can enable experimental features on an ember canary build
12 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
13 | },
14 | EXTEND_PROTOTYPES: {
15 | // Prevent Ember Data from overriding Date.parse.
16 | Date: false
17 | }
18 | },
19 |
20 | APP: {
21 | // Here you can pass flags/options to your application instance
22 | // when it is created
23 | }
24 | };
25 |
26 | if (environment === 'development') {
27 | // ENV.APP.LOG_RESOLVER = true;
28 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
29 | // ENV.APP.LOG_TRANSITIONS = true;
30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
31 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
32 | }
33 |
34 | if (environment === 'test') {
35 | // Testem prefers this...
36 | ENV.locationType = 'none';
37 |
38 | // keep test console app quieter
39 | ENV.APP.LOG_ACTIVE_GENERATION = false;
40 | ENV.APP.LOG_VIEW_LOOKUPS = false;
41 |
42 | ENV.APP.rootElement = '#ember-testing';
43 | ENV.APP.autoboot = false;
44 | }
45 |
46 | if (environment === 'production') {
47 | // here you can enable a production-specific feature
48 | }
49 |
50 | return ENV;
51 | };
52 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/config/environment.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(environment) {
4 | let ENV = {
5 | modulePrefix: 'app',
6 | environment,
7 | rootURL: '/',
8 | locationType: 'auto',
9 | EmberENV: {
10 | FEATURES: {
11 | // Here you can enable experimental features on an ember canary build
12 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
13 | },
14 | EXTEND_PROTOTYPES: {
15 | // Prevent Ember Data from overriding Date.parse.
16 | Date: false
17 | }
18 | },
19 |
20 | APP: {
21 | // Here you can pass flags/options to your application instance
22 | // when it is created
23 | }
24 | };
25 |
26 | if (environment === 'development') {
27 | // ENV.APP.LOG_RESOLVER = true;
28 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
29 | // ENV.APP.LOG_TRANSITIONS = true;
30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
31 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
32 | }
33 |
34 | if (environment === 'test') {
35 | // Testem prefers this...
36 | ENV.locationType = 'none';
37 |
38 | // keep test console output quieter
39 | ENV.APP.LOG_ACTIVE_GENERATION = false;
40 | ENV.APP.LOG_VIEW_LOOKUPS = false;
41 |
42 | ENV.APP.rootElement = '#ember-testing';
43 | ENV.APP.autoboot = false;
44 | }
45 |
46 | if (environment === 'production') {
47 | // here you can enable a production-specific feature
48 | }
49 |
50 | return ENV;
51 | };
52 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/config/environment.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(environment) {
4 | let ENV = {
5 | modulePrefix: 'app',
6 | environment,
7 | rootURL: '/',
8 | locationType: 'auto',
9 | EmberENV: {
10 | FEATURES: {
11 | // Here you can enable experimental features on an ember canary build
12 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true
13 | },
14 | EXTEND_PROTOTYPES: {
15 | // Prevent Ember Data from overriding Date.parse.
16 | Date: false
17 | }
18 | },
19 |
20 | APP: {
21 | // Here you can pass flags/options to your application instance
22 | // when it is created
23 | }
24 | };
25 |
26 | if (environment === 'development') {
27 | // ENV.APP.LOG_RESOLVER = true;
28 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
29 | // ENV.APP.LOG_TRANSITIONS = true;
30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
31 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
32 | }
33 |
34 | if (environment === 'test') {
35 | // Testem prefers this...
36 | ENV.locationType = 'none';
37 |
38 | // keep test console app quieter
39 | ENV.APP.LOG_ACTIVE_GENERATION = false;
40 | ENV.APP.LOG_VIEW_LOOKUPS = false;
41 |
42 | ENV.APP.rootElement = '#ember-testing';
43 | ENV.APP.autoboot = false;
44 | }
45 |
46 | if (environment === 'production') {
47 | // here you can enable a production-specific feature
48 | }
49 |
50 | return ENV;
51 | };
52 |
--------------------------------------------------------------------------------
/test/run-test.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 |
3 | import { stripIndent } from 'common-tags';
4 |
5 | import { error } from './helpers/utils';
6 | import { runTestIntegrationSequence } from './helpers/sequence';
7 |
8 | const allVersions = ['3.10', '3.13'];
9 |
10 | (async (): Promise => {
11 | const emberVersion = process.env['EMBER_VERSION'];
12 |
13 | if (!emberVersion) {
14 | console.error(`No EMBER_VERSION set. No scenarios to run.`);
15 | process.exit(1);
16 | }
17 |
18 | if (!allVersions.includes(`${emberVersion}`)) {
19 | console.error(`EMBER_VERSION is not allowed. Available: ${allVersions.join(', ')}`);
20 | process.exit(1);
21 | }
22 |
23 | let didSucceed = false;
24 |
25 | try {
26 | process.env['DEBUG'] = 'true'; // hacks for now
27 | await runTestIntegrationSequence(emberVersion);
28 | didSucceed = true;
29 | } catch (e) {
30 | error(e);
31 |
32 | didSucceed = false;
33 | } finally {
34 | // TODO: if there were any changes to the fixtures directories, revert them
35 | try {
36 | // const fixturePath = path.join(process.cwd(), 'test', 'fixtures', emberVersion);
37 | // await execa(`git checkout -- .`, { cwd: fixturePath });
38 | } catch (e) {
39 | error(stripIndent`
40 | There was a problem during cleanup.
41 | Do not commit any changes to the fixtures directory`);
42 | console.error(e);
43 | }
44 | }
45 |
46 | process.exit(didSucceed ? 0 : 1);
47 | })().catch(e => {
48 | console.error(e);
49 | process.exit(1);
50 | });
51 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/README.md:
--------------------------------------------------------------------------------
1 | # app
2 |
3 | This README outlines the details of collaborating on this Ember application.
4 | A short introduction of this app could easily go here.
5 |
6 | ## Prerequisites
7 |
8 | You will need the following things properly installed on your computer.
9 |
10 | * [Git](https://git-scm.com/)
11 | * [Node.js](https://nodejs.org/) (with npm)
12 | * [Ember CLI](https://ember-cli.com/)
13 | * [Google Chrome](https://google.com/chrome/)
14 |
15 | ## Installation
16 |
17 | * `git clone ` this repository
18 | * `cd app`
19 | * `npm install`
20 |
21 | ## Running / Development
22 |
23 | * `ember serve`
24 | * Visit your app at [http://localhost:4200](http://localhost:4200).
25 | * Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
26 |
27 | ### Code Generators
28 |
29 | Make use of the many generators for code, try `ember help generate` for more details
30 |
31 | ### Running Tests
32 |
33 | * `ember test`
34 | * `ember test --server`
35 |
36 | ### Linting
37 |
38 | * `npm run lint:hbs`
39 | * `npm run lint:js`
40 | * `npm run lint:js -- --fix`
41 |
42 | ### Building
43 |
44 | * `ember build` (development)
45 | * `ember build --environment production` (production)
46 |
47 | ### Deploying
48 |
49 | Specify what it takes to deploy your app.
50 |
51 | ## Further Reading / Useful Links
52 |
53 | * [ember.js](https://emberjs.com/)
54 | * [ember-cli](https://ember-cli.com/)
55 | * Development Browser Extensions
56 | * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
57 | * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
58 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/input/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app",
3 | "version": "0.0.0",
4 | "private": true,
5 | "description": "Small description for app goes here",
6 | "repository": "",
7 | "license": "MIT",
8 | "author": "",
9 | "directories": {
10 | "doc": "doc",
11 | "test": "tests"
12 | },
13 | "scripts": {
14 | "build": "ember build",
15 | "lint:hbs": "ember-template-lint .",
16 | "lint:js": "eslint .",
17 | "start": "ember serve",
18 | "test": "ember test"
19 | },
20 | "devDependencies": {
21 | "@ember/jquery": "^0.6.0",
22 | "@ember/optional-features": "^0.7.0",
23 | "broccoli-asset-rev": "^3.0.0",
24 | "ember-ajax": "^5.0.0",
25 | "ember-cli": "~3.10.1",
26 | "ember-cli-app-version": "^3.2.0",
27 | "ember-cli-babel": "^7.7.3",
28 | "ember-cli-dependency-checker": "^3.1.0",
29 | "ember-cli-eslint": "^5.1.0",
30 | "ember-cli-htmlbars": "^3.0.1",
31 | "ember-cli-htmlbars-inline-precompile": "^2.1.0",
32 | "ember-cli-inject-live-reload": "^1.8.2",
33 | "ember-cli-sri": "^2.1.1",
34 | "ember-cli-template-lint": "^1.0.0-beta.1",
35 | "ember-cli-uglify": "^2.1.0",
36 | "ember-data": "~3.10.0",
37 | "ember-export-application-global": "^2.0.0",
38 | "ember-load-initializers": "^2.0.0",
39 | "ember-maybe-import-regenerator": "^0.1.6",
40 | "ember-qunit": "^4.4.1",
41 | "ember-resolver": "^5.0.1",
42 | "ember-source": "~3.10.0",
43 | "ember-welcome-page": "^4.0.0",
44 | "eslint-plugin-ember": "^6.2.0",
45 | "eslint-plugin-node": "^9.0.1",
46 | "loader.js": "^4.7.0",
47 | "qunit-dom": "^0.8.4"
48 | },
49 | "engines": {
50 | "node": "8.* || >= 10.*"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/README.md:
--------------------------------------------------------------------------------
1 | # app
2 |
3 | This README outlines the details of collaborating on this Ember application.
4 | A short introduction of this app could easily go here.
5 |
6 | ## Prerequisites
7 |
8 | You will need the following things properly installed on your computer.
9 |
10 | * [Git](https://git-scm.com/)
11 | * [Node.js](https://nodejs.org/) (with npm)
12 | * [Ember CLI](https://ember-cli.com/)
13 | * [Google Chrome](https://google.com/chrome/)
14 |
15 | ## Installation
16 |
17 | * `git clone ` this repository
18 | * `cd app`
19 | * `npm install`
20 |
21 | ## Running / Development
22 |
23 | * `ember serve`
24 | * Visit your app at [http://localhost:4200](http://localhost:4200).
25 | * Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
26 |
27 | ### Code Generators
28 |
29 | Make use of the many generators for code, try `ember help generate` for more details
30 |
31 | ### Running Tests
32 |
33 | * `ember test`
34 | * `ember test --server`
35 |
36 | ### Linting
37 |
38 | * `npm run lint:hbs`
39 | * `npm run lint:js`
40 | * `npm run lint:js -- --fix`
41 |
42 | ### Building
43 |
44 | * `ember build` (development)
45 | * `ember build --environment production` (production)
46 |
47 | ### Deploying
48 |
49 | Specify what it takes to deploy your app.
50 |
51 | ## Further Reading / Useful Links
52 |
53 | * [ember.js](https://emberjs.com/)
54 | * [ember-cli](https://ember-cli.com/)
55 | * Development Browser Extensions
56 | * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
57 | * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
58 |
--------------------------------------------------------------------------------
/test/fixtures/3.10/output/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app",
3 | "version": "0.0.0",
4 | "private": true,
5 | "description": "Small description for app goes here",
6 | "repository": "",
7 | "license": "MIT",
8 | "author": "",
9 | "directories": {
10 | "doc": "doc",
11 | "test": "tests"
12 | },
13 | "scripts": {
14 | "build": "ember build",
15 | "lint:hbs": "ember-template-lint .",
16 | "lint:js": "eslint .",
17 | "start": "ember serve",
18 | "test": "ember test"
19 | },
20 | "devDependencies": {
21 | "@ember/jquery": "^0.6.0",
22 | "@ember/optional-features": "^0.7.0",
23 | "broccoli-asset-rev": "^3.0.0",
24 | "ember-ajax": "^5.0.0",
25 | "ember-cli": "~3.10.1",
26 | "ember-cli-app-version": "^3.2.0",
27 | "ember-cli-babel": "^7.7.3",
28 | "ember-cli-dependency-checker": "^3.1.0",
29 | "ember-cli-eslint": "^5.1.0",
30 | "ember-cli-htmlbars": "^3.0.1",
31 | "ember-cli-htmlbars-inline-precompile": "^2.1.0",
32 | "ember-cli-inject-live-reload": "^1.8.2",
33 | "ember-cli-sri": "^2.1.1",
34 | "ember-cli-template-lint": "^1.0.0-beta.1",
35 | "ember-cli-uglify": "^2.1.0",
36 | "ember-data": "~3.10.0",
37 | "ember-export-application-global": "^2.0.0",
38 | "ember-load-initializers": "^2.0.0",
39 | "ember-maybe-import-regenerator": "^0.1.6",
40 | "ember-qunit": "^4.4.1",
41 | "ember-resolver": "^5.0.1",
42 | "ember-source": "~3.10.0",
43 | "ember-welcome-page": "^4.0.0",
44 | "eslint-plugin-ember": "^6.2.0",
45 | "eslint-plugin-node": "^9.0.1",
46 | "loader.js": "^4.7.0",
47 | "qunit-dom": "^0.8.4"
48 | },
49 | "engines": {
50 | "node": "8.* || >= 10.*"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/README.md:
--------------------------------------------------------------------------------
1 | # app
2 |
3 | This README outlines the details of collaborating on this Ember application.
4 | A short introduction of this app could easily go here.
5 |
6 | ## Prerequisites
7 |
8 | You will need the following things properly installed on your computer.
9 |
10 | * [Git](https://git-scm.com/)
11 | * [Node.js](https://nodejs.org/) (with npm)
12 | * [Ember CLI](https://ember-cli.com/)
13 | * [Google Chrome](https://google.com/chrome/)
14 |
15 | ## Installation
16 |
17 | * `git clone ` this repository
18 | * `cd app`
19 | * `npm install`
20 |
21 | ## Running / Development
22 |
23 | * `ember serve`
24 | * Visit your app at [http://localhost:4200](http://localhost:4200).
25 | * Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
26 |
27 | ### Code Generators
28 |
29 | Make use of the many generators for code, try `ember help generate` for more details
30 |
31 | ### Running Tests
32 |
33 | * `ember test`
34 | * `ember test --server`
35 |
36 | ### Linting
37 |
38 | * `npm run lint:hbs`
39 | * `npm run lint:js`
40 | * `npm run lint:js -- --fix`
41 |
42 | ### Building
43 |
44 | * `ember build` (development)
45 | * `ember build --environment production` (production)
46 |
47 | ### Deploying
48 |
49 | Specify what it takes to deploy your app.
50 |
51 | ## Further Reading / Useful Links
52 |
53 | * [ember.js](https://emberjs.com/)
54 | * [ember-cli](https://ember-cli.com/)
55 | * Development Browser Extensions
56 | * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
57 | * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
58 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/README.md:
--------------------------------------------------------------------------------
1 | # app
2 |
3 | This README outlines the details of collaborating on this Ember application.
4 | A short introduction of this app could easily go here.
5 |
6 | ## Prerequisites
7 |
8 | You will need the following things properly installed on your computer.
9 |
10 | * [Git](https://git-scm.com/)
11 | * [Node.js](https://nodejs.org/) (with npm)
12 | * [Ember CLI](https://ember-cli.com/)
13 | * [Google Chrome](https://google.com/chrome/)
14 |
15 | ## Installation
16 |
17 | * `git clone ` this repository
18 | * `cd app`
19 | * `npm install`
20 |
21 | ## Running / Development
22 |
23 | * `ember serve`
24 | * Visit your app at [http://localhost:4200](http://localhost:4200).
25 | * Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
26 |
27 | ### Code Generators
28 |
29 | Make use of the many generators for code, try `ember help generate` for more details
30 |
31 | ### Running Tests
32 |
33 | * `ember test`
34 | * `ember test --server`
35 |
36 | ### Linting
37 |
38 | * `npm run lint:hbs`
39 | * `npm run lint:js`
40 | * `npm run lint:js -- --fix`
41 |
42 | ### Building
43 |
44 | * `ember build` (development)
45 | * `ember build --environment production` (production)
46 |
47 | ### Deploying
48 |
49 | Specify what it takes to deploy your app.
50 |
51 | ## Further Reading / Useful Links
52 |
53 | * [ember.js](https://emberjs.com/)
54 | * [ember-cli](https://ember-cli.com/)
55 | * Development Browser Extensions
56 | * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
57 | * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
58 |
--------------------------------------------------------------------------------
/RELEASE.md:
--------------------------------------------------------------------------------
1 | # Release Process
2 |
3 | Releases in this repo are mostly automated using [release-plan](https://github.com/embroider-build/release-plan/). Once you label all your PRs correctly (see below) you will have an automatically generated PR that updates your CHANGELOG.md file and a `.release-plan.json` that is used prepare the release once the PR is merged.
4 |
5 | ## Preparation
6 |
7 | Since the majority of the actual release process is automated, the remaining tasks before releasing are:
8 |
9 | - correctly labeling **all** pull requests that have been merged since the last release
10 | - updating pull request titles so they make sense to our users
11 |
12 | Some great information on why this is important can be found at [keepachangelog.com](https://keepachangelog.com/en/1.1.0/), but the overall
13 | guiding principle here is that changelogs are for humans, not machines.
14 |
15 | When reviewing merged PR's the labels to be used are:
16 |
17 | * breaking - Used when the PR is considered a breaking change.
18 | * enhancement - Used when the PR adds a new feature or enhancement.
19 | * bug - Used when the PR fixes a bug included in a previous release.
20 | * documentation - Used when the PR adds or updates documentation.
21 | * internal - Internal changes or things that don't fit in any other category.
22 |
23 | **Note:** `release-plan` requires that **all** PRs are labeled. If a PR doesn't fit in a category it's fine to label it as `internal`
24 |
25 | ## Release
26 |
27 | Once the prep work is completed, the actual release is straight forward: you just need to merge the open [Plan Release](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pulls?q=is%3Apr+is%3Aopen+%22Prepare+Release%22+in%3Atitle) PR
28 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/input/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app",
3 | "version": "0.0.0",
4 | "private": true,
5 | "description": "Small description for app goes here",
6 | "repository": "",
7 | "license": "MIT",
8 | "author": "",
9 | "directories": {
10 | "doc": "doc",
11 | "test": "tests"
12 | },
13 | "scripts": {
14 | "build": "ember build",
15 | "lint:hbs": "ember-template-lint .",
16 | "lint:js": "eslint .",
17 | "start": "ember serve",
18 | "test": "ember test"
19 | },
20 | "devDependencies": {
21 | "@ember/jquery": "^1.1.0",
22 | "@ember/optional-features": "^1.0.0",
23 | "broccoli-asset-rev": "^3.0.0",
24 | "ember-ajax": "^5.0.0",
25 | "ember-cli": "~3.13.1",
26 | "ember-cli-app-version": "^3.2.0",
27 | "ember-cli-babel": "^7.7.3",
28 | "ember-cli-dependency-checker": "^3.1.0",
29 | "ember-cli-eslint": "^5.1.0",
30 | "ember-cli-htmlbars": "^4.0.5",
31 | "ember-cli-htmlbars-inline-precompile": "^3.0.1",
32 | "ember-cli-inject-live-reload": "^2.0.2",
33 | "ember-cli-sri": "^2.1.1",
34 | "ember-cli-template-lint": "^1.0.0-beta.1",
35 | "ember-cli-uglify": "^3.0.0",
36 | "ember-data": "~3.13.1",
37 | "ember-export-application-global": "^2.0.0",
38 | "ember-load-initializers": "^2.0.0",
39 | "ember-maybe-import-regenerator": "^0.1.6",
40 | "ember-qunit": "^4.4.1",
41 | "ember-resolver": "^5.0.1",
42 | "ember-source": "~3.13.3",
43 | "ember-truth-helpers": "^2.1.0",
44 | "ember-welcome-page": "^4.0.0",
45 | "eslint-plugin-ember": "^7.1.0",
46 | "eslint-plugin-node": "^10.0.0",
47 | "loader.js": "^4.7.0",
48 | "qunit-dom": "^0.9.0"
49 | },
50 | "engines": {
51 | "node": "8.* || >= 10.*"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/test/fixtures/3.13/output/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app",
3 | "version": "0.0.0",
4 | "private": true,
5 | "description": "Small description for app goes here",
6 | "repository": "",
7 | "license": "MIT",
8 | "author": "",
9 | "directories": {
10 | "doc": "doc",
11 | "test": "tests"
12 | },
13 | "scripts": {
14 | "build": "ember build",
15 | "lint:hbs": "ember-template-lint .",
16 | "lint:js": "eslint .",
17 | "start": "ember serve",
18 | "test": "ember test"
19 | },
20 | "devDependencies": {
21 | "@ember/jquery": "^1.1.0",
22 | "@ember/optional-features": "^1.0.0",
23 | "broccoli-asset-rev": "^3.0.0",
24 | "ember-ajax": "^5.0.0",
25 | "ember-cli": "~3.13.1",
26 | "ember-cli-app-version": "^3.2.0",
27 | "ember-cli-babel": "^7.7.3",
28 | "ember-cli-dependency-checker": "^3.1.0",
29 | "ember-cli-eslint": "^5.1.0",
30 | "ember-cli-htmlbars": "^4.0.5",
31 | "ember-cli-htmlbars-inline-precompile": "^3.0.1",
32 | "ember-cli-inject-live-reload": "^2.0.2",
33 | "ember-cli-sri": "^2.1.1",
34 | "ember-cli-template-lint": "^1.0.0-beta.1",
35 | "ember-cli-uglify": "^3.0.0",
36 | "ember-data": "~3.13.1",
37 | "ember-export-application-global": "^2.0.0",
38 | "ember-load-initializers": "^2.0.0",
39 | "ember-maybe-import-regenerator": "^0.1.6",
40 | "ember-qunit": "^4.4.1",
41 | "ember-resolver": "^5.0.1",
42 | "ember-source": "~3.13.3",
43 | "ember-truth-helpers": "^2.1.0",
44 | "ember-welcome-page": "^4.0.0",
45 | "eslint-plugin-ember": "^7.1.0",
46 | "eslint-plugin-node": "^10.0.0",
47 | "loader.js": "^4.7.0",
48 | "qunit-dom": "^0.9.0"
49 | },
50 | "engines": {
51 | "node": "8.* || >= 10.*"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/helpers/telemetry.ts:
--------------------------------------------------------------------------------
1 | import { getTelemetry as getRawTelemetry } from 'ember-codemods-telemetry-helpers';
2 | import { z } from 'zod';
3 |
4 | const RuntimeData = z.object({
5 | type: z.string().optional(),
6 | computedProperties: z.array(z.string()).default([]),
7 | offProperties: z.record(z.array(z.string())).default({}),
8 | overriddenActions: z.array(z.string()).default([]),
9 | overriddenProperties: z.array(z.string()).default([]),
10 | unobservedProperties: z.record(z.array(z.string())).default({}),
11 | });
12 |
13 | type RuntimeData = z.infer;
14 |
15 | export const Telemetry = z.record(RuntimeData);
16 |
17 | export type Telemetry = z.infer;
18 |
19 | /**
20 | * Gets telemetry data and parses it into a valid `Telemetry` object.
21 | */
22 | export function getTelemetry(): Telemetry {
23 | let rawTelemetry = getRawTelemetry();
24 | if (!rawTelemetry) {
25 | // Do not re-throw. The most likely reason this happened was because
26 | // the user's app threw an error. We still want the codemod to work if so.
27 | // FIXME: debug log
28 | // logger.error({
29 | // filePath,
30 | // error: new RuntimeDataError('Could not find runtime data'),
31 | // });
32 | rawTelemetry = {};
33 | }
34 |
35 | const result = Telemetry.safeParse(rawTelemetry);
36 | if (result.success) {
37 | return result.data;
38 | } else {
39 | const { errors } = result.error;
40 | const messages = errors.map(error => {
41 | return `[${error.path.join('.')}]: ${error.message}`;
42 | });
43 | throw new TelemetryError(`Could not parse telemetry: \n\t${messages.join('\n\t')}`);
44 | }
45 | }
46 |
47 | class TelemetryError extends Error {
48 | constructor(message: string) {
49 | super(message);
50 | this.name = 'TelemetryError';
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/helpers/tagged-templates.ts:
--------------------------------------------------------------------------------
1 | import type { ASTNode } from 'ast-types';
2 | import { NodePath } from 'ast-types/lib/node-path';
3 |
4 | const TEMPLATE_TAG_IMPORTS = [
5 | { source: 'ember-cli-htmlbars', name: 'hbs' },
6 | { source: 'htmlbars-inline-precompile', name: 'default' },
7 | { source: 'ember-cli-htmlbars-inline-precompile', name: 'default' },
8 | ];
9 |
10 | // Identifies whether a TaggedTemplateExpression corresponds to an Ember template
11 | // using one of a known set of `hbs` tags.
12 | export function isEmberTemplate(path: NodePath) {
13 | let tag = path.get('tag');
14 | // @ts-expect-error FIXME: UGH
15 | let hasInterpolation = path.node.quasi.quasis.length !== 1;
16 | let isKnownTag = TEMPLATE_TAG_IMPORTS.some(({ source, name }) =>
17 | isImportReference(tag, source, name)
18 | );
19 |
20 | return isKnownTag && !hasInterpolation;
21 | }
22 |
23 | // Determines whether the given identifier is a reference to an export
24 | // from a particular module.
25 | function isImportReference(
26 | path: NodePath,
27 | importSource: string,
28 | importName: string
29 | ) {
30 | let scope = path.scope.lookup(path.node.name);
31 | let bindings = scope ? scope.getBindings() : {};
32 | let bindingIdentifiers = bindings[path.node.name] || [];
33 |
34 | for (let binding of bindingIdentifiers) {
35 | let specifier = binding.parent.node;
36 | let importDeclaration = binding.parent.parent.node;
37 | let bindingImportedName =
38 | specifier.type === 'ImportDefaultSpecifier'
39 | ? 'default'
40 | : specifier.type === 'ImportSpecifier'
41 | ? specifier.imported.name
42 | : null;
43 |
44 | if (bindingImportedName === importName && importDeclaration.source.value === importSource) {
45 | return true;
46 | }
47 | }
48 |
49 | return false;
50 | }
51 |
--------------------------------------------------------------------------------
/.release-plan.json:
--------------------------------------------------------------------------------
1 | {
2 | "solution": {
3 | "ember-no-implicit-this-codemod": {
4 | "impact": "major",
5 | "oldVersion": "2.1.0",
6 | "newVersion": "3.0.0",
7 | "constraints": [
8 | {
9 | "impact": "major",
10 | "reason": "Appears in changelog section :boom: Breaking Change"
11 | },
12 | {
13 | "impact": "minor",
14 | "reason": "Appears in changelog section :rocket: Enhancement"
15 | },
16 | {
17 | "impact": "patch",
18 | "reason": "Appears in changelog section :house: Internal"
19 | }
20 | ],
21 | "pkgJSONPath": "./package.json"
22 | }
23 | },
24 | "description": "## Release (2024-01-19)\n\nember-no-implicit-this-codemod 3.0.0 (major)\n\n#### :boom: Breaking Change\n* `ember-no-implicit-this-codemod`\n * [#405](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/405) drop support for Node < 16 ([@mansona](https://github.com/mansona))\n\n#### :rocket: Enhancement\n* `ember-no-implicit-this-codemod`\n * [#400](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/400) Update ember-codemods-telemetry-helpers for Mac M support ([@Mikek2252](https://github.com/Mikek2252))\n\n#### :house: Internal\n* `ember-no-implicit-this-codemod`\n * [#418](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/418) Typescript ([@mansona](https://github.com/mansona))\n * [#416](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/416) setup release-plan ([@mansona](https://github.com/mansona))\n * [#401](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/401) swap to pnpm ([@mansona](https://github.com/mansona))\n * [#409](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/409) add grouping to dependabot config ([@mansona](https://github.com/mansona))\n\n#### Committers: 2\n- Chris Manson ([@mansona](https://github.com/mansona))\n- Michael Kerr ([@Mikek2252](https://github.com/Mikek2252))\n"
25 | }
26 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | # For every push to the master branch, this checks if the release-plan was
2 | # updated and if it was it will publish stable npm packages based on the
3 | # release plan
4 |
5 | name: Publish Stable
6 |
7 | on:
8 | workflow_dispatch:
9 | push:
10 | branches:
11 | - main
12 | - master
13 |
14 | concurrency:
15 | group: publish-${{ github.head_ref || github.ref }}
16 | cancel-in-progress: true
17 |
18 | jobs:
19 | check-plan:
20 | name: "Check Release Plan"
21 | runs-on: ubuntu-latest
22 | outputs:
23 | command: ${{ steps.check-release.outputs.command }}
24 |
25 | steps:
26 | - uses: actions/checkout@v4
27 | with:
28 | fetch-depth: 0
29 | ref: 'main'
30 | # This will only cause the `check-plan` job to have a result of `success`
31 | # when the .release-plan.json file was changed on the last commit. This
32 | # plus the fact that this action only runs on main will be enough of a guard
33 | - id: check-release
34 | run: if git diff --name-only HEAD HEAD~1 | grep -w -q ".release-plan.json"; then echo "command=release"; fi >> $GITHUB_OUTPUT
35 |
36 | publish:
37 | name: "NPM Publish"
38 | runs-on: ubuntu-latest
39 | needs: check-plan
40 | if: needs.check-plan.outputs.command == 'release'
41 | permissions:
42 | contents: write
43 | pull-requests: write
44 |
45 | steps:
46 | - uses: actions/checkout@v4
47 | - uses: actions/setup-node@v4
48 | with:
49 | node-version: 18
50 | # This creates an .npmrc that reads the NODE_AUTH_TOKEN environment variable
51 | registry-url: 'https://registry.npmjs.org'
52 |
53 | - uses: pnpm/action-setup@v2
54 | with:
55 | version: 8
56 | - run: pnpm install --frozen-lockfile
57 | - name: npm publish
58 | run: pnpm release-plan publish
59 |
60 | env:
61 | GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
62 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
63 |
--------------------------------------------------------------------------------
/test/helpers/test-runner.ts:
--------------------------------------------------------------------------------
1 | import execa, { CommonOptions } from 'execa';
2 | import path from 'node:path';
3 | import { kill, timeoutAfter } from './utils';
4 | import { isRecord } from '../../helpers/types';
5 |
6 | const devServerTimeout = 60000;
7 |
8 | export class TestRunner {
9 | version: string;
10 | inputDir: string;
11 | execOpts: CommonOptions<'utf8'>;
12 |
13 | private emberProcess?: execa.ExecaChildProcess;
14 |
15 | constructor(version: string) {
16 | this.version = version;
17 |
18 | // resolved from the root of the project
19 | const inputPath = path.join('test', 'fixtures', version, 'input');
20 | this.inputDir = path.resolve(inputPath);
21 | this.execOpts = { cwd: this.inputDir, stderr: 'inherit' };
22 | }
23 |
24 | async installDeps(): Promise {
25 | await execa('rm', ['-rf', 'node_modules'], { cwd: this.inputDir });
26 | await execa('yarn', ['install'], { cwd: this.inputDir });
27 | }
28 |
29 | async runCodemod() {
30 | await execa('../../../../bin/cli.js', ['http://localhost:4200', 'app'], this.execOpts);
31 | }
32 |
33 | async startEmber(): Promise {
34 | const emberServe = execa('yarn', ['ember', 'serve'], {
35 | cwd: this.inputDir,
36 | env: {
37 | JOBS: '1',
38 | },
39 | });
40 |
41 | if (process.env['DEBUG']) {
42 | emberServe.stdout?.pipe(process.stdout);
43 | emberServe.stderr?.pipe(process.stderr);
44 | }
45 |
46 | const serverWaiter = new Promise(resolve => {
47 | emberServe.stdout?.on('data', data => {
48 | if (data.toString().includes('Build successful')) {
49 | resolve();
50 | }
51 | });
52 | });
53 |
54 | try {
55 | await timeoutAfter(devServerTimeout, serverWaiter);
56 | } catch (e) {
57 | console.error(e);
58 | throw new Error('Ember server failed to start');
59 | }
60 |
61 | this.emberProcess = emberServe;
62 | }
63 |
64 | async stopEmber(): Promise {
65 | const { emberProcess } = this;
66 | if (emberProcess) {
67 | await timeoutAfter(devServerTimeout, kill(emberProcess));
68 | }
69 | }
70 |
71 | async compare() {
72 | try {
73 | const actual = path.join('app');
74 | const expectedApp = path.join('..', 'output', 'app');
75 |
76 | await execa('diff', ['-rq', actual, expectedApp], { cwd: this.inputDir, stdio: 'inherit' });
77 | } catch (e) {
78 | console.log(isRecord(e) ? e['stdout']: 'codemod did not run successfully');
79 |
80 | throw new Error('codemod did not run successfully');
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/helpers/options.ts:
--------------------------------------------------------------------------------
1 | import { getOptions as getCLIOptions } from 'codemod-cli';
2 | import fs from 'node:fs';
3 | import path from 'node:path';
4 | import { type ZodError, type ZodType, z } from 'zod';
5 | import { Telemetry, getTelemetry } from './telemetry';
6 |
7 | export interface Options {
8 | customHelpers: string[],
9 | telemetry: Telemetry
10 | }
11 |
12 | const CLIOptions = z.object({
13 | config: z.string().optional(),
14 | });
15 |
16 | type CLIOptions = z.infer;
17 |
18 | const FileOptions = z.object({
19 | helpers: z.array(z.string()),
20 | });
21 |
22 | type FileOptions = z.infer;
23 |
24 | /**
25 | * Returns custom options object to support the custom helpers config path passed
26 | * by the user.
27 | */
28 | export function getOptions(): Options {
29 | const cliOptions = parse(getCLIOptions(), CLIOptions);
30 | return {
31 | customHelpers: getCustomHelpersFromConfig(cliOptions.config),
32 | telemetry: getTelemetry(),
33 | };
34 | }
35 |
36 | // FIXME: Document
37 | /**
38 | * Accepts the config path for custom helpers and returns the array of helpers
39 | * if the file path is resolved.
40 | * Context: This will allow the users to specify their custom list of helpers
41 | * along with the known helpers, this would give them more flexibility for handling
42 | * special use cases.
43 | */
44 | function getCustomHelpersFromConfig(configPath: string | undefined): string[] {
45 | if (configPath) {
46 | const filePath = path.join(process.cwd(), configPath);
47 | const config = JSON.parse(fs.readFileSync(filePath, 'utf8')) as unknown;
48 | const parsed = parse(config, FileOptions);
49 | if (parsed.helpers) {
50 | return parsed.helpers;
51 | }
52 | }
53 | return [];
54 | }
55 |
56 | function parse(raw: unknown, type: Z): z.infer {
57 | const parsed = type.safeParse(raw);
58 | if (parsed.success) {
59 | return parsed.data;
60 | } else {
61 | throw makeConfigError('cli', parsed.error);
62 | }
63 | }
64 |
65 | function makeConfigError(source: string, error: ZodError): ConfigError {
66 | const flattened = error.flatten();
67 | const errors = flattened.formErrors;
68 | for (const [key, value] of Object.entries(flattened.fieldErrors)) {
69 | errors.push(`[${key}] ${value.join('; ')}`);
70 | }
71 | const message = errors.join('\n\t');
72 | return new ConfigError(`${source} Config Error\n\t${message}`);
73 | }
74 |
75 | class ConfigError extends Error {
76 | constructor(message: string) {
77 | super(message);
78 | this.name = 'ConfigError';
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/index.ts:
--------------------------------------------------------------------------------
1 | import Debug from 'debug';
2 | import { parse, print } from 'ember-template-recast';
3 | import { API, FileInfo, Transform } from 'jscodeshift';
4 | import path from 'node:path';
5 | import { Options, getOptions } from './helpers/options';
6 | import transform from './helpers/plugin';
7 | import { isEmberTemplate } from './helpers/tagged-templates';
8 |
9 | const debug = Debug('ember-no-implicit-this-codemod:transform');
10 |
11 | /**
12 | * Given the location and source text of a template, as well as codemod options,
13 | * returns the rewritten template contents with `this` references inserted where
14 | * necessary.
15 | */
16 | function rewriteTemplate(path: string, source: string, options: Options): string {
17 | debug('Parsing %s ...', path);
18 | const root = parse(source);
19 |
20 | debug('Transforming %s ...', path);
21 | transform(root, options);
22 |
23 | debug('Generating new content for %s ...', path);
24 | return print(root);
25 | }
26 |
27 | /**
28 | * Given a JS or TS file that potentially has embedded templates within it,
29 | * returns updated source with those templates rewritten to include `this`
30 | * references where needed.
31 | */
32 | function rewriteEmbeddedTemplates(file: FileInfo, options: Options, { jscodeshift }: API): string {
33 | return (
34 | jscodeshift(file.source)
35 | // @ts-expect-error FIXME: UGH
36 | .find('TaggedTemplateExpression', { tag: { type: 'Identifier' } })
37 | .forEach(path => {
38 | if (isEmberTemplate(path)) {
39 | // @ts-expect-error FIXME: UGH
40 | let { value } = path.node.quasi.quasis[0];
41 | value.raw = rewriteTemplate(file.path, value.raw, options);
42 | }
43 | })
44 | .toSource()
45 | );
46 | }
47 |
48 | // FIXME: Ensure this is what is happening
49 | /**
50 | * | Result | How-to | Meaning |
51 | * | :------ | :------ | :------- |
52 | * | `errors` | `throw` | we attempted to transform but encountered an error |
53 | * | `unmodified` | return `string` (unchanged) | we attempted to transform but it was unnecessary |
54 | * | `skipped` | return `undefined` | we did not attempt to transform |
55 | * | `ok` | return `string` (changed) | we successfully transformed |
56 | */
57 | const transformer: Transform = function transformer(file, api) {
58 | const extension = path.extname(file.path).toLowerCase();
59 | const options = getOptions();
60 | if (extension === '.hbs') {
61 | return rewriteTemplate(file.path, file.source, options);
62 | } else if (extension === '.js' || extension === '.ts') {
63 | return rewriteEmbeddedTemplates(file, options, api);
64 | } else {
65 | debug('Skipping %s because it does not match a known extension with templates', file.path);
66 | return;
67 | }
68 | };
69 |
70 | export default transformer;
71 |
72 | // Set the parser, needed for supporting decorators
73 | export { default as parser } from './helpers/parse';
74 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ember-no-implicit-this-codemod",
3 | "version": "3.0.0",
4 | "description": "Codemods for transforming variable usage to be prefixed with `this`, when appropriate",
5 | "keywords": [
6 | "codemod-cli"
7 | ],
8 | "homepage": "https://github.com/ember-codemods/ember-no-implicit-this-codemod#readme",
9 | "bugs": {
10 | "url": "https://github.com/ember-codemods/ember-no-implicit-this-codemod"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/ember-codemods/ember-no-implicit-this-codemod"
15 | },
16 | "license": "MIT",
17 | "author": "",
18 | "bin": {
19 | "ember-no-implicit-this-codemod": "./bin/cli.js"
20 | },
21 | "files": [
22 | "/bin",
23 | "/helpers/**/*.js",
24 | "/transforms/no-implicit-this/index.js",
25 | "/transforms/no-implicit-this/helpers/**/*.js"
26 | ],
27 | "scripts": {
28 | "build": "tsc",
29 | "clean": "tsc --build --clean",
30 | "codemod": "jscodeshift -t ./transforms/no-implicit-this/index.js --extensions js,ts,hbs --run-in-band",
31 | "coveralls": "cat ./coverage/lcov.info | node node_modules/.bin/coveralls",
32 | "debug:codemod": "node --inspect-brk node_modules/jscodeshift/bin/jscodeshift.js -t ./transforms/no-implicit-this/index.js --run-in-band --extensions js,ts,hbs ",
33 | "debug:codemod:not-working": "node --inspect-brk ./bin/cli",
34 | "debug:telemetry": "node --inspect-brk ./bin/telemetry.js",
35 | "lint:js": "eslint .",
36 | "lint:ts": "tsc --noEmit",
37 | "prepublishOnly": "yarn build",
38 | "release": "release-it",
39 | "test": "jest",
40 | "pretest:integration": "yarn build",
41 | "test:integration": "ts-node ./test/run-test.ts",
42 | "update-docs": "codemod-cli update-docs"
43 | },
44 | "jest": {
45 | "preset": "ts-jest",
46 | "testEnvironment": "node",
47 | "testMatch": [
48 | "/transforms/**/test.{js,ts}"
49 | ]
50 | },
51 | "dependencies": {
52 | "@babel/parser": "^7.23.6",
53 | "codemod-cli": "^3.2.0",
54 | "debug": "^4.1.1",
55 | "ember-codemods-telemetry-helpers": "^3.0.0",
56 | "ember-template-recast": "^6.1.4",
57 | "zod": "^3.22.4"
58 | },
59 | "devDependencies": {
60 | "@tsconfig/node16": "^1.0.4",
61 | "@tsconfig/strictest": "^2.0.1",
62 | "@types/babel__core": "^7.20.5",
63 | "@types/chalk": "^2.2.0",
64 | "@types/common-tags": "^1.8.0",
65 | "@types/debug": "^4.1.8",
66 | "@types/jscodeshift": "^0.11.6",
67 | "@types/node": "^20.11.5",
68 | "@typescript-eslint/eslint-plugin": "^5.59.7",
69 | "@typescript-eslint/parser": "^5.59.7",
70 | "ast-types": "^0.14.2",
71 | "babel-plugin-htmlbars-inline-precompile": "^3.0.1",
72 | "chalk": "^4.1.1",
73 | "common-tags": "^1.8.0",
74 | "coveralls": "^3.1.0",
75 | "eslint": "^6.8.0",
76 | "eslint-config-prettier": "^6.15.0",
77 | "eslint-plugin-prettier": "^3.4.0",
78 | "execa": "^3.4.0",
79 | "jest": "^29.1.0",
80 | "prettier": "^1.19.1",
81 | "release-plan": "^0.6.0",
82 | "ts-jest": "^29.1.0",
83 | "ts-node": "^10.9.1",
84 | "typescript": "~5.0.4"
85 | },
86 | "engines": {
87 | "node": "16.* || 18.* || >= 20"
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/.github/workflows/plan-release.yml:
--------------------------------------------------------------------------------
1 | name: Release Plan Review
2 | on:
3 | push:
4 | branches:
5 | - main
6 | - master
7 | pull_request:
8 | types:
9 | - labeled
10 |
11 | concurrency:
12 | group: plan-release # only the latest one of these should ever be running
13 | cancel-in-progress: true
14 |
15 | jobs:
16 | check-plan:
17 | name: "Check Release Plan"
18 | runs-on: ubuntu-latest
19 | outputs:
20 | command: ${{ steps.check-release.outputs.command }}
21 |
22 | steps:
23 | - uses: actions/checkout@v4
24 | with:
25 | fetch-depth: 0
26 | ref: 'main'
27 | # This will only cause the `check-plan` job to have a "command" of `release`
28 | # when the .release-plan.json file was changed on the last commit.
29 | - id: check-release
30 | run: if git diff --name-only HEAD HEAD~1 | grep -w -q ".release-plan.json"; then echo "command=release"; fi >> $GITHUB_OUTPUT
31 |
32 | prepare_release_notes:
33 | name: Prepare Release Notes
34 | runs-on: ubuntu-latest
35 | timeout-minutes: 5
36 | needs: check-plan
37 | permissions:
38 | contents: write
39 | pull-requests: write
40 | outputs:
41 | explanation: ${{ steps.explanation.outputs.text }}
42 | # only run on push event if plan wasn't updated (don't create a release plan when we're releasing)
43 | # only run on labeled event if the PR has already been merged
44 | if: (github.event_name == 'push' && needs.check-plan.outputs.command != 'release') || (github.event_name == 'pull_request' && github.event.pull_request.merged == true)
45 |
46 | steps:
47 | - uses: actions/checkout@v4
48 | # We need to download lots of history so that
49 | # lerna-changelog can discover what's changed since the last release
50 | with:
51 | fetch-depth: 0
52 | - uses: actions/setup-node@v4
53 | with:
54 | node-version: 18
55 |
56 | - uses: pnpm/action-setup@v2
57 | with:
58 | version: 8
59 | - run: pnpm install --frozen-lockfile
60 |
61 | - name: "Update Docs"
62 | run: pnpm update-docs
63 |
64 | - name: "Generate Explanation and Prep Changelogs"
65 | id: explanation
66 | run: |
67 | set -x
68 |
69 | pnpm release-plan prepare
70 |
71 | echo 'text<> $GITHUB_OUTPUT
72 | jq .description .release-plan.json -r >> $GITHUB_OUTPUT
73 | echo 'EOF' >> $GITHUB_OUTPUT
74 | env:
75 | GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
76 |
77 | - uses: peter-evans/create-pull-request@v5
78 | with:
79 | commit-message: "Prepare Release using 'release-plan'"
80 | author: "github-actions[bot] "
81 | labels: "internal"
82 | branch: release-preview
83 | title: Prepare Release
84 | body: |
85 | This PR is a preview of the release that [release-plan](https://github.com/embroider-build/release-plan) has prepared. To release you should just merge this PR 👍
86 |
87 | -----------------------------------------
88 |
89 | ${{ steps.explanation.outputs.text }}
90 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/helpers/plugin.ts:
--------------------------------------------------------------------------------
1 | import Debug from 'debug';
2 | import { builders as b, AST, traverse } from 'ember-template-recast';
3 | import KNOWN_HELPERS from './known-helpers';
4 | import { Options } from './options';
5 | import { Telemetry } from './telemetry';
6 |
7 | const debug = Debug('ember-no-implicit-this-codemod:plugin');
8 |
9 | // everything is copy-pasteable to astexplorer.net.
10 | // sorta. telemetry needs to be defined.
11 | // telemetry can be populated with -mock-telemetry.json
12 |
13 | /**
14 | * plugin entrypoint
15 | */
16 | export default function transform(root: AST.Node, { telemetry, customHelpers }: Options) {
17 |
18 | const scopedParams: string[] = [];
19 | const [components, helpers] = populateInvokeables(telemetry);
20 |
21 | const paramTracker = {
22 | enter(node: { blockParams: any[] }) {
23 | node.blockParams.forEach((param: string) => {
24 | scopedParams.push(param);
25 | });
26 | },
27 |
28 | exit(node: { blockParams: any[] }) {
29 | node.blockParams.forEach(() => {
30 | scopedParams.pop();
31 | });
32 | },
33 | };
34 |
35 | function handleParams(params: AST.Expression[]) {
36 | for (const param of params) {
37 | if (param.type !== 'PathExpression') continue;
38 | handlePathExpression(param);
39 | }
40 | }
41 |
42 | function handleHash(hash: AST.Hash) {
43 | for (const pair of hash.pairs) {
44 | if (pair.value.type !== 'PathExpression') continue;
45 | handlePathExpression(pair.value);
46 | }
47 | }
48 |
49 | function handlePathExpression(node: AST.PathExpression) {
50 | // skip this.foo
51 | if (node.this) {
52 | debug(`Skipping \`%s\` because it is already prefixed with \`this.\``, node.original);
53 | return;
54 | }
55 |
56 | // skip @foo
57 | if (node.data) {
58 | debug(`Skipping \`%s\` because it is already prefixed with \`@\``, node.original);
59 | return;
60 | }
61 |
62 | // skip {#foo as |bar|}}{{bar}}{{/foo}}
63 | // skip {{bar}}
64 | const firstPart = node.parts[0];
65 | if (firstPart && scopedParams.includes(firstPart)) {
66 | debug(`Skipping \`%s\` because it is a scoped variable`, node.original);
67 | return;
68 | }
69 |
70 | // skip `hasBlock` keyword
71 | if (node.original === 'hasBlock') {
72 | debug(`Skipping \`%s\` because it is a keyword`, node.original);
73 | return;
74 | }
75 |
76 | // add `this.` prefix
77 | debug(`Transforming \`%s\` to \`this.%s\``, node.original, node.original);
78 | Object.assign(node, b.path(`this.${node.original}`));
79 | }
80 |
81 | function isHelper(name: string) {
82 | if (KNOWN_HELPERS.includes(name)) {
83 | debug(`Skipping \`%s\` because it is a known helper`, name);
84 | return true;
85 | }
86 |
87 | if (customHelpers.includes(name)) {
88 | debug(`Skipping \`%s\` because it is a custom configured helper`, name);
89 | return true;
90 | }
91 |
92 | const helper = helpers.find(path => path.endsWith(`/${name}`));
93 | if (helper) {
94 | const message = `Skipping \`%s\` because it appears to be a helper from the telemetry data: %s`;
95 | debug(message, name, helper);
96 | return true;
97 | }
98 |
99 | return false;
100 | }
101 |
102 | function isComponent(name: string) {
103 | const component = components.find(path => path.endsWith(`/${name}`));
104 | if (component) {
105 | const message = `Skipping \`%s\` because it appears to be a component from the telemetry data: %s`;
106 | debug(message, name, component);
107 | return true;
108 | }
109 |
110 | return false;
111 | }
112 |
113 | let inAttrNode = false;
114 |
115 | traverse(root, {
116 | Block: paramTracker,
117 | ElementNode: paramTracker,
118 |
119 | AttrNode: {
120 | enter() {
121 | inAttrNode = true;
122 | },
123 | exit() {
124 | inAttrNode = false;
125 | },
126 | },
127 |
128 | MustacheStatement(node) {
129 | const { path, params, hash } = node;
130 |
131 | // {{foo BAR}}
132 | handleParams(params);
133 |
134 | // {{foo bar=BAZ}}
135 | handleHash(hash);
136 |
137 | const hasParams = params.length !== 0;
138 | const hasHashPairs = hash.pairs.length !== 0;
139 |
140 | // {{FOO}}
141 | if (path.type === 'PathExpression' && !hasParams && !hasHashPairs) {
142 | // {{FOO.bar}}
143 | if (path.parts.length > 1) {
144 | handlePathExpression(path);
145 | return;
146 | }
147 |
148 | // skip ember-holy-futuristic-template-namespacing-batman component/helper invocations
149 | // (see https://github.com/rwjblue/ember-holy-futuristic-template-namespacing-batman)
150 | if (path.original.includes('$') || path.original.includes('::')) {
151 | const message = `Skipping \`%s\` because it looks like a helper/component invocation from ember-holy-futuristic-template-namespacing-batman`;
152 | debug(message, path.original);
153 | return;
154 | }
155 |
156 | // skip helpers
157 | if (isHelper(path.original)) return;
158 |
159 | // skip components
160 | if (!inAttrNode && isComponent(path.original)) return;
161 |
162 | handlePathExpression(path);
163 | }
164 | },
165 |
166 | BlockStatement(node) {
167 | // {{#foo BAR}}{{/foo}}
168 | handleParams(node.params);
169 |
170 | // {{#foo bar=BAZ}}{{/foo}}
171 | handleHash(node.hash);
172 | },
173 |
174 | SubExpression(node) {
175 | // (foo BAR)
176 | handleParams(node.params);
177 |
178 | // (foo bar=BAZ)
179 | handleHash(node.hash);
180 | },
181 |
182 | ElementModifierStatement(node) {
183 | //
184 | handleParams(node.params);
185 |
186 | //
187 | handleHash(node.hash);
188 | },
189 | });
190 | }
191 |
192 | function populateInvokeables(telemetry: Telemetry): [components: string[], helpers: string[]] {
193 | const components = [];
194 | const helpers = [];
195 |
196 | for (const [name, datum] of Object.entries(telemetry)) {
197 | switch (datum.type) {
198 | case 'Component':
199 | components.push(name);
200 | break;
201 | case 'Helper':
202 | helpers.push(name);
203 | break;
204 | }
205 | }
206 |
207 | return [components, helpers];
208 | }
209 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | ## Release (2024-01-19)
3 |
4 | ember-no-implicit-this-codemod 3.0.0 (major)
5 |
6 | #### :boom: Breaking Change
7 | * `ember-no-implicit-this-codemod`
8 | * [#405](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/405) drop support for Node < 16 ([@mansona](https://github.com/mansona))
9 |
10 | #### :rocket: Enhancement
11 | * `ember-no-implicit-this-codemod`
12 | * [#400](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/400) Update ember-codemods-telemetry-helpers for Mac M support ([@Mikek2252](https://github.com/Mikek2252))
13 |
14 | #### :house: Internal
15 | * `ember-no-implicit-this-codemod`
16 | * [#418](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/418) Typescript ([@mansona](https://github.com/mansona))
17 | * [#416](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/416) setup release-plan ([@mansona](https://github.com/mansona))
18 | * [#401](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/401) swap to pnpm ([@mansona](https://github.com/mansona))
19 | * [#409](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/409) add grouping to dependabot config ([@mansona](https://github.com/mansona))
20 |
21 | #### Committers: 2
22 | - Chris Manson ([@mansona](https://github.com/mansona))
23 | - Michael Kerr ([@Mikek2252](https://github.com/Mikek2252))
24 |
25 | ## v2.1.0 (2022-01-11)
26 |
27 | #### :rocket: Enhancement
28 | * [#83](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/83) Add `debug` logging ([@Turbo87](https://github.com/Turbo87))
29 | * [#85](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/85) Remove unused logging code ([@Turbo87](https://github.com/Turbo87))
30 |
31 | #### :bug: Bug Fix
32 | * [#86](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/86) Fix substring component matches ([@Turbo87](https://github.com/Turbo87))
33 |
34 | #### Committers: 4
35 | - Dan Freeman ([@dfreeman](https://github.com/dfreeman))
36 | - Jeldrik Hanschke ([@jelhan](https://github.com/jelhan))
37 | - Tobias Bieniek ([@Turbo87](https://github.com/Turbo87))
38 | - [@dependabot-preview[bot]](https://github.com/apps/dependabot-preview)
39 |
40 | ## v2.0.0 (2019-12-15)
41 |
42 | #### :bug: Bug Fix
43 | * [#80](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/80) Fix `hasBlock` handling ([@Turbo87](https://github.com/Turbo87))
44 |
45 | #### :house: Internal
46 | * [#82](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/82) Replace `recast.transform()` call with `recast.traverse()` ([@Turbo87](https://github.com/Turbo87))
47 | * [#81](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/81) known-helpers: Remove helpers from addons ([@Turbo87](https://github.com/Turbo87))
48 | * [#79](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/79) Remove unused `listr` dependency ([@Turbo87](https://github.com/Turbo87))
49 | * [#70](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/70) Move `getTelemetry()` call out of `plugin.js` file ([@Turbo87](https://github.com/Turbo87))
50 | * [#67](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/67) Use Jest directly ([@Turbo87](https://github.com/Turbo87))
51 |
52 | #### Committers: 2
53 | - Tobias Bieniek ([@Turbo87](https://github.com/Turbo87))
54 | - [@dependabot-preview[bot]](https://github.com/apps/dependabot-preview)
55 |
56 | ## v1.0.1 (2019-12-14)
57 |
58 | #### :bug: Bug Fix
59 | * [#65](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/65) Fix broken `path.parts` condition ([@Turbo87](https://github.com/Turbo87))
60 |
61 | #### :house: Internal
62 | * [#66](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/66) Add `ember-holy-futuristic-template-namespacing-batman` test cases ([@Turbo87](https://github.com/Turbo87))
63 | * [#64](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/64) CI: Run with code coverage tracking ([@Turbo87](https://github.com/Turbo87))
64 |
65 | #### Committers: 1
66 | - Tobias Bieniek ([@Turbo87](https://github.com/Turbo87))
67 |
68 | ## v1.0.0 (2019-12-14)
69 |
70 | #### :boom: Breaking Change
71 | * [#62](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/62) Rewrite `PathExpression` visitor code ([@Turbo87](https://github.com/Turbo87))
72 |
73 | #### :rocket: Enhancement
74 | * [#62](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/62) Rewrite `PathExpression` visitor code ([@Turbo87](https://github.com/Turbo87))
75 |
76 | #### :house: Internal
77 | * [#54](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/54) Remove unused explicit dependencies ([@Turbo87](https://github.com/Turbo87))
78 | * [#55](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/55) Add dependabot config file ([@Turbo87](https://github.com/Turbo87))
79 |
80 | #### Committers: 2
81 | - Tobias Bieniek ([@Turbo87](https://github.com/Turbo87))
82 | - [@dependabot-preview[bot]](https://github.com/apps/dependabot-preview)
83 |
84 | * Merge pull request #50 from suchitadoshi1987/suchita/customHelpers (9713041)
85 | * Merge pull request #49 from suchitadoshi1987/suchita/supportwallstreet (57d0a65)
86 | * Add config option to support custom helpers (c1c4918)
87 | * add support for ember-holy-futuristic-template-namespacing-batman syntax as well as for Nested Invocations in Angle Bracket Syntax (cec9fc4)
88 |
89 | ## v0.7.3 (2019-10-28)
90 |
91 | #### :house: Internal
92 | * [#39](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/39) Improve Integration Tests ([@NullVoxPopuli](https://github.com/NullVoxPopuli))
93 |
94 | #### Committers: 1
95 | - L. Preston Sego III ([@NullVoxPopuli](https://github.com/NullVoxPopuli))
96 |
97 | * Fix incorrect transform of naked pre-existing this (#41) (87fa534)
98 | * update readme with generated transform output (7d7e035)
99 |
100 | * Fix @args swapped with this.args (#40) (5f6ae02)
101 | * update telemetry helpers tp (#38) (e3e4c1c)
102 | * Update telemetry-helpers (#37) (4f08318)
103 | * Test multiple ember versions (#29) (cb53ef2)
104 | * Use GitHub Actions for parallel running (4c395fc)
105 | * add 3.13 app (4c259f3)
106 | * move old app to 3.10 (2849e1c)
107 |
108 | * add minimal docs + collect telemetry while running the codemod (#8) (27aad4e)
109 | * update readme (5b86872)
110 |
111 | * Data attributes smoosh fix (#22) (03d9c79)
112 | * Fixes Void element bug (#23) (9b46cd6)
113 |
114 | * Bump telemetry-helpers to 0.4.0 (#21) (16f9e80)
115 | * fix label on readme (9332a1d)
116 | * add badges (#20) (0aaa0ae)
117 | * update readme (3915484)
118 | * use travis.com instead of org (30abe60)
119 | * add badges (9fa0aee)
120 |
121 | * Add ES5 getters to telemetry data (#10) (26a181d)
122 |
123 |
124 |
125 | * update readme (cefef89)
126 |
127 | ## v0.2.0 (2019-08-09)
128 |
129 | #### :rocket: Enhancement
130 | * [#2](https://github.com/ember-codemods/ember-no-implicit-this-codemod/pull/2) Initial implementation ([@NullVoxPopuli](https://github.com/NullVoxPopuli))
131 |
132 | #### Committers: 3
133 | - Dustin Masters ([@dustinsoftware](https://github.com/dustinsoftware))
134 | - L. Preston Sego III ([@NullVoxPopuli](https://github.com/NullVoxPopuli))
135 | - Pat O'Callaghan ([@patocallaghan](https://github.com/patocallaghan))
136 |
137 |
--------------------------------------------------------------------------------
/transforms/no-implicit-this/README.md:
--------------------------------------------------------------------------------
1 | # no-implicit-this
2 |
3 |
4 | ## Usage
5 |
6 | ```
7 | npx ember-no-implicit-this-codemod no-implicit-this path/of/files/ or/some**/*glob.js
8 |
9 | # or
10 |
11 | yarn global add ember-no-implicit-this-codemod
12 | ember-no-implicit-this-codemod no-implicit-this path/of/files/ or/some**/*glob.js
13 | ```
14 |
15 | ## Input / Output
16 |
17 |
18 | * [angle-brackets-with-block-params](#angle-brackets-with-block-params)
19 | * [angle-brackets-with-hash-params](#angle-brackets-with-hash-params)
20 | * [angle-brackets-without-params](#angle-brackets-without-params)
21 | * [batman](#batman)
22 | * [built-in-helpers](#built-in-helpers)
23 | * [comments](#comments)
24 | * [custom-helpers](#custom-helpers)
25 | * [handlebars-with-block-params](#handlebars-with-block-params)
26 | * [handlebars-with-hash-params](#handlebars-with-hash-params)
27 | * [handlebars-with-positional-params](#handlebars-with-positional-params)
28 | * [handlebars-with-wall-street-syntax](#handlebars-with-wall-street-syntax)
29 | * [handlebars-without-params](#handlebars-without-params)
30 | * [has-block](#has-block)
31 | * [paths](#paths)
32 | * [tagged-templates-js](#tagged-templates-js)
33 | * [tagged-templates-ts](#tagged-templates-ts)
34 | * [void-elements](#void-elements)
35 |
36 |
37 |
38 | ---
39 | **angle-brackets-with-block-params**
40 |
41 | **Input** ([angle-brackets-with-block-params.input.hbs](transforms/no-implicit-this/__testfixtures__/angle-brackets-with-block-params.input.hbs)):
42 | ```hbs
43 |
44 | {{foo}}
45 | {{hash.property}}
46 |
47 |
48 | {{property}}
49 |
50 |
51 |
52 |
53 |
54 |
55 | ```
56 |
57 | **Output** ([angle-brackets-with-block-params.output.hbs](transforms/no-implicit-this/__testfixtures__/angle-brackets-with-block-params.output.hbs)):
58 | ```hbs
59 |
60 | {{foo}}
61 | {{hash.property}}
62 |
63 |
64 | {{property}}
65 |
66 |
67 |
68 |
69 |
70 |
71 | ```
72 | ---
73 | **angle-brackets-with-hash-params**
74 |
75 | **Input** ([angle-brackets-with-hash-params.input.hbs](transforms/no-implicit-this/__testfixtures__/angle-brackets-with-hash-params.input.hbs)):
76 | ```hbs
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 | ```
95 |
96 | **Output** ([angle-brackets-with-hash-params.output.hbs](transforms/no-implicit-this/__testfixtures__/angle-brackets-with-hash-params.output.hbs)):
97 | ```hbs
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
114 |
115 | ```
116 | ---
117 | **angle-brackets-without-params**
118 |
119 | **Input** ([angle-brackets-without-params.input.hbs](transforms/no-implicit-this/__testfixtures__/angle-brackets-without-params.input.hbs)):
120 | ```hbs
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | ```
130 |
131 | **Output** ([angle-brackets-without-params.output.hbs](transforms/no-implicit-this/__testfixtures__/angle-brackets-without-params.output.hbs)):
132 | ```hbs
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | ```
142 | ---
143 | **batman**
144 |
145 | **Input** ([batman.input.hbs](transforms/no-implicit-this/__testfixtures__/batman.input.hbs)):
146 | ```hbs
147 | {{addon-name$helper-name}}
148 | {{addon-name$component-name}}
149 |
150 |
151 |
152 | ```
153 |
154 | **Output** ([batman.output.hbs](transforms/no-implicit-this/__testfixtures__/batman.output.hbs)):
155 | ```hbs
156 | {{addon-name$helper-name}}
157 | {{addon-name$component-name}}
158 |
159 |
160 |
161 | ```
162 | ---
163 | **built-in-helpers**
164 |
165 | **Input** ([built-in-helpers.input.hbs](transforms/no-implicit-this/__testfixtures__/built-in-helpers.input.hbs)):
166 | ```hbs
167 | {{debugger}}
168 | {{has-block}}
169 | {{hasBlock}}
170 | {{input}}
171 | {{outlet}}
172 | {{textarea}}
173 | {{yield}}
174 |
175 | {{#let (concat "a" "b") as |ab|}}
176 | {{ab}}
177 | {{/let}}
178 |
179 | {{#each records as |record|}}
180 | {{record.property}}
181 | {{/each}}
182 |
183 |
184 |
185 |
186 |
187 | {{link-to 'name' 'route'}}
188 |
189 | ```
190 |
191 | **Output** ([built-in-helpers.output.hbs](transforms/no-implicit-this/__testfixtures__/built-in-helpers.output.hbs)):
192 | ```hbs
193 | {{debugger}}
194 | {{has-block}}
195 | {{hasBlock}}
196 | {{input}}
197 | {{outlet}}
198 | {{textarea}}
199 | {{yield}}
200 |
201 | {{#let (concat "a" "b") as |ab|}}
202 | {{ab}}
203 | {{/let}}
204 |
205 | {{#each this.records as |record|}}
206 | {{record.property}}
207 | {{/each}}
208 |
209 |
210 |
211 |
212 |
213 | {{link-to 'name' 'route'}}
214 |
215 | ```
216 | ---
217 |
218 |
219 | **Input** ([comments.input.hbs](transforms/no-implicit-this/__testfixtures__/comments.input.hbs)):
220 | ```hbs
221 |
222 |
223 | {{!-- foo bar --}}
224 | {{!-- {{foo-bar}} --}}
225 |
226 | ```
227 |
228 | **Output** ([comments.output.hbs](transforms/no-implicit-this/__testfixtures__/comments.output.hbs)):
229 | ```hbs
230 |
231 |
232 | {{!-- foo bar --}}
233 | {{!-- {{foo-bar}} --}}
234 |
235 | ```
236 | ---
237 | **custom-helpers**
238 |
239 | **Input** ([custom-helpers.input.hbs](transforms/no-implicit-this/__testfixtures__/custom-helpers.input.hbs)):
240 | ```hbs
241 | {{biz}}
242 | {{bang}}
243 |
244 | ```
245 |
246 | **Output** ([custom-helpers.output.hbs](transforms/no-implicit-this/__testfixtures__/custom-helpers.output.hbs)):
247 | ```hbs
248 | {{biz}}
249 | {{bang}}
250 |
251 | ```
252 | ---
253 | **handlebars-with-block-params**
254 |
255 | **Input** ([handlebars-with-block-params.input.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-with-block-params.input.hbs)):
256 | ```hbs
257 | {{#my-component as |foo myAction hash components|}}
258 | {{foo}} {{myAction}}
259 | {{hash.property}} {{hash.foo}}
260 |
261 | {{components.foo}}
262 |
263 | {{#components.my-component}}
264 |
265 | {{/components.my-component}}
266 |
267 | {{#components.block as |block|}}
268 | {{block}}
269 | {{/components.block}}
270 | {{/my-component}}
271 |
272 |
273 | ```
274 |
275 | **Output** ([handlebars-with-block-params.output.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-with-block-params.output.hbs)):
276 | ```hbs
277 | {{#my-component as |foo myAction hash components|}}
278 | {{foo}} {{myAction}}
279 | {{hash.property}} {{hash.foo}}
280 |
281 | {{components.foo}}
282 |
283 | {{#components.my-component}}
284 |
285 | {{/components.my-component}}
286 |
287 | {{#components.block as |block|}}
288 | {{block}}
289 | {{/components.block}}
290 | {{/my-component}}
291 |
292 |
293 | ```
294 | ---
295 | **handlebars-with-hash-params**
296 |
297 | **Input** ([handlebars-with-hash-params.input.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-with-hash-params.input.hbs)):
298 | ```hbs
299 | {{my-component arg="string"}}
300 | {{my-component arg=2}}
301 | {{my-component arg=foo}}
302 | {{my-component arg=property}}
303 | {{my-component arg=(my-helper property)}}
304 | {{my-component arg=(my-helper (fn myAction property) foo)}}
305 | {{my-component arg=property arg2=foo}}
306 | {{my-component arg=property arg2=(fn myAction foo)}}
307 |
308 |
309 | ```
310 |
311 | **Output** ([handlebars-with-hash-params.output.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-with-hash-params.output.hbs)):
312 | ```hbs
313 | {{my-component arg="string"}}
314 | {{my-component arg=2}}
315 | {{my-component arg=this.foo}}
316 | {{my-component arg=this.property}}
317 | {{my-component arg=(my-helper this.property)}}
318 | {{my-component arg=(my-helper (fn this.myAction this.property) this.foo)}}
319 | {{my-component arg=this.property arg2=this.foo}}
320 | {{my-component arg=this.property arg2=(fn this.myAction this.foo)}}
321 |
322 |
323 | ```
324 | ---
325 | **handlebars-with-positional-params**
326 |
327 | **Input** ([handlebars-with-positional-params.input.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-with-positional-params.input.hbs)):
328 | ```hbs
329 | {{my-component "string"}}
330 | {{my-component 1}}
331 | {{my-component foo}}
332 | {{my-component @foo}}
333 | {{my-component property}}
334 | {{my-component (my-helper property)}}
335 | {{my-component (my-helper "string")}}
336 | {{my-component (my-helper 1)}}
337 | {{get this 'key'}}
338 |
339 |
340 | ```
341 |
342 | **Output** ([handlebars-with-positional-params.output.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-with-positional-params.output.hbs)):
343 | ```hbs
344 | {{my-component "string"}}
345 | {{my-component 1}}
346 | {{my-component this.foo}}
347 | {{my-component @foo}}
348 | {{my-component this.property}}
349 | {{my-component (my-helper this.property)}}
350 | {{my-component (my-helper "string")}}
351 | {{my-component (my-helper 1)}}
352 | {{get this 'key'}}
353 |
354 | ```
355 | ---
356 | **handlebars-with-wall-street-syntax**
357 |
358 | **Input** ([handlebars-with-wall-street-syntax.input.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-with-wall-street-syntax.input.hbs)):
359 | ```hbs
360 | {{my-addon$my-component foo}}
361 | {{my-addon$namespace::my-component @foo}}
362 | {{my-addon$namespace::my-component property}}
363 | {{my-addon$my-component (my-helper property)}}
364 | {{my-addon$my-component (my-helper "string")}}
365 | {{my-addon$namespace::my-component (my-helper 1)}}
366 |
367 | ```
368 |
369 | **Output** ([handlebars-with-wall-street-syntax.output.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-with-wall-street-syntax.output.hbs)):
370 | ```hbs
371 | {{my-addon$my-component this.foo}}
372 | {{my-addon$namespace::my-component @foo}}
373 | {{my-addon$namespace::my-component this.property}}
374 | {{my-addon$my-component (my-helper this.property)}}
375 | {{my-addon$my-component (my-helper "string")}}
376 | {{my-addon$namespace::my-component (my-helper 1)}}
377 |
378 | ```
379 | ---
380 | **handlebars-without-params**
381 |
382 | **Input** ([handlebars-without-params.input.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-without-params.input.hbs)):
383 | ```hbs
384 | {{my-component}}
385 | {{a-helper}}
386 | {{foo}}
387 | {{property}}
388 | {{namespace/foo}}
389 | {{someGetter}}
390 |
391 | ```
392 |
393 | **Output** ([handlebars-without-params.output.hbs](transforms/no-implicit-this/__testfixtures__/handlebars-without-params.output.hbs)):
394 | ```hbs
395 | {{my-component}}
396 | {{a-helper}}
397 | {{foo}}
398 | {{this.property}}
399 | {{namespace/foo}}
400 | {{this.someGetter}}
401 |
402 | ```
403 | ---
404 | **has-block**
405 |
406 | **Input** ([has-block.input.hbs](transforms/no-implicit-this/__testfixtures__/has-block.input.hbs)):
407 | ```hbs
408 | {{if hasBlock "block"}}
409 | {{#if hasBlock}}block{{/if}}
410 | {{if (has-block) "block"}}
411 | {{#if (has-block)}}block{{/if}}
412 | {{if (has-block "main") "block"}}
413 | {{#if (has-block "main")}}block{{/if}}
414 | {{if (has-block-params "main") "block"}}
415 | {{#if (has-block-params "main")}}block{{/if}}
416 |
417 | ```
418 |
419 | **Output** ([has-block.output.hbs](transforms/no-implicit-this/__testfixtures__/has-block.output.hbs)):
420 | ```hbs
421 | {{if hasBlock "block"}}
422 | {{#if hasBlock}}block{{/if}}
423 | {{if (has-block) "block"}}
424 | {{#if (has-block)}}block{{/if}}
425 | {{if (has-block "main") "block"}}
426 | {{#if (has-block "main")}}block{{/if}}
427 | {{if (has-block-params "main") "block"}}
428 | {{#if (has-block-params "main")}}block{{/if}}
429 |
430 | ```
431 | ---
432 | **paths**
433 |
434 | **Input** ([paths.input.hbs](transforms/no-implicit-this/__testfixtures__/paths.input.hbs)):
435 | ```hbs
436 | {{foo-bar-baz}}
437 | {{baz}}
438 |
439 | ```
440 |
441 | **Output** ([paths.output.hbs](transforms/no-implicit-this/__testfixtures__/paths.output.hbs)):
442 | ```hbs
443 | {{foo-bar-baz}}
444 | {{this.baz}}
445 |
446 | ```
447 | ---
448 | **tagged-templates-js**
449 |
450 | **Input** ([tagged-templates-js.input.js](transforms/no-implicit-this/__testfixtures__/tagged-templates-js.input.js)):
451 | ```js
452 | import { hbs as echHBS } from 'ember-cli-htmlbars';
453 | import hipHBS from 'htmlbars-inline-precompile';
454 | import echipHBS from 'ember-cli-htmlbars-inline-precompile';
455 | import { hbs } from 'unknown-tag-source';
456 |
457 | echHBS`
458 | Hello,
459 | {{target}}!
460 | \n
461 | `;
462 |
463 | hipHBS`Hello, {{target}}!`;
464 |
465 | echipHBS`Hello, {{target}}!`;
466 |
467 | hbs`Hello, {{target}}!`;
468 |
469 | ```
470 |
471 | **Output** ([tagged-templates-js.output.js](transforms/no-implicit-this/__testfixtures__/tagged-templates-js.output.js)):
472 | ```js
473 | import { hbs as echHBS } from 'ember-cli-htmlbars';
474 | import hipHBS from 'htmlbars-inline-precompile';
475 | import echipHBS from 'ember-cli-htmlbars-inline-precompile';
476 | import { hbs } from 'unknown-tag-source';
477 |
478 | echHBS`
479 | Hello,
480 | {{this.target}}!
481 | \n
482 | `;
483 |
484 | hipHBS`Hello, {{this.target}}!`;
485 |
486 | echipHBS`Hello, {{this.target}}!`;
487 |
488 | hbs`Hello, {{target}}!`;
489 |
490 | ```
491 | ---
492 | **tagged-templates-ts**
493 |
494 | **Input** ([tagged-templates-ts.input.ts](transforms/no-implicit-this/__testfixtures__/tagged-templates-ts.input.ts)):
495 | ```ts
496 | import { hbs as echHBS } from 'ember-cli-htmlbars';
497 | import hipHBS from 'htmlbars-inline-precompile';
498 | import echipHBS from 'ember-cli-htmlbars-inline-precompile';
499 |
500 | declare const hbs: unknown;
501 |
502 | echHBS`
503 | Hello,
504 | {{target}}!
505 | \n
506 | `;
507 |
508 | hipHBS`Hello, {{target}}!`;
509 |
510 | echipHBS`Hello, {{target}}!`;
511 |
512 | hbs`Hello, {{target}}!`;
513 |
514 | ```
515 |
516 | **Output** ([tagged-templates-ts.output.ts](transforms/no-implicit-this/__testfixtures__/tagged-templates-ts.output.ts)):
517 | ```ts
518 | import { hbs as echHBS } from 'ember-cli-htmlbars';
519 | import hipHBS from 'htmlbars-inline-precompile';
520 | import echipHBS from 'ember-cli-htmlbars-inline-precompile';
521 |
522 | declare const hbs: unknown;
523 |
524 | echHBS`
525 | Hello,
526 | {{this.target}}!
527 | \n
528 | `;
529 |
530 | hipHBS`Hello, {{this.target}}!`;
531 |
532 | echipHBS`Hello, {{this.target}}!`;
533 |
534 | hbs`Hello, {{target}}!`;
535 |
536 | ```
537 | ---
538 | **void-elements**
539 |
540 | **Input** ([void-elements.input.hbs](transforms/no-implicit-this/__testfixtures__/void-elements.input.hbs)):
541 | ```hbs
542 |
547 |
548 |
553 | ```
554 |
555 | **Output** ([void-elements.output.hbs](transforms/no-implicit-this/__testfixtures__/void-elements.output.hbs)):
556 | ```hbs
557 |
562 |
563 |
568 | ```
569 |
--------------------------------------------------------------------------------