• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 - 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 {ArkFile, BUILD_PROFILE_JSON5, parseJsonText, Scene} from 'arkanalyzer';
17import {File, FileDepsGraph} from './fileComponent';
18import {ArkFileDeps} from './fileDeps';
19import Logger, {LOG_MODULE_TYPE} from 'arkanalyzer/lib/utils/logger';
20import {Module, ModuleDepsGraph} from './moduleComponent';
21import {ModuleDeps} from './moduleDeps';
22import {getModuleKind} from './utils';
23import path from 'path';
24import fs from 'fs';
25
26const logger = Logger.getLogger(LOG_MODULE_TYPE.TOOL, 'DepGraph');
27
28export function buildFileDepGraph(arkFiles: ArkFile[]): FileDepsGraph {
29    let depGraph: FileDepsGraph = new FileDepsGraph();
30    let arkFileDeps = ArkFileDeps.getInstance();
31    arkFiles.forEach(arkFile => {
32        const nodeAttr: File = {
33            name: arkFile.getFilePath(),
34            kind: 0,
35        };
36        let srcNode = depGraph.addDepsNode(arkFile.getFilePath(), nodeAttr);
37        arkFileDeps.addDeps(depGraph, srcNode, arkFile);
38    });
39    return depGraph;
40}
41
42export function buildModuleDepGraph(scene: Scene): ModuleDepsGraph {
43    let moduleGraph: ModuleDepsGraph = new ModuleDepsGraph();
44    let moduleDeps: ModuleDeps = ModuleDeps.getInstance();
45    const modules = getModules(scene.getRealProjectDir());
46    modules.forEach((modulePath) => {
47        logger.info(`Project module: ${modulePath} found.`);
48        const nodeAttr: Module = {
49            name: modulePath,
50            kind: getModuleKind(modulePath),
51        };
52        if (!moduleGraph.hasDepsNode(modulePath)) {
53            let srcNode = moduleGraph.addDepsNode(modulePath, nodeAttr);
54            moduleDeps.addDeps(moduleGraph, srcNode);
55        }
56    });
57    return moduleGraph;
58}
59
60function getModules(projectPath: string): string[] {
61    const buildProfile = path.join(projectPath, BUILD_PROFILE_JSON5);
62    let modulePaths: string[] = [];
63    if (fs.existsSync(buildProfile)) {
64        let configurationsText: string;
65        try {
66            configurationsText = fs.readFileSync(buildProfile, 'utf-8');
67        } catch (error) {
68            logger.error(`Error reading file: ${error}`);
69            return modulePaths;
70        }
71        const buildProfileJson = parseJsonText(configurationsText);
72        const modules = buildProfileJson.modules;
73        if (modules instanceof Array) {
74            modules.forEach((module) => {
75                modulePaths.push(path.resolve(projectPath, module.srcPath as string));
76            });
77        }
78    } else {
79        logger.warn('There is no build-profile.json5 for this project.');
80    }
81    return modulePaths;
82}