• 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 Text, List, Dict, AnyStr, DefaultDict
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
35def extension_handler(paragraph: Text):
36    return GnVariableParser.string_parser("output_extension", paragraph).strip('"')
37
38
39def hap_name_handler(paragraph: Text):
40    return GnVariableParser.string_parser("hap_name", paragraph).strip('"')
41
42
43def target_type_handler(paragraph: Text):
44    tt = GnVariableParser.string_parser("target_type", paragraph).strip('"')
45    return tt
46
47
48def mod_handler(paragraph: Text):
49    return GnVariableParser.string_parser("mode", paragraph).strip('"')
50
51
52def gn_lineno_collect(match_pattern: str, project_path: str) -> DefaultDict[str, List[int]]:
53    """
54    在整个项目路径下搜索有特定target类型的BUILD.gn
55    :param match_pattern: 进行grep的pattern,支持扩展的正则
56    :param project_path: 项目路径(搜索路径)
57    :return: {gn_file: [line_no_1, line_no_2, ..]}
58    """
59    black_list = _config.get("black_list")
60    tbl = [x for x in black_list if os.sep in x]
61
62    def handler(content: Text) -> List[str]:
63        t = list(filter(lambda y: len(y) > 0, list(
64            map(lambda x: x.strip(), content.split("\n")))))
65        for item in tbl:
66            p = os.path.join(project_path, item)
67            t = list(filter(lambda x: p not in x, t))
68        return t
69
70    grep_list = BasicTool.grep_ern(match_pattern, path=project_path,
71                                   include="BUILD.gn", exclude=tuple(black_list), post_handler=handler)
72    gn_line_dict: DefaultDict[str, List[int]] = defaultdict(list)
73    for gl in grep_list:
74        gn_file, line_no, _ = gl.split(":")
75        gn_line_dict[gn_file].append(line_no)
76    return gn_line_dict
77
78
79class TargetNameParser:
80    @classmethod
81    def single_parser(cls, paragraph: Text) -> str:
82        """
83        查找类似shared_library("xxx")这种括号内只有一个参数的target的名称
84        :param paragraph: 要解析的段落
85        :return: target名称,如果是变量,不会对其进行解析
86        """
87        return BasicTool.re_group_1(paragraph, r"\w+\((.*)\)")
88
89    @classmethod
90    def second_parser(cls, paragraph: Text) -> str:
91        """
92        查找类似target("shared_library","xxx")这种的target名称(括号内第二个参数)
93        :param paragraph: 要解析的段落
94        :return: target名称,如果是变量,不会的其进行解析
95        """
96        return BasicTool.re_group_1(paragraph, r"\w+\(.*?, *(.*?)\)")
97
98
99
100class BasePostHandler(ABC):
101    def __call__(self, unit: Dict[str, AnyStr]) -> str:
102        return self.run(unit)
103
104    @abstractmethod
105    def run(self, unit: Dict[str, AnyStr]) -> str:
106        ...
107
108
109def add_prefix(content: str, prefix: str) -> str:
110    if content and (not content.startswith(prefix)):
111        return prefix+content
112    return content
113
114
115def add_postfix(content: str, postfix: str) -> str:
116    if content and (not content.endswith(postfix)):
117        return content+postfix
118    return content
119
120
121class DefaultPostHandler(BasePostHandler):
122    def run(self, unit: Dict[str, AnyStr]):
123        if "extension" in unit.keys() and (not unit["output_name"].endswith(unit["extension"])):
124            out = unit["output_name"].rstrip(
125                ".")+"."+unit["extension"].lstrip(".")
126            return out
127        return unit["output_name"]
128
129
130class UnittestPostHandler(BasePostHandler):
131    def run(self, unit: Dict[str, AnyStr]):
132        if "output_extension" in unit.keys() and (not unit["output_name"].endswith(unit["output_extension"])):
133            out = unit["output_name"].rstrip(
134                ".")+"."+unit["output_extension"].lstrip(".")
135            return out
136        return unit["output_name"]
137
138
139class HapPackPostHandler(BasePostHandler):
140    def run(self, unit: Dict[str, AnyStr]):
141        hap_name = unit.get("hap_name")
142        mode = unit.get("mode")
143        return hap_name + "." + mode
144
145
146class HAPPostHandler(BasePostHandler):
147    """
148    for ohos_hap
149    """
150
151    def run(self, unit: Dict[str, AnyStr]):
152        extension = _config.get("default_extension").get("app")
153        gn_hap_name = unit.get("hap_name")
154        if gn_hap_name:
155            return add_postfix(gn_hap_name, extension)
156        return unit["output_name"]+extension
157
158
159class SOPostHandler(BasePostHandler):
160    """
161    for shared_library
162    """
163
164    def run(self, unit: Dict[str, AnyStr]):
165        output_name = unit["output_name"]
166        prefix = _config.get("default_prefix").get("shared_library")
167        if unit.get("extension"):
168            extension = unit.get("extension")
169        else:
170            extension = _config.get("default_extension").get("shared_library")
171        if not extension.startswith('.'):
172            extension = '.'+extension
173        output_name = add_postfix(output_name, extension)
174        return add_prefix(output_name, prefix)
175
176
177class APostHandler(BasePostHandler):
178    """
179    for static library
180    """
181
182    def run(self, unit: Dict[str, AnyStr]):
183        output_name = unit["output_name"]
184        prefix = _config.get("default_prefix").get("static_library")
185        extension: str = _config.get("default_extension").get("static_library")
186        if not extension.startswith('.'):
187            extension = '.'+extension
188        output_name = add_postfix(output_name, extension)
189        return add_prefix(output_name, prefix)
190
191
192class LiteLibPostHandler(BasePostHandler):
193    """
194    for lite_library
195    """
196
197    def run(self, unit: Dict[str, AnyStr]):
198        tp = unit["real_target_type"]
199        output_name = unit["output_name"]
200        if tp == "static_library":
201            prefix = _config.get("default_prefix").get("static_library")
202            extension = _config.get("default_extension").get("static_library")
203        elif tp == "shared_library":
204            prefix = _config.get("default_prefix").get("shared_library")
205            extension = _config.get("default_extension").get("shared_library")
206        else:
207            prefix = str()
208            extension = str()
209        if extension and (not extension.startswith('.')):
210            extension = '.'+extension
211        output_name = add_postfix(output_name, extension)
212        return add_prefix(output_name, prefix)
213
214
215class LiteComponentPostHandler(BasePostHandler):
216    """
217    for lite_component
218    """
219
220    def run(self, unit: Dict[str, AnyStr]):
221        tp = unit["real_target_type"]
222        output_name = unit["output_name"]
223        extension = unit.get("output_extension")
224        if tp == "shared_library":
225            prefix = _config.get("default_prefix").get("shared_library")
226            extension = _config.get("default_extension").get("shared_library")
227        else:
228            if tp != "executable":
229                unit["description"] = "virtual node"
230            prefix = str()
231            extension = str()
232        if extension and (not extension.startswith('.')):
233            extension = '.'+extension
234        output_name = add_postfix(output_name, extension)
235        return add_prefix(output_name, prefix)
236
237
238class TargetPostHandler(BasePostHandler):
239    """
240    for target(a,b){}
241    """
242
243    def run(self, unit: Dict[str, AnyStr]):
244        ...
245
246
247def lite_lib_s2m_post_handler(unit: Dict, result_dict: Dict) -> None:
248    rt = unit.get("real_target_type")
249    new_unit = copy.deepcopy(unit)
250    if rt == "shared_library":
251        new_unit["real_target_type"] = "static_library"
252        k = LiteLibPostHandler()(new_unit)
253        new_unit["description"] = "may not exist"
254        result_dict["lite_library"][k] = new_unit
255    elif rt == "static_library":
256        new_unit["real_target_type"] = "shared_library"
257        k = LiteLibPostHandler()(new_unit)
258        new_unit["description"] = "may not exist"
259        result_dict["lite_library"][k] = new_unit
260    else:
261        new_unit["real_target_type"] = "shared_library"
262        k = LiteLibPostHandler()(new_unit)
263        new_unit["description"] = "may not exist"
264        result_dict["lite_library"][k] = new_unit
265
266        new_new_unit = copy.deepcopy(unit)
267        new_new_unit["real_target_type"] = "static_library"
268        k = LiteLibPostHandler()(new_new_unit)
269        new_new_unit["description"] = "may not exist"
270        result_dict["lite_library"][k] = new_new_unit
271
272
273def target_s2m_post_handler(unit: Dict, result_dict: Dict) -> None:
274    unit["description"] = "may not exist"
275    tmp_a = copy.deepcopy(unit)
276    tmp_a["real_target_type"] = "static_library"
277    k = LiteLibPostHandler()(tmp_a)
278    result_dict["target"][k] = tmp_a
279
280    tmp_s = copy.deepcopy(unit)
281    tmp_s["real_target_type"] = "shared_library"
282    k = LiteLibPostHandler()(tmp_s)
283    result_dict["target"][k] = tmp_s