• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# coding=utf-8
2#
3# Copyright (c) 2025 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
16from abc import ABCMeta
17
18from typing_extensions import override
19
20from taihe.semantics.declarations import (
21    EnumDecl,
22    GlobFuncDecl,
23    IfaceDecl,
24    IfaceMethodDecl,
25    PackageDecl,
26    StructDecl,
27    UnionDecl,
28)
29from taihe.semantics.types import (
30    ArrayType,
31    CallbackType,
32    EnumType,
33    IfaceType,
34    MapType,
35    OpaqueType,
36    OptionalType,
37    ScalarKind,
38    ScalarType,
39    SetType,
40    StringType,
41    StructType,
42    Type,
43    UnionType,
44    VectorType,
45)
46from taihe.semantics.visitor import TypeVisitor
47from taihe.utils.analyses import AbstractAnalysis, AnalysisManager
48
49
50class PackageCppInfo(AbstractAnalysis[PackageDecl]):
51    def __init__(self, am: AnalysisManager, p: PackageDecl) -> None:
52        super().__init__(am, p)
53        self.header = f"{p.name}.proj.hpp"
54
55
56class IfaceMethodCppInfo(AbstractAnalysis[IfaceMethodDecl]):
57    def __init__(self, am: AnalysisManager, f: IfaceMethodDecl) -> None:
58        super().__init__(am, f)
59        self.call_name = f.name
60        self.impl_name = f.name
61
62
63class EnumCppInfo(AbstractAnalysis[EnumDecl]):
64    def __init__(self, am: AnalysisManager, d: EnumDecl) -> None:
65        super().__init__(am, d)
66        self.decl_header = f"{d.parent_pkg.name}.{d.name}.proj.0.hpp"
67        self.defn_header = f"{d.parent_pkg.name}.{d.name}.proj.1.hpp"
68
69        self.namespace = "::".join(d.parent_pkg.segments)
70        self.name = d.name
71        self.full_name = "::" + self.namespace + "::" + self.name
72
73        self.as_owner = self.full_name
74        self.as_param = self.full_name
75
76
77class StructCppInfo(AbstractAnalysis[StructDecl]):
78    def __init__(self, am: AnalysisManager, d: StructDecl) -> None:
79        super().__init__(am, d)
80        self.decl_header = f"{d.parent_pkg.name}.{d.name}.proj.0.hpp"
81        self.defn_header = f"{d.parent_pkg.name}.{d.name}.proj.1.hpp"
82        self.impl_header = f"{d.parent_pkg.name}.{d.name}.proj.2.hpp"
83
84        self.namespace = "::".join(d.parent_pkg.segments)
85        self.name = d.name
86        self.full_name = "::" + self.namespace + "::" + self.name
87
88        self.as_owner = self.full_name
89        self.as_param = self.full_name + " const&"
90
91
92class UnionCppInfo(AbstractAnalysis[UnionDecl]):
93    def __init__(self, am: AnalysisManager, d: UnionDecl) -> None:
94        super().__init__(am, d)
95        self.decl_header = f"{d.parent_pkg.name}.{d.name}.proj.0.hpp"
96        self.defn_header = f"{d.parent_pkg.name}.{d.name}.proj.1.hpp"
97        self.impl_header = f"{d.parent_pkg.name}.{d.name}.proj.2.hpp"
98
99        self.namespace = "::".join(d.parent_pkg.segments)
100        self.name = d.name
101        self.full_name = "::" + self.namespace + "::" + self.name
102
103        self.as_owner = self.full_name
104        self.as_param = self.full_name + " const&"
105
106
107class IfaceCppInfo(AbstractAnalysis[IfaceDecl]):
108    def __init__(self, am: AnalysisManager, d: IfaceDecl) -> None:
109        super().__init__(am, d)
110        self.decl_header = f"{d.parent_pkg.name}.{d.name}.proj.0.hpp"
111        self.defn_header = f"{d.parent_pkg.name}.{d.name}.proj.1.hpp"
112        self.impl_header = f"{d.parent_pkg.name}.{d.name}.proj.2.hpp"
113
114        self.namespace = "::".join(d.parent_pkg.segments)
115        self.norm_name = d.name
116        self.full_norm_name = "::" + self.namespace + "::" + self.norm_name
117
118        self.weakspace = "::".join(d.parent_pkg.segments) + "::weak"
119        self.weak_name = d.name
120        self.full_weak_name = "::" + self.weakspace + "::" + self.weak_name
121
122        self.as_owner = self.full_norm_name
123        self.as_param = self.full_weak_name
124
125
126class AbstractTypeCppInfo(metaclass=ABCMeta):
127    decl_headers: list[str]
128    defn_headers: list[str]
129    impl_headers: list[str]
130    as_owner: str
131    as_param: str
132
133    def return_from_abi(self, val):
134        return f"::taihe::from_abi<{self.as_owner}>({val})"
135
136    def return_into_abi(self, val):
137        return f"::taihe::into_abi<{self.as_owner}>({val})"
138
139    def pass_from_abi(self, val):
140        return f"::taihe::from_abi<{self.as_param}>({val})"
141
142    def pass_into_abi(self, val):
143        return f"::taihe::into_abi<{self.as_param}>({val})"
144
145
146class EnumTypeCppInfo(AbstractAnalysis[EnumType], AbstractTypeCppInfo):
147    def __init__(self, am: AnalysisManager, t: EnumType):
148        super().__init__(am, t)
149        enum_cpp_info = EnumCppInfo.get(am, t.ty_decl)
150        self.decl_headers = [enum_cpp_info.decl_header]
151        self.defn_headers = [enum_cpp_info.defn_header]
152        self.impl_headers = [enum_cpp_info.defn_header]
153        self.as_owner = enum_cpp_info.as_owner
154        self.as_param = enum_cpp_info.as_param
155
156
157class UnionTypeCppInfo(AbstractAnalysis[UnionType], AbstractTypeCppInfo):
158    def __init__(self, am: AnalysisManager, t: UnionType):
159        super().__init__(am, t)
160        union_cpp_info = UnionCppInfo.get(am, t.ty_decl)
161        self.decl_headers = [union_cpp_info.decl_header]
162        self.defn_headers = [union_cpp_info.defn_header]
163        self.impl_headers = [union_cpp_info.impl_header]
164        self.as_owner = union_cpp_info.as_owner
165        self.as_param = union_cpp_info.as_param
166
167
168class StructTypeCppInfo(AbstractAnalysis[StructType], AbstractTypeCppInfo):
169    def __init__(self, am: AnalysisManager, t: StructType):
170        super().__init__(am, t)
171        struct_cpp_info = StructCppInfo.get(am, t.ty_decl)
172        self.decl_headers = [struct_cpp_info.decl_header]
173        self.defn_headers = [struct_cpp_info.defn_header]
174        self.impl_headers = [struct_cpp_info.impl_header]
175        self.as_owner = struct_cpp_info.as_owner
176        self.as_param = struct_cpp_info.as_param
177
178
179class IfaceTypeCppInfo(AbstractAnalysis[IfaceType], AbstractTypeCppInfo):
180    def __init__(self, am: AnalysisManager, t: IfaceType):
181        super().__init__(am, t)
182        iface_cpp_info = IfaceCppInfo.get(am, t.ty_decl)
183        self.decl_headers = [iface_cpp_info.decl_header]
184        self.defn_headers = [iface_cpp_info.defn_header]
185        self.impl_headers = [iface_cpp_info.impl_header]
186        self.as_owner = iface_cpp_info.as_owner
187        self.as_param = iface_cpp_info.as_param
188
189
190class ScalarTypeCppInfo(AbstractAnalysis[ScalarType], AbstractTypeCppInfo):
191    def __init__(self, am: AnalysisManager, t: ScalarType):
192        super().__init__(am, t)
193        res = {
194            ScalarKind.BOOL: "bool",
195            ScalarKind.F32: "float",
196            ScalarKind.F64: "double",
197            ScalarKind.I8: "int8_t",
198            ScalarKind.I16: "int16_t",
199            ScalarKind.I32: "int32_t",
200            ScalarKind.I64: "int64_t",
201            ScalarKind.U8: "uint8_t",
202            ScalarKind.U16: "uint16_t",
203            ScalarKind.U32: "uint32_t",
204            ScalarKind.U64: "uint64_t",
205        }.get(t.kind)
206        if res is None:
207            raise ValueError
208        self.decl_headers = []
209        self.defn_headers = []
210        self.impl_headers = []
211        self.as_param = res
212        self.as_owner = res
213
214
215class OpaqueTypeCppInfo(AbstractAnalysis[OpaqueType], AbstractTypeCppInfo):
216    def __init__(self, am: AnalysisManager, t: OpaqueType) -> None:
217        super().__init__(am, t)
218        self.decl_headers = []
219        self.defn_headers = []
220        self.impl_headers = []
221        self.as_param = "uintptr_t"
222        self.as_owner = "uintptr_t"
223
224
225class StringTypeCppInfo(AbstractAnalysis[StringType], AbstractTypeCppInfo):
226    def __init__(self, am: AnalysisManager, t: StringType):
227        super().__init__(am, t)
228        self.decl_headers = ["taihe/string.hpp"]
229        self.defn_headers = ["taihe/string.hpp"]
230        self.impl_headers = ["taihe/string.hpp"]
231        self.as_owner = "::taihe::string"
232        self.as_param = "::taihe::string_view"
233
234
235class ArrayTypeCppInfo(AbstractAnalysis[ArrayType], AbstractTypeCppInfo):
236    def __init__(self, am: AnalysisManager, t: ArrayType) -> None:
237        super().__init__(am, t)
238        arg_ty_cpp_info = TypeCppInfo.get(am, t.item_ty)
239        self.decl_headers = ["taihe/array.hpp", *arg_ty_cpp_info.decl_headers]
240        self.defn_headers = ["taihe/array.hpp", *arg_ty_cpp_info.decl_headers]
241        self.impl_headers = ["taihe/array.hpp", *arg_ty_cpp_info.impl_headers]
242        self.as_owner = f"::taihe::array<{arg_ty_cpp_info.as_owner}>"
243        self.as_param = f"::taihe::array_view<{arg_ty_cpp_info.as_owner}>"
244
245
246class OptionalTypeCppInfo(AbstractAnalysis[OptionalType], AbstractTypeCppInfo):
247    def __init__(self, am: AnalysisManager, t: OptionalType) -> None:
248        super().__init__(am, t)
249        arg_ty_cpp_info = TypeCppInfo.get(am, t.item_ty)
250        self.decl_headers = ["taihe/optional.hpp", *arg_ty_cpp_info.decl_headers]
251        self.defn_headers = ["taihe/optional.hpp", *arg_ty_cpp_info.decl_headers]
252        self.impl_headers = ["taihe/optional.hpp", *arg_ty_cpp_info.impl_headers]
253        self.as_owner = f"::taihe::optional<{arg_ty_cpp_info.as_owner}>"
254        self.as_param = f"::taihe::optional_view<{arg_ty_cpp_info.as_owner}>"
255
256
257class VectorTypeCppInfo(AbstractAnalysis[VectorType], AbstractTypeCppInfo):
258    def __init__(self, am: AnalysisManager, t: VectorType) -> None:
259        super().__init__(am, t)
260        val_ty_cpp_info = TypeCppInfo.get(am, t.val_ty)
261        self.decl_headers = ["taihe/vector.hpp", *val_ty_cpp_info.decl_headers]
262        self.defn_headers = ["taihe/vector.hpp", *val_ty_cpp_info.decl_headers]
263        self.impl_headers = ["taihe/vector.hpp", *val_ty_cpp_info.impl_headers]
264        self.as_owner = f"::taihe::vector<{val_ty_cpp_info.as_owner}>"
265        self.as_param = f"::taihe::vector_view<{val_ty_cpp_info.as_owner}>"
266
267
268class MapTypeCppInfo(AbstractAnalysis[MapType], AbstractTypeCppInfo):
269    def __init__(self, am: AnalysisManager, t: MapType) -> None:
270        super().__init__(am, t)
271        key_ty_cpp_info = TypeCppInfo.get(am, t.key_ty)
272        val_ty_cpp_info = TypeCppInfo.get(am, t.val_ty)
273        self.decl_headers = [
274            "taihe/map.hpp",
275            *key_ty_cpp_info.decl_headers,
276            *val_ty_cpp_info.decl_headers,
277        ]
278        self.defn_headers = [
279            "taihe/map.hpp",
280            *key_ty_cpp_info.decl_headers,
281            *val_ty_cpp_info.decl_headers,
282        ]
283        self.impl_headers = [
284            "taihe/map.hpp",
285            *key_ty_cpp_info.impl_headers,
286            *val_ty_cpp_info.impl_headers,
287        ]
288        self.as_owner = (
289            f"::taihe::map<{key_ty_cpp_info.as_owner}, {val_ty_cpp_info.as_owner}>"
290        )
291        self.as_param = (
292            f"::taihe::map_view<{key_ty_cpp_info.as_owner}, {val_ty_cpp_info.as_owner}>"
293        )
294
295
296class SetTypeCppInfo(AbstractAnalysis[SetType], AbstractTypeCppInfo):
297    def __init__(self, am: AnalysisManager, t: SetType) -> None:
298        super().__init__(am, t)
299        key_ty_cpp_info = TypeCppInfo.get(am, t.key_ty)
300        self.decl_headers = ["taihe/set.hpp", *key_ty_cpp_info.decl_headers]
301        self.defn_headers = ["taihe/set.hpp", *key_ty_cpp_info.decl_headers]
302        self.impl_headers = ["taihe/set.hpp", *key_ty_cpp_info.impl_headers]
303        self.as_owner = f"::taihe::set<{key_ty_cpp_info.as_owner}>"
304        self.as_param = f"::taihe::set_view<{key_ty_cpp_info.as_owner}>"
305
306
307class CallbackTypeCppInfo(AbstractAnalysis[CallbackType], AbstractTypeCppInfo):
308    def __init__(self, am: AnalysisManager, t: CallbackType) -> None:
309        super().__init__(am, t)
310        if return_ty := t.return_ty:
311            return_ty_cpp_info = TypeCppInfo.get(am, return_ty)
312            return_ty_decl_headers = return_ty_cpp_info.decl_headers
313            return_ty_impl_headers = return_ty_cpp_info.impl_headers
314            return_ty_as_owner = return_ty_cpp_info.as_owner
315        else:
316            return_ty_decl_headers = []
317            return_ty_impl_headers = []
318            return_ty_as_owner = "void"
319        params_ty_decl_headers = []
320        params_ty_impl_headers = []
321        params_ty_as_param = []
322        for param_ty in t.params_ty:
323            param_ty_cpp_info = TypeCppInfo.get(am, param_ty)
324            params_ty_decl_headers.extend(param_ty_cpp_info.decl_headers)
325            params_ty_impl_headers.extend(param_ty_cpp_info.impl_headers)
326            params_ty_as_param.append(param_ty_cpp_info.as_param)
327        params_fmt = ", ".join(params_ty_as_param)
328        self.decl_headers = [
329            "taihe/callback.hpp",
330            *return_ty_decl_headers,
331            *params_ty_decl_headers,
332        ]
333        self.defn_headers = [
334            "taihe/callback.hpp",
335            *return_ty_decl_headers,
336            *params_ty_decl_headers,
337        ]
338        self.impl_headers = [
339            "taihe/callback.hpp",
340            *return_ty_impl_headers,
341            *params_ty_impl_headers,
342        ]
343        self.as_owner = f"::taihe::callback<{return_ty_as_owner}({params_fmt})>"
344        self.as_param = f"::taihe::callback_view<{return_ty_as_owner}({params_fmt})>"
345
346
347class TypeCppInfo(TypeVisitor[AbstractTypeCppInfo]):
348    def __init__(self, am: AnalysisManager):
349        self.am = am
350
351    @staticmethod
352    def get(am: AnalysisManager, t: Type) -> AbstractTypeCppInfo:
353        return TypeCppInfo(am).handle_type(t)
354
355    @override
356    def visit_enum_type(self, t: EnumType) -> AbstractTypeCppInfo:
357        return EnumTypeCppInfo.get(self.am, t)
358
359    @override
360    def visit_union_type(self, t: UnionType) -> AbstractTypeCppInfo:
361        return UnionTypeCppInfo.get(self.am, t)
362
363    @override
364    def visit_struct_type(self, t: StructType) -> AbstractTypeCppInfo:
365        return StructTypeCppInfo.get(self.am, t)
366
367    @override
368    def visit_iface_type(self, t: IfaceType) -> AbstractTypeCppInfo:
369        return IfaceTypeCppInfo.get(self.am, t)
370
371    @override
372    def visit_scalar_type(self, t: ScalarType) -> AbstractTypeCppInfo:
373        return ScalarTypeCppInfo.get(self.am, t)
374
375    @override
376    def visit_opaque_type(self, t: OpaqueType) -> AbstractTypeCppInfo:
377        return OpaqueTypeCppInfo.get(self.am, t)
378
379    @override
380    def visit_string_type(self, t: StringType) -> AbstractTypeCppInfo:
381        return StringTypeCppInfo.get(self.am, t)
382
383    @override
384    def visit_array_type(self, t: ArrayType) -> AbstractTypeCppInfo:
385        return ArrayTypeCppInfo.get(self.am, t)
386
387    @override
388    def visit_optional_type(self, t: OptionalType) -> AbstractTypeCppInfo:
389        return OptionalTypeCppInfo.get(self.am, t)
390
391    @override
392    def visit_vector_type(self, t: VectorType) -> AbstractTypeCppInfo:
393        return VectorTypeCppInfo.get(self.am, t)
394
395    @override
396    def visit_map_type(self, t: MapType) -> AbstractTypeCppInfo:
397        return MapTypeCppInfo.get(self.am, t)
398
399    @override
400    def visit_set_type(self, t: SetType) -> AbstractTypeCppInfo:
401        return SetTypeCppInfo.get(self.am, t)
402
403    @override
404    def visit_callback_type(self, t: CallbackType) -> AbstractTypeCppInfo:
405        return CallbackTypeCppInfo.get(self.am, t)
406
407
408class PackageCppUserInfo(AbstractAnalysis[PackageDecl]):
409    def __init__(self, am: AnalysisManager, p: PackageDecl) -> None:
410        super().__init__(am, p)
411        self.header = f"{p.name}.user.hpp"
412
413
414class GlobFuncCppUserInfo(AbstractAnalysis[GlobFuncDecl]):
415    def __init__(self, am: AnalysisManager, f: GlobFuncDecl) -> None:
416        super().__init__(am, f)
417        self.namespace = "::".join(f.parent_pkg.segments)
418        self.call_name = f.name
419        self.full_name = "::" + self.namespace + "::" + self.call_name