From 4b93c7a612dea023514b283d6994a816ab72d745 Mon Sep 17 00:00:00 2001 From: wangzhiyusss Date: Mon, 8 Sep 2025 14:30:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0use=20static=E5=AD=97?= =?UTF-8?q?=E7=AC=A6&=E4=BF=AE=E5=A4=8D=E7=89=88=E6=9D=83=E5=A4=B4?= =?UTF-8?q?=E4=B8=A2=E5=A4=B1=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangzhiyusss --- build-tools/delete_systemapi_plugin.js | 36 ++++---- build-tools/handleApiFiles.js | 122 +++++++++++++++++-------- 2 files changed, 101 insertions(+), 57 deletions(-) diff --git a/build-tools/delete_systemapi_plugin.js b/build-tools/delete_systemapi_plugin.js index 2f584e4f5e..460af93228 100644 --- a/build-tools/delete_systemapi_plugin.js +++ b/build-tools/delete_systemapi_plugin.js @@ -121,17 +121,17 @@ function tsTransformKitFile(kitPath) { kitFiles.forEach((kitFile) => { const kitName = processFileNameWithoutExt(kitFile).replace('@kit.', ''); const content = fs.readFileSync(kitFile, 'utf-8'); + const fileAndKitComment = getFileAndKitComment(content); + const copyrightMessage = getCopyrightComment(content); const fileName = processFileName(kitFile); let sourceFile = ts.createSourceFile(fileName, content, ts.ScriptTarget.ES2017, true); - const sourceInfo = getKitNewSourceFile(sourceFile, kitName); - if (isEmptyFile(sourceInfo.sourceFile)) { + const newSourceFile = getKitNewSourceFile(sourceFile, kitName); + if (isEmptyFile(newSourceFile)) { return; } const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); - let result = printer.printNode(ts.EmitHint.Unspecified, sourceInfo.sourceFile, sourceFile); - if (sourceInfo.copyrightMessage !== '') { - result = sourceInfo.copyrightMessage + result; - } + let result = printer.printNode(ts.EmitHint.Unspecified, newSourceFile, sourceFile); + result = collectCopyrightMessage(result, copyrightMessage, fileAndKitComment); writeFile(kitFile, result); }); } @@ -153,18 +153,18 @@ function getKitNewSourceFile(sourceFile, kitName) { const newStatement = processKitImportDeclaration(statement, needDeleteExportName); if (newStatement) { newStatements.push(newStatement); - } else if (index === 0) { - copyrightMessage = sourceFile.getFullText().replace(sourceFile.getText(), ''); } } else if (ts.isExportDeclaration(statement)) { const newStatement = processKitExportDeclaration(statement, needDeleteExportName); if (newStatement) { newStatements.push(newStatement); } + } else { + newStatements.push(statement); } }); sourceFile = factory.updateSourceFile(sourceFile, newStatements); - return { sourceFile, copyrightMessage }; + return sourceFile; } function addImportToNeedDeleteExportName(importClause, needDeleteExportName) { @@ -596,7 +596,7 @@ function visitEachChild(context, node) { * @param {boolean} firstNodeIsStatic 第一个节点是否为use static * @returns {Function} */ -function formatImportDeclaration(url, copyrightMessage = '', fileAndKitComment = '', firstNodeIsStatic = false) { +function formatImportDeclaration(url, copyrightMessage = '', fileAndKitComment = '') { const allIdentifierSet = new Set([]); return (context) => { return (node) => { @@ -610,7 +610,7 @@ function formatImportDeclaration(url, copyrightMessage = '', fileAndKitComment = } const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); let result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile); - result = collectCopyrightMessage(result, copyrightMessage, fileAndKitComment, firstNodeIsStatic); + result = collectCopyrightMessage(result, copyrightMessage, fileAndKitComment); copyrightMessage = node.getFullText().replace(node.getText(), ''); if (referencesMessage) { // 将references写入文件 result = result.substring(0, copyrightMessage.length) + '\n' + referencesMessage + @@ -657,18 +657,16 @@ function collectillegalNodes(decorator, allIdentifierSet) { * @param {string} result 文件内容 * @param {string} copyrightMessage 版权头注释 * @param {string} fileAndKitComment 文件kit注释 - * @param {boolean} firstNodeIsStatic 第一个节点是否为use static * @returns */ -function collectCopyrightMessage(result, copyrightMessage, fileAndKitComment, firstNodeIsStatic) { +function collectCopyrightMessage(result, copyrightMessage, fileAndKitComment) { const newFileAndKitComment = getFileAndKitComment(result); const newCopyrightMessage = getCopyrightComment(result); let commentIndex = 0; - if (firstNodeIsStatic) { - const indexStatic = result.match(/use static.*\n/); - if (indexStatic) { - commentIndex = indexStatic.index + indexStatic[0].length; - } + const useStaticRegex = /^\s*(['"])use static\1\s*;?$/gm; + if (useStaticRegex.test(result) && useStaticRegex.exec(result) && + useStaticRegex.exec(result).index === 0) { + commentIndex = indexStatic.index + indexStatic[0].length; } if (newFileAndKitComment === '') { result = @@ -969,7 +967,7 @@ function deleteSystemApi(url) { ts.transpileModule(result, { compilerOptions: COMPILER_OPTIONS, fileName: fileName, - transformers: { before: [formatImportDeclaration(url, copyrightMessage, fileAndKitComment, deleteNode.firstNodeIsStatic)] }, + transformers: { before: [formatImportDeclaration(url, copyrightMessage, fileAndKitComment)] }, }); } return ts.factory.createSourceFile([], ts.SyntaxKind.EndOfFileToken, ts.NodeFlags.None); diff --git a/build-tools/handleApiFiles.js b/build-tools/handleApiFiles.js index 1301616b12..8298f30ee7 100755 --- a/build-tools/handleApiFiles.js +++ b/build-tools/handleApiFiles.js @@ -21,6 +21,7 @@ const commander = require('commander'); let dirType = ''; const deleteApiSet = new Set(); const importNameSet = new Set(); +const ARKTS_FLAG = 'use static'; // 处理的目录类型,ets代表处理的是1.1目录,ets2代表处理的是1.2目录里有@arkts 1.1&1.2标签的文件, // noTagInEts2代表处理的是1.2目录里无标签的文件 @@ -233,24 +234,26 @@ function isHandleFullPath(fullPath, apiRelativePath, type) { * @returns */ function handleArktsDefinition(type, fileContent) { - let regx = /\/\*\*\* if arkts 1\.1 \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; - let regx2 = /\/\*\*\* if arkts 1\.2 \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; - let regx3 = /\/\*\*\* if arkts 1\.1\&1\.2 \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; - fileContent = fileContent.replace(regx, (substring, p1) => { - return type === 'ets' ? p1 : ''; + const REGX_DYNAMIC = /\/\*\*\* if arkts (1\.1|dynamic) \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; + const REGX_STATIC = /\/\*\*\* if arkts (1\.2|static) \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; + const REGX_DYNAMIC_STATIC = /\/\*\*\* if arkts (1.1&1.2|dynamic&static) \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; + fileContent = fileContent.replace(REGX_DYNAMIC, (substring, p1, p2) => { + return type === 'ets' ? p2 : ''; }); - fileContent = fileContent.replace(regx2, (substring, p1) => { + fileContent = fileContent.replace(REGX_STATIC, (substring, p1, p2) => { + // todo if arkts 特殊用法 if (type === 'ets2') { - return p1.replace(/(\s*)(\*\s\@since)/g, '$1* @arkts 1.2$1$2'); + return p2.replace(/(\s*)(\*\s\@since)/g, '$1* @arkts 1.2$1$2'); } else { return ''; } }); - fileContent = fileContent.replace(regx3, (substring, p1) => { + fileContent = fileContent.replace(REGX_DYNAMIC_STATIC, (substring, p1, p2) => { + // todo if arkts 特殊用法 if (type === 'ets') { - return p1; + return p2; } else { - return p1.replace(/(\s*)(\*\s\@since)/g, '$1* @arkts 1.2$1$2'); + return p2.replace(/(\s*)(\*\s\@since)/g, '$1* @arkts 1.2$1$2'); } }); return fileContent; @@ -288,8 +291,8 @@ function handleFileInFirstType(apiRelativePath, fullPath, type, output) { fileContent = handleArktsDefinition(type, fileContent); const sourceFile = ts.createSourceFile(path.basename(apiRelativePath), fileContent, ts.ScriptTarget.ES2017, true); - const secondRegx = /(?:@arkts1.2only|@arkts\s+>=\s*1.2|@arkts\s*1.2)/; - const thirdRegx = /(?:\*\s*@arkts\s+1.1&1.2\s*(\r|\n)\s*)/; + const secondRegx = /(?:\*\s(@arkts\s1.2|@arkts\sstatic)\s*(\r|\n)\s*)/; + const thirdRegx = /(?:\*\s(@arkts\s1\.1&1\.2|@arkts\sdynamic&static)\s*(\r|\n)\s*)/; if (sourceFile.statements.length === 0) { // reference文件识别不到首段jsdoc,全文匹配1.2标签,有的话直接删除 if (secondRegx.test(sourceFile.getFullText())) { @@ -357,10 +360,23 @@ function handleNoTagFileInFirstType(sourceFile, outputPath, fileContent) { * @returns */ function deleteArktsTag(fileContent) { - const arktsTagRegx = /\*\s*@arkts\s+1.1&1.2\s*(\r|\n)\s*|\*\s*@arkts\s*1.2s*(\r|\n)\s*|\*\s*@arkts\s*1.1s*(\r|\n)\s*/g; + const arktsTagRegx = /\*\s*@arkts\s(1\.1|1\.2|1\.1&1\.2|dynamic|static|dynamic&static)\s*(\r|\n)\s*/g; fileContent = fileContent.replace(arktsTagRegx, (substring, p1) => { return ''; }); + const arktsSinceTagRegx = /\*\s*@since\s\S*\s(dynamic&static|dynamic|static)\s*(\r|\n)\s*/g; + // 处理@since xx dynamic&static格式标签文本 + fileContent = fileContent.replace(arktsSinceTagRegx, (substring, p1) => { + if (dirType === DirType.typeOne && substring.indexOf('dynamic') !== -1) { + substring = substring.replace(/\sdynamic(&static)?/g, ''); + } else if ((dirType === DirType.typeTwo || dirType === DirType.typeThree) && substring.indexOf('static') !== -1) { + substring = substring.replace(/\s(dynamic&)?static/g, ''); + } else { + substring = ''; + } + return substring; + }); + return fileContent; } @@ -388,7 +404,9 @@ function deleteUnsportedTag(fileContent) { function handleSinceInFirstType(fileContent) { const regx = /@since\s+arkts\s*(\{.*\})/g; fileContent = fileContent.replace(regx, (substring, p1) => { - return '@since ' + JSON.parse(p1.replace(/'/g, '"'))['1.1']; + const versionObj = JSON.parse(p1.replace(/'/g, '"')); + const dynamicVersion = versionObj['1.1'] || versionObj['dynamic']; + return '@since ' + dynamicVersion; }); return fileContent; } @@ -400,9 +418,9 @@ function handleSinceInFirstType(fileContent) { * @returns */ function handleFileInSecondType(apiRelativePath, fullPath, type, output) { - const secondRegx = /(?:@arkts1.2only|@arkts\s+>=\s*1.2|@arkts\s*1.2)/; - const thirdRegx = /(?:\*\s*@arkts\s+1.1&1.2\s*(\r|\n)\s*)/; - const arktsRegx = /\/\*\*\* if arkts (1.1&)?1.2 \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; + const secondRegx = /(?:\*\s(@arkts\s1.2|@arkts\sstatic|@since\s\S*\sstatic)\s*(\r|\n)\s*)/; + const thirdRegx = /(?:\*\s(@arkts\s1\.1&1\.2|@arkts\sdynamic&static|@since\s\S*\sdynamic&static)\s*(\r|\n)\s*)/; + const arktsRegx = /\/\*\*\* if arkts ((1.1|dynamic)&)?(1.2|static) \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; let fileContent = fs.readFileSync(fullPath, 'utf-8'); let sourceFile = ts.createSourceFile(path.basename(fullPath), fileContent, ts.ScriptTarget.ES2017, true); const outputPath = output ? path.join(output, apiRelativePath) : fullPath; @@ -413,13 +431,13 @@ function handleFileInSecondType(apiRelativePath, fullPath, type, output) { //删除使用/*** if arkts 1.2 */ fileContent = handleArktsDefinition(type, fileContent); sourceFile = ts.createSourceFile(path.basename(fullPath), fileContent, ts.ScriptTarget.ES2017, true); - const regx = /(?:@arkts1.1only|@arkts\s+<=\s+1.1)/; + const regx = /(?:\*\s(@arkts\s1\.1|@since\s\S\sdynamic)\s*(\r|\n)\s*)/; if (sourceFile.statements.length === 0) { // 有1.2标签的文件,删除标记 if (secondRegx.test(sourceFile.getFullText())) { - let newFileContent = deleteUnsportedTag(fileContent); - newFileContent = getFileContent(newFileContent, fullPath); + let newFileContent = getFileContent(deleteUnsportedTag(fileContent), fullPath); + newFileContent = addStaticString(newFileContent); writeFile(outputPath, deleteArktsTag(newFileContent)); return; } @@ -444,8 +462,8 @@ function handleFileInSecondType(apiRelativePath, fullPath, type, output) { } // 有1.2标签的文件,删除标记 if (secondRegx.test(firstJsdocText)) { - let newFileContent = deleteUnsportedTag(fileContent); - newFileContent = getFileContent(newFileContent, fullPath); + let newFileContent = getFileContent(deleteUnsportedTag(fileContent), fullPath); + newFileContent = addStaticString(newFileContent); writeFile(outputPath, deleteArktsTag(newFileContent)); return; } @@ -504,7 +522,7 @@ function handlehasTagFile(sourceFile, outputPath) { */ function handleNoTagFileInSecondType(sourceFile, outputPath, fullPath) { dirType = DirType.typeThree; - const arktsTagRegx = /\*\s*@arkts\s+1.1&1.2\s*(\r|\n)\s*|@arkts\s*1.2/g; + const arktsTagRegx = /\*\s*(@arkts\s(1.1&)?1.2|@since\s\S*\s(dynamic&)?static)\s*(\r|\n)\s*/g; const fileContent = sourceFile.getFullText(); let newContent = ''; // API未标@arkts 1.2或@arkts 1.1&1.2标签,删除文件 @@ -595,14 +613,15 @@ function processStructDeclaration(node) { * @param {*} outputPath */ function saveApiByArktsDefinition(sourceFile, fileContent, outputPath) { - const regx = /\/\*\*\* if arkts (1.1&)?1.2 \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; + const regx = /\/\*\*\* if arkts ((1\.1|dynamic)&)?(1\.2|static) \*\/\s*([\s\S]*?)\s*\/\*\*\* endif \*\//g; const regex = /\/\*\r?\n\s*\*\s*Copyright[\s\S]*?\*\//g; const copyrightMessage = fileContent.match(regex)[0]; const firstNode = sourceFile.statements.find(statement => { return !ts.isExpressionStatement(statement); }); let fileJsdoc = firstNode ? getFileJsdoc(firstNode) + '*/\n' : ''; - let newContent = copyrightMessage + fileJsdoc + Array.from(fileContent.matchAll(regx), match => match[2]).join('\n'); + let newContent = copyrightMessage + fileJsdoc + Array.from(fileContent.matchAll(regx), match => match[4]).join('\n'); + newContent = addStaticString(newContent); writeFile(outputPath, saveLatestJsDoc(newContent)); } @@ -637,6 +656,7 @@ function joinFileJsdoc(deletionContent, sourceFile) { if (dirType !== DirType.typeOne) { // TODO:添加use static字符串 + newContent = addStaticString(newContent); } return newContent; } @@ -678,14 +698,18 @@ function writeFile(outputPath, fileContent) { * @param {*} copyrightMessage 版权头内容 * @returns */ -function addStaticString(fileContent, copyrightMessage) { - const hasStaticMessage = /use\s+static/g.test(fileContent); - const regex = /\/\*\r?\n\s*\*\s*Copyright[\s\S]*?limitations under the License\.\r?\n\s*\*\//g; - const staticMessage = 'use static'; +function addStaticString(fileContent) { let newContent = fileContent; + //判断是否存在use static且位置在第一个行 + const fileContentRegex = /^\s*(['"])use static\1\s*;?$/gm; + if (fileContentRegex.test(fileContent) && fileContentRegex.exec(fileContent) && + fileContentRegex.exec(fileContent).index > 0) { + newContent = newContent.replace(/^\s*(['"])use static\1\s*;?$/gm, ''); + } + const hasStaticMessage = fileContentRegex.test(newContent); + const staticMessage = 'use static'; if (!hasStaticMessage) { - const newfileJsdoc = `${copyrightMessage}'${staticMessage}'\r\n`; - newContent = newContent.replace(regex, newfileJsdoc); + newContent = `'${staticMessage}'\r\n${newContent}`; } return newContent; } @@ -788,12 +812,28 @@ const transformExportApi = (context) => { }; }; +/** + * 判断是否为use static标记 + * @param { ts.Node } node + * @returns { boolean } + */ +function isStaticFlag(node) { + return ts.isExpressionStatement(node) && + node.expression && + ts.isStringLiteral(node.expression) && + node.expression.text && + node.expression.text === ARKTS_FLAG; +} + function isEmptyFile(node) { let isEmpty = true; if (ts.isSourceFile(node) && node.statements) { const needExportName = new Set(); for (let i = 0; i < node.statements.length; i++) { const statement = node.statements[i]; + if (isStaticFlag(statement)) { + continue; + } if (ts.isExportDeclaration(statement) && statement.moduleSpecifier) { isEmpty = false; break; @@ -884,26 +924,30 @@ function processImportDeclaration(statement, needExportName) { * @returns */ function judgeIsDeleteApi(node) { - const notesContent = node.getFullText().replace(node.getText(), '').replace(/[\s]/g, ''); + // 删除api适配arkts标签 + const notesContent = node.getFullText().replace(node.getText(), ''); + if (notesContent.replace(/\s/g, '') === '') { + return false; + } const notesArr = notesContent.split(/\/\*\*/); const notesStr = notesArr[notesArr.length - 1]; - const sinceArr = notesStr.match(/@since\d+/); + const sinceArr = notesStr.match(/@since\s*\d+/); let sinceVersion = 20; if (dirType === DirType.typeOne) { - return /@arkts1\.2(?!\d)/g.test(notesStr); + return /@arkts\s*1\.2/g.test(notesStr) || (/@since\s\S*\sstatic/g.test(notesStr) && !/@since\s\S*\sdynamic/g.test(notesStr)); } if (sinceArr) { - sinceVersion = sinceArr[0].replace('@since', ''); + sinceVersion = sinceArr[0].replace(/@since\s*/, ''); } if (dirType === DirType.typeTwo) { - return (/@deprecated/g.test(notesStr) && sinceVersion < 20) || /@arkts<=1.1/g.test(notesStr); + return (/@deprecated/g.test(notesStr) && sinceVersion < 20) || /@arkts\s*1\.1(?!&1\.2)/g.test(notesStr) || (/@since\s\S*\sdynamic/g.test(notesStr) && !/@since\s\S*\s(dynamic&)?static/g.test(notesStr)); } if (dirType === DirType.typeThree) { - return !/@arkts1\.2\*|@arkts1\.1&1\.2\*/g.test(notesStr); + return !/@arkts\s*(1\.1&)?1\.2/g.test(notesStr) && !/@since\s\S*\s(dynamic&)?static/g.test(notesStr); } return false; @@ -918,7 +962,9 @@ function judgeIsDeleteApi(node) { function handleSinceInSecondType(fileContent) { const regx = /@since\s+arkts\s*(\{.*\})/g; fileContent = fileContent.replace(regx, (substring, p1) => { - return '@since ' + JSON.parse(p1.replace(/'/g, '"'))['1.2']; + const versionObj = JSON.parse(p1.replace(/'/g, '"')); + const staticVersion = versionObj['1.2'] || versionObj['static']; + return '@since ' + staticVersion; }); return fileContent; } -- Gitee