• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 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  factory,
18  isBlock,
19  isCallExpression,
20  isElementAccessExpression,
21  isExpressionStatement,
22  isIdentifier,
23  isPropertyAccessExpression,
24  isSourceFile,
25  setParentRecursive,
26  visitEachChild
27} from 'typescript';
28
29import type {
30  Block,
31  LeftHandSideExpression,
32  Node,
33  NodeArray,
34  SourceFile,
35  Statement,
36  TransformationContext,
37  Transformer,
38  TransformerFactory
39} from 'typescript';
40
41import type {IOptions} from '../../configs/IOptions';
42import type {TransformPlugin} from '../TransformPlugin';
43import {OhPackType, isCommentedNode} from '../../utils/TransformUtil';
44import {findOhImportStatement} from '../../utils/OhsUtil';
45
46namespace secharmony {
47  const TRANSFORMER_ORDER: number = 2;
48  export let transformerPlugin: TransformPlugin = {
49    'name': 'disableHilogPlugin',
50    'order': (1 << TRANSFORMER_ORDER),
51    'createTransformerFactory': createDisableHilogFactory
52  };
53
54  export function createDisableHilogFactory(option: IOptions): TransformerFactory<Node> {
55    if (!option.mDisableHilog) {
56      return null;
57    }
58
59    return disableHilogFactory;
60
61    function disableHilogFactory(context: TransformationContext): Transformer<Node> {
62      let sourceFile: SourceFile;
63      return transformer;
64
65      function transformer(node: Node): Node {
66        if (!isSourceFile(node) || node.fileName.endsWith('.d.ts')) {
67          return node;
68        }
69
70        sourceFile = node;
71        let resultAst: Node = visitAst(node);
72        return setParentRecursive(resultAst, true);
73      }
74
75      function visitAst(node: Node): Node {
76        if (isSourceFile(node)) {
77          const visitedAst: SourceFile = visitEachChild(node, visitAst, context);
78          const deletedStatements: Statement[] = deleteHilogStatement(visitedAst.statements);
79
80          return factory.updateSourceFile(node, deletedStatements);
81        }
82
83        if (!isBlock(node)) {
84          return visitEachChild(node, visitAst, context);
85        }
86
87        const visitedBlock: Block = visitEachChild(node, visitAst, context);
88        const newStatements: Statement[] = deleteHilogStatement(visitedBlock.statements);
89
90        return factory.createBlock(newStatements, true);
91      }
92
93      function deleteHilogStatement(statements: NodeArray<Statement>): Statement[] {
94        const reservedStatements: Statement[] = [];
95        statements.forEach((child) => {
96          if (isSimpleHilogStatement(child)) {
97            return;
98          }
99
100          if (isHilogImportStatement(child)) {
101            if (isCommentedNode(child, sourceFile)) {
102              reservedStatements.push(child);
103            }
104
105            return;
106          }
107
108          reservedStatements.push(child);
109        });
110
111        return reservedStatements;
112      }
113
114      function isHilogImportStatement(node: Statement): boolean {
115        const ohPackType: OhPackType = findOhImportStatement(node, '@ohos.hilog');
116        return ohPackType !== OhPackType.NONE;
117      }
118
119      function isSimpleHilogStatement(node: Statement): boolean {
120        if (!isExpressionStatement(node)) {
121          return false;
122        }
123
124        if (!node.expression || !isCallExpression(node.expression)) {
125          return false;
126        }
127
128        const expressionCalled: LeftHandSideExpression = node.expression.expression;
129        if (!expressionCalled) {
130          return false;
131        }
132
133        if (isPropertyAccessExpression(expressionCalled) && expressionCalled.expression) {
134          if (isIdentifier(expressionCalled.expression) && expressionCalled.expression.text === 'hilog') {
135            return true;
136          }
137        }
138
139        if (isElementAccessExpression(expressionCalled) && expressionCalled.expression) {
140          if (isIdentifier(expressionCalled.expression) && expressionCalled.expression.text === 'hilog') {
141            return true;
142          }
143        }
144
145        return false;
146      }
147    }
148  }
149}
150
151export = secharmony;
152