• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import * as path from 'path';
17
18import { ABC_SUFFIX, ARKTSCONFIG_JSON_FILE, LANGUAGE_VERSION } from '../preDefine';
19import { changeFileExtension } from '../utils';
20import { BuildConfig, DependentModuleConfig, ModuleInfo, CompileFileInfo } from '../types';
21import { ArkTSConfigGenerator } from './generateArkTSConfig';
22
23export class BuildMode {
24  buildConfig: BuildConfig;
25  entryFiles: Set<string>;
26  compileFiles: Map<string, CompileFileInfo>;
27  cacheDir: string;
28  pandaSdkPath: string;
29  buildSdkPath: string;
30  packageName: string;
31  sourceRoots: string[];
32  moduleRootPath: string;
33  moduleType: string;
34  dependentModuleList: DependentModuleConfig[];
35  moduleInfos: Map<string, ModuleInfo>;
36  declgenV1OutPath: string | undefined;
37  declgenBridgeCodePath: string | undefined;
38  hasMainModule: boolean;
39
40  constructor(buildConfig: BuildConfig) {
41    this.buildConfig = buildConfig;
42    this.entryFiles = new Set<string>(buildConfig.compileFiles as string[]);
43    this.cacheDir = buildConfig.cachePath as string;
44    this.pandaSdkPath = buildConfig.pandaSdkPath as string;
45    this.buildSdkPath = buildConfig.buildSdkPath as string;
46    this.packageName = buildConfig.packageName as string;
47    this.sourceRoots = buildConfig.sourceRoots as string[];
48    this.moduleRootPath = buildConfig.moduleRootPath as string;
49    this.moduleType = buildConfig.moduleType as string;
50    this.dependentModuleList = buildConfig.dependentModuleList;
51    this.hasMainModule = buildConfig.hasMainModule;
52
53    this.declgenV1OutPath = buildConfig.declgenV1OutPath as string | undefined;
54    this.declgenBridgeCodePath = buildConfig.declgenBridgeCodePath as string | undefined;
55
56    this.moduleInfos = new Map<string, ModuleInfo>();
57    this.compileFiles = new Map<string, CompileFileInfo>();
58  }
59
60  private getDependentModules(moduleInfo: ModuleInfo): Map<string, ModuleInfo>[] {
61    let dynamicDepModules: Map<string, ModuleInfo> = new Map<string, ModuleInfo>();
62    let staticDepModules: Map<string, ModuleInfo> = new Map<string, ModuleInfo>();
63
64    if (moduleInfo.isMainModule) {
65      this.moduleInfos.forEach((module: ModuleInfo, packageName: string) => {
66        if (module.isMainModule) {
67          return;
68        }
69        module.language === LANGUAGE_VERSION.ARKTS_1_2
70          ? staticDepModules.set(packageName, module)
71          : dynamicDepModules.set(packageName, module);
72      });
73      return [dynamicDepModules, staticDepModules];
74    }
75
76    if (moduleInfo.dependencies) {
77      moduleInfo.dependencies.forEach((packageName: string) => {
78        let depModuleInfo: ModuleInfo | undefined = this.moduleInfos.get(packageName);
79        if (!depModuleInfo) {
80          console.error(`Module ${packageName} not found in moduleInfos`);
81        } else {
82          depModuleInfo.language === LANGUAGE_VERSION.ARKTS_1_2
83            ? staticDepModules.set(packageName, depModuleInfo)
84            : dynamicDepModules.set(packageName, depModuleInfo);
85        }
86      });
87    }
88    return [dynamicDepModules, staticDepModules];
89  }
90
91  private generateArkTSConfigForModules(compileFileInfos: Record<string, string>): void {
92    let generator = ArkTSConfigGenerator.getGenerator(this.buildConfig, this.moduleInfos);
93    this.moduleInfos.forEach((moduleInfo: ModuleInfo, moduleRootPath: string) => {
94      for (const fileInfo of moduleInfo.compileFileInfos) {
95        compileFileInfos[fileInfo.filePath] = fileInfo.arktsConfigFile;
96      }
97      generator.writeArkTSConfigFile(moduleInfo);
98    });
99  }
100
101  private collectDepModuleInfos(): void {
102    this.moduleInfos.forEach((moduleInfo) => {
103      let [dynamicDepModules, staticDepModules] = this.getDependentModules(moduleInfo);
104      moduleInfo.dynamicDepModuleInfos = dynamicDepModules;
105      moduleInfo.staticDepModuleInfos = staticDepModules;
106    });
107  }
108
109  private collectModuleInfos(): void {
110    if (this.hasMainModule && (!this.packageName || !this.moduleRootPath || !this.sourceRoots)) {
111      console.error('Main module info from hvigor is not correct.');
112    }
113    let mainModuleInfo: ModuleInfo = {
114      isMainModule: this.hasMainModule,
115      packageName: this.packageName,
116      moduleRootPath: this.moduleRootPath,
117      moduleType: this.moduleType,
118      sourceRoots: this.sourceRoots,
119      entryFile: '',
120      arktsConfigFile: path.resolve(this.cacheDir, this.packageName, ARKTSCONFIG_JSON_FILE),
121      dynamicDepModuleInfos: new Map<string, ModuleInfo>(),
122      staticDepModuleInfos: new Map<string, ModuleInfo>(),
123      compileFileInfos: [],
124      declgenV1OutPath: this.declgenV1OutPath,
125      declgenBridgeCodePath: this.declgenBridgeCodePath
126    };
127    this.moduleInfos.set(this.packageName, mainModuleInfo);
128    this.dependentModuleList.forEach((module: DependentModuleConfig) => {
129      if (!module.packageName || !module.modulePath || !module.sourceRoots || !module.entryFile) {
130        console.error('Dependent module info from hvigor is not correct.');
131      }
132      let moduleInfo: ModuleInfo = {
133        isMainModule: false,
134        packageName: module.packageName,
135        moduleRootPath: module.modulePath,
136        moduleType: module.moduleType,
137        sourceRoots: module.sourceRoots,
138        entryFile: module.entryFile,
139        arktsConfigFile: path.resolve(this.cacheDir, module.packageName, ARKTSCONFIG_JSON_FILE),
140        compileFileInfos: [],
141        dynamicDepModuleInfos: new Map<string, ModuleInfo>(),
142        staticDepModuleInfos: new Map<string, ModuleInfo>(),
143        declgenV1OutPath: undefined,
144        declgenBridgeCodePath: undefined,
145        language: module.language,
146        declFilesPath: module.declFilesPath,
147        dependencies: module.dependencies
148      };
149      this.moduleInfos.set(module.packageName, moduleInfo);
150    });
151    this.collectDepModuleInfos();
152  }
153
154  private collectCompileFiles(): void {
155    this.entryFiles.forEach((file: string) => {
156      for (const [packageName, moduleInfo] of this.moduleInfos) {
157        if (!file.startsWith(moduleInfo.moduleRootPath)) {
158          continue;
159        }
160        let filePathFromModuleRoot: string = path.relative(moduleInfo.moduleRootPath, file);
161        let filePathInCache: string = path.join(this.cacheDir, moduleInfo.packageName, filePathFromModuleRoot);
162        let abcFilePath: string = path.resolve(changeFileExtension(filePathInCache, ABC_SUFFIX));
163
164        let fileInfo: CompileFileInfo = {
165          filePath: file,
166          dependentFiles: [],
167          abcFilePath: abcFilePath,
168          arktsConfigFile: moduleInfo.arktsConfigFile,
169          packageName: moduleInfo.packageName
170        };
171        moduleInfo.compileFileInfos.push(fileInfo);
172        this.compileFiles.set(file, fileInfo);
173        return;
174      }
175      console.error('File does not belong to any module in moduleInfos.');
176    });
177  }
178
179  public generateModuleInfos(): void {
180    this.collectModuleInfos();
181    this.collectCompileFiles();
182  }
183
184  public async generateArkTSConfig(compileFileInfos: Record<string, string>): Promise<void> {
185    this.generateModuleInfos();
186    this.generateArkTSConfigForModules(compileFileInfos);
187  }
188}
189