(file *ast.File, iota int, expr ast.Expr, globalEvaluator ConstVariableGlobalEvaluator, recursiveStack map[string]struct{})
| 76 | } |
| 77 | |
| 78 | func (pkg *PackageDefinitions) evaluateConstValue(file *ast.File, iota int, expr ast.Expr, globalEvaluator ConstVariableGlobalEvaluator, recursiveStack map[string]struct{}) (interface{}, ast.Expr) { |
| 79 | switch valueExpr := expr.(type) { |
| 80 | case *ast.Ident: |
| 81 | if valueExpr.Name == "iota" { |
| 82 | return iota, nil |
| 83 | } |
| 84 | if pkg.ConstTable != nil { |
| 85 | if cv, ok := pkg.ConstTable[valueExpr.Name]; ok { |
| 86 | return globalEvaluator.EvaluateConstValue(pkg, cv, recursiveStack) |
| 87 | } |
| 88 | } |
| 89 | case *ast.SelectorExpr: |
| 90 | pkgIdent, ok := valueExpr.X.(*ast.Ident) |
| 91 | if !ok { |
| 92 | return nil, nil |
| 93 | } |
| 94 | return globalEvaluator.EvaluateConstValueByName(file, pkgIdent.Name, valueExpr.Sel.Name, recursiveStack) |
| 95 | case *ast.BasicLit: |
| 96 | switch valueExpr.Kind { |
| 97 | case token.INT: |
| 98 | // handle underscored number, such as 1_000_000 |
| 99 | if strings.ContainsRune(valueExpr.Value, '_') { |
| 100 | valueExpr.Value = strings.Replace(valueExpr.Value, "_", "", -1) |
| 101 | } |
| 102 | if len(valueExpr.Value) >= 2 && valueExpr.Value[0] == '0' { |
| 103 | var start, base = 2, 8 |
| 104 | switch valueExpr.Value[1] { |
| 105 | case 'x', 'X': |
| 106 | //hex |
| 107 | base = 16 |
| 108 | case 'b', 'B': |
| 109 | //binary |
| 110 | base = 2 |
| 111 | default: |
| 112 | //octet |
| 113 | start = 1 |
| 114 | } |
| 115 | if x, err := strconv.ParseInt(valueExpr.Value[start:], base, 64); err == nil { |
| 116 | return int(x), nil |
| 117 | } else if x, err := strconv.ParseUint(valueExpr.Value[start:], base, 64); err == nil { |
| 118 | return x, nil |
| 119 | } else { |
| 120 | panic(err) |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | //a basic literal integer is int type in default, or must have an explicit converting type in front |
| 125 | if x, err := strconv.ParseInt(valueExpr.Value, 10, 64); err == nil { |
| 126 | return int(x), nil |
| 127 | } else if x, err := strconv.ParseUint(valueExpr.Value, 10, 64); err == nil { |
| 128 | return x, nil |
| 129 | } else { |
| 130 | panic(err) |
| 131 | } |
| 132 | case token.STRING: |
| 133 | if valueExpr.Value[0] == '`' { |
| 134 | return valueExpr.Value[1 : len(valueExpr.Value)-1], nil |
| 135 | } |
no test coverage detected