MCPcopy
hub / github.com/marmotedu/iam / genDecl

Method genDecl

tools/codegen/codegen.go:345–440  ·  view source on GitHub ↗

nolint: gocognit genDecl processes one declaration clause.

(node ast.Node)

Source from the content-addressed store, hash-verified

343// nolint: gocognit
344// genDecl processes one declaration clause.
345func (f *File) genDecl(node ast.Node) bool {
346 decl, ok := node.(*ast.GenDecl)
347 if !ok || decl.Tok != token.CONST {
348 // We only care about const declarations.
349 return true
350 }
351 // The name of the type of the constants we are declaring.
352 // Can change if this is a multi-element declaration.
353 typ := ""
354 // Loop over the elements of the declaration. Each element is a ValueSpec:
355 // a list of names possibly followed by a type, possibly followed by values.
356 // If the type and value are both missing, we carry down the type (and value,
357 // but the "go/types" package takes care of that).
358 for _, spec := range decl.Specs {
359 vspec, _ := spec.(*ast.ValueSpec) // Guaranteed to succeed as this is CONST.
360 if vspec.Type == nil && len(vspec.Values) > 0 {
361 // "X = 1". With no type but a value. If the constant is untyped,
362 // skip this vspec and reset the remembered type.
363 typ = ""
364
365 // If this is a simple type conversion, remember the type.
366 // We don't mind if this is actually a call; a qualified call won't
367 // be matched (that will be SelectorExpr, not Ident), and only unusual
368 // situations will result in a function call that appears to be
369 // a type conversion.
370 ce, ok := vspec.Values[0].(*ast.CallExpr)
371 if !ok {
372 continue
373 }
374 id, ok := ce.Fun.(*ast.Ident)
375 if !ok {
376 continue
377 }
378 typ = id.Name
379 }
380 if vspec.Type != nil {
381 // "X T". We have a type. Remember it.
382 ident, ok := vspec.Type.(*ast.Ident)
383 if !ok {
384 continue
385 }
386 typ = ident.Name
387 }
388 if typ != f.typeName {
389 // This is not the type we're looking for.
390 continue
391 }
392 // We now have a list of names (from one line of source code) all being
393 // declared with the desired type.
394 // Grab their names and actual values and store them in f.values.
395 for _, name := range vspec.Names {
396 if name.Name == "_" {
397 continue
398 }
399 // This dance lets the type checker find the values for us. It's a
400 // bit tricky: look up the object declared by the name, find its
401 // types.Const, and extract its value.
402 obj, ok := f.pkg.defs[name]

Callers

nothing calls this directly

Calls 4

TypeMethod · 0.80
FatalfMethod · 0.65
InfoMethod · 0.65
StringMethod · 0.65

Tested by

no test coverage detected