@@ -331,28 +331,81 @@ func (obj *TypeName) IsAlias() bool {
331
331
// A Variable represents a declared variable (including function parameters and results, and struct fields).
332
332
type Var struct {
333
333
object
334
+ kind VarKind
334
335
embedded bool // if set, the variable is an embedded struct field, and name is the type name
335
- isField bool // var is struct field
336
336
used bool // set if the variable was used
337
337
origin * Var // if non-nil, the Var from which this one was instantiated
338
338
}
339
339
340
+ // A VarKind discriminates the various kinds of variables.
341
+ type VarKind uint8
342
+
343
+ const (
344
+ _ VarKind = iota // (not meaningful)
345
+ PackageVar // a package-level variable
346
+ LocalVar // a local variable
347
+ RecvVar // a method receiver variable
348
+ ParamVar // a function parameter variable
349
+ ResultVar // a function result variable
350
+ FieldVar // a struct field
351
+ )
352
+
353
+ var varKindNames = [... ]string {
354
+ 0 : "VarKind(0)" ,
355
+ PackageVar : "PackageVar" ,
356
+ LocalVar : "LocalVar" ,
357
+ RecvVar : "RecvVar" ,
358
+ ParamVar : "ParamVar" ,
359
+ ResultVar : "ResultVar" ,
360
+ FieldVar : "FieldVar" ,
361
+ }
362
+
363
+ func (kind VarKind ) String () string {
364
+ if 0 <= kind && int (kind ) < len (varKindNames ) {
365
+ return varKindNames [kind ]
366
+ }
367
+ return fmt .Sprintf ("VarKind(%d)" , kind )
368
+ }
369
+
370
+ // Kind reports what kind of variable v is.
371
+ func (v * Var ) Kind () VarKind { return v .kind }
372
+
373
+ // SetKind sets the kind of the variable.
374
+ // It should be used only immediately after [NewVar] or [NewParam].
375
+ func (v * Var ) SetKind (kind VarKind ) { v .kind = kind }
376
+
340
377
// NewVar returns a new variable.
341
378
// The arguments set the attributes found with all Objects.
379
+ //
380
+ // The caller must subsequently call [Var.SetKind]
381
+ // if the desired Var is not of kind [PackageVar].
342
382
func NewVar (pos syntax.Pos , pkg * Package , name string , typ Type ) * Var {
343
- return & Var { object : object { nil , pos , pkg , name , typ , 0 , colorFor ( typ ), nopos }}
383
+ return newVar ( PackageVar , pos , pkg , name , typ )
344
384
}
345
385
346
386
// NewParam returns a new variable representing a function parameter.
387
+ //
388
+ // The caller must subsequently call [Var.SetKind] if the desired Var
389
+ // is not of kind [ParamVar]: for example, [RecvVar] or [ResultVar].
347
390
func NewParam (pos syntax.Pos , pkg * Package , name string , typ Type ) * Var {
348
- return & Var { object : object { nil , pos , pkg , name , typ , 0 , colorFor ( typ ), nopos }, used : true } // parameters are always 'used'
391
+ return newVar ( ParamVar , pos , pkg , name , typ )
349
392
}
350
393
351
394
// NewField returns a new variable representing a struct field.
352
395
// For embedded fields, the name is the unqualified type name
353
396
// under which the field is accessible.
354
397
func NewField (pos syntax.Pos , pkg * Package , name string , typ Type , embedded bool ) * Var {
355
- return & Var {object : object {nil , pos , pkg , name , typ , 0 , colorFor (typ ), nopos }, embedded : embedded , isField : true }
398
+ v := newVar (FieldVar , pos , pkg , name , typ )
399
+ v .embedded = embedded
400
+ return v
401
+ }
402
+
403
+ // newVar returns a new variable.
404
+ // The arguments set the attributes found with all Objects.
405
+ func newVar (kind VarKind , pos syntax.Pos , pkg * Package , name string , typ Type ) * Var {
406
+ // Function parameters are always 'used'.
407
+ used := kind == RecvVar || kind == ParamVar || kind == ResultVar
408
+ return & Var {object : object {nil , pos , pkg , name , typ , 0 , colorFor (typ ), nopos }, kind : kind , used : used }
356
409
}
357
410
358
411
// Anonymous reports whether the variable is an embedded field.
@@ -363,7 +416,7 @@ func (obj *Var) Anonymous() bool { return obj.embedded }
363
416
func (obj * Var ) Embedded () bool { return obj .embedded }
364
417
365
418
// IsField reports whether the variable is a struct field.
366
- func (obj * Var ) IsField () bool { return obj .isField }
419
+ func (obj * Var ) IsField () bool { return obj .kind == FieldVar }
367
420
368
421
// Origin returns the canonical Var for its receiver, i.e. the Var object
369
422
// recorded in Info.Defs.
@@ -526,7 +579,7 @@ func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
526
579
}
527
580
528
581
case * Var :
529
- if obj .isField {
582
+ if obj .IsField () {
530
583
buf .WriteString ("field" )
531
584
} else {
532
585
buf .WriteString ("var" )
0 commit comments