• 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 {
17    ArkAssignStmt,
18    ArkMethod,
19    CallGraph,
20    CallGraphBuilder,
21    Local,
22    LOG_MODULE_TYPE,
23    Logger,
24    Scene,
25    Stmt,
26    Value,
27} from 'arkanalyzer/lib';
28import { WarnInfo } from '../../utils/common/Utils';
29import { Language } from 'arkanalyzer/lib/core/model/ArkFile';
30import { DVFG, DVFGNode } from 'arkanalyzer/lib/VFG/DVFG';
31import { DVFGBuilder } from 'arkanalyzer/lib/VFG/builder/DVFGBuilder';
32
33const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'Utils');
34
35export const CALL_DEPTH_LIMIT = 2;
36export class CallGraphHelper {
37    private static cgInstance: CallGraph | null = null;
38
39    public static dispose(): void {
40        this.cgInstance = null;
41    }
42
43    public static getCGInstance(scene: Scene): CallGraph {
44        if (!this.cgInstance) {
45            this.cgInstance = new CallGraph(scene);
46        }
47        return this.cgInstance;
48    }
49}
50
51export class GlobalCallGraphHelper {
52    private static cgInstance: CallGraph | null = null;
53
54    public static dispose(): void {
55        this.cgInstance = null;
56    }
57
58    public static getCGInstance(scene: Scene): CallGraph {
59        if (!this.cgInstance) {
60            this.cgInstance = new CallGraph(scene);
61            let cgBuilder = new CallGraphBuilder(this.cgInstance, scene);
62            cgBuilder.buildCHA4WholeProject(true);
63        }
64        return this.cgInstance;
65    }
66}
67
68export class DVFGHelper {
69    private static dvfgInstance: DVFG;
70    private static dvfgBuilder: DVFGBuilder;
71    private static built: Set<ArkMethod> = new Set();
72
73    public static dispose(): void {
74        // @ts-ignore
75        this.dvfgInstance = null;
76        // @ts-ignore
77        this.dvfgBuilder = null;
78        this.built.clear();
79    }
80
81    private static createDVFGInstance(scene: Scene): void {
82        if (!this.dvfgInstance) {
83            this.dvfgInstance = new DVFG(GlobalCallGraphHelper.getCGInstance(scene));
84            this.dvfgBuilder = new DVFGBuilder(this.dvfgInstance, scene);
85        }
86    }
87
88    public static buildSingleDVFG(method: ArkMethod, scene: Scene): void {
89        if (!this.dvfgInstance) {
90            this.createDVFGInstance(scene);
91        }
92        if (!this.built.has(method)) {
93            this.dvfgBuilder.buildForSingleMethod(method);
94            this.built.add(method);
95        }
96    }
97
98    public static getOrNewDVFGNode(stmt: Stmt, scene: Scene): DVFGNode {
99        if (!this.dvfgInstance) {
100            this.createDVFGInstance(scene);
101        }
102        return this.dvfgInstance!.getOrNewDVFGNode(stmt);
103    }
104}
105
106export const CALLBACK_METHOD_NAME: string[] = [
107    'onClick', // 点击事件,当用户点击组件时触发
108    'onTouch', // 触摸事件,当手指在组件上按下、滑动、抬起时触发
109    'onAppear', // 组件挂载显示时触发
110    'onDisAppear', // 组件卸载消失时触发
111    'onDragStart', // 拖拽开始事件,当组件被长按后开始拖拽时触发
112    'onDragEnter', // 拖拽进入组件范围时触发
113    'onDragMove', // 拖拽在组件范围内移动时触发
114    'onDragLeave', // 拖拽离开组件范围内时触发
115    'onDrop', // 拖拽释放目标,当在本组件范围内停止拖拽行为时触发
116    'onKeyEvent', // 按键事件,当组件获焦后,按键动作触发
117    'onFocus', // 焦点事件,当组件获取焦点时触发
118    'onBlur', // 当组件失去焦点时触发的回调
119    'onHover', // 鼠标悬浮事件,鼠标进入或退出组件时触发
120    'onMouse', // 鼠标事件,当鼠标按键点击或在组件上移动时触发
121    'onAreaChange', // 组件区域变化事件,组件尺寸、位置变化时触发
122    'onVisibleAreaChange', // 组件可见区域变化事件,组件在屏幕中的显示区域面积变化时触发
123];
124
125export function getLanguageStr(language: Language): string {
126    let targetLan: string = '';
127    switch (language) {
128        case Language.JAVASCRIPT:
129            targetLan = 'javascript';
130            break;
131        case Language.TYPESCRIPT:
132            targetLan = 'typescript';
133            break;
134        case Language.ARKTS1_1:
135            targetLan = 'arkts1.1';
136            break;
137        case Language.ARKTS1_2:
138            targetLan = 'arkts1.2';
139            break;
140        default:
141            break;
142    }
143    return targetLan;
144}
145
146export function getLineAndColumn(stmt: Stmt, operand: Value): WarnInfo {
147    const arkFile = stmt.getCfg().getDeclaringMethod().getDeclaringArkFile();
148    const originPosition = stmt.getOperandOriginalPosition(operand);
149    if (arkFile && originPosition) {
150        const originPath = arkFile.getFilePath();
151        const line = originPosition.getFirstLine();
152        const startCol = originPosition.getFirstCol();
153        const endCol = startCol;
154        return { line, startCol, endCol, filePath: originPath };
155    } else {
156        logger.debug('ArkFile or operand position is null.');
157    }
158    return { line: -1, startCol: -1, endCol: -1, filePath: '' };
159}
160
161export function getGlobalsDefineInDefaultMethod(defaultMethod: ArkMethod): Map<string, Stmt[]> {
162    const globalVarMap: Map<string, Stmt[]> = new Map();
163    const stmts = defaultMethod.getBody()?.getCfg().getStmts() ?? [];
164    for (const stmt of stmts) {
165        if (!(stmt instanceof ArkAssignStmt)) {
166            continue;
167        }
168        const leftOp = stmt.getLeftOp();
169        if (!(leftOp instanceof Local)) {
170            continue;
171        }
172        const name = leftOp.getName();
173        if (name.startsWith('%') || name === 'this') {
174            continue;
175        }
176        globalVarMap.set(name, [...(globalVarMap.get(name) ?? []), stmt]);
177    }
178    return globalVarMap;
179}
180