Skip to content

Commit

Permalink
fix(bundle-utils): existing functions not being generated (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon authored Mar 22, 2023
1 parent e864140 commit 4d3fa98
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 52 deletions.
2 changes: 2 additions & 0 deletions packages/bundle-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
"@intlify/message-compiler": "9.3.0-beta.17",
"@intlify/shared": "9.3.0-beta.17",
"acorn": "^8.8.2",
"escodegen": "^2.0.0",
"estree-walker": "^2.0.2",
"jsonc-eslint-parser": "^1.0.1",
"magic-string": "^0.30.0",
"source-map": "0.6.1",
"yaml-eslint-parser": "^0.3.2"
},
"devDependencies": {
"@types/escodegen": "^0.0.7",
"@types/estree": "^1.0.0"
},
"engines": {
Expand Down
124 changes: 72 additions & 52 deletions packages/bundle-utils/src/js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import { isString, isBoolean, isNumber } from '@intlify/shared'
import { parse as parseJavaScript } from 'acorn'
import { generate as generateJavaScript } from 'escodegen'
import { walk } from 'estree-walker'
import {
createCodeGenerator,
Expand Down Expand Up @@ -223,69 +224,86 @@ function generateNode(
}
break
case 'Property':
if (node != null) {
if (
isJSONablePrimitiveLiteral(node.value) &&
(node.key.type === 'Literal' || node.key.type === 'Identifier')
) {
// prettier-ignore
const name = node.key.type === 'Literal'
? String(node.key.value)
: node.key.name
if (parent != null && parent.type === 'ObjectExpression') {
if (node != null) {
if (
(node.value.type === 'Literal' && isString(node.value.value)) ||
node.value.type === 'TemplateLiteral'
isJSONablePrimitiveLiteral(node.value) &&
(node.key.type === 'Literal' || node.key.type === 'Identifier')
) {
const value = getValue(node.value) as string
generator.push(`${JSON.stringify(name)}: `)
pathStack.push(name)
const { code, map } = generateMessageFunction(
value,
options,
pathStack
)
sourceMap && map != null && codeMaps.set(value, map)
generator.push(`${code}`, node.value, value)
skipStack.push(false)
} else {
const value = getValue(node.value)
if (forceStringify) {
const strValue = JSON.stringify(value)
// prettier-ignore
const name = node.key.type === 'Literal'
? String(node.key.value)
: node.key.name
if (
(node.value.type === 'Literal' &&
isString(node.value.value)) ||
node.value.type === 'TemplateLiteral'
) {
const value = getValue(node.value) as string
generator.push(`${JSON.stringify(name)}: `)
pathStack.push(name)
const { code, map } = generateMessageFunction(
strValue,
value,
options,
pathStack
)
sourceMap && map != null && codeMaps.set(strValue, map)
generator.push(`${code}`, node.value, strValue)
sourceMap && map != null && codeMaps.set(value, map)
generator.push(`${code}`, node.value, value)
skipStack.push(false)
} else {
generator.push(
`${JSON.stringify(name)}: ${JSON.stringify(value)}`
)
pathStack.push(name)
const value = getValue(node.value)
if (forceStringify) {
const strValue = JSON.stringify(value)
generator.push(`${JSON.stringify(name)}: `)
pathStack.push(name)
const { code, map } = generateMessageFunction(
strValue,
options,
pathStack
)
sourceMap && map != null && codeMaps.set(strValue, map)
generator.push(`${code}`, node.value, strValue)
} else {
generator.push(
`${JSON.stringify(name)}: ${JSON.stringify(value)}`
)
pathStack.push(name)
}
skipStack.push(false)
}
} else if (
(node.value.type === 'FunctionExpression' ||
node.value.type === 'ArrowFunctionExpression') &&
(node.key.type === 'Literal' || node.key.type === 'Identifier')
) {
// prettier-ignore
const name = node.key.type === 'Literal'
? String(node.key.value)
: node.key.name
generator.push(`${JSON.stringify(name)}: `)
pathStack.push(name)
const code = generateJavaScript(node.value)
generator.push(`${code}`, node.value, code)
skipStack.push(false)
}
} else if (
(node.value.type === 'ObjectExpression' ||
node.value.type === 'ArrayExpression') &&
(node.key.type === 'Literal' || node.key.type === 'Identifier')
) {
// prettier-ignore
const name = node.key.type === 'Literal'
} else if (
(node.value.type === 'ObjectExpression' ||
node.value.type === 'ArrayExpression') &&
(node.key.type === 'Literal' || node.key.type === 'Identifier')
) {
// prettier-ignore
const name = node.key.type === 'Literal'
? String(node.key.value)
: node.key.name
generator.push(`${JSON.stringify(name)}: `)
pathStack.push(name)
} else {
// for Regex, function, etc.
skipStack.push(true)
generator.push(`${JSON.stringify(name)}: `)
pathStack.push(name)
} else {
// for Regex, function, etc.
skipStack.push(true)
}
}
const lastIndex = propsCountStack.length - 1
propsCountStack[lastIndex] = --propsCountStack[lastIndex]
}
const lastIndex = propsCountStack.length - 1
propsCountStack[lastIndex] = --propsCountStack[lastIndex]
break
case 'ArrayExpression':
generator.push(`[`)
Expand Down Expand Up @@ -389,10 +407,12 @@ function generateNode(
}
break
case 'Property':
if (propsCountStack[propsCountStack.length - 1] !== 0) {
pathStack.pop()
if (!skipStack.pop()) {
generator.pushline(`,`)
if (parent != null && parent.type === 'ObjectExpression') {
if (propsCountStack[propsCountStack.length - 1] !== 0) {
pathStack.pop()
if (!skipStack.pop()) {
generator.pushline(`,`)
}
}
}
break
Expand Down
10 changes: 10 additions & 0 deletions packages/bundle-utils/test/fixtures/codegen/functions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default {
hello: 'hello',
pagination: {
pages: ({ named }) => `${named('number')}/page`,
total: ({ named }) => `${named('number')} records in total`
},
foo: {
bar: 'bar'
}
}
30 changes: 30 additions & 0 deletions packages/bundle-utils/test/generator/__snapshots__/js.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,10 @@ exports[`force stringify: code 1`] = `
\\"falseValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"false\\"])};fn.source=\\"false\\";return fn;})(),
\\"nullValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"null\\"])};fn.source=\\"null\\";return fn;})(),
\\"numberValue\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"1\\"])};fn.source=\\"1\\";return fn;})(),
\\"funcValue1\\": function () {
},
\\"funcValue2\\": () => {
},
\\"items\\": [
(()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"null\\"])};fn.source=\\"null\\";return fn;})(),
(()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"1\\"])};fn.source=\\"1\\";return fn;})(),
Expand Down Expand Up @@ -483,6 +487,28 @@ Array [
]
`;

exports[`include function: code 1`] = `
"export default {
\\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"hello\\"])};fn.source=\\"hello\\";return fn;})(),
\\"pagination\\": {
\\"pages\\": ({named}) => \`\${ named('number') }/page\`,
\\"total\\": ({named}) => \`\${ named('number') } records in total\`
},
\\"foo\\": {
\\"bar\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"bar\\"])};fn.source=\\"bar\\";return fn;})()
}
}"
`;
exports[`include function: map 1`] = `
Object {
"mappings": "",
"names": Array [],
"sources": Array [],
"version": 3,
}
`;
exports[`invalid message syntax: code 1`] = `
"{
\\"hello\\": (()=>{const fn=(ctx) => {const { normalize: _normalize } = ctx;return _normalize([\\"こんにちは\\"])};fn.source=\\"こんにちは\\";return fn;})(),
Expand Down Expand Up @@ -614,6 +640,10 @@ exports[`unhandling: code 1`] = `
\\"falseValue\\": false,
\\"nullValue\\": null,
\\"numberValue\\": 1,
\\"funcValue1\\": function () {
},
\\"funcValue2\\": () => {
},
\\"items\\": [
null,
1,
Expand Down
11 changes: 11 additions & 0 deletions packages/bundle-utils/test/generator/js.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,14 @@ describe(`'allowDynamic' option`, () => {
expect(map).toMatchSnapshot('map')
})
})

test('include function', async () => {
const { source } = await readFile('./fixtures/codegen/functions.js')
const { code, map } = generate(source, {
sourceMap: true,
env: 'development'
})

expect(code).toMatchSnapshot('code')
expect(map).toMatchSnapshot('map')
})
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,10 @@ __metadata:
dependencies:
"@intlify/message-compiler": 9.3.0-beta.17
"@intlify/shared": 9.3.0-beta.17
"@types/escodegen": ^0.0.7
"@types/estree": ^1.0.0
acorn: ^8.8.2
escodegen: ^2.0.0
estree-walker: ^2.0.2
jsonc-eslint-parser: ^1.0.1
magic-string: ^0.30.0
Expand Down Expand Up @@ -2264,6 +2266,13 @@ __metadata:
languageName: node
linkType: hard

"@types/escodegen@npm:^0.0.7":
version: 0.0.7
resolution: "@types/escodegen@npm:0.0.7"
checksum: 19625e3f61096e989c851e5db9758636618fb841d6adb295494a46613f68b025cb79474401e7b25508506799f94adcb17bb04b4f355862671caf8002ca77af0d
languageName: node
linkType: hard

"@types/eslint-scope@npm:^3.7.3":
version: 3.7.3
resolution: "@types/eslint-scope@npm:3.7.3"
Expand Down

0 comments on commit 4d3fa98

Please sign in to comment.