FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
codeql/misc/codegen/generators/cppgen.py at codeql-cli/v2.25.1 · github/codeql · GitHub
Uh oh!
There was an error while loading.
Please reload this page
.
github
/
codeql
Public
Notifications
You must be signed in to change notification settings
Fork
2.1k
Star
10k
Code
Issues
997
Pull requests
454
Discussions
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Discussions
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
codeql
/
misc
/
codegen
/
generators
/
cppgen.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
118 lines (101 loc) · 3.65 KB
Breadcrumbs
codeql
/
misc
/
codegen
/
generators
/
cppgen.py
Copy path
File metadata and controls
118 lines (101 loc) · 3.65 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
"""
C++ trap class generation
`generate(opts, renderer)` will generate `TrapClasses.h` out of a `yml` schema file.
Each class in the schema gets a corresponding `struct` in `TrapClasses.h`, where:
* inheritance is preserved
* each property will be a corresponding field in the `struct` (with repeated properties mapping to `std::vector` and
optional ones to `std::optional`)
* final classes get a streaming operator that serializes the whole class into the corresponding trap emissions (using
`TrapEntries.h` from `trapgen`).
"""
import
functools
import
typing
import
inflection
from
misc
.
codegen
.
lib
import
cpp
,
schema
from
misc
.
codegen
.
loaders
import
schemaloader
def
_get_type
(
t
:
str
,
add_or_none_except
:
typing
.
Optional
[
str
]
=
None
)
->
str
:
if
t
is
None
:
# this is a predicate
return
"bool"
if
t
==
"string"
:
return
"std::string"
if
t
==
"boolean"
:
return
"bool"
if
t
[
0
].
isupper
():
if
add_or_none_except
is
not
None
and
t
!=
add_or_none_except
:
suffix
=
"OrNone"
else
:
suffix
=
""
return
f"TrapLabel<
{
t
}
{
suffix
}
Tag>"
return
t
def
_get_trap_name
(
cls
:
schema
.
Class
,
p
:
schema
.
Property
)
->
str
|
None
:
if
p
.
is_single
:
return
None
overridden_trap_name
=
p
.
pragmas
.
get
(
"ql_db_table_name"
)
if
overridden_trap_name
:
return
inflection
.
camelize
(
overridden_trap_name
)
trap_name
=
inflection
.
camelize
(
f"
{
cls
.
name
}
_
{
p
.
name
}
"
)
if
p
.
is_predicate
:
return
trap_name
return
inflection
.
pluralize
(
trap_name
)
def
_get_field
(
cls
:
schema
.
Class
,
p
:
schema
.
Property
,
add_or_none_except
:
typing
.
Optional
[
str
]
=
None
,
)
->
cpp
.
Field
:
args
=
dict
(
field_name
=
p
.
name
+
(
"_"
if
p
.
name
in
cpp
.
cpp_keywords
else
""
),
base_type
=
_get_type
(
p
.
type
,
add_or_none_except
),
is_optional
=
p
.
is_optional
,
is_repeated
=
p
.
is_repeated
,
is_predicate
=
p
.
is_predicate
,
is_unordered
=
p
.
is_unordered
,
trap_name
=
_get_trap_name
(
cls
,
p
),
)
args
.
update
(
cpp
.
get_field_override
(
p
.
name
))
return
cpp
.
Field
(
**
args
)
class
Processor
:
def
__init__
(
self
,
data
:
schema
.
Schema
):
self
.
_classmap
=
data
.
classes
if
data
.
null
:
root_type
=
next
(
iter
(
data
.
classes
))
self
.
_add_or_none_except
=
root_type
else
:
self
.
_add_or_none_except
=
None
@
functools
.
lru_cache
(
maxsize
=
None
)
def
_get_class
(
self
,
name
:
str
)
->
cpp
.
Class
:
cls
=
self
.
_classmap
[
name
]
trap_name
=
None
if
not
cls
.
derived
or
any
(
p
.
is_single
for
p
in
cls
.
properties
):
trap_name
=
inflection
.
pluralize
(
cls
.
name
)
return
cpp
.
Class
(
name
=
name
,
bases
=
[
self
.
_get_class
(
b
)
for
b
in
cls
.
bases
],
fields
=
[
_get_field
(
cls
,
p
,
self
.
_add_or_none_except
)
for
p
in
cls
.
properties
if
"cpp_skip"
not
in
p
.
pragmas
and
not
p
.
synth
],
final
=
not
cls
.
derived
,
trap_name
=
trap_name
,
)
def
get_classes
(
self
):
ret
=
{
""
: []}
for
k
,
cls
in
self
.
_classmap
.
items
():
if
not
cls
.
synth
:
ret
.
setdefault
(
cls
.
group
, []).
append
(
self
.
_get_class
(
cls
.
name
))
return
ret
def
generate
(
opts
,
renderer
):
assert
opts
.
cpp_output
processor
=
Processor
(
schemaloader
.
load_file
(
opts
.
schema
))
out
=
opts
.
cpp_output
for
dir
,
classes
in
processor
.
get_classes
().
items
():
renderer
.
render
(
cpp
.
ClassList
(
classes
,
opts
.
schema
,
include_parent
=
bool
(
dir
),
trap_library
=
opts
.
trap_library
,
),
out
/
dir
/
"TrapClasses"
,
)
Back
|
FazBrowse Home
|
New Git URL