Skip to content

Commit

Permalink
Merge pull request #1806 from embroider-build/emit-imports-for-known-…
Browse files Browse the repository at this point in the history
…built-ins

resolver transform to emit imports for helper and modifiers that need…
  • Loading branch information
ef4 authored Apr 2, 2024
2 parents 2694ad9 + b727fc9 commit 60441fa
Show file tree
Hide file tree
Showing 2 changed files with 248 additions and 57 deletions.
197 changes: 147 additions & 50 deletions packages/compat/src/resolver-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,51 +43,78 @@ export interface Options {
appRoot: string;
}

export const builtInKeywords = [
'-get-dynamic-var',
'-in-element',
'-with-dynamic-vars',
'action',
'array',
'component',
'concat',
'debugger',
'each-in',
'each',
'fn',
'get',
'has-block-params',
'has-block',
'hasBlock',
'hasBlockParams',
'hash',
'helper',
'if',
'in-element',
'input',
'let',
'link-to',
'loc',
'log',
'modifier',
'mount',
'mut',
'on',
'outlet',
'partial',
'query-params',
'readonly',
'textarea',
'unbound',
'unique-id',
'unless',
'with',
'yield',
];
type BuiltIn = {
importableHelper?: [string, string];
importableComponent?: [string, string];
importableModifier?: [string, string];
};

const builtInKeywords: Record<string, BuiltIn | undefined> = {
'-get-dynamic-var': {},
'-in-element': {},
'-with-dynamic-vars': {},
action: {},
array: {
importableHelper: ['array', '@ember/helper'],
},
component: {},
concat: {
importableHelper: ['concat', '@ember/helper'],
},
debugger: {},
'each-in': {},
each: {},
fn: {
importableHelper: ['fn', '@ember/helper'],
},
get: {
importableHelper: ['get', '@ember/helper'],
},
'has-block-params': {},
'has-block': {},
hasBlock: {},
hasBlockParams: {},
hash: {
importableHelper: ['hash', '@ember/helper'],
},
helper: {},
if: {},
'in-element': {},
input: {
importableComponent: ['Input', '@ember/component'],
},
let: {},
'link-to': {
importableComponent: ['LinkTo', '@ember/routing'],
},
loc: {},
log: {},
modifier: {},
mount: {},
mut: {},
on: {
importableModifier: ['on', '@ember/modifier'],
},
outlet: {},
partial: {},
'query-params': {},
readonly: {},
textarea: {
importableComponent: ['Textarea', '@ember/component'],
},
unbound: {},
'unique-id': {
importableHelper: ['uniqueId', '@ember/helper'],
},
unless: {},
with: {},
yield: {},
};

interface ComponentResolution {
type: 'component';
specifier: string;
importedName: string;
yieldsComponents: Required<ComponentRules>['yieldsSafeComponents'];
yieldsArguments: Required<ComponentRules>['yieldsArguments'];
argumentsAreComponents: string[];
Expand All @@ -98,11 +125,13 @@ type HelperResolution = {
type: 'helper';
nameHint: string;
specifier: string;
importedName: string;
};

type ModifierResolution = {
type: 'modifier';
specifier: string;
importedName: string;
nameHint: string;
};

Expand Down Expand Up @@ -157,7 +186,7 @@ class TemplateResolver implements ASTPlugin {
case 'component':
case 'modifier':
case 'helper': {
let name = this.env.meta.jsutils.bindImport(resolution.specifier, 'default', parentPath, {
let name = this.env.meta.jsutils.bindImport(resolution.specifier, resolution.importedName, parentPath, {
nameHint: resolution.nameHint,
});
setter(parentPath.node, this.env.syntax.builders.path(name));
Expand Down Expand Up @@ -370,7 +399,22 @@ class TemplateResolver implements ASTPlugin {
return null;
}

if (builtInKeywords.includes(name)) {
const builtIn = builtInKeywords[name];

if (builtIn?.importableComponent) {
let [importedName, specifier] = builtIn.importableComponent;
return {
type: 'component',
specifier,
importedName,
yieldsComponents: [],
yieldsArguments: [],
argumentsAreComponents: [],
nameHint: importedName,
};
}

if (builtIn) {
return null;
}
if (this.isIgnoredComponent(name)) {
Expand All @@ -381,6 +425,7 @@ class TemplateResolver implements ASTPlugin {
return {
type: 'component',
specifier: `#embroider_compat/components/${name}`,
importedName: 'default',
yieldsComponents: componentRules ? componentRules.yieldsSafeComponents : [],
yieldsArguments: componentRules ? componentRules.yieldsArguments : [],
argumentsAreComponents: componentRules ? componentRules.argumentsAreComponents : [],
Expand Down Expand Up @@ -437,13 +482,26 @@ class TemplateResolver implements ASTPlugin {
// globally-named helpers. It throws an error. So it's fine for us to
// prioritize the builtIns here without bothering to resolve a user helper
// of the same name.
if (builtInKeywords.includes(path)) {
const builtIn = builtInKeywords[path];

if (builtIn?.importableHelper) {
let [importedName, specifier] = builtIn.importableHelper;
return {
type: 'helper',
specifier,
importedName,
nameHint: importedName,
};
}

if (builtIn) {
return null;
}

return {
type: 'helper',
specifier: `#embroider_compat/helpers/${path}`,
importedName: 'default',
nameHint: this.nameHint(path),
};
}
Expand Down Expand Up @@ -505,11 +563,36 @@ class TemplateResolver implements ASTPlugin {
*/

// first, bail out on all the stuff we can obviously ignore
if (
(!this.staticHelpersEnabled && !this.staticComponentsEnabled) ||
builtInKeywords.includes(path) ||
this.isIgnoredComponent(path)
) {
if ((!this.staticHelpersEnabled && !this.staticComponentsEnabled) || this.isIgnoredComponent(path)) {
return null;
}

let builtIn = builtInKeywords[path];

if (builtIn?.importableComponent) {
let [importedName, specifier] = builtIn.importableComponent;
return {
type: 'component',
specifier,
importedName,
yieldsComponents: [],
yieldsArguments: [],
argumentsAreComponents: [],
nameHint: importedName,
};
}

if (builtIn?.importableHelper) {
let [importedName, specifier] = builtIn.importableHelper;
return {
type: 'helper',
specifier,
importedName,
nameHint: importedName,
};
}

if (builtIn) {
return null;
}

Expand Down Expand Up @@ -560,6 +643,7 @@ class TemplateResolver implements ASTPlugin {
return {
type: 'component',
specifier: `#embroider_compat/ambiguous/${path}`,
importedName: 'default',
yieldsComponents: componentRules ? componentRules.yieldsSafeComponents : [],
yieldsArguments: componentRules ? componentRules.yieldsArguments : [],
argumentsAreComponents: componentRules ? componentRules.argumentsAreComponents : [],
Expand All @@ -571,13 +655,26 @@ class TemplateResolver implements ASTPlugin {
if (!this.staticModifiersEnabled) {
return null;
}
if (builtInKeywords.includes(path)) {

const builtIn = builtInKeywords[path];
if (builtIn?.importableModifier) {
let [importedName, specifier] = builtIn.importableModifier;
return {
type: 'modifier',
specifier,
importedName,
nameHint: importedName,
};
}

if (builtIn) {
return null;
}

return {
type: 'modifier',
specifier: `#embroider_compat/modifiers/${path}`,
importedName: 'default',
nameHint: this.nameHint(path),
};
}
Expand Down
Loading

0 comments on commit 60441fa

Please sign in to comment.