107ac75b1Sopenharmony_ci/* 207ac75b1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 307ac75b1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 407ac75b1Sopenharmony_ci * you may not use this file except in compliance with the License. 507ac75b1Sopenharmony_ci * You may obtain a copy of the License at 607ac75b1Sopenharmony_ci * 707ac75b1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 807ac75b1Sopenharmony_ci * 907ac75b1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1007ac75b1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1107ac75b1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1207ac75b1Sopenharmony_ci * See the License for the specific language governing permissions and 1307ac75b1Sopenharmony_ci * limitations under the License. 1407ac75b1Sopenharmony_ci */ 1507ac75b1Sopenharmony_ci 1607ac75b1Sopenharmony_ciimport ts from 'typescript'; 1707ac75b1Sopenharmony_ciimport fs from 'fs'; 1807ac75b1Sopenharmony_ciimport path from 'path'; 1907ac75b1Sopenharmony_ciimport { SourceMapGenerator } from 'source-map'; 2007ac75b1Sopenharmony_ci 2107ac75b1Sopenharmony_ciimport { 2207ac75b1Sopenharmony_ci validateUISyntax, 2307ac75b1Sopenharmony_ci componentCollection, 2407ac75b1Sopenharmony_ci ReplaceResult, 2507ac75b1Sopenharmony_ci sourceReplace 2607ac75b1Sopenharmony_ci} from './validate_ui_syntax'; 2707ac75b1Sopenharmony_ciimport { 2807ac75b1Sopenharmony_ci LogType, 2907ac75b1Sopenharmony_ci LogInfo, 3007ac75b1Sopenharmony_ci mkDir, 3107ac75b1Sopenharmony_ci emitLogInfo 3207ac75b1Sopenharmony_ci} from './utils'; 3307ac75b1Sopenharmony_ciimport { 3407ac75b1Sopenharmony_ci MODULE_ETS_PATH, 3507ac75b1Sopenharmony_ci MODULE_VISUAL_PATH, 3607ac75b1Sopenharmony_ci SUPERVISUAL, 3707ac75b1Sopenharmony_ci SUPERVISUAL_SOURCEMAP_EXT 3807ac75b1Sopenharmony_ci} from './pre_define'; 3907ac75b1Sopenharmony_ci 4007ac75b1Sopenharmony_ciimport { projectConfig } from '../main.js'; 4107ac75b1Sopenharmony_ciimport { genETS } from '../codegen/codegen_ets.js'; 4207ac75b1Sopenharmony_ci 4307ac75b1Sopenharmony_ciconst visualMap: Map<number, number> = new Map(); 4407ac75b1Sopenharmony_ciconst slotMap: Map<number, number> = new Map(); 4507ac75b1Sopenharmony_ci 4607ac75b1Sopenharmony_ciconst red: string = '\u001b[31m'; 4707ac75b1Sopenharmony_ciconst reset: string = '\u001b[39m'; 4807ac75b1Sopenharmony_ci 4907ac75b1Sopenharmony_ciconst compilerOptions = ts.readConfigFile( 5007ac75b1Sopenharmony_ci path.resolve(__dirname, '../tsconfig.json'), 5107ac75b1Sopenharmony_ci ts.sys.readFile 5207ac75b1Sopenharmony_ci).config.compilerOptions; 5307ac75b1Sopenharmony_cicompilerOptions.sourceMap = false; 5407ac75b1Sopenharmony_ci 5507ac75b1Sopenharmony_ciexport function visualTransform(code: string, id: string, logger: any) { 5607ac75b1Sopenharmony_ci const log: LogInfo[] = []; 5707ac75b1Sopenharmony_ci const content: string | null = getParsedContent(code, path.normalize(id), log); 5807ac75b1Sopenharmony_ci if (!content) { 5907ac75b1Sopenharmony_ci return code; 6007ac75b1Sopenharmony_ci } 6107ac75b1Sopenharmony_ci if (log.length) { 6207ac75b1Sopenharmony_ci emitLogInfo(logger, log, true, id); 6307ac75b1Sopenharmony_ci } 6407ac75b1Sopenharmony_ci generateSourceMapForNewAndOriEtsFile(path.normalize(id), code); 6507ac75b1Sopenharmony_ci return content; 6607ac75b1Sopenharmony_ci} 6707ac75b1Sopenharmony_ci 6807ac75b1Sopenharmony_ciexport function parseVisual(resourcePath: string, resourceQuery: string, content: string, 6907ac75b1Sopenharmony_ci log: LogInfo[], source: string): string { 7007ac75b1Sopenharmony_ci let code: string | null = getParsedContent(content, resourcePath, log); 7107ac75b1Sopenharmony_ci if (!code) { 7207ac75b1Sopenharmony_ci return content; 7307ac75b1Sopenharmony_ci } 7407ac75b1Sopenharmony_ci const result: ReplaceResult = sourceReplace(code, resourcePath); 7507ac75b1Sopenharmony_ci code = result.content; 7607ac75b1Sopenharmony_ci log.concat(result.log); 7707ac75b1Sopenharmony_ci const resultLog: LogInfo[] = validateUISyntax(source, code, resourcePath, resourceQuery); 7807ac75b1Sopenharmony_ci log.concat(resultLog); 7907ac75b1Sopenharmony_ci if (!log.length) { 8007ac75b1Sopenharmony_ci generateSourceMapForNewAndOriEtsFile(resourcePath, source); 8107ac75b1Sopenharmony_ci } 8207ac75b1Sopenharmony_ci return code; 8307ac75b1Sopenharmony_ci} 8407ac75b1Sopenharmony_ci 8507ac75b1Sopenharmony_cifunction parseStatement(statement: ts.Statement, content: string, log: LogInfo[], 8607ac75b1Sopenharmony_ci visualContent: any): string { 8707ac75b1Sopenharmony_ci if (statement.kind === ts.SyntaxKind.StructDeclaration && statement.name) { 8807ac75b1Sopenharmony_ci if (statement.members) { 8907ac75b1Sopenharmony_ci statement.members.forEach(member => { 9007ac75b1Sopenharmony_ci if (member.kind && member.kind === ts.SyntaxKind.MethodDeclaration) { 9107ac75b1Sopenharmony_ci content = parseMember(statement, member, content, log, visualContent); 9207ac75b1Sopenharmony_ci } 9307ac75b1Sopenharmony_ci }); 9407ac75b1Sopenharmony_ci } 9507ac75b1Sopenharmony_ci } 9607ac75b1Sopenharmony_ci return content; 9707ac75b1Sopenharmony_ci} 9807ac75b1Sopenharmony_ci 9907ac75b1Sopenharmony_cifunction parseMember(statement: ts.Statement, member: ts.MethodDeclaration, content: string, 10007ac75b1Sopenharmony_ci log: LogInfo[], visualContent: any): string { 10107ac75b1Sopenharmony_ci let newContent: string = content; 10207ac75b1Sopenharmony_ci if (member.name && member.name.getText() === 'build') { 10307ac75b1Sopenharmony_ci const buildBody: string = member.getText(); 10407ac75b1Sopenharmony_ci if (buildBody.replace(/\ +/g, '').replace(/[\r\n]/g, '') === 'build(){}') { 10507ac75b1Sopenharmony_ci newContent = insertVisualCode(statement, member, visualContent, newContent); 10607ac75b1Sopenharmony_ci } else { 10707ac75b1Sopenharmony_ci log.push({ 10807ac75b1Sopenharmony_ci type: LogType.ERROR, 10907ac75b1Sopenharmony_ci message: `when the corresponding visual file exists,` + 11007ac75b1Sopenharmony_ci ` the build function of the entry component must be empty.`, 11107ac75b1Sopenharmony_ci pos: member.pos 11207ac75b1Sopenharmony_ci }); 11307ac75b1Sopenharmony_ci } 11407ac75b1Sopenharmony_ci } 11507ac75b1Sopenharmony_ci return newContent; 11607ac75b1Sopenharmony_ci} 11707ac75b1Sopenharmony_ci 11807ac75b1Sopenharmony_cifunction insertVisualCode(statement: ts.Statement, member: ts.MethodDeclaration, 11907ac75b1Sopenharmony_ci visualContent: any, content: string): string { 12007ac75b1Sopenharmony_ci let newContent: string = content; 12107ac75b1Sopenharmony_ci newContent = insertImport(visualContent, newContent); 12207ac75b1Sopenharmony_ci newContent = insertVarAndFunc(member, visualContent, newContent, content); 12307ac75b1Sopenharmony_ci newContent = insertBuild(member, visualContent, newContent, content); 12407ac75b1Sopenharmony_ci newContent = insertAboutToAppear(statement, member, visualContent, newContent, content); 12507ac75b1Sopenharmony_ci return newContent; 12607ac75b1Sopenharmony_ci} 12707ac75b1Sopenharmony_ci 12807ac75b1Sopenharmony_cifunction insertImport(visualContent: any, content: string): string { 12907ac75b1Sopenharmony_ci if (!visualContent.etsImport) { 13007ac75b1Sopenharmony_ci return content; 13107ac75b1Sopenharmony_ci } 13207ac75b1Sopenharmony_ci const mediaQueryImport: string = visualContent.etsImport + '\n'; 13307ac75b1Sopenharmony_ci const newContent: string = mediaQueryImport + content; 13407ac75b1Sopenharmony_ci slotMap.set(0, mediaQueryImport.length); 13507ac75b1Sopenharmony_ci visualMap.set(0, mediaQueryImport.split('\n').length - 1); 13607ac75b1Sopenharmony_ci return newContent; 13707ac75b1Sopenharmony_ci} 13807ac75b1Sopenharmony_ci 13907ac75b1Sopenharmony_cifunction insertVarAndFunc(build: ts.MethodDeclaration, visualContent: any, 14007ac75b1Sopenharmony_ci content: string, oriContent: string): string { 14107ac75b1Sopenharmony_ci const visualVarAndFunc: string = (visualContent.etsVariable ? visualContent.etsVariable : '') + 14207ac75b1Sopenharmony_ci (visualContent.etsFunction ? visualContent.etsFunction : ''); 14307ac75b1Sopenharmony_ci return visualVarAndFunc ? insertVisualCodeBeforePos(build, '\n' + visualVarAndFunc, content, 14407ac75b1Sopenharmony_ci oriContent) : content; 14507ac75b1Sopenharmony_ci} 14607ac75b1Sopenharmony_ci 14707ac75b1Sopenharmony_cifunction insertBuild(build: ts.MethodDeclaration, visualContent: any, content: string, 14807ac75b1Sopenharmony_ci oriContent: string): string { 14907ac75b1Sopenharmony_ci return visualContent.build ? insertVisualCodeAfterPos(build.body, 15007ac75b1Sopenharmony_ci '\n' + visualContent.build + '\n', content, oriContent) : content; 15107ac75b1Sopenharmony_ci} 15207ac75b1Sopenharmony_ci 15307ac75b1Sopenharmony_cifunction insertAboutToAppear(statement: ts.Statement, build: ts.MethodDeclaration, 15407ac75b1Sopenharmony_ci visualContent: any, content: string, oriContent: string): string { 15507ac75b1Sopenharmony_ci if (!visualContent.aboutToAppear) { 15607ac75b1Sopenharmony_ci return content; 15707ac75b1Sopenharmony_ci } 15807ac75b1Sopenharmony_ci for (const member of statement.members) { 15907ac75b1Sopenharmony_ci const hasAboutToAppear: boolean = member.kind && member.kind === ts.SyntaxKind.MethodDeclaration && 16007ac75b1Sopenharmony_ci member.name && member.name.getText() === 'aboutToAppear'; 16107ac75b1Sopenharmony_ci if (hasAboutToAppear) { 16207ac75b1Sopenharmony_ci return insertVisualCodeAfterPos(member.body, '\n' + visualContent.aboutToAppear, content, 16307ac75b1Sopenharmony_ci oriContent); 16407ac75b1Sopenharmony_ci } 16507ac75b1Sopenharmony_ci } 16607ac75b1Sopenharmony_ci 16707ac75b1Sopenharmony_ci const aboutToAppearFunc: string = '\n aboutToAppear() {\n' + visualContent.aboutToAppear + 16807ac75b1Sopenharmony_ci ' }\n'; 16907ac75b1Sopenharmony_ci return insertVisualCodeBeforePos(build, aboutToAppearFunc, content, oriContent); 17007ac75b1Sopenharmony_ci} 17107ac75b1Sopenharmony_ci 17207ac75b1Sopenharmony_cifunction insertVisualCodeAfterPos(member: ts.Block, visualContent: string, content: string, 17307ac75b1Sopenharmony_ci oriContent: string): string { 17407ac75b1Sopenharmony_ci const contentBeforePos: string = oriContent.substring(0, member.getStart() + 1); 17507ac75b1Sopenharmony_ci const originEtsFileLineNumber: number = contentBeforePos.split('\n').length; 17607ac75b1Sopenharmony_ci const visualLines: number = visualContent.split('\n').length - 1; 17707ac75b1Sopenharmony_ci const insertedLineNumbers: number = visualMap.get(originEtsFileLineNumber); 17807ac75b1Sopenharmony_ci visualMap.set(originEtsFileLineNumber, insertedLineNumbers ? insertedLineNumbers + visualLines : 17907ac75b1Sopenharmony_ci visualLines); 18007ac75b1Sopenharmony_ci 18107ac75b1Sopenharmony_ci let newPos: number = member.getStart() + 1; 18207ac75b1Sopenharmony_ci for (const [key, value] of slotMap) { 18307ac75b1Sopenharmony_ci if (member.getStart() >= key) { 18407ac75b1Sopenharmony_ci newPos += value; 18507ac75b1Sopenharmony_ci } 18607ac75b1Sopenharmony_ci } 18707ac75b1Sopenharmony_ci 18807ac75b1Sopenharmony_ci const newContent: string = content.substring(0, newPos) + visualContent + 18907ac75b1Sopenharmony_ci content.substring(newPos); 19007ac75b1Sopenharmony_ci slotMap.set(member.getStart(), visualContent.length); 19107ac75b1Sopenharmony_ci return newContent; 19207ac75b1Sopenharmony_ci} 19307ac75b1Sopenharmony_ci 19407ac75b1Sopenharmony_cifunction insertVisualCodeBeforePos(member: ts.MethodDeclaration, visualContent: string, 19507ac75b1Sopenharmony_ci content: string, oriContent: string): string { 19607ac75b1Sopenharmony_ci const contentBeforePos: string = oriContent.substring(0, member.pos); 19707ac75b1Sopenharmony_ci const originEtsFileLineNumber: number = contentBeforePos.split('\n').length; 19807ac75b1Sopenharmony_ci const visualLines: number = visualContent.split('\n').length - 1; 19907ac75b1Sopenharmony_ci const insertedLineNumbers: number = visualMap.get(originEtsFileLineNumber); 20007ac75b1Sopenharmony_ci visualMap.set(originEtsFileLineNumber, insertedLineNumbers ? insertedLineNumbers + visualLines : 20107ac75b1Sopenharmony_ci visualLines); 20207ac75b1Sopenharmony_ci let newPos: number = member.pos; 20307ac75b1Sopenharmony_ci for (const [key, value] of slotMap) { 20407ac75b1Sopenharmony_ci if (member.pos >= key) { 20507ac75b1Sopenharmony_ci newPos += value; 20607ac75b1Sopenharmony_ci } 20707ac75b1Sopenharmony_ci } 20807ac75b1Sopenharmony_ci const newContent: string = content.substring(0, newPos) + visualContent + 20907ac75b1Sopenharmony_ci content.substring(newPos); 21007ac75b1Sopenharmony_ci slotMap.set(member.pos, visualContent.length); 21107ac75b1Sopenharmony_ci return newContent; 21207ac75b1Sopenharmony_ci} 21307ac75b1Sopenharmony_ci 21407ac75b1Sopenharmony_cifunction generateSourceMapForNewAndOriEtsFile(resourcePath: string, content: string) { 21507ac75b1Sopenharmony_ci if (!process.env.cachePath) { 21607ac75b1Sopenharmony_ci return; 21707ac75b1Sopenharmony_ci } 21807ac75b1Sopenharmony_ci const sourcemap: SourceMapGenerator = new SourceMapGenerator({ 21907ac75b1Sopenharmony_ci file: resourcePath 22007ac75b1Sopenharmony_ci }); 22107ac75b1Sopenharmony_ci const lines: Array<string> = content.split('\n'); 22207ac75b1Sopenharmony_ci const originEtsFileLines: number = lines.length; 22307ac75b1Sopenharmony_ci for (let l: number = 1; l <= originEtsFileLines; l++) { 22407ac75b1Sopenharmony_ci let newEtsFileLineNumber: number = l; 22507ac75b1Sopenharmony_ci for (const [originEtsFileLineNumber, visualLines] of visualMap) { 22607ac75b1Sopenharmony_ci if (l > originEtsFileLineNumber) { 22707ac75b1Sopenharmony_ci newEtsFileLineNumber += visualLines; 22807ac75b1Sopenharmony_ci } 22907ac75b1Sopenharmony_ci } 23007ac75b1Sopenharmony_ci sourcemap.addMapping({ 23107ac75b1Sopenharmony_ci generated: { 23207ac75b1Sopenharmony_ci line: newEtsFileLineNumber, 23307ac75b1Sopenharmony_ci column: 0 23407ac75b1Sopenharmony_ci }, 23507ac75b1Sopenharmony_ci source: resourcePath, 23607ac75b1Sopenharmony_ci original: { 23707ac75b1Sopenharmony_ci line: l, 23807ac75b1Sopenharmony_ci column: 0 23907ac75b1Sopenharmony_ci } 24007ac75b1Sopenharmony_ci }); 24107ac75b1Sopenharmony_ci } 24207ac75b1Sopenharmony_ci const visualMapName: string = path.parse(resourcePath).name + SUPERVISUAL_SOURCEMAP_EXT; 24307ac75b1Sopenharmony_ci const visualDirPath: string = path.parse(resourcePath).dir; 24407ac75b1Sopenharmony_ci const etsDirPath: string = path.parse(projectConfig.projectPath).dir; 24507ac75b1Sopenharmony_ci let visualMapDirPath: string = path.resolve(process.env.cachePath, SUPERVISUAL + 24607ac75b1Sopenharmony_ci visualDirPath.replace(etsDirPath, '')); 24707ac75b1Sopenharmony_ci if (!visualDirPath.includes(etsDirPath)) { 24807ac75b1Sopenharmony_ci const projectRootPath = getProjectRootPath(); 24907ac75b1Sopenharmony_ci visualMapDirPath = path.resolve(process.env.cachePath, SUPERVISUAL + 25007ac75b1Sopenharmony_ci visualDirPath.replace(projectRootPath, '')); 25107ac75b1Sopenharmony_ci } 25207ac75b1Sopenharmony_ci if (!(fs.existsSync(visualMapDirPath) && fs.statSync(visualMapDirPath).isDirectory())) { 25307ac75b1Sopenharmony_ci mkDir(visualMapDirPath); 25407ac75b1Sopenharmony_ci } 25507ac75b1Sopenharmony_ci fs.writeFile(path.resolve(visualMapDirPath, visualMapName), sourcemap.toString(), (err) => { 25607ac75b1Sopenharmony_ci if (err) { 25707ac75b1Sopenharmony_ci console.error(red, 'ERROR: Failed to write visual.js.map', reset); 25807ac75b1Sopenharmony_ci } 25907ac75b1Sopenharmony_ci }); 26007ac75b1Sopenharmony_ci} 26107ac75b1Sopenharmony_ci 26207ac75b1Sopenharmony_cifunction getProjectRootPath(): string { 26307ac75b1Sopenharmony_ci let projectRootPath = projectConfig.projectRootPath; 26407ac75b1Sopenharmony_ci if (!projectRootPath) { 26507ac75b1Sopenharmony_ci if (!projectConfig.aceModuleJsonPath) { 26607ac75b1Sopenharmony_ci projectRootPath = path.resolve(projectConfig.projectPath, '../../../../../'); 26707ac75b1Sopenharmony_ci } else { 26807ac75b1Sopenharmony_ci projectRootPath = path.resolve(projectConfig.projectPath, '../../../../'); 26907ac75b1Sopenharmony_ci } 27007ac75b1Sopenharmony_ci } 27107ac75b1Sopenharmony_ci return projectRootPath; 27207ac75b1Sopenharmony_ci} 27307ac75b1Sopenharmony_ci 27407ac75b1Sopenharmony_ciexport function findVisualFile(filePath: string): string { 27507ac75b1Sopenharmony_ci if (!/\.ets$/.test(filePath)) { 27607ac75b1Sopenharmony_ci return ''; 27707ac75b1Sopenharmony_ci } 27807ac75b1Sopenharmony_ci let etsDirPath: string = path.parse(projectConfig.projectPath).dir; 27907ac75b1Sopenharmony_ci let visualDirPath: string = path.parse(projectConfig.aceSuperVisualPath).dir; 28007ac75b1Sopenharmony_ci let resolvePath = filePath.replace(projectConfig.projectPath, projectConfig.aceSuperVisualPath) 28107ac75b1Sopenharmony_ci .replace(etsDirPath, visualDirPath).replace(/\.ets$/, '.visual'); 28207ac75b1Sopenharmony_ci if (fs.existsSync(resolvePath)) { 28307ac75b1Sopenharmony_ci return resolvePath; 28407ac75b1Sopenharmony_ci } 28507ac75b1Sopenharmony_ci try { 28607ac75b1Sopenharmony_ci const projectRootPath = getProjectRootPath(); 28707ac75b1Sopenharmony_ci let moduleName = ''; 28807ac75b1Sopenharmony_ci const relativePath = filePath.replace(projectRootPath, ''); 28907ac75b1Sopenharmony_ci const moduleNames = relativePath.split(path.sep); 29007ac75b1Sopenharmony_ci for (let i = 0; i < moduleNames.length; ++i) { 29107ac75b1Sopenharmony_ci if (moduleNames[i] === 'src') { 29207ac75b1Sopenharmony_ci if (i >= moduleNames.length - 2) { 29307ac75b1Sopenharmony_ci break; 29407ac75b1Sopenharmony_ci } 29507ac75b1Sopenharmony_ci const modulePath = path.join(moduleNames[i], moduleNames[i + 1], moduleNames[i + 2]); 29607ac75b1Sopenharmony_ci if (modulePath === MODULE_ETS_PATH) { 29707ac75b1Sopenharmony_ci break; 29807ac75b1Sopenharmony_ci } 29907ac75b1Sopenharmony_ci } 30007ac75b1Sopenharmony_ci moduleName = path.join(moduleName, moduleNames[i]); 30107ac75b1Sopenharmony_ci } 30207ac75b1Sopenharmony_ci etsDirPath = path.join(projectRootPath, moduleName, MODULE_ETS_PATH); 30307ac75b1Sopenharmony_ci visualDirPath = path.join(projectRootPath, moduleName, MODULE_VISUAL_PATH); 30407ac75b1Sopenharmony_ci resolvePath = filePath.replace(etsDirPath, visualDirPath).replace(/\.ets$/, '.visual'); 30507ac75b1Sopenharmony_ci return resolvePath; 30607ac75b1Sopenharmony_ci } catch (e) { 30707ac75b1Sopenharmony_ci // avoid projectConfig attributes has undefined value 30807ac75b1Sopenharmony_ci return ''; 30907ac75b1Sopenharmony_ci } 31007ac75b1Sopenharmony_ci} 31107ac75b1Sopenharmony_ci 31207ac75b1Sopenharmony_cifunction getVisualContent(visualPath: string, log: LogInfo[]): any { 31307ac75b1Sopenharmony_ci const parseContent: any = genETS(fs.readFileSync(visualPath, 'utf-8')); 31407ac75b1Sopenharmony_ci if (parseContent && parseContent.errorType && parseContent.errorType !== '') { 31507ac75b1Sopenharmony_ci log.push({ 31607ac75b1Sopenharmony_ci type: LogType.ERROR, 31707ac75b1Sopenharmony_ci message: parseContent.errorMessage 31807ac75b1Sopenharmony_ci }); 31907ac75b1Sopenharmony_ci } 32007ac75b1Sopenharmony_ci return parseContent ? parseContent.ets : null; 32107ac75b1Sopenharmony_ci} 32207ac75b1Sopenharmony_ci 32307ac75b1Sopenharmony_cifunction getParsedContent(code: string, id: string, log: LogInfo[]): string | null { 32407ac75b1Sopenharmony_ci if (!projectConfig.aceSuperVisualPath || 32507ac75b1Sopenharmony_ci !(componentCollection.entryComponent || componentCollection.customComponents)) { 32607ac75b1Sopenharmony_ci return null; 32707ac75b1Sopenharmony_ci } 32807ac75b1Sopenharmony_ci const visualPath: string = findVisualFile(id); 32907ac75b1Sopenharmony_ci if (!visualPath || !fs.existsSync(visualPath)) { 33007ac75b1Sopenharmony_ci return null; 33107ac75b1Sopenharmony_ci } 33207ac75b1Sopenharmony_ci const visualContent: any = getVisualContent(visualPath, log); 33307ac75b1Sopenharmony_ci if (!visualContent) { 33407ac75b1Sopenharmony_ci return null; 33507ac75b1Sopenharmony_ci } 33607ac75b1Sopenharmony_ci clearVisualSlotMap(); 33707ac75b1Sopenharmony_ci const sourceFile: ts.SourceFile = ts.createSourceFile( 33807ac75b1Sopenharmony_ci id, 33907ac75b1Sopenharmony_ci code, 34007ac75b1Sopenharmony_ci ts.ScriptTarget.Latest, 34107ac75b1Sopenharmony_ci true, 34207ac75b1Sopenharmony_ci ts.ScriptKind.ETS, 34307ac75b1Sopenharmony_ci compilerOptions 34407ac75b1Sopenharmony_ci ); 34507ac75b1Sopenharmony_ci let content: string = code; 34607ac75b1Sopenharmony_ci if (sourceFile.statements) { 34707ac75b1Sopenharmony_ci sourceFile.statements.forEach(statement => { 34807ac75b1Sopenharmony_ci content = parseStatement(statement, content, log, visualContent); 34907ac75b1Sopenharmony_ci }); 35007ac75b1Sopenharmony_ci } 35107ac75b1Sopenharmony_ci return content; 35207ac75b1Sopenharmony_ci} 35307ac75b1Sopenharmony_ci 35407ac75b1Sopenharmony_cifunction clearVisualSlotMap(): void { 35507ac75b1Sopenharmony_ci visualMap.clear(); 35607ac75b1Sopenharmony_ci slotMap.clear(); 35707ac75b1Sopenharmony_ci}