1
1
import typing
2
2
from dataclasses import dataclass , field
3
3
4
-
5
- @dataclass
6
- class Token :
7
- """
8
- In an ideal world, this Token class would not be exposed via the user
9
- visible API. Unfortunately, getting to that point would take a significant
10
- amount of effort.
11
-
12
- It is not expected that these will change, but they might.
13
-
14
- At the moment, the only supported use of Token objects are in conjunction
15
- with the ``tokfmt`` function. As this library matures, we'll try to clarify
16
- the expectations around these. File an issue on github if you have ideas!
17
- """
18
-
19
- #: Raw value of the token
20
- value : str
21
-
22
- #: Lex type of the token
23
- type : str = field (repr = False , compare = False , default = "" )
4
+ from .tokfmt import tokfmt , Token
24
5
25
6
26
7
@dataclass
@@ -37,6 +18,9 @@ class Value:
37
18
#: Tokens corresponding to the value
38
19
tokens : typing .List [Token ]
39
20
21
+ def format (self ) -> str :
22
+ return tokfmt (self .tokens )
23
+
40
24
41
25
@dataclass
42
26
class NamespaceAlias :
@@ -94,6 +78,9 @@ class DecltypeSpecifier:
94
78
#: Unparsed tokens within the decltype
95
79
tokens : typing .List [Token ]
96
80
81
+ def format (self ) -> str :
82
+ return f"decltype({ tokfmt (self .tokens )} )"
83
+
97
84
98
85
@dataclass
99
86
class FundamentalSpecifier :
@@ -107,6 +94,9 @@ class FundamentalSpecifier:
107
94
108
95
name : str
109
96
97
+ def format (self ) -> str :
98
+ return self .name
99
+
110
100
111
101
@dataclass
112
102
class NameSpecifier :
@@ -124,6 +114,12 @@ class NameSpecifier:
124
114
125
115
specialization : typing .Optional ["TemplateSpecialization" ] = None
126
116
117
+ def format (self ) -> str :
118
+ if self .specialization :
119
+ return f"{ self .name } { self .specialization .format ()} "
120
+ else :
121
+ return self .name
122
+
127
123
128
124
@dataclass
129
125
class AutoSpecifier :
@@ -133,6 +129,9 @@ class AutoSpecifier:
133
129
134
130
name : str = "auto"
135
131
132
+ def format (self ) -> str :
133
+ return self .name
134
+
136
135
137
136
@dataclass
138
137
class AnonymousName :
@@ -145,6 +144,10 @@ class AnonymousName:
145
144
#: Unique id associated with this name (only unique per parser instance!)
146
145
id : int
147
146
147
+ def format (self ) -> str :
148
+ # TODO: not sure what makes sense here, subject to change
149
+ return f"<<id={ self .id } >>"
150
+
148
151
149
152
PQNameSegment = typing .Union [
150
153
AnonymousName , FundamentalSpecifier , NameSpecifier , DecltypeSpecifier , AutoSpecifier
@@ -170,6 +173,13 @@ class PQName:
170
173
#: Set to true if the type was preceded with 'typename'
171
174
has_typename : bool = False
172
175
176
+ def format (self ) -> str :
177
+ tn = "typename " if self .has_typename else ""
178
+ if self .classkey :
179
+ return f"{ tn } { self .classkey } { '::' .join (seg .format () for seg in self .segments )} "
180
+ else :
181
+ return tn + "::" .join (seg .format () for seg in self .segments )
182
+
173
183
174
184
@dataclass
175
185
class TemplateArgument :
@@ -189,6 +199,12 @@ class TemplateArgument:
189
199
190
200
param_pack : bool = False
191
201
202
+ def format (self ) -> str :
203
+ if self .param_pack :
204
+ return f"{ self .arg .format ()} ..."
205
+ else :
206
+ return self .arg .format ()
207
+
192
208
193
209
@dataclass
194
210
class TemplateSpecialization :
@@ -204,6 +220,9 @@ class TemplateSpecialization:
204
220
205
221
args : typing .List [TemplateArgument ]
206
222
223
+ def format (self ) -> str :
224
+ return f"<{ ', ' .join (arg .format () for arg in self .args )} >"
225
+
207
226
208
227
@dataclass
209
228
class FunctionType :
@@ -238,6 +257,23 @@ class FunctionType:
238
257
#: calling convention
239
258
msvc_convention : typing .Optional [str ] = None
240
259
260
+ def format (self ) -> str :
261
+ vararg = "..." if self .vararg else ""
262
+ params = ", " .join (p .format () for p in self .parameters )
263
+ if self .has_trailing_return :
264
+ return f"auto ({ params } { vararg } ) -> { self .return_type .format ()} "
265
+ else :
266
+ return f"{ self .return_type .format ()} ({ params } { vararg } )"
267
+
268
+ def format_decl (self , name : str ) -> str :
269
+ """Format as a named declaration"""
270
+ vararg = "..." if self .vararg else ""
271
+ params = ", " .join (p .format () for p in self .parameters )
272
+ if self .has_trailing_return :
273
+ return f"auto { name } ({ params } { vararg } ) -> { self .return_type .format ()} "
274
+ else :
275
+ return f"{ self .return_type .format ()} { name } ({ params } { vararg } )"
276
+
241
277
242
278
@dataclass
243
279
class Type :
@@ -250,6 +286,17 @@ class Type:
250
286
const : bool = False
251
287
volatile : bool = False
252
288
289
+ def format (self ) -> str :
290
+ c = "const " if self .const else ""
291
+ v = "volatile " if self .volatile else ""
292
+ return f"{ c } { v } { self .typename .format ()} "
293
+
294
+ def format_decl (self , name : str ):
295
+ """Format as a named declaration"""
296
+ c = "const " if self .const else ""
297
+ v = "volatile " if self .volatile else ""
298
+ return f"{ c } { v } { self .typename .format ()} { name } "
299
+
253
300
254
301
@dataclass
255
302
class Array :
@@ -269,6 +316,14 @@ class Array:
269
316
#: ~~
270
317
size : typing .Optional [Value ]
271
318
319
+ def format (self ) -> str :
320
+ s = self .size .format () if self .size else ""
321
+ return f"{ self .array_of .format ()} [{ s } ]"
322
+
323
+ def format_decl (self , name : str ) -> str :
324
+ s = self .size .format () if self .size else ""
325
+ return f"{ self .array_of .format ()} { name } [{ s } ]"
326
+
272
327
273
328
@dataclass
274
329
class Pointer :
@@ -282,6 +337,25 @@ class Pointer:
282
337
const : bool = False
283
338
volatile : bool = False
284
339
340
+ def format (self ) -> str :
341
+ c = " const" if self .const else ""
342
+ v = " volatile" if self .volatile else ""
343
+ ptr_to = self .ptr_to
344
+ if isinstance (ptr_to , (Array , FunctionType )):
345
+ return ptr_to .format_decl (f"(*{ c } { v } )" )
346
+ else :
347
+ return f"{ ptr_to .format ()} *{ c } { v } "
348
+
349
+ def format_decl (self , name : str ):
350
+ """Format as a named declaration"""
351
+ c = " const" if self .const else ""
352
+ v = " volatile" if self .volatile else ""
353
+ ptr_to = self .ptr_to
354
+ if isinstance (ptr_to , (Array , FunctionType )):
355
+ return ptr_to .format_decl (f"(*{ c } { v } { name } )" )
356
+ else :
357
+ return f"{ ptr_to .format ()} *{ c } { v } { name } "
358
+
285
359
286
360
@dataclass
287
361
class Reference :
@@ -291,6 +365,22 @@ class Reference:
291
365
292
366
ref_to : typing .Union [Array , FunctionType , Pointer , Type ]
293
367
368
+ def format (self ) -> str :
369
+ ref_to = self .ref_to
370
+ if isinstance (ref_to , Array ):
371
+ return ref_to .format_decl ("(&)" )
372
+ else :
373
+ return f"{ ref_to .format ()} &"
374
+
375
+ def format_decl (self , name : str ):
376
+ """Format as a named declaration"""
377
+ ref_to = self .ref_to
378
+
379
+ if isinstance (ref_to , Array ):
380
+ return ref_to .format_decl (f"(& { name } )" )
381
+ else :
382
+ return f"{ ref_to .format ()} & { name } "
383
+
294
384
295
385
@dataclass
296
386
class MoveReference :
@@ -300,6 +390,13 @@ class MoveReference:
300
390
301
391
moveref_to : typing .Union [Array , FunctionType , Pointer , Type ]
302
392
393
+ def format (self ) -> str :
394
+ return f"{ self .moveref_to .format ()} &&"
395
+
396
+ def format_decl (self , name : str ):
397
+ """Format as a named declaration"""
398
+ return f"{ self .moveref_to .format ()} && { name } "
399
+
303
400
304
401
#: A type or function type that is decorated with various things
305
402
#:
@@ -505,6 +602,15 @@ class Parameter:
505
602
default : typing .Optional [Value ] = None
506
603
param_pack : bool = False
507
604
605
+ def format (self ) -> str :
606
+ default = f" = { self .default .format ()} " if self .default else ""
607
+ pp = "... " if self .param_pack else ""
608
+ name = self .name
609
+ if name :
610
+ return f"{ self .type .format_decl (f'{ pp } { name } ' )} { default } "
611
+ else :
612
+ return f"{ self .type .format ()} { pp } { default } "
613
+
508
614
509
615
@dataclass
510
616
class Function :
0 commit comments