diff options
Diffstat (limited to 'packages/pogen/src/potextract.ts')
-rw-r--r-- | packages/pogen/src/potextract.ts | 743 |
1 files changed, 438 insertions, 305 deletions
diff --git a/packages/pogen/src/potextract.ts b/packages/pogen/src/potextract.ts index 243d44c6f..3ebcb3700 100644 --- a/packages/pogen/src/potextract.ts +++ b/packages/pogen/src/potextract.ts @@ -19,7 +19,7 @@ */ import * as ts from "typescript"; import * as fs from "fs"; -import * as path from "path" +import * as path from "path"; const DEFAULT_PO_HEADER = `# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER @@ -38,368 +38,501 @@ msgstr "" "Language: \\n" "MIME-Version: 1.0\\n" "Content-Type: text/plain; charset=UTF-8\\n" -"Content-Transfer-Encoding: 8bit\\n"\n\n` - +"Content-Transfer-Encoding: 8bit\\n"\n\n`; function wordwrap(str: string, width: number = 80): string[] { var regex = ".{1," + width + "}(\\s|$)|\\S+(\\s|$)"; return str.match(RegExp(regex, "g")); } -function processFile( +function getTemplate(node: ts.Node): string { + switch (node.kind) { + case ts.SyntaxKind.FirstTemplateToken: + return (<any>node).text; + case ts.SyntaxKind.TemplateExpression: + let te = <ts.TemplateExpression>node; + let textFragments = [te.head.text]; + for (let tsp of te.templateSpans) { + textFragments.push(`%${(textFragments.length - 1) / 2 + 1}$s`); + textFragments.push(tsp.literal.text.replace(/%/g, "%%")); + } + return textFragments.join(""); + default: + return "(pogen.ts: unable to parse)"; + } +} + +function getComment( sourceFile: ts.SourceFile, - outChunks: string[], - knownMessageIds: Set<string>, -) { - let lastTokLine = 0; - let preLastTokLine = 0; - processNode(sourceFile); - - function getTemplate(node: ts.Node): string { - switch (node.kind) { - case ts.SyntaxKind.FirstTemplateToken: - return (<any>node).text; - case ts.SyntaxKind.TemplateExpression: - let te = <ts.TemplateExpression>node; - let textFragments = [te.head.text]; - for (let tsp of te.templateSpans) { - textFragments.push(`%${(textFragments.length - 1) / 2 + 1}$s`); - textFragments.push(tsp.literal.text.replace(/%/g, "%%")); - } - return textFragments.join(""); - default: - return "(pogen.ts: unable to parse)"; + preLastTokLine: number, + lastTokLine: number, + node: ts.Node, +): string { + let lc = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); + let lastComments: ts.CommentRange[]; + for (let l = preLastTokLine; l < lastTokLine; l++) { + let pos = ts.getPositionOfLineAndCharacter(sourceFile, l, 0); + let comments = ts.getTrailingCommentRanges(sourceFile.text, pos); + if (comments) { + lastComments = comments; } } + if (!lastComments) { + return; + } + let candidate = lastComments[lastComments.length - 1]; + let candidateEndLine = ts.getLineAndCharacterOfPosition( + sourceFile, + candidate.end, + ).line; + if (candidateEndLine != lc.line - 1) { + return; + } + let text = sourceFile.text.slice(candidate.pos, candidate.end); + switch (candidate.kind) { + case ts.SyntaxKind.SingleLineCommentTrivia: + // Remove comment leader + text = text.replace(/^[/][/]\s*/, ""); + break; + case ts.SyntaxKind.MultiLineCommentTrivia: + // Remove comment leader and trailer, + // handling white space just like xgettext. + text = text + .replace(/^[/][*](\s*?\n|\s*)?/, "") + .replace(/(\n[ \t]*?)?[*][/]$/, ""); + break; + } + return text; +} - function getComment(node: ts.Node): string { - let lc = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); - let lastComments; - for (let l = preLastTokLine; l < lastTokLine; l++) { - let pos = ts.getPositionOfLineAndCharacter(sourceFile, l, 0); - let comments = ts.getTrailingCommentRanges(sourceFile.text, pos); - if (comments) { - lastComments = comments; - } +function getPath(node: ts.Node): { path: string[]; ctx: string } { + switch (node.kind) { + case ts.SyntaxKind.PropertyAccessExpression: { + let pae = <ts.PropertyAccessExpression>node; + return { + path: Array.prototype.concat(getPath(pae.expression).path, [ + pae.name.text, + ]), + ctx: "", + }; } - if (!lastComments) { - return; + case ts.SyntaxKind.Identifier: { + let id = <ts.Identifier>node; + return { + path: [id.text], + ctx: "", + }; } - let candidate = lastComments[lastComments.length - 1]; - let candidateEndLine = ts.getLineAndCharacterOfPosition( - sourceFile, - candidate.end, - ).line; - if (candidateEndLine != lc.line - 1) { - return; + case ts.SyntaxKind.CallExpression: { + const call = <ts.CallExpression>node; + + const firstArg = call.arguments[0]; + if ( + call.arguments.length === 1 && + firstArg.kind === ts.SyntaxKind.StringLiteral + ) { + const str = <ts.StringLiteral>firstArg; + return { + path: getPath(call.expression).path, + ctx: str.text, + }; + } } - let text = sourceFile.text.slice(candidate.pos, candidate.end); - switch (candidate.kind) { - case ts.SyntaxKind.SingleLineCommentTrivia: - // Remove comment leader - text = text.replace(/^[/][/]\s*/, ""); - break; - case ts.SyntaxKind.MultiLineCommentTrivia: - // Remove comment leader and trailer, - // handling white space just like xgettext. - text = text - .replace(/^[/][*](\s*?\n|\s*)?/, "") - .replace(/(\n[ \t]*?)?[*][/]$/, ""); - break; + default: { + // console.log("ASDASD", ts.SyntaxKind[node.kind], node); } - return text; } + return { + path: ["(other)"], + ctx: "", + }; +} - function getPath(node: ts.Node): string[] { - switch (node.kind) { - case ts.SyntaxKind.PropertyAccessExpression: - let pae = <ts.PropertyAccessExpression>node; - return Array.prototype.concat(getPath(pae.expression), [pae.name.text]); - case ts.SyntaxKind.Identifier: - let id = <ts.Identifier>node; - return [id.text]; - } - return ["(other)"]; +function arrayEq<T>(a1: T[], a2: T[]) { + if (a1.length != a2.length) { + return false; } - - function arrayEq<T>(a1: T[], a2: T[]) { - if (a1.length != a2.length) { + for (let i = 0; i < a1.length; i++) { + if (a1[i] != a2[i]) { return false; } - for (let i = 0; i < a1.length; i++) { - if (a1[i] != a2[i]) { - return false; - } - } - return true; } + return true; +} - interface TemplateResult { - comment: string; - path: string[]; - template: string; - line: number; - } +interface TemplateResult { + comment: string; + path: string[]; + template: string; + line: number; + context: string; +} - function processTaggedTemplateExpression( - tte: ts.TaggedTemplateExpression, - ): TemplateResult { - let lc = ts.getLineAndCharacterOfPosition(sourceFile, tte.pos); - if (lc.line != lastTokLine) { - preLastTokLine = lastTokLine; - lastTokLine = lc.line; - } - let path = getPath(tte.tag); - let res: TemplateResult = { - path, - line: lc.line, - comment: getComment(tte), - template: getTemplate(tte.template), - }; - return res; - } +function processTaggedTemplateExpression( + sourceFile: ts.SourceFile, + preLastTokLine: number, + lastTokLine: number, + tte: ts.TaggedTemplateExpression, +): TemplateResult { + let path = getPath(tte.tag); + let res: TemplateResult = { + path: path.path, + line: lastTokLine, + comment: getComment(sourceFile, preLastTokLine, lastTokLine, tte), + template: getTemplate(tte.template), + context: path.ctx, + }; + return res; +} - function formatMsgComment(line: number, comment?: string) { - if (comment) { - for (let cl of comment.split("\n")) { - outChunks.push(`#. ${cl}\n`); - } +function formatMsgComment( + sourceFile: ts.SourceFile, + outChunks: string[], + line: number, + comment?: string, +) { + if (comment) { + for (let cl of comment.split("\n")) { + outChunks.push(`#. ${cl}\n`); } - const fn = path.posix.relative(process.cwd(), sourceFile.fileName); - outChunks.push(`#: ${fn}:${line + 1}\n`); - outChunks.push(`#, c-format\n`); } + const fn = path.posix.relative(process.cwd(), sourceFile.fileName); + outChunks.push(`#: ${fn}:${line + 1}\n`); + outChunks.push(`#, c-format\n`); +} - function formatMsgLine(head: string, msg: string) { - const m = msg.match(/(.*\n|.+$)/g) - if (!m) return; - // Do escaping, wrap break at newlines - console.log("head", JSON.stringify(head)); - console.log("msg", JSON.stringify(msg)); - let parts = m.map((x) => x.replace(/\n/g, "\\n").replace(/"/g, '\\"')) - .map((p) => wordwrap(p)) - .reduce((a, b) => a.concat(b)); - if (parts.length == 1) { - outChunks.push(`${head} "${parts[0]}"\n`); - } else { - outChunks.push(`${head} ""\n`); - for (let p of parts) { - outChunks.push(`"${p}"\n`); - } +function formatMsgLine(outChunks: string[], head: string, msg: string) { + const m = msg.match(/(.*\n|.+$)/g); + if (!m) return; + // Do escaping, wrap break at newlines + // console.log("head", JSON.stringify(head)); + // console.log("msg", JSON.stringify(msg)); + let parts = m + .map((x) => x.replace(/\n/g, "\\n").replace(/"/g, '\\"')) + .map((p) => wordwrap(p)) + .reduce((a, b) => a.concat(b)); + if (parts.length == 1) { + outChunks.push(`${head} "${parts[0]}"\n`); + } else { + outChunks.push(`${head} ""\n`); + for (let p of parts) { + outChunks.push(`"${p}"\n`); } } +} - function getJsxElementPath(node: ts.Node) { - let path; - let process = (childNode) => { - switch (childNode.kind) { - case ts.SyntaxKind.JsxOpeningElement: { - let e = childNode as ts.JsxOpeningElement; - return (path = getPath(e.tagName)); - } - default: - break; - } - }; - ts.forEachChild(node, process); - return path; - } - - function translateJsxExpression(node: ts.Node, h) { - switch (node.kind) { - case ts.SyntaxKind.StringLiteral: { - let e = node as ts.StringLiteral; - return e.text; +function getJsxElementPath(node: ts.Node) { + let path; + let process = (childNode) => { + switch (childNode.kind) { + case ts.SyntaxKind.JsxOpeningElement: { + let e = childNode as ts.JsxOpeningElement; + return (path = getPath(e.tagName).path); } default: - return `%${h[0]++}$s`; + break; } - } + }; + ts.forEachChild(node, process); + return path; +} - function trim(s: string) { - return s.replace(/^[ \n\t]*/, "").replace(/[ \n\t]*$/, ""); +function translateJsxExpression(node: ts.Node, h) { + switch (node.kind) { + case ts.SyntaxKind.StringLiteral: { + let e = node as ts.StringLiteral; + return e.text; + } + default: + return `%${h[0]++}$s`; } +} - function getJsxContent(node: ts.Node) { - let fragments = []; - let holeNum = [1]; - let process = (childNode) => { - switch (childNode.kind) { - case ts.SyntaxKind.JsxText: { - let e = childNode as ts.JsxText; - let s = e.text; - let t = s.split("\n").map(trim).join(" "); - if (s[0] === " ") { - t = " " + t; - } - if (s[s.length - 1] === " ") { - t = t + " "; +function trim(s: string) { + return s.replace(/^[ \n\t]*/, "").replace(/[ \n\t]*$/, ""); +} + +function getJsxAttribute(sour: ts.SourceFile, node: ts.Node) { + const result = {}; + ts.forEachChild(node, (childNode: ts.Node) => { + switch (childNode.kind) { + case ts.SyntaxKind.JsxOpeningElement: { + let e = childNode as ts.JsxOpeningElement; + + e.attributes.properties.map((p) => { + const id = p.getChildAt(0, sour).getText(sour); + const v = p.getChildAt(2, sour); + if (v.kind !== ts.SyntaxKind.StringLiteral) { + return undefined; } - fragments.push(t); - } - case ts.SyntaxKind.JsxOpeningElement: - break; - case ts.SyntaxKind.JsxSelfClosingElement: - case ts.SyntaxKind.JsxElement: - fragments.push(`%${holeNum[0]++}$s`); - break; - case ts.SyntaxKind.JsxExpression: { - let e = childNode as ts.JsxExpression; - fragments.push(translateJsxExpression(e.expression, holeNum)); - break; - } - case ts.SyntaxKind.JsxClosingElement: - break; - default: - console.log("unhandled node type: ", childNode.kind) - let lc = ts.getLineAndCharacterOfPosition( - childNode.getSourceFile(), - childNode.getStart(), - ); - console.error( - `unrecognized syntax in JSX Element ${ts.SyntaxKind[childNode.kind]} (${childNode.getSourceFile().fileName}:${lc.line + 1}:${lc.character + 1}`, - ); - break; + result[id] = JSON.parse(v.getText(sour)); + }); + return; } - }; - ts.forEachChild(node, process); - return fragments.join("").trim().replace(/ +/g, " "); - } + } + }); + return result; +} - function getJsxSingular(node: ts.Node) { - let res; - let process = (childNode) => { - switch (childNode.kind) { - case ts.SyntaxKind.JsxElement: { - let path = getJsxElementPath(childNode); - if (arrayEq(path, ["i18n", "TranslateSingular"])) { - res = getJsxContent(childNode); - } +function getJsxContent(node: ts.Node) { + let fragments = []; + let holeNum = [1]; + let process = (childNode) => { + switch (childNode.kind) { + case ts.SyntaxKind.JsxText: { + let e = childNode as ts.JsxText; + let s = e.text; + let t = s.split("\n").map(trim).join(" "); + if (s[0] === " ") { + t = " " + t; + } + if (s[s.length - 1] === " ") { + t = t + " "; } - default: - break; + fragments.push(t); } - }; - ts.forEachChild(node, process); - return res; - } + case ts.SyntaxKind.JsxOpeningElement: + break; + case ts.SyntaxKind.JsxSelfClosingElement: + case ts.SyntaxKind.JsxElement: + fragments.push(`%${holeNum[0]++}$s`); + break; + case ts.SyntaxKind.JsxExpression: { + let e = childNode as ts.JsxExpression; + fragments.push(translateJsxExpression(e.expression, holeNum)); + break; + } + case ts.SyntaxKind.JsxClosingElement: + break; + default: + console.log("unhandled node type: ", childNode.kind); + let lc = ts.getLineAndCharacterOfPosition( + childNode.getSourceFile(), + childNode.getStart(), + ); + console.error( + `unrecognized syntax in JSX Element ${ + ts.SyntaxKind[childNode.kind] + } (${childNode.getSourceFile().fileName}:${lc.line + 1}:${ + lc.character + 1 + }`, + ); + break; + } + }; + ts.forEachChild(node, process); + return fragments.join("").trim().replace(/ +/g, " "); +} - function getJsxPlural(node: ts.Node) { - let res; - let process = (childNode) => { - switch (childNode.kind) { - case ts.SyntaxKind.JsxElement: { - let path = getJsxElementPath(childNode); - if (arrayEq(path, ["i18n", "TranslatePlural"])) { - res = getJsxContent(childNode); - } +function getJsxSingular(node: ts.Node) { + let res; + let process = (childNode) => { + switch (childNode.kind) { + case ts.SyntaxKind.JsxElement: { + let path = getJsxElementPath(childNode); + if (arrayEq(path, ["i18n", "TranslateSingular"])) { + res = getJsxContent(childNode); } - default: - break; } - }; - ts.forEachChild(node, process); - return res; - } + default: + break; + } + }; + ts.forEachChild(node, process); + return res; +} - function processNode(node: ts.Node) { - switch (node.kind) { - case ts.SyntaxKind.JsxElement: - let path = getJsxElementPath(node); - if (arrayEq(path, ["i18n", "Translate"])) { - let content = getJsxContent(node); - let { line } = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); - let comment = getComment(node); - if (!knownMessageIds.has(content)) { - knownMessageIds.add(content); - formatMsgComment(line, comment); - formatMsgLine("msgid", content); - outChunks.push(`msgstr ""\n`); - outChunks.push("\n"); - } - return; - } - if (arrayEq(path, ["i18n", "TranslateSwitch"])) { - let { line } = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); - let comment = getComment(node); - formatMsgComment(line, comment); - let singularForm = getJsxSingular(node); - if (!singularForm) { - console.error("singular form missing"); - process.exit(1); - } - let pluralForm = getJsxPlural(node); - if (!pluralForm) { - console.error("plural form missing"); - process.exit(1); - } - if (!knownMessageIds.has(singularForm)) { - knownMessageIds.add(singularForm); - formatMsgLine("msgid", singularForm); - formatMsgLine("msgid_plural", pluralForm); - outChunks.push(`msgstr[0] ""\n`); - outChunks.push(`msgstr[1] ""\n`); - outChunks.push(`\n`); - } - return; +function getJsxPlural(node: ts.Node) { + let res; + let process = (childNode) => { + switch (childNode.kind) { + case ts.SyntaxKind.JsxElement: { + let path = getJsxElementPath(childNode); + if (arrayEq(path, ["i18n", "TranslatePlural"])) { + res = getJsxContent(childNode); } + } + default: break; - case ts.SyntaxKind.CallExpression: { - // might be i18n.plural(i18n[.X]`...`, i18n[.X]`...`) - let ce = <ts.CallExpression>node; - let path = getPath(ce.expression); - if (!arrayEq(path, ["i18n", "plural"])) { - break; - } - if (ce.arguments[0].kind != ts.SyntaxKind.TaggedTemplateExpression) { - break; - } - if (ce.arguments[1].kind != ts.SyntaxKind.TaggedTemplateExpression) { - break; - } - let { line } = ts.getLineAndCharacterOfPosition(sourceFile, ce.pos); - let t1 = processTaggedTemplateExpression( - <ts.TaggedTemplateExpression>ce.arguments[0], - ); - let t2 = processTaggedTemplateExpression( - <ts.TaggedTemplateExpression>ce.arguments[1], + } + }; + ts.forEachChild(node, process); + return res; +} + +function processNode( + node: ts.Node, + preLastTokLine: number, + lastTokLine: number, + sourceFile: ts.SourceFile, + outChunks: string[], + knownMessageIds: Set<string>, +) { + switch (node.kind) { + case ts.SyntaxKind.JsxElement: + let path = getJsxElementPath(node); + if (arrayEq(path, ["i18n", "Translate"])) { + const content = getJsxContent(node); + const { line } = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); + const comment = getComment( + sourceFile, + preLastTokLine, + lastTokLine, + node, ); - let comment = getComment(ce); - const msgid = t1.template; + const context = getJsxAttribute(sourceFile, node)["context"] ?? ""; + const msgid = context + content; if (!knownMessageIds.has(msgid)) { knownMessageIds.add(msgid); - formatMsgComment(line, comment); - formatMsgLine("msgid", t1.template); - formatMsgLine("msgid_plural", t2.template); - outChunks.push(`msgstr[0] ""\n`); - outChunks.push(`msgstr[1] ""\n`); + formatMsgComment(sourceFile, outChunks, line, comment); + formatMsgLine(outChunks, "msgctxt", context); + formatMsgLine(outChunks, "msgid", content); + outChunks.push(`msgstr ""\n`); outChunks.push("\n"); } - - // Important: no processing for child i18n expressions here return; } - case ts.SyntaxKind.TaggedTemplateExpression: { - let tte = <ts.TaggedTemplateExpression>node; - let { comment, template, line, path } = - processTaggedTemplateExpression(tte); - if (path[0] != "i18n") { - break; + if (arrayEq(path, ["i18n", "TranslateSwitch"])) { + let { line } = ts.getLineAndCharacterOfPosition(sourceFile, node.pos); + let comment = getComment(sourceFile, preLastTokLine, lastTokLine, node); + formatMsgComment(sourceFile, outChunks, line, comment); + let singularForm = getJsxSingular(node); + if (!singularForm) { + console.error("singular form missing"); + process.exit(1); } - const msgid = template; + let pluralForm = getJsxPlural(node); + if (!pluralForm) { + console.error("plural form missing"); + process.exit(1); + } + const context = getJsxAttribute(sourceFile, node)["context"] ?? ""; + const msgid = context + singularForm; if (!knownMessageIds.has(msgid)) { knownMessageIds.add(msgid); - formatMsgComment(line, comment); - formatMsgLine("msgid", template); - outChunks.push(`msgstr ""\n`); - outChunks.push("\n"); + formatMsgLine(outChunks, "msgctxt", context); + formatMsgLine(outChunks, "msgid", singularForm); + formatMsgLine(outChunks, "msgid_plural", pluralForm); + outChunks.push(`msgstr[0] ""\n`); + outChunks.push(`msgstr[1] ""\n`); + outChunks.push(`\n`); } + return; + } + break; + case ts.SyntaxKind.CallExpression: { + // might be i18n.plural(i18n[.X]`...`, i18n[.X]`...`) + let ce = <ts.CallExpression>node; + let path = getPath(ce.expression); + if (!arrayEq(path.path, ["i18n", "plural"])) { break; } - } + if (ce.arguments[0].kind != ts.SyntaxKind.TaggedTemplateExpression) { + break; + } + if (ce.arguments[1].kind != ts.SyntaxKind.TaggedTemplateExpression) { + break; + } + let { line } = ts.getLineAndCharacterOfPosition(sourceFile, ce.pos); + const tte1 = <ts.TaggedTemplateExpression>ce.arguments[0]; + let lc1 = ts.getLineAndCharacterOfPosition(sourceFile, tte1.pos); + if (lc1.line != lastTokLine) { + preLastTokLine = lastTokLine; // HERE + lastTokLine = lc1.line; + } + let t1 = processTaggedTemplateExpression( + sourceFile, + preLastTokLine, + lastTokLine, + tte1, + ); + + const tte2 = <ts.TaggedTemplateExpression>ce.arguments[1]; + let lc2 = ts.getLineAndCharacterOfPosition(sourceFile, tte2.pos); + if (lc2.line != lastTokLine) { + preLastTokLine = lastTokLine; // HERE + lastTokLine = lc2.line; + } + let t2 = processTaggedTemplateExpression( + sourceFile, + preLastTokLine, + lastTokLine, + tte2, + ); + let comment = getComment(sourceFile, preLastTokLine, lastTokLine, ce); + const msgid = path.ctx + t1.template; + if (!knownMessageIds.has(msgid)) { + knownMessageIds.add(msgid); + formatMsgComment(sourceFile, outChunks, line, comment); + formatMsgLine(outChunks, "msgctxt", path.ctx); + formatMsgLine(outChunks, "msgid", t1.template); + formatMsgLine(outChunks, "msgid_plural", t2.template); + outChunks.push(`msgstr[0] ""\n`); + outChunks.push(`msgstr[1] ""\n`); + outChunks.push("\n"); + } - ts.forEachChild(node, processNode); + // Important: no processing for child i18n expressions here + return; + } + case ts.SyntaxKind.TaggedTemplateExpression: { + let tte = <ts.TaggedTemplateExpression>node; + let lc2 = ts.getLineAndCharacterOfPosition(sourceFile, tte.pos); + if (lc2.line != lastTokLine) { + preLastTokLine = lastTokLine; + lastTokLine = lc2.line; + } + let { comment, template, line, path, context } = + processTaggedTemplateExpression( + sourceFile, + preLastTokLine, + lastTokLine, + tte, + ); + if (path[0] != "i18n") { + break; + } + const msgid = context + template; + if (!knownMessageIds.has(msgid)) { + knownMessageIds.add(msgid); + formatMsgComment(sourceFile, outChunks, line, comment); + formatMsgLine(outChunks, "msgctxt", context); + formatMsgLine(outChunks, "msgid", template); + outChunks.push(`msgstr ""\n`); + outChunks.push("\n"); + } + break; + } } + + ts.forEachChild(node, (n) => { + processNode( + n, + lastTokLine, + preLastTokLine, + sourceFile, + outChunks, + knownMessageIds, + ); + }); +} + +export function processFile2(sourceFile: ts.SourceFile): string { + // let lastTokLine = 0; + // let preLastTokLine = 0; + const result: string[] = new Array<string>(); + processNode(sourceFile, 0, 0, sourceFile, result, new Set<string>()); + return result.join(""); +} + +export function processFile( + sourceFile: ts.SourceFile, + outChunks: string[], + knownMessageIds: Set<string>, +) { + // let lastTokLine = 0; + // let preLastTokLine = 0; + processNode(sourceFile, 0, 0, sourceFile, outChunks, knownMessageIds); } export function potextract() { @@ -439,11 +572,11 @@ export function potextract() { !prog.isSourceFileDefaultLibrary(x), ); - let header: string + let header: string; try { - header = fs.readFileSync("src/i18n/poheader", "utf-8") + header = fs.readFileSync("src/i18n/poheader", "utf-8"); } catch (e) { - header = DEFAULT_PO_HEADER + header = DEFAULT_PO_HEADER; } const chunks = [header]; |