15
15
16
16
// Package starcgenx is a Static Analysis Type Assertion shim and Registration Code Generator
17
17
// which provides an extractor to extract types from a package, in order to generate
18
- // approprate shimsr a package so code can be generated for it.
18
+ // appropriate shims for a package so code can be generated for it.
19
19
//
20
20
// It's written for use by the starcgen tool, but separate to permit
21
21
// alternative "go/importer" Importers for accessing types from imported packages.
@@ -336,6 +336,7 @@ func (e *Extractor) isRequired(ident string, obj types.Object, idsRequired, idsF
336
336
// or it's receiver type identifier needs to be in the filtered identifiers.
337
337
if idsRequired [ident ] {
338
338
idsFound [ident ] = true
339
+ e .Printf ("isRequired found: %s\n " , ident )
339
340
return true
340
341
}
341
342
// Check if this is a function.
@@ -347,10 +348,10 @@ func (e *Extractor) isRequired(ident string, obj types.Object, idsRequired, idsF
347
348
if recv := sig .Recv (); recv != nil && graph .IsLifecycleMethod (ident ) {
348
349
// We don't want to care about pointers, so dereference to value type.
349
350
t := recv .Type ()
350
- p , ok := t .(* types.Pointer )
351
+ p , ok := types . Unalias ( t ) .(* types.Pointer )
351
352
for ok {
352
353
t = p .Elem ()
353
- p , ok = t .(* types.Pointer )
354
+ p , ok = types . Unalias ( t ) .(* types.Pointer )
354
355
}
355
356
ts := types .TypeString (t , e .qualifier )
356
357
e .Printf ("recv %v has %v, ts: %s %s--- " , recv , sig , ts , ident )
@@ -384,14 +385,16 @@ func (e *Extractor) fromObj(fset *token.FileSet, id *ast.Ident, obj types.Object
384
385
ident = obj .Name ()
385
386
}
386
387
if ! e .isRequired (ident , obj , idsRequired , idsFound ) {
388
+ e .Printf ("%s: %q with package %q is not required \n " ,
389
+ fset .Position (id .Pos ()), id .Name , pkg .Name ())
387
390
return
388
391
}
389
392
390
393
switch ot := obj .(type ) {
391
394
case * types.Var :
392
395
// Vars are tricky since they could be anything, and anywhere (package scope, parameters, etc)
393
396
// eg. Flags, or Field Tags, among others.
394
- // I'm increasingly convinced that we should simply igonore vars.
397
+ // I'm increasingly convinced that we should simply ignore vars.
395
398
// Do nothing for vars.
396
399
case * types.Func :
397
400
sig := obj .Type ().(* types.Signature )
@@ -405,10 +408,10 @@ func (e *Extractor) fromObj(fset *token.FileSet, id *ast.Ident, obj types.Object
405
408
}
406
409
// This must be a structural DoFn! We should generate a closure wrapper for it.
407
410
t := recv .Type ()
408
- p , ok := t .(* types.Pointer )
411
+ p , ok := types . Unalias ( t ) .(* types.Pointer )
409
412
for ok {
410
413
t = p .Elem ()
411
- p , ok = t .(* types.Pointer )
414
+ p , ok = types . Unalias ( t ) .(* types.Pointer )
412
415
}
413
416
ts := types .TypeString (t , e .qualifier )
414
417
mthdMap := e .wraps [ts ]
@@ -453,6 +456,10 @@ func (e *Extractor) extractType(ot *types.TypeName) {
453
456
// A single level is safe since the code we're analysing imports it,
454
457
// so we can assume the generated code can access it too.
455
458
if ot .IsAlias () {
459
+ if t , ok := ot .Type ().(* types.Alias ); ok {
460
+ ot = t .Obj ()
461
+ name = types .TypeString (t , e .qualifier )
462
+ }
456
463
if t , ok := ot .Type ().(* types.Named ); ok {
457
464
ot = t .Obj ()
458
465
name = types .TypeString (t , e .qualifier )
@@ -461,7 +468,7 @@ func (e *Extractor) extractType(ot *types.TypeName) {
461
468
// Only register non-universe types (eg. avoid `error` and similar)
462
469
if pkg := ot .Pkg (); pkg != nil {
463
470
path := pkg .Path ()
464
- e .imports [pkg . Path () ] = struct {}{}
471
+ e .imports [path ] = struct {}{}
465
472
466
473
// Do not add universal types to be registered.
467
474
if path == shimx .TypexImport {
@@ -484,17 +491,17 @@ func (e *Extractor) extractFromContainer(t types.Type) types.Type {
484
491
// Container types need to be iteratively unwrapped until we're at the base type,
485
492
// so we can get the import if necessary.
486
493
for {
487
- if s , ok := t .(* types.Slice ); ok {
494
+ if s , ok := types . Unalias ( t ) .(* types.Slice ); ok {
488
495
t = s .Elem ()
489
496
continue
490
497
}
491
498
492
- if p , ok := t .(* types.Pointer ); ok {
499
+ if p , ok := types . Unalias ( t ) .(* types.Pointer ); ok {
493
500
t = p .Elem ()
494
501
continue
495
502
}
496
503
497
- if a , ok := t .(* types.Array ); ok {
504
+ if a , ok := types . Unalias ( t ) .(* types.Array ); ok {
498
505
t = a .Elem ()
499
506
continue
500
507
}
@@ -510,9 +517,17 @@ func (e *Extractor) extractFromTuple(tuple *types.Tuple) {
510
517
t := e .extractFromContainer (s .Type ())
511
518
512
519
// Here's where we ensure we register new imports.
520
+ if at , ok := t .(* types.Alias ); ok {
521
+ if pkg := at .Obj ().Pkg (); pkg != nil {
522
+ e .imports [pkg .Path ()] = struct {}{}
523
+ }
524
+ }
513
525
if t , ok := t .(* types.Named ); ok {
514
526
if pkg := t .Obj ().Pkg (); pkg != nil {
527
+ e .Printf ("extractType: adding import path %q for %v\n " , pkg .Path (), t )
515
528
e .imports [pkg .Path ()] = struct {}{}
529
+ } else {
530
+ e .Printf ("extractType: %v has no package to import\n " , t )
516
531
}
517
532
e .extractType (t .Obj ())
518
533
}
@@ -683,7 +698,7 @@ func (e *Extractor) makeEmitter(sig *types.Signature) (shimx.Emitter, bool) {
683
698
684
699
// makeInput checks if the given signature is an iterator or not, and if so,
685
700
// returns a shimx.Input struct for the signature for use by the code
686
- // generator. The canonical check for an iterater signature is in the
701
+ // generator. The canonical check for an iterator signature is in the
687
702
// funcx.UnfoldIter function which uses the reflect library,
688
703
// and this logic is replicated here.
689
704
func (e * Extractor ) makeInput (sig * types.Signature ) (shimx.Input , bool ) {
@@ -692,13 +707,13 @@ func (e *Extractor) makeInput(sig *types.Signature) (shimx.Input, bool) {
692
707
return shimx.Input {}, false
693
708
}
694
709
// Iterators must return a bool.
695
- if b , ok := r .At (0 ).Type ().(* types.Basic ); ! ok || b .Kind () != types .Bool {
710
+ if b , ok := types . Unalias ( r .At (0 ).Type () ).(* types.Basic ); ! ok || b .Kind () != types .Bool {
696
711
return shimx.Input {}, false
697
712
}
698
713
p := sig .Params ()
699
714
for i := 0 ; i < p .Len (); i ++ {
700
715
// All params for iterators must be pointers.
701
- if _ , ok := p .At (i ).Type ().(* types.Pointer ); ! ok {
716
+ if _ , ok := types . Unalias ( p .At (i ).Type () ).(* types.Pointer ); ! ok {
702
717
return shimx.Input {}, false
703
718
}
704
719
}
0 commit comments