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