Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

Commit

Permalink
feat(parser): Added support for custom import names
Browse files Browse the repository at this point in the history
import x, { i18nGroup as y } from 'es2015-i18n-tag' is now detected by i18n-tag-schema
  • Loading branch information
skolmer committed Jan 26, 2017
1 parent 9941beb commit 3c6de75
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 31 deletions.
26 changes: 14 additions & 12 deletions __tests__/data/grouped.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
@i18nGroup('custom group')
import i18nc, { i18nGroup as e } from 'es2015-i18n-tag'

@e('custom group')
export class Test {
log() {
console.log(this.i18n`Hello ${name}, you have ${amount}:c in your bank account.`)
console.log(i18n('custom inline group') `Hello!`)
console.log(i18nc('custom inline group') `Hello!`)
console.log(this.i18n('custom inline group') `Welcome!`)

console.log(i18n`
console.log(i18nc`
<users>
${hello.map((item) => i18n`
${hello.map((item) => i18nc`
<user name="${item.name}">${item.percentage}:p</user>
`).join('')}
</users>
`)

}
}
}


class TestX {
log() {
console.log(this.i18n`Hello ${name}, you have ${amount}:c in your bank account.`)
console.log(i18n('custom inline group') `Hello!`)
console.log(i18nc('custom inline group') `Hello!`)
console.log(this.i18n('custom inline group') `Welcome!`)
console.log(i18n(__translationGroup) `Hello!`)
}
console.log(i18nc(__translationGroup) `Hello!`)
}
}
export default i18nGroup('custom group 2')(TestX)
export default e('custom group 2')(TestX)

@i18nGroup(__translationGroup)
@e(__translationGroup)
export class TestY {
log() {
console.log(this.i18n`Hello ${name}, you have ${amount}:c in your bank account.`)
console.log(i18n('custom inline group') `Hello!`)
console.log(i18nc('custom inline group') `Hello!`)
console.log(this.i18n('custom inline group') `Welcome!`)
}
}
}
2 changes: 2 additions & 0 deletions __tests__/data/multiline.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import i18n, { i18nGroup } from 'es2015-i18n-tag'

console.log(i18n`
<users>
${hello.map((item) => i18n`
Expand Down
13 changes: 5 additions & 8 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,13 @@ const defaultBabylonConfig = {
}

export const parseFile = (contents, templatePatterns, preprocessor, babylonConfig) => {
if(!contents) return { templates: [], templatePatterns }
contents = processObject(contents, preprocessor)
const templateRegEx = /i18n(?:\(.*?\))?\s*`[^`]*`/g
const matches = templateRegEx.exec(contents)
const templates = []
if (matches && matches.length) {
const ev = (source) => {
const ast = babylon.parse(source, babylonConfig || defaultBabylonConfig)
traverseAst(ast, source, templates, templatePatterns)
}
ev(contents)
const ev = (source) => {
const ast = babylon.parse(source, babylonConfig || defaultBabylonConfig)
traverseAst(ast, source, templates, templatePatterns)
}
ev(contents)
return { templates, templatePatterns }
}
42 changes: 31 additions & 11 deletions lib/traversal.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import escapeStringRegexp from 'escape-string-regexp'
import traverse from 'babel-traverse'

const traverseTemplateExpressions = {
TaggedTemplateExpression: (path, { source, templates, groupName, templatePatterns }) => {
TaggedTemplateExpression: (path, { source, templates, groupName, templatePatterns, importNames }) => {
const node = path.node
if (node.scanned) return
node.scanned = true
if (node.tag.name === 'i18n' || (node.tag.callee && (node.tag.callee.name === 'i18n' || (node.tag.callee.property && node.tag.callee.property.name === 'i18n'))) || (node.tag.property && node.tag.property.name === 'i18n')) {
if (node.tag.name === importNames.i18n || (node.tag.callee && (node.tag.callee.name === importNames.i18n || (node.tag.callee.property && node.tag.callee.property.name === 'i18n'))) || (node.tag.property && node.tag.property.name === 'i18n')) {
if (node.tag.arguments && node.tag.arguments.length) {
groupName = node.tag.arguments[0].value || node.tag.arguments[0].name
}
Expand Down Expand Up @@ -37,27 +37,45 @@ const traverseTemplateExpressions = {
}
}

const traverseImportDeclarations = {
ImportDeclaration: (path, { importNames }) => {
const node = path.node
if (node.source &&
node.source.value &&
node.source.value.indexOf('es2015-i18n-tag') > -1 &&
node.specifiers) {
node.specifiers.forEach((spec) => {
if(spec.type === 'ImportDefaultSpecifier' && spec.local && spec.local.name !== importNames.i18n) {
importNames.i18n = spec.local.name
} else if(spec.type === 'ImportSpecifier' && spec.local && spec.imported && spec.imported.name === 'i18nGroup' && spec.local.name !== importNames.i18nGroup) {
importNames.i18nGroup = spec.local.name
}
})
}
}
}

const traverseClassDeclarations = {
ClassDeclaration: (path, { source, templates, groups, templatePatterns }) => {
ClassDeclaration: (path, { source, templates, groups, templatePatterns, importNames }) => {
const node = path.node
if (node.decorators && node.decorators.length) {
const groupNames = node.decorators.map((d) => d.expression).filter((e) => e.callee && e.callee.name === 'i18nGroup' && e.arguments && e.arguments.length).map((d) => d.arguments.map((a) => a.name || a.value)).reduce((p, n) => p.concat(n), [])
const groupNames = node.decorators.map((d) => d.expression).filter((e) => e.callee && e.callee.name === importNames.i18nGroup && e.arguments && e.arguments.length).map((d) => d.arguments.map((a) => a.name || a.value)).reduce((p, n) => p.concat(n), [])
const groupName = (groupNames.length) ? groupNames[0] : null
path.traverse(traverseTemplateExpressions, { source, templates, groupName, templatePatterns })
path.traverse(traverseTemplateExpressions, { source, templates, groupName, templatePatterns, importNames })
} else {
path.traverse(traverseTemplateExpressions, { source, templates, groupName: groups[node.id.name], templatePatterns })
path.traverse(traverseTemplateExpressions, { source, templates, groupName: groups[node.id.name], templatePatterns, importNames })
}
}
}

const traverseExportDeclarations = {
CallExpression: (path, { groups }) => {
CallExpression: (path, { groups, importNames }) => {
const node = path.node
if (node.callee &&
node.callee.type === 'CallExpression' &&
node.callee.callee &&
node.callee.callee.type === 'Identifier' &&
node.callee.callee.name === 'i18nGroup' &&
node.callee.callee.name === importNames.i18nGroup &&
node.callee.arguments &&
node.callee.arguments.length &&
node.arguments &&
Expand All @@ -71,9 +89,11 @@ export const traverseAst = (ast, source, templates, templatePatterns) => {
const groups = []
traverse(ast, {
Program: (path) => {
path.traverse(traverseExportDeclarations, { source, templates, groups }) // find all i18nGroup calls
path.traverse(traverseClassDeclarations, { source, templates, groups, templatePatterns }) // traverse classes first to get group decorators
path.traverse(traverseTemplateExpressions, { source, templates, groupName: null, templatePatterns }) // traverse all template expressions
const importNames = { i18n: 'i18n', i18nGroup: 'i18nGroup'}
path.traverse(traverseImportDeclarations, { importNames })
path.traverse(traverseExportDeclarations, { groups, importNames }) // find all i18nGroup calls
path.traverse(traverseClassDeclarations, { source, templates, groups, templatePatterns, importNames }) // traverse classes first to get group decorators
path.traverse(traverseTemplateExpressions, { source, templates, groupName: null, templatePatterns, importNames }) // traverse all template expressions
}
})
}

0 comments on commit 3c6de75

Please sign in to comment.