• 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 */
15import { ArkFile } from 'arkanalyzer';
16import { BaseChecker } from '../checker/BaseChecker';
17import { MatcherTypes } from '../matcher/Matchers';
18import { matchFiles } from '../matcher/matcherAdapter/matchFiles';
19import { matchNameSpaces } from '../matcher/matcherAdapter/matchNameSpaces';
20import { matchClass } from '../matcher/matcherAdapter/matchClass';
21import { matchMethods } from '../matcher/matcherAdapter/matchMethods';
22import { matchFields } from '../matcher/matcherAdapter/matchFields';
23import { FileUtils } from '../utils/common/FileUtils';
24import { filterDisableIssue } from '../utils/common/Disable';
25import Logger, { LOG_MODULE_TYPE } from 'arkanalyzer/lib/utils/logger';
26import { IssueReport } from './Defects';
27
28const logger = Logger.getLogger(LOG_MODULE_TYPE.HOMECHECK, 'File2Check');
29
30export class File2Check {
31    public arkFile: ArkFile;
32    public enabledRuleCheckerMap: Map<string, BaseChecker> = new Map(); // TODO: key改为枚举
33    public issues: IssueReport[] = [];
34
35    private flMatcherMap = new Map();
36    private nsMatcherMap = new Map();
37    private clsMatcherMap = new Map();
38    private mtdMatcherMap = new Map();
39    private fieldMatcherMap = new Map();
40
41    constructor() {}
42
43    public addChecker(ruleId: string, checker: BaseChecker): void {
44        this.enabledRuleCheckerMap.set(ruleId, checker);
45    }
46
47    public collectMatcherCallbacks(): void {
48        this.enabledRuleCheckerMap.forEach(checker => {
49            const matcherCallbacks = checker.registerMatchers();
50            matcherCallbacks.forEach(obj => {
51                const matcher = obj.matcher;
52                const callback = obj.callback;
53                switch (matcher?.matcherType) {
54                    case MatcherTypes.FILE:
55                        this.flMatcherMap.set(matcher, callback);
56                        break;
57                    case MatcherTypes.NAMESPACE:
58                        this.nsMatcherMap.set(matcher, callback);
59                        break;
60                    case MatcherTypes.CLASS:
61                        this.clsMatcherMap.set(matcher, callback);
62                        break;
63                    case MatcherTypes.METHOD:
64                        this.mtdMatcherMap.set(matcher, callback);
65                        break;
66                    case MatcherTypes.FIELD:
67                        this.fieldMatcherMap.set(matcher, callback);
68                        break;
69                }
70            });
71        });
72    }
73
74    public async emitCheck(): Promise<void> {
75        this.flMatcherMap.forEach((callback, matcher) => {
76            matchFiles([this.arkFile], matcher, callback);
77        });
78        this.nsMatcherMap.forEach((callback, matcher) => {
79            matchNameSpaces([this.arkFile], matcher, callback);
80        });
81        this.clsMatcherMap.forEach((callback, matcher) => {
82            matchClass([this.arkFile], matcher, callback);
83        });
84        this.mtdMatcherMap.forEach((callback, matcher) => {
85            matchMethods([this.arkFile], matcher, callback);
86        });
87        this.fieldMatcherMap.forEach((callback, matcher) => {
88            matchFields([this.arkFile], matcher, callback);
89        });
90    }
91
92    public collectIssues(): void {
93        this.enabledRuleCheckerMap.forEach((v, k) => {
94            this.issues.push(
95                ...v.issues?.reduce((acc, cur) => {
96                    if (acc.some(item => item.defect.mergeKey === cur.defect.mergeKey)) {
97                        logger.debug('Skip the repeated issue, please check. issue.mergeKey = ' + cur.defect.mergeKey);
98                    } else {
99                        acc.push(cur);
100                    }
101                    return acc;
102                }, [] as IssueReport[])
103            );
104        });
105    }
106
107    public async checkDisable(): Promise<void> {
108        try {
109            const fileLineList = await FileUtils.readLinesFromFile(this.arkFile.getFilePath());
110            this.issues = await filterDisableIssue(fileLineList, this.issues, this.arkFile.getFilePath());
111        } catch (e) {
112            logger.error(e);
113        }
114    }
115
116    public async run(): Promise<void> {
117        this.collectMatcherCallbacks();
118        await this.emitCheck();
119        this.collectIssues();
120        await this.checkDisable();
121    }
122}
123