Skip to content

Commit f473236

Browse files
committed
Go: extract type parameters in type definitions
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
1 parent b9ad065 commit f473236

File tree

3 files changed

+112
-3
lines changed

3 files changed

+112
-3
lines changed

Units/parser-go.r/go-generics.d/expected.tags

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@ F0 input.go /^func F0[L ~[]M, M comparable, _, G any](s L, v M) int {$/;" f pack
1313
N input.go /^func F1[N ~[]O, O comparable, _ any](s N, v O) int {$/;" Z func:x.F1 typeref:constraint:~[]O nth:0
1414
O input.go /^func F1[N ~[]O, O comparable, _ any](s N, v O) int {$/;" Z func:x.F1 typeref:constraint:comparable nth:1
1515
F1 input.go /^func F1[N ~[]O, O comparable, _ any](s N, v O) int {$/;" f package:x typeref:typename:int signature:(s N, v O) tparams:[N ~[]O, O comparable, _ any]
16+
T input.go /^type List[T any] struct {$/;" Z struct:x.List typeref:constraint:any nth:0
17+
List input.go /^type List[T any] struct {$/;" s package:x tparams:[T any]
18+
next input.go /^ next *List[T]$/;" m struct:x.List typeref:typename:*List
19+
value input.go /^ value T$/;" m struct:x.List typeref:typename:T
20+
UUIDBuflen input.go /^ UUIDBuflen = 256$/;" c package:x
21+
UUID input.go /^type UUID [UUIDBuflen]byte$/;" t package:x typeref:typename:[UUIDBuflen]byte

Units/parser-go.r/go-generics.d/input.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,15 @@ func F0[L ~[]M, M comparable, _, G any](s L, v M) int {
3030
func F1[N ~[]O, O comparable, _ any](s N, v O) int {
3131
return -1
3232
}
33+
34+
// Taken from https://go.dev/ref/spec#Type_definitions
35+
type List[T any] struct {
36+
next *List[T]
37+
value T
38+
}
39+
40+
// Taken from podman/vendor/github.com/digitalocean/go-libvirt/remote_protocol.gen.go
41+
const (
42+
UUIDBuflen = 256
43+
)
44+
type UUID [UUIDBuflen]byte

parsers/go.c

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,44 @@ static void attachConstraint (intArray *tparams_indexes, collector *constraint)
842842
}
843843
}
844844

845+
static bool isArraySpec (intArray *corks, vString *tparams_str)
846+
{
847+
const char *cstr = vStringValue (tparams_str);
848+
size_t cstr_len = vStringLength (tparams_str);
849+
850+
if (intArrayCount (corks) > 1 ||
851+
(cstr_len > 2
852+
&& cstr
853+
&& cstr [cstr_len - 1] == ']'
854+
&& cstr [cstr_len - 2] == ','))
855+
return false;
856+
857+
for (unsigned int i = 0; i < intArrayCount (corks); i++)
858+
{
859+
int cork = intArrayItem (corks, i);
860+
tagEntryInfo *e = getEntryInCorkQueue (cork);
861+
if (!e)
862+
return false; /* Maybe "_" in the array. */
863+
864+
if (e->extensionFields.typeRef [0])
865+
return false; /* a constraint is given */
866+
}
867+
868+
return true;
869+
}
870+
871+
static void markCorkEntryAsPlaceholderInBatch (intArray *corks)
872+
{
873+
for (unsigned int i = 0; i < intArrayCount (corks); i++)
874+
{
875+
int cork = intArrayItem (corks, i);
876+
if (cork == CORK_NIL)
877+
continue;
878+
879+
markCorkEntryAsPlaceholder (cork, true);
880+
}
881+
}
882+
845883
static intArray * parseTypeParameters (tokenInfo *const token, collector *tparams)
846884
{
847885
// TypeParameters = "[" TypeParamList [ "," ] "]" .
@@ -908,6 +946,14 @@ static intArray * parseTypeParameters (tokenInfo *const token, collector *tparam
908946
/* Read the next token as the other parser* functions do.
909947
* However, don't put the token to the collector. */
910948
readToken (token);
949+
950+
if (isArraySpec (tparams_indexes, tparams->str))
951+
{
952+
markCorkEntryAsPlaceholderInBatch (tparams_indexes);
953+
intArrayDelete (tparams_indexes);
954+
tparams_indexes = NULL;
955+
}
956+
911957
return tparams_indexes;
912958
}
913959

@@ -1310,7 +1356,9 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind, const int sc
13101356
// IdentifierList = identifier { "," identifier } .
13111357
// ExpressionList = Expression { "," Expression } .
13121358
// TypeDecl = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
1313-
// TypeSpec = identifier [ "=" ] Type .
1359+
// TypeSpec = AliasDecl | TypeDef .
1360+
// AliasDecl = identifier [ TypeParameters ] "=" Type .
1361+
// TypeDef = identifier [ TypeParameters ] Type .
13141362
// VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
13151363
// VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
13161364
bool usesParens = false;
@@ -1330,15 +1378,30 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind, const int sc
13301378
tokenInfo *typeToken = NULL;
13311379
int member_scope = scope;
13321380

1381+
char *array_spec = NULL;
1382+
13331383
while (!isType (token, TOKEN_EOF))
13341384
{
13351385
if (isType (token, TOKEN_IDENTIFIER))
13361386
{
13371387
if (kind == GOTAG_TYPE)
13381388
{
1389+
vString *buffer = vStringNew ();
1390+
collector collector = COLLECTOR (buffer);
1391+
char *tparams = NULL;
1392+
intArray *tparams_indexes = NULL;
1393+
13391394
typeToken = newToken ();
13401395
copyToken (typeToken, token);
1341-
readToken (token);
1396+
readTokenFull (token, &collector);
1397+
if (isType (token, TOKEN_OPEN_SQUARE))
1398+
{
1399+
tparams_indexes = parseTypeParameters (token, &collector);
1400+
collectorTruncate (&collector, false);
1401+
tparams = vStringStrdup (buffer);
1402+
}
1403+
vStringDelete (buffer);
1404+
13421405
if (isType (token, TOKEN_EQUAL))
13431406
{
13441407
kind = GOTAG_TALIAS;
@@ -1356,7 +1419,29 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind, const int sc
13561419
scope, NULL, NULL);
13571420

13581421
if (member_scope != CORK_NIL)
1422+
{
1423+
tagEntryInfo *e = getEntryInCorkQueue (member_scope);
1424+
if (e && tparams_indexes)
1425+
{
1426+
fillScopeAndNthFields (member_scope, tparams_indexes);
1427+
if (tparams)
1428+
attachParserField (e, GoFields [F_TPARAMS].ftype, tparams);
1429+
}
1430+
13591431
registerEntry (member_scope);
1432+
}
1433+
1434+
if (tparams_indexes)
1435+
{
1436+
intArrayDelete (tparams_indexes); /* NULL is acceptable. */
1437+
tparams_indexes = NULL;
1438+
if (tparams)
1439+
eFree (tparams);
1440+
}
1441+
else
1442+
array_spec = tparams;
1443+
tparams = NULL;
1444+
13601445
break;
13611446
}
13621447
else
@@ -1381,7 +1466,7 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind, const int sc
13811466
else
13821467
{
13831468
/* Filling "typeref:" field of typeToken. */
1384-
vString *buffer = vStringNew ();
1469+
vString *buffer = vStringNewInit (array_spec ? array_spec : "");
13851470
collector collector = COLLECTOR(buffer);
13861471

13871472
collectorAppendToken (&collector, token);
@@ -1400,6 +1485,12 @@ static void parseConstTypeVar (tokenInfo *const token, goKind kind, const int sc
14001485
else
14011486
vStringDelete (buffer);
14021487
}
1488+
1489+
if (array_spec)
1490+
{
1491+
eFree (array_spec);
1492+
array_spec = NULL;
1493+
}
14031494
deleteToken (typeToken);
14041495
}
14051496
else if (corks)

0 commit comments

Comments
 (0)