-
Notifications
You must be signed in to change notification settings - Fork 368
/
index.js
135 lines (113 loc) 路 3.43 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { createMacro, MacroError } from "babel-plugin-macros"
import makeJsTransformer from "./js"
import JSXTransformer from "@lingui/babel-plugin-transform-react/transformer"
function macro({ references, state, babel }) {
const { types: t } = babel
const transformer = makeJsTransformer(babel)
const jsxTransformer = new JSXTransformer(babel)
const reactImportsToCarryOver = ["DateFormat", "NumberFormat"]
const reactImports = []
Object.keys(references).forEach(tagName => {
const tags = references[tagName]
const macroType = getMacroType(tagName)
if (macroType === "jsx") {
if (!reactImports.includes("Trans")) {
reactImports.push("Trans")
}
if (reactImportsToCarryOver.includes(tagName)) {
reactImports.push(tagName)
}
// Trick the plugin into thinking we've processed an import
jsxTransformer.setImportDeclarations(
Object.keys(references).reduce((obj, key) => {
if (key !== "default" || key !== "Trans") obj[key] = key
return obj
}, {})
)
tags.forEach(openingTag => {
if (!t.isJSXOpeningElement(openingTag.container)) return // Exclude closing elements
const node = openingTag.context.parentPath.container
jsxTransformer.transform({ node }, state.file)
})
} else {
tags.forEach(tag => {
let expression = tag.parentPath
if (tagName === "t" && t.isCallExpression(expression)) {
expression = expression.parentPath
}
transformer(expression, state.file)
})
}
})
addLinguiReactImports(babel, state, reactImports)
if (process.env.LINGUI_EXTRACT === "1") {
return {
keepImports: true
}
}
}
function getMacroType(tagName) {
switch (tagName) {
case "t":
case "plural":
case "select":
case "selectOrdinal":
case "number":
case "date":
return "js"
case "Trans":
case "Plural":
case "Select":
case "SelectOrdinal":
case "NumberFormat":
case "DateFormat":
return "jsx"
}
}
function addLinguiReactImports(babel, state, imports) {
if (!imports.length) return
const { types: t } = babel
const linguiReactImport = state.file.path.node.body.find(
importNode =>
t.isImportDeclaration(importNode) &&
importNode.source.value === "@lingui/react"
)
// Handle adding the import or altering the existing import
if (linguiReactImport) {
imports.forEach(name => {
if (
linguiReactImport.specifiers.findIndex(
specifier => specifier.imported && specifier.imported.name === name
) === -1
) {
linguiReactImport.specifiers.push(
t.importSpecifier(t.identifier(name), t.identifier(name))
)
}
})
} else {
state.file.path.node.body.unshift(
t.importDeclaration(
imports.map(name =>
t.importSpecifier(t.identifier(name), t.identifier(name))
),
t.stringLiteral("@lingui/react")
)
)
}
}
const Trans = () => {}
const Plural = () => {}
const Select = () => {}
const SelectOrdinal = () => {}
const DateFormat = () => {}
const NumberFormat = () => {}
const t = () => {}
const plural = () => {}
const select = () => {}
const selectOrdinal = () => {}
const date = () => {}
const number = () => {}
export { Trans, Plural, Select, SelectOrdinal, DateFormat, NumberFormat }
export { t, plural, select, selectOrdinal, date, number }
export default createMacro(macro)