• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright (c) 2022 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16# This file is for get the mapping relationship of subsystem_name/component_name
17# and their directory. The code is from Yude Chen.
18
19import logging
20import copy
21import os
22import logging
23from abc import ABC, abstractmethod
24from collections import defaultdict
25from typing import *
26from pprint import pprint
27import preprocess
28from pkgs.gn_common_tool import GnVariableParser
29from pkgs.simple_yaml_tool import SimpleYamlTool
30from pkgs.basic_tool import BasicTool
31
32
33_config = SimpleYamlTool.read_yaml("config.yaml")
34"""
35===============info handlers===============
36"""
37
38
39def extension_handler(paragraph: Text):
40    return GnVariableParser.string_parser("output_extension", paragraph).strip('"')
41
42
43def hap_name_handler(paragraph: Text):
44    return GnVariableParser.string_parser("hap_name", paragraph).strip('"')
45
46
47def target_type_handler(paragraph: Text):
48    tt = GnVariableParser.string_parser("target_type", paragraph).strip('"')
49    return tt
50
51
52def mod_handler(paragraph: Text):
53    return GnVariableParser.string_parser("mode", paragraph).strip('"')
54
55
56"""
57===============gn lineno collector===============
58"""
59
60
61def gn_lineno_collect(match_pattern: str, project_path: str) -> DefaultDict[str, List[int]]:
62    """
63    在整个项目路径下搜索有特定target类型的BUILD.gn
64    :param match_pattern: 进行grep的pattern,支持扩展的正则
65    :param project_path: 项目路径(搜索路径)
66    :return: {gn_file: [line_no_1, line_no_2, ..]}
67    """
68    black_list = _config.get("black_list")
69    tbl = [x for x in black_list if os.sep in x]
70
71    def handler(content: Text) -> List[str]:
72        t = list(filter(lambda y: len(y) > 0, list(
73            map(lambda x: x.strip(), content.split("\n")))))
74        for item in tbl:
75            p = os.path.join(project_path, item)
76            t = list(filter(lambda x: p not in x, t))
77        return t
78
79    grep_list = BasicTool.grep_ern(match_pattern, path=project_path,
80                                   include="BUILD.gn", exclude=tuple(black_list), post_handler=handler)
81    gn_line_dict: DefaultDict[str, List[int]] = defaultdict(list)
82    for gl in grep_list:
83        gn_file, line_no, _ = gl.split(":")
84        gn_line_dict[gn_file].append(line_no)
85    return gn_line_dict
86
87
88"""
89===============target name parser===============
90"""
91
92
93class TargetNameParser:
94    @classmethod
95    def single_parser(cls, paragraph: Text) -> str:
96        """
97        查找类似shared_library("xxx")这种括号内只有一个参数的target的名称
98        :param paragraph: 要解析的段落
99        :return: target名称,如果是变量,不会对其进行解析
100        """
101        return BasicTool.re_group_1(paragraph, r"\w+\((.*)\)")
102
103    @classmethod
104    def second_parser(cls, paragraph: Text) -> str:
105        """
106        查找类似target("shared_library","xxx")这种的target名称(括号内第二个参数)
107        :param paragraph: 要解析的段落
108        :return: target名称,如果是变量,不会的其进行解析
109        """
110        return BasicTool.re_group_1(paragraph, r"\w+\(.*?, *(.*?)\)")
111
112
113"""
114===============post handlers===============
115"""
116
117
118class BasePostHandler(ABC):
119    @abstractmethod
120    def run(self, unit: Dict[str, AnyStr]) -> str:
121        ...
122
123    def __call__(self, unit: Dict[str, AnyStr]) -> str:
124        return self.run(unit)
125
126
127def add_prefix(content: str, prefix: str) -> str:
128    if content and (not content.startswith(prefix)):
129        return prefix+content
130    return content
131
132
133def add_postfix(content: str, postfix: str) -> str:
134    if content and (not content.endswith(postfix)):
135        return content+postfix
136    return content
137
138
139class DefaultPostHandler(BasePostHandler):
140    def run(self, unit: Dict[str, AnyStr]):
141        if "extension" in unit.keys() and (not unit["output_name"].endswith(unit["extension"])):
142            out = unit["output_name"].rstrip(
143                ".")+"."+unit["extension"].lstrip(".")
144            return out
145        return unit["output_name"]
146
147
148class UnittestPostHandler(BasePostHandler):
149    def run(self, unit: Dict[str, AnyStr]):
150        if "output_extension" in unit.keys() and (not unit["output_name"].endswith(unit["output_extension"])):
151            out = unit["output_name"].rstrip(
152                ".")+"."+unit["output_extension"].lstrip(".")
153            return out
154        return unit["output_name"]
155
156
157class HapPackPostHandler(BasePostHandler):
158    def run(self, unit: Dict[str, AnyStr]):
159        hap_name = unit.get("hap_name")
160        mode = unit.get("mode")
161        return hap_name + "." + mode
162
163
164class HAPPostHandler(BasePostHandler):
165    """
166    for ohos_hap"""
167
168    def run(self, unit: Dict[str, AnyStr]):
169        extension = _config.get("default_extension").get("app")
170        gn_hap_name = unit.get("hap_name")
171        if gn_hap_name:
172            return add_postfix(gn_hap_name, extension)
173        return unit["output_name"]+extension
174
175
176class SOPostHandler(BasePostHandler):
177    """
178    for shared_library"""
179
180    def run(self, unit: Dict[str, AnyStr]):
181        output_name = unit["output_name"]
182        prefix = _config.get("default_prefix").get("shared_library")
183        if unit.get("extension"):
184            extension = unit.get("extension")
185        else:
186            extension = _config.get("default_extension").get("shared_library")
187        if not extension.startswith('.'):
188            extension = '.'+extension
189        output_name = add_postfix(output_name, extension)
190        return add_prefix(output_name, prefix)
191
192
193class APostHandler(BasePostHandler):
194    """
195    for static library"""
196
197    def run(self, unit: Dict[str, AnyStr]):
198        output_name = unit["output_name"]
199        prefix = _config.get("default_prefix").get("static_library")
200        extension: str = _config.get("default_extension").get("static_library")
201        if not extension.startswith('.'):
202            extension = '.'+extension
203        output_name = add_postfix(output_name, extension)
204        return add_prefix(output_name, prefix)
205
206
207class LiteLibPostHandler(BasePostHandler):
208    """
209    for lite_library"""
210
211    def run(self, unit: Dict[str, AnyStr]):
212        tp = unit["real_target_type"]
213        output_name = unit["output_name"]
214        if tp == "static_library":
215            prefix = _config.get("default_prefix").get("static_library")
216            extension = _config.get("default_extension").get("static_library")
217        elif tp == "shared_library":
218            prefix = _config.get("default_prefix").get("shared_library")
219            extension = _config.get("default_extension").get("shared_library")
220        else:
221            prefix = str()
222            extension = str()
223        if extension and (not extension.startswith('.')):
224            extension = '.'+extension
225        output_name = add_postfix(output_name, extension)
226        return add_prefix(output_name, prefix)
227
228
229class LiteComponentPostHandler(BasePostHandler):
230    """
231    for lite_component"""
232
233    def run(self, unit: Dict[str, AnyStr]):
234        tp = unit["real_target_type"]
235        output_name = unit["output_name"]
236        extension = unit.get("output_extension")
237        if tp == "shared_library":
238            prefix = _config.get("default_prefix").get("shared_library")
239            extension = _config.get("default_extension").get("shared_library")
240        else:
241            if tp != "executable":
242                unit["description"] = "virtual node"
243            prefix = str()
244            extension = str()
245        if extension and (not extension.startswith('.')):
246            extension = '.'+extension
247        output_name = add_postfix(output_name, extension)
248        return add_prefix(output_name, prefix)
249
250
251class TargetPostHandler(BasePostHandler):
252    """
253    for target(a,b){}"""
254
255    def run(self, unit: Dict[str, AnyStr]):
256        ...
257
258
259def LiteLibS2MPostHandler(unit: Dict, result_dict: Dict) -> None:
260    rt = unit.get("real_target_type")
261    new_unit = copy.deepcopy(unit)
262    if rt == "shared_library":
263        new_unit["real_target_type"] = "static_library"
264        k = LiteLibPostHandler()(new_unit)
265        new_unit["description"] = "may not exist"
266        result_dict["lite_library"][k] = new_unit
267    elif rt == "static_library":
268        new_unit["real_target_type"] = "shared_library"
269        k = LiteLibPostHandler()(new_unit)
270        new_unit["description"] = "may not exist"
271        result_dict["lite_library"][k] = new_unit
272    else:
273        new_unit["real_target_type"] = "shared_library"
274        k = LiteLibPostHandler()(new_unit)
275        new_unit["description"] = "may not exist"
276        result_dict["lite_library"][k] = new_unit
277
278        new_new_unit = copy.deepcopy(unit)
279        new_new_unit["real_target_type"] = "static_library"
280        k = LiteLibPostHandler()(new_new_unit)
281        new_new_unit["description"] = "may not exist"
282        result_dict["lite_library"][k] = new_new_unit
283
284
285def TargetS2MPostHandler(unit: Dict, result_dict: Dict) -> None:
286    unit["description"] = "may not exist"
287    tmp_a = copy.deepcopy(unit)
288    tmp_a["real_target_type"] = "static_library"
289    k = LiteLibPostHandler()(tmp_a)
290    result_dict["target"][k] = tmp_a
291
292    tmp_s = copy.deepcopy(unit)
293    tmp_s["real_target_type"] = "shared_library"
294    k = LiteLibPostHandler()(tmp_s)
295    result_dict["target"][k] = tmp_s
296