Skip to content

Commit 564ed0d

Browse files
committed
refactor: add support for relative export and import expression matching
1 parent 829d951 commit 564ed0d

File tree

9 files changed

+187
-0
lines changed

9 files changed

+187
-0
lines changed

src/compileMatcher/CallExpression.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { NodePath, CallExpression } from '../types'
22
import { CompiledMatcher, CompileOptions } from '.'
33
import compileSpecialMatcher from './SpecialMatcher'
4+
import { compileRelativeSourceMatcher } from './RelativeSource'
45

56
export default function compileCallExpressionMatcher(
67
path: NodePath<CallExpression, CallExpression>,
@@ -19,4 +20,29 @@ export default function compileCallExpressionMatcher(
1920

2021
if (special) return special
2122
}
23+
if (n.Import.check(callee)) {
24+
const sourceMatcher = compileRelativeSourceMatcher(
25+
path.get('arguments').get(0),
26+
compileOptions
27+
)
28+
if (sourceMatcher) {
29+
return {
30+
pattern: path,
31+
match: (path, matchSoFar, options) => {
32+
const { value } = path
33+
if (
34+
value.type !== 'CallExpression' ||
35+
!n.Import.check(value.callee)
36+
) {
37+
return null
38+
}
39+
return sourceMatcher.match(
40+
path.get('arguments').get(0),
41+
matchSoFar,
42+
options
43+
)
44+
},
45+
}
46+
}
47+
}
2248
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { ExportAllDeclaration, NodePath } from '../types'
2+
import { CompiledMatcher, CompileOptions, MatchResult } from '.'
3+
import compileGenericNodeMatcher from './GenericNodeMatcher'
4+
import { compileRelativeSourceMatcher } from './RelativeSource'
5+
6+
export default function compileImportSpecifierMatcher(
7+
path: NodePath<ExportAllDeclaration, ExportAllDeclaration>,
8+
compileOptions: CompileOptions
9+
): CompiledMatcher | void {
10+
const pattern: ExportAllDeclaration = path.value
11+
12+
const importKind = (pattern as any).importKind || 'value'
13+
14+
const sourceMatcher = compileRelativeSourceMatcher(
15+
path.get('source'),
16+
compileOptions
17+
)
18+
19+
return compileGenericNodeMatcher(path, compileOptions, {
20+
keyMatchers: {
21+
importKind: {
22+
pattern: path.get('importKind') as any,
23+
match: (
24+
path: NodePath<any, any>,
25+
matchSoFar: MatchResult
26+
): MatchResult => {
27+
return (path.value || 'value') === importKind
28+
? matchSoFar || {}
29+
: null
30+
},
31+
},
32+
...(sourceMatcher ? { source: sourceMatcher } : {}),
33+
},
34+
})
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { ExportNamedDeclaration, NodePath } from '../types'
2+
import { CompiledMatcher, CompileOptions, MatchResult } from '.'
3+
import compileGenericNodeMatcher from './GenericNodeMatcher'
4+
import { compileRelativeSourceMatcher } from './RelativeSource'
5+
6+
export default function compileImportSpecifierMatcher(
7+
path: NodePath<ExportNamedDeclaration, ExportNamedDeclaration>,
8+
compileOptions: CompileOptions
9+
): CompiledMatcher | void {
10+
const pattern: ExportNamedDeclaration = path.value
11+
12+
const importKind = (pattern as any).importKind || 'value'
13+
14+
const sourceMatcher = compileRelativeSourceMatcher(
15+
path.get('source'),
16+
compileOptions
17+
)
18+
19+
return compileGenericNodeMatcher(path, compileOptions, {
20+
keyMatchers: {
21+
importKind: {
22+
pattern: path.get('importKind') as any,
23+
match: (
24+
path: NodePath<any, any>,
25+
matchSoFar: MatchResult
26+
): MatchResult => {
27+
return (path.value || 'value') === importKind
28+
? matchSoFar || {}
29+
: null
30+
},
31+
},
32+
...(sourceMatcher ? { source: sourceMatcher } : {}),
33+
},
34+
})
35+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { ImportExpression, NodePath } from '../types'
2+
import { CompiledMatcher, CompileOptions } from '.'
3+
import compileGenericNodeMatcher from './GenericNodeMatcher'
4+
import { compileRelativeSourceMatcher } from './RelativeSource'
5+
6+
export default function compileImportExpressionMatcher(
7+
path: NodePath<ImportExpression, ImportExpression>,
8+
compileOptions: CompileOptions
9+
): CompiledMatcher | void {
10+
const sourceMatcher = compileRelativeSourceMatcher(
11+
path.get('source'),
12+
compileOptions
13+
)
14+
15+
return compileGenericNodeMatcher(path, compileOptions, {
16+
keyMatchers: {
17+
...(sourceMatcher ? { source: sourceMatcher } : {}),
18+
},
19+
})
20+
}

src/compileMatcher/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ import ClassImplements from './ClassImplements'
99
import ClassProperty from './ClassProperty'
1010
import compileGenericArrayMatcher from './GenericArrayMatcher'
1111
import compileGenericNodeMatcher from './GenericNodeMatcher'
12+
import ExportAllDeclaration from './ExportAllDeclaration'
13+
import ExportNamedDeclaration from './ExportNamedDeclaration'
1214
import ExportSpecifier from './ExportSpecifier'
1315
import ExpressionStatement from './ExpressionStatement'
1416
import FunctionTypeParam from './FunctionTypeParam'
1517
import GenericTypeAnnotation from './GenericTypeAnnotation'
1618
import Identifier from './Identifier'
1719
import ImportDeclaration from './ImportDeclaration'
20+
import ImportExpression from './ImportExpression'
1821
import ImportSpecifier from './ImportSpecifier'
1922
import JSXAttribute from './JSXAttribute'
2023
import JSXElement from './JSXElement'
@@ -139,12 +142,15 @@ const nodeMatchers: Record<
139142
CallExpression,
140143
ClassImplements,
141144
ClassProperty,
145+
ExportAllDeclaration,
146+
ExportNamedDeclaration,
142147
ExportSpecifier,
143148
ExpressionStatement,
144149
FunctionTypeParam,
145150
GenericTypeAnnotation,
146151
Identifier,
147152
ImportDeclaration,
153+
ImportExpression,
148154
ImportSpecifier,
149155
JSXAttribute,
150156
JSXElement,

src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ export type CallExpression = b.CallExpression | k.CallExpressionKind
104104
export type ClassDeclaration = b.ClassImplements | k.ClassImplementsKind
105105
export type ClassImplements = b.ClassImplements | k.ClassImplementsKind
106106
export type ClassProperty = b.ClassProperty | k.ClassPropertyKind
107+
export type ExportAllDeclaration =
108+
| b.ExportAllDeclaration
109+
| k.ExportAllDeclarationKind
107110
export type ExportDeclaration = b.ExportDeclaration | k.ExportDeclarationKind
108111
export type ExportDefaultSpecifier =
109112
| b.ExportDefaultSpecifier
@@ -127,6 +130,7 @@ export type ImportDefaultSpecifier =
127130
| b.ImportDefaultSpecifier
128131
| k.ImportDefaultSpecifierKind
129132
export type ImportDeclaration = b.ImportDeclaration | k.ImportDeclarationKind
133+
export type ImportExpression = b.ImportExpression | k.ImportExpressionKind
130134
export type ImportNamespaceSpecifier =
131135
| b.ImportNamespaceSpecifier
132136
| k.ImportNamespaceSpecifierKind
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { findReplaceTestcase } from '../findReplaceTestcase'
2+
import dedent from 'dedent-js'
3+
import path from 'path'
4+
5+
findReplaceTestcase({
6+
file: __filename,
7+
transformFile: path.resolve(__dirname, 'test/transform.ts'),
8+
input: dedent`
9+
export * from '../foo'
10+
export * from './foo'
11+
`,
12+
find: dedent`
13+
export * from '../../foo'
14+
`,
15+
expectedFind: [
16+
{
17+
node: `export * from '../foo'`,
18+
},
19+
],
20+
})
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { findReplaceTestcase } from '../findReplaceTestcase'
2+
import dedent from 'dedent-js'
3+
import path from 'path'
4+
5+
findReplaceTestcase({
6+
file: __filename,
7+
transformFile: path.resolve(__dirname, 'test/transform.ts'),
8+
input: dedent`
9+
export { a } from '../foo'
10+
export { b } from './foo'
11+
`,
12+
find: dedent`
13+
export { $$a } from '../../foo'
14+
`,
15+
expectedFind: [
16+
{
17+
arrayCaptures: { $$a: ['a'] },
18+
node: `export { a } from '../foo'`,
19+
},
20+
],
21+
})
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { findReplaceTestcase } from '../findReplaceTestcase'
2+
import dedent from 'dedent-js'
3+
import path from 'path'
4+
5+
findReplaceTestcase({
6+
file: __filename,
7+
transformFile: path.resolve(__dirname, 'test/transform.ts'),
8+
input: dedent`
9+
import('../foo')
10+
import('./foo')
11+
`,
12+
find: dedent`
13+
import('../../foo')
14+
`,
15+
expectedFind: [
16+
{
17+
node: `import('../foo')`,
18+
},
19+
],
20+
})

0 commit comments

Comments
 (0)