func TestNewScopeAndPackage2(t *testing.T) { c := initTestChecker() c.NewScopeAndPackage() c.sc.Insert(types.NewConst(0, c.pkg, "testfloat1", types.New("float64"), exact.MakeFloat64(1))) c.NewScopeAndPackage() for _, name := range c.sc.Names() { if name == "testfloat1" { t.Errorf("scope not reset") } } o := c.sc.Insert(types.NewConst(0, c.pkg, "testfloat1", types.New("float64"), exact.MakeFloat64(2))) if o != nil { t.Errorf("did not reset scope") } }
//insertMetricValues inserts the values and rates of the metrics collected // as constants into the scope used to evaluate the expressions func (c *checker) InsertMetricValuesFromJSON() error { //get metrics from json package //TODO: get directly from metric context if available resp, err := http.Get("http://" + c.hostport + "/api/v1/metrics.json/") if err != nil { return err } defer resp.Body.Close() d := json.NewDecoder(resp.Body) var metrics []metrics.MetricJSON err = d.Decode(&metrics) if err != nil { return err } //insert metric value into scope for _, m := range metrics { switch val := m.Value.(type) { case float64: name := strings.Replace(m.Name, ".", "_", -1) + "_value" c.sc.Insert(types.NewConst(0, c.pkg, name, types.New("float64"), exact.MakeFloat64(val))) case map[string]interface{}: //TODO: make sure we don't panic in case something is not formatted // like expected if current, ok := val["current"]; ok { name := strings.Replace(m.Name, ".", "_", -1) + "_current" c.sc.Insert(types.NewConst(0, c.pkg, name, types.New("float64"), exact.MakeFloat64(current.(float64)))) } if rate, ok := val["rate"]; ok { name := strings.Replace(m.Name, ".", "_", -1) + "_rate" c.sc.Insert(types.NewConst(0, c.pkg, name, types.New("float64"), exact.MakeFloat64(rate.(float64)))) } default: //a value type came up that wasn't anticipated fmt.Fprintln(os.Stderr, reflect.TypeOf(val)) } } return nil }
func (c *checker) InsertMetricValuesFromContext(m *metrics.MetricContext) error { for metricName, metric := range m.Gauges { name := strings.Replace(metricName, ".", "_", -1) + "_value" c.sc.Insert(types.NewConst(0, c.pkg, name, types.New("float64"), exact.MakeFloat64(metric.Get()))) sname := name + "_string" c.sc.Insert(types.NewConst(0, c.pkg, sname, types.New("string"), exact.MakeString(fmt.Sprintf("%0.2f", metric.Get())))) } for metricName, metric := range m.Counters { name := strings.Replace(metricName, ".", "_", -1) + "_current" c.sc.Insert(types.NewConst(0, c.pkg, name, types.New("float64"), exact.MakeUint64(metric.Get()))) sname := name + "_string" c.sc.Insert(types.NewConst(0, c.pkg, sname, types.New("string"), exact.MakeString(fmt.Sprintf("%d", metric.Get())))) name = strings.Replace(metricName, ".", "_", -1) + "_rate" c.sc.Insert(types.NewConst(0, c.pkg, name, types.New("float64"), exact.MakeFloat64(metric.ComputeRate()))) } return nil }
// Const = Name [Type] "=" ConstValue . func (p *parser) parseConst(pkg *types.Package) *types.Const { name := p.parseName() var typ types.Type if p.tok == '<' { typ = p.parseType(pkg) } p.expect('=') val, vtyp := p.parseConstValue() if typ == nil { typ = vtyp } return types.NewConst(token.NoPos, pkg, name, typ, val) }
func (p *importer) obj(pkg *types.Package) { var obj types.Object switch tag := p.int(); tag { case constTag: obj = types.NewConst(token.NoPos, pkg, p.string(), p.typ(), p.value()) case typeTag: // type object is added to scope via respective named type _ = p.typ().(*types.Named) return case varTag: obj = types.NewVar(token.NoPos, pkg, p.string(), p.typ()) case funcTag: obj = types.NewFunc(token.NoPos, pkg, p.string(), p.typ().(*types.Signature)) default: panic(fmt.Sprintf("unexpected object tag %d", tag)) } if alt := pkg.Scope().Insert(obj); alt != nil { panic(fmt.Sprintf("%s already declared", alt.Name())) } }
// ConstDecl = "const" ExportedName [ Type ] "=" Literal . // Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit . // bool_lit = "true" | "false" . // complex_lit = "(" float_lit "+" float_lit "i" ")" . // rune_lit = "(" int_lit "+" int_lit ")" . // string_lit = `"` { unicode_char } `"` . // func (p *parser) parseConstDecl() { p.expectKeyword("const") pkg, name := p.parseExportedName() var typ0 types.Type if p.tok != '=' { typ0 = p.parseType() } p.expect('=') var typ types.Type var val exact.Value switch p.tok { case scanner.Ident: // bool_lit if p.lit != "true" && p.lit != "false" { p.error("expected true or false") } typ = types.Typ[types.UntypedBool] val = exact.MakeBool(p.lit == "true") p.next() case '-', scanner.Int: // int_lit typ, val = p.parseNumber() case '(': // complex_lit or rune_lit p.next() if p.tok == scanner.Char { p.next() p.expect('+') typ = types.Typ[types.UntypedRune] _, val = p.parseNumber() p.expect(')') break } _, re := p.parseNumber() p.expect('+') _, im := p.parseNumber() p.expectKeyword("i") p.expect(')') typ = types.Typ[types.UntypedComplex] val = exact.BinaryOp(re, token.ADD, exact.MakeImag(im)) case scanner.Char: // rune_lit typ = types.Typ[types.UntypedRune] val = exact.MakeFromLiteral(p.lit, token.CHAR) p.next() case scanner.String: // string_lit typ = types.Typ[types.UntypedString] val = exact.MakeFromLiteral(p.lit, token.STRING) p.next() default: p.errorf("expected literal got %s", scanner.TokenString(p.tok)) } if typ0 == nil { typ0 = typ } pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val)) }