From 82c17371de18933fa5900f75023c165fd49c6d89 Mon Sep 17 00:00:00 2001 From: gavin1012_hw Date: Thu, 17 Nov 2022 11:51:27 +0000 Subject: [PATCH] Make unique name for generated node Issue:I61RK3 Signed-off-by: gavin1012_hw Change-Id: Ie62a3fc866202b3375f922a53541bd7fbd33160a --- ts2panda/src/base/util.ts | 91 ++++++++++++++++++++++++++++++++++++++- ts2panda/src/index.ts | 31 ++----------- 2 files changed, 94 insertions(+), 28 deletions(-) diff --git a/ts2panda/src/base/util.ts b/ts2panda/src/base/util.ts index 2453424609f..4cbbb292a68 100644 --- a/ts2panda/src/base/util.ts +++ b/ts2panda/src/base/util.ts @@ -420,4 +420,93 @@ export function getRecordName(node: ts.SourceFile): string { export function getLiteralKey(node: ts.SourceFile, idx:number): string { return `${getRecordName(node)}_${idx}`; -} \ No newline at end of file +} + +/** + * Gets the node from which a name should be generated, from tsc logic + */ +function getNodeForGeneratedName( + // @ts-ignore + name: ts.GeneratedIdentifier) { + const autoGenerateId = name.autoGenerateId; + let node = name as ts.Node; + // @ts-ignore + let original = node.original; + while (original) { + node = original; + + // if "node" is a different generated name (having a different "autoGenerateId"), use it and stop traversing. + if (ts.isIdentifier(node) + // @ts-ignore + && !!(node.autoGenerateFlags! & ts.GeneratedIdentifierFlags.Node) + // @ts-ignore + && node.autoGenerateId !== autoGenerateId) { + break; + } + // @ts-ignore + original = node.original; + } + + // otherwise, return the original node for the source; + return node; +} + +let uniqueNameIndex = 0; +let nodeIdNameMap = new Map(); +let tempAndLoopVariablesNameMap = new Map(); + +function generateUniqueName(): string { + if (uniqueNameIndex < 26) { // #a ~ #z + return "#" + String.fromCharCode(97 /* a */ + uniqueNameIndex++); + } + return "#" + (uniqueNameIndex++ - 26); +} + +function generateNameCached(node: ts.Node): string { + // @ts-ignore + const nodeId = ts.getNodeId(node); + if (nodeIdNameMap.get(nodeId)) { + return nodeIdNameMap.get(nodeId); + } + let generatedName = generateUniqueName(); + nodeIdNameMap.set(nodeId, generatedName); + return generatedName; +} + +function generateNameForTempAndLoopVariable(autoGenerateId: number): string { + if (tempAndLoopVariablesNameMap.get(autoGenerateId)) { + return tempAndLoopVariablesNameMap.get(autoGenerateId); + } + let generatedName = generateUniqueName(); + tempAndLoopVariablesNameMap.set(autoGenerateId, generatedName); + return generatedName; +} + +export function makeNameForGeneratedNode(node: ts.Node) { + node.forEachChild(childNode => { + switch (childNode.kind) { + case ts.SyntaxKind.Identifier: { + // @ts-ignore + if (ts.isGeneratedIdentifier(childNode) && (childNode).escapedText == "") { + // Node names generate unique names based on their original node and are cached based on that node's id. + // @ts-ignore + if ((childNode.autoGenerateFlags & ts.GeneratedIdentifierFlags.KindMask) === + // @ts-ignore + ts.GeneratedIdentifierFlags.Node) { + let originalNode = getNodeForGeneratedName(childNode); + // @ts-ignore + (childNode).escapedText = generateNameCached(originalNode); + } else { + // Auto, Loop, and Unique names are cached based on their unique autoGenerateId. + // @ts-ignore + const autoGenerateId = childNode.autoGenerateId!; + // @ts-ignore + (childNode).escapedText = generateNameForTempAndLoopVariable(autoGenerateId); + } + } + break; + } + } + makeNameForGeneratedNode(childNode); + }); +} diff --git a/ts2panda/src/index.ts b/ts2panda/src/index.ts index 41c8d54f0ad..fe54a87c38f 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -34,7 +34,8 @@ import { transformCommonjsModule, getRecordName, getOutputBinName, - terminateWritePipe + terminateWritePipe, + makeNameForGeneratedNode } from "./base/util"; function checkIsGlobalDeclaration(sourceFile: ts.SourceFile) { @@ -135,7 +136,7 @@ function main(fileNames: string[], options: ts.CompilerOptions, cmdArgsSet?: Map return node; } } - makeAutoGeneratedNodeName(node); + makeNameForGeneratedNode(node); if (ts.getEmitHelpers(node)) { let newStatements = []; ts.getEmitHelpers(node)?.forEach( @@ -227,30 +228,6 @@ function transformSourcefilesList(parsed: ts.ParsedCommandLine | undefined) { main(files, parsed.options, cmdArgsSet); } -let generatedVarId = 0; - -function makeAutoGeneratedNodeName(node: ts.Node) { - node.forEachChild(childNode => { - switch (childNode.kind) { - case ts.SyntaxKind.Identifier: { - // @ts-ignore - if (ts.isGeneratedIdentifier(childNode) && (childNode).escapedText == "") { - if (generatedVarId < 26) { // #a ~ #z - // @ts-ignore - (childNode).escapedText = "#" + String.fromCharCode(97 /* a */ + generatedVarId); - } else { - // @ts-ignore - (childNode).escapedText = "#" + (generatedVarId - 26); - } - generatedVarId++; - } - break; - } - } - makeAutoGeneratedNodeName(childNode); - }); -} - function getDtsFiles(libDir: string): string[] { let dtsFiles:string[] = []; function finDtsFile(dir){ @@ -411,7 +388,7 @@ function compileWatchExpression(jsFileName: string, errorMsgFileName: string, op // @ts-ignore (ctx: ts.TransformationContext) => { return (node: ts.SourceFile) => { - makeAutoGeneratedNodeName(node); + makeNameForGeneratedNode(node); if (ts.getEmitHelpers(node)) { let newStatements = []; ts.getEmitHelpers(node)?.forEach( -- Gitee