Skip to content

Commit

Permalink
Merge pull request #810 from NullVoxPopuli/copy-ember-template-lint-t…
Browse files Browse the repository at this point in the history
…o-be-internal-until-packages-are-extracted

I made a long branch name
  • Loading branch information
NullVoxPopuli authored Mar 31, 2023
2 parents a315f99 + ace80e7 commit c539278
Show file tree
Hide file tree
Showing 11 changed files with 895 additions and 43 deletions.
9 changes: 7 additions & 2 deletions apps/repl/tests/application/output-demos-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,13 @@ module('Output > Demos', function (hooks) {
this.owner.register('controller:edit', FakeController);
this.owner.register(
'template:edit',
hbs`{{! @glint-ignore }}
<Limber::Output @messagingAPI={{this.api}} />`
hbs`
<fieldset class="border">
<legend>Limber::Output</legend>
{{! @glint-ignore }}
<Limber::Output @messagingAPI={{this.api}} />
</fieldset>
`
);

await visit('/edit');
Expand Down
10 changes: 8 additions & 2 deletions apps/repl/tests/test-helper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { getSettledState, resetOnerror, setApplication } from '@ember/test-helpers';
import {
currentRouteName,
currentURL,
getSettledState,
resetOnerror,
setApplication,
} from '@ember/test-helpers';
import { getPendingWaiterState } from '@ember/test-waiters';
import * as QUnit from 'qunit';
import { setup as setupDom } from 'qunit-dom';
Expand All @@ -9,7 +15,7 @@ import config from 'limber/config/environment';

setApplication(Application.create(config.APP));

Object.assign(window, { getSettledState, getPendingWaiterState });
Object.assign(window, { getSettledState, getPendingWaiterState, currentURL, currentRouteName });

setupDom(QUnit.assert);

Expand Down
105 changes: 105 additions & 0 deletions packages/ember-repl/addon/cjs/eti/babel-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { ImportUtil } from 'babel-import-util';

import { transformTemplateTag } from './template-tag-transform';
import * as util from './util';

import type { NodePath } from '@babel/traverse';
import type { CallExpression, Class, Program } from '@babel/types';

/**
* This Babel plugin takes parseable code emitted by the string-based
* preprocessor plugin in this package and converts it into calls to
* the standardized `precompileTemplate` macro from `@ember/template-compilation`.
*
* Its goal is to convert code like this:
*
* ```js
* import { hbs } from 'ember-template-imports';
*
* const A = hbs(`A`, {...});
* const B = [__GLIMMER_TEMPLATE(`B`, {...})];
* class C {
* template = hbs(`C`, {...});
* }
*
* [__GLIMMER_TEMPLATE(`default`, {...})];
*
* class D {
* [__GLIMMER_TEMPLATE(`D`, {...})]
* }
* ```
*
* Into this:
*
* ```js
* import { precompileTemplate } from '@ember/template-compilation';
* import { setComponentTemplate } from '@ember/component';
* import templateOnlyComponent from '@ember/component/template-only';
*
* const A = setComponentTemplate(
* precompileTemplate(`A`, {...}),
* templateOnlyComponent('this-module.js', 'A')
* );
* const B = setComponentTemplate(
* precompileTemplate(`B`, {...}),
* templateOnlyComponent('this-module.js', 'B')
* );
* class C {}
* setComponentTemplate(precompileTemplate(`C`, {...}), C);
*
* export default setComponentTemplate(
* precompileTemplate(`default`, {...}),
* templateOnlyComponent('this-module.js', '_thisModule')
* );
*
* class D {}
* setComponentTemplate(precompileTemplate(`D`, {...}), D);
* ```
*/
export default function (babel: any) {
let t = babel.types;

let visitor: any = {
Program: {
enter(path: NodePath<Program>, state: any) {
state.importUtil = new ImportUtil(t, path);
},
},

// Process class bodies before things like class properties get transformed
// into imperative constructor code that we can't recognize. Taken directly
// from babel-plugin-htmlbars-inline-precompile https://git.io/JMi1G
Class(path: NodePath<Class>, state: any) {
let bodyPath = path.get('body.body');

if (!Array.isArray(bodyPath)) return;

bodyPath.forEach((path) => {
if (path.type !== 'ClassProperty') return;

let keyPath = path.get('key');
let valuePath = path.get('value');

if (Array.isArray(keyPath)) return;

if (keyPath && visitor[keyPath.type]) {
visitor[keyPath.type](keyPath, state);
}

if (Array.isArray(valuePath)) return;

if (valuePath && visitor[valuePath.type]) {
visitor[valuePath.type](valuePath, state);
}
});
},

CallExpression(path: NodePath<CallExpression>, state: any) {
if (util.isTemplateTag(path)) {
transformTemplateTag(t, path, state);
}
},
};

return { visitor };
}
7 changes: 7 additions & 0 deletions packages/ember-repl/addon/cjs/eti/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function expect<T>(value: T | null | undefined, message: string): T {
if (value === undefined || value === null) {
throw new Error(`LIBRARY BUG: ${message}`);
}

return value;
}
Loading

0 comments on commit c539278

Please sign in to comment.