diff --git a/.changeset/itchy-eggs-impress.md b/.changeset/itchy-eggs-impress.md new file mode 100644 index 000000000..c3d70dc8c --- /dev/null +++ b/.changeset/itchy-eggs-impress.md @@ -0,0 +1,7 @@ +--- +'@linaria/babel-preset': patch +'@linaria/tags': patch +'@linaria/testkit': patch +--- + +Add the tagSource property for processors, indicating the package and name of the imported processor. diff --git a/packages/babel/src/utils/getTagProcessor.ts b/packages/babel/src/utils/getTagProcessor.ts index 8cd5a721e..ed52c10a8 100644 --- a/packages/babel/src/utils/getTagProcessor.ts +++ b/packages/babel/src/utils/getTagProcessor.ts @@ -18,6 +18,7 @@ import type { Params, IFileContext, ExpressionValue, + TagSource, } from '@linaria/tags'; import type { IImport, StrictOptions } from '@linaria/utils'; import { @@ -34,6 +35,7 @@ import getSource from './getSource'; type BuilderArgs = ConstructorParameters extends [ Params, + TagSource, typeof t, SourceLocation | null, (replacement: Expression, isPure: boolean) => void, @@ -164,11 +166,13 @@ function getProcessorForIdentifier( StrictOptions, 'classNameSlug' | 'displayName' | 'evaluate' | 'tagResolver' > -): [ProcessorClass, NodePath] | [null, null] { +): + | [ProcessorClass, TagSource, NodePath] + | [null, null, null] { const pathBinding = path.scope.getBinding(path.node.name); if (!pathBinding) { // It's not a binding, so it's not a tag - return [null, null]; + return [null, null, null]; } const tagResolver = options.tagResolver ?? (() => null); @@ -203,28 +207,29 @@ function getProcessorForIdentifier( .filter((i) => i[1] === null || i[1].isExpression()); if (relatedImports.length === 0) { - return [null, null]; + return [null, null, null]; } - const [Processor = null, tagPath = null] = + const [Processor = null, tagSource = null, tagPath = null] = relatedImports .map( - ([imp, p]): [ + ([{ imported, source }, p]): [ ProcessorClass | null, + TagSource, NodePath | null ] => { - const source = tagResolver(imp.source, imp.imported); - const processor = source - ? getProcessorFromFile(source) - : getProcessorFromPackage(imp.source, imp.imported, filename); - return [processor, p]; + const customFile = tagResolver(source, imported); + const processor = customFile + ? getProcessorFromFile(customFile) + : getProcessorFromPackage(source, imported, filename); + return [processor, { imported, source }, p]; } ) .find(([proc]) => proc) ?? []; - return Processor === null || tagPath === null - ? [null, null] - : [Processor, tagPath]; + return Processor === null || tagSource === null || tagPath === null + ? [null, null, null] + : [Processor, tagSource, tagPath]; } function getBuilderForIdentifier( @@ -236,14 +241,14 @@ function getBuilderForIdentifier( 'classNameSlug' | 'displayName' | 'evaluate' | 'tagResolver' > ): Builder | null { - const [Processor, tagPath] = getProcessorForIdentifier( + const [Processor, tagSource, tagPath] = getProcessorForIdentifier( path, imports, filename, options ); - if (!Processor || !tagPath) { + if (!Processor || !tagSource || !tagPath) { return null; } @@ -345,6 +350,7 @@ function getBuilderForIdentifier( return (...args: BuilderArgs) => new Processor( params, + tagSource, astService, tagPath.node.loc ?? null, replacer, diff --git a/packages/tags/src/BaseProcessor.ts b/packages/tags/src/BaseProcessor.ts index e45b5330d..4647203f3 100644 --- a/packages/tags/src/BaseProcessor.ts +++ b/packages/tags/src/BaseProcessor.ts @@ -29,6 +29,11 @@ export type TailProcessorParams = ProcessorParams extends [Params, ...infer T] ? T : never; +export type TagSource = { + imported: string; + source: string; +}; + export default abstract class BaseProcessor { public static SKIP = Symbol('skip'); @@ -50,6 +55,7 @@ export default abstract class BaseProcessor { public constructor( params: Params, + public tagSource: TagSource, protected readonly astService: typeof t & { addDefaultImport: (source: string, nameHint?: string) => Identifier; addNamedImport: ( diff --git a/packages/testkit/src/utils/getTagProcessor.test.ts b/packages/testkit/src/utils/getTagProcessor.test.ts index be8bd0387..60043a461 100644 --- a/packages/testkit/src/utils/getTagProcessor.test.ts +++ b/packages/testkit/src/utils/getTagProcessor.test.ts @@ -32,7 +32,7 @@ const run = (code: string): BaseProcessor | null => { return result; }; -function tagSource(processor: BaseProcessor | null): string | undefined { +function tagToString(processor: BaseProcessor | null): string | undefined { if (!processor) return undefined; return processor.toString(); } @@ -50,7 +50,11 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('renamedStyled(Cmp)`…`'); + expect(tagToString(result)).toBe('renamedStyled(Cmp)`…`'); + expect(result?.tagSource).toEqual({ + imported: 'styled', + source: '@linaria/atomic', + }); }); it('imported component', () => { @@ -63,7 +67,11 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('styled(Layout)`…`'); + expect(tagToString(result)).toBe('styled(Layout)`…`'); + expect(result?.tagSource).toEqual({ + imported: 'styled', + source: '@linaria/react', + }); }); it('renamedStyled(Cmp)``', () => { @@ -77,7 +85,11 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('renamedStyled(Cmp)`…`'); + expect(tagToString(result)).toBe('renamedStyled(Cmp)`…`'); + expect(result?.tagSource).toEqual({ + imported: 'styled', + source: '@linaria/react', + }); }); it('(0, react_1.styled)(Cmp)``', () => { @@ -91,7 +103,11 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('react_1.styled(Cmp)`…`'); + expect(tagToString(result)).toBe('react_1.styled(Cmp)`…`'); + expect(result?.tagSource).toEqual({ + imported: 'styled', + source: '@linaria/react', + }); }); it('styled(Cmp)``', () => { @@ -105,7 +121,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('styled(Cmp)`…`'); + expect(tagToString(result)).toBe('styled(Cmp)`…`'); }); it('styled(hoc(Title))``', () => { @@ -126,7 +142,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('styled(hoc(Title))`…`'); + expect(tagToString(result)).toBe('styled(hoc(Title))`…`'); }); it('styled(() => { someLogic(); })``', () => { @@ -143,7 +159,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('styled(() => {…})`…`'); + expect(tagToString(result)).toBe('styled(() => {…})`…`'); }); it('renamedStyled.div``', () => { @@ -155,7 +171,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe("renamedStyled('div')`…`"); + expect(tagToString(result)).toBe("renamedStyled('div')`…`"); }); it('(0, react_1.styled.div)``', () => { @@ -167,7 +183,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe("react_1.styled('div')`…`"); + expect(tagToString(result)).toBe("react_1.styled('div')`…`"); }); it('styled.div``', () => { @@ -179,7 +195,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe("styled('div')`…`"); + expect(tagToString(result)).toBe("styled('div')`…`"); }); it('styled("div")``', () => { @@ -191,7 +207,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe("styled('div')`…`"); + expect(tagToString(result)).toBe("styled('div')`…`"); }); it('(0, core_1.css)``', () => { @@ -203,7 +219,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('core_1.css`…`'); + expect(tagToString(result)).toBe('core_1.css`…`'); }); it('css``', () => { @@ -215,7 +231,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('css`…`'); + expect(tagToString(result)).toBe('css`…`'); }); it('atomic css``', () => { @@ -227,7 +243,11 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('css`…`'); + expect(tagToString(result)).toBe('css`…`'); + expect(result?.tagSource).toEqual({ + imported: 'css', + source: '@linaria/atomic', + }); }); it('re-imported css', () => { @@ -239,7 +259,11 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe('css`…`'); + expect(tagToString(result)).toBe('css`…`'); + expect(result?.tagSource).toEqual({ + imported: 'css', + source: 'linaria', + }); }); it('re-imported styled', () => { @@ -251,7 +275,11 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe("styled('div')`…`"); + expect(tagToString(result)).toBe("styled('div')`…`"); + expect(result?.tagSource).toEqual({ + imported: 'styled', + source: 'linaria/react', + }); }); it('import from unknown package', () => { @@ -274,7 +302,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe("renamedStyled('div')`…`"); + expect(tagToString(result)).toBe("renamedStyled('div')`…`"); }); it('require and destructing', () => { @@ -285,7 +313,7 @@ describe('getTagProcessor', () => { ` ); - expect(tagSource(result)).toBe("styled('div')`…`"); + expect(tagToString(result)).toBe("styled('div')`…`"); }); describe('invalid usage', () => {