예제 #1
0
파일: utils.go 프로젝트: umisama/gopherjs
func WriteInterfaces(dependencies []*types.Package, w io.Writer, merge bool) {
	allTypeNames := []*types.TypeName{types.New("error").(*types.Named).Obj()}
	for _, dep := range dependencies {
		scope := dep.Scope()
		for _, name := range scope.Names() {
			if typeName, isTypeName := scope.Lookup(name).(*types.TypeName); isTypeName {
				allTypeNames = append(allTypeNames, typeName)
			}
		}
	}
	for _, t := range allTypeNames {
		if in, isInterface := t.Type().Underlying().(*types.Interface); isInterface {
			if in.MethodSet().Len() == 0 {
				continue
			}
			implementedBy := make(map[string]bool, 0)
			for _, other := range allTypeNames {
				otherType := other.Type()
				switch otherType.Underlying().(type) {
				case *types.Interface:
					// skip
				case *types.Struct:
					if types.IsAssignableTo(otherType, in) {
						implementedBy[fmt.Sprintf("Go$packages[\"%s\"].%s.Go$NonPointer", other.Pkg().Path(), other.Name())] = true
					}
					if types.IsAssignableTo(types.NewPointer(otherType), in) {
						implementedBy[fmt.Sprintf("Go$packages[\"%s\"].%s", other.Pkg().Path(), other.Name())] = true
					}
				default:
					if types.IsAssignableTo(otherType, in) {
						implementedBy[fmt.Sprintf("Go$packages[\"%s\"].%s", other.Pkg().Path(), other.Name())] = true
					}
					if types.IsAssignableTo(types.NewPointer(otherType), in) {
						implementedBy[fmt.Sprintf("Go$packages[\"%s\"].%s.Go$Pointer", other.Pkg().Path(), other.Name())] = true
					}
				}
			}
			list := make([]string, 0, len(implementedBy))
			for ref := range implementedBy {
				list = append(list, ref)
			}
			sort.Strings(list)
			var target string
			switch t.Name() {
			case "error":
				target = "Go$error"
			default:
				target = fmt.Sprintf("Go$packages[\"%s\"].%s", t.Pkg().Path(), t.Name())
			}
			if merge {
				for _, entry := range list {
					fmt.Fprintf(w, "if (%s.Go$implementedBy.indexOf(%s) === -1) { %s.Go$implementedBy.push(%s); }\n", target, entry, target, entry)
				}
				continue
			}
			fmt.Fprintf(w, "%s.Go$implementedBy = [%s];\n", target, strings.Join(list, ", "))
		}
	}
}
예제 #2
0
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")
	}
}
예제 #3
0
//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
}
예제 #4
0
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
}
예제 #5
0
func WriteProgramCode(pkgs []*Archive, importContext *ImportContext, w *SourceMapFilter) {
	mainPkg := pkgs[len(pkgs)-1]
	minify := mainPkg.Minified

	declsByObject := make(map[string][]*Decl)
	var pendingDecls []*Decl
	for _, pkg := range pkgs {
		for i := range pkg.Declarations {
			d := &pkg.Declarations[i]
			if len(d.DceFilters) == 0 {
				pendingDecls = append(pendingDecls, d)
				continue
			}
			for _, f := range d.DceFilters {
				o := string(pkg.ImportPath) + ":" + string(f)
				declsByObject[o] = append(declsByObject[o], d)
			}
		}
	}

	for len(pendingDecls) != 0 {
		d := pendingDecls[len(pendingDecls)-1]
		pendingDecls = pendingDecls[:len(pendingDecls)-1]
		for _, dep := range d.DceDeps {
			o := string(dep)
			if decls, ok := declsByObject[o]; ok {
				delete(declsByObject, o)
				name := strings.Split(o, ":")[1]
				for _, d := range decls {
					for i, f := range d.DceFilters {
						if string(f) == name {
							d.DceFilters[i] = d.DceFilters[len(d.DceFilters)-1]
							d.DceFilters = d.DceFilters[:len(d.DceFilters)-1]
							break
						}
					}
					if len(d.DceFilters) == 0 {
						pendingDecls = append(pendingDecls, d)
					}
				}
			}
		}
	}

	w.Write([]byte("\"use strict\";\n(function() {\n\n"))
	w.Write(removeWhitespace([]byte(strings.TrimSpace(prelude)), minify))
	w.Write([]byte("\n"))

	// write packages
	for _, pkg := range pkgs {
		WritePkgCode(pkg, minify, w)
	}

	// write interfaces
	allTypeNames := []*types.TypeName{types.New("error").(*types.Named).Obj()}
	for _, pkg := range pkgs {
		scope := importContext.Packages[string(pkg.ImportPath)].Scope()
		for _, name := range scope.Names() {
			if typeName, isTypeName := scope.Lookup(name).(*types.TypeName); isTypeName {
				if _, notUsed := declsByObject[string(pkg.ImportPath)+":"+name]; !notUsed {
					allTypeNames = append(allTypeNames, typeName)
				}
			}
		}
	}
	for _, t := range allTypeNames {
		if in, isInterface := t.Type().Underlying().(*types.Interface); isInterface {
			if in.Empty() {
				continue
			}
			implementedBy := make(map[string]bool, 0)
			for _, other := range allTypeNames {
				otherType := other.Type()
				switch otherType.Underlying().(type) {
				case *types.Interface:
					// skip
				case *types.Struct:
					if types.AssignableTo(otherType, in) {
						implementedBy[fmt.Sprintf("$packages[\"%s\"].%s", other.Pkg().Path(), other.Name())] = true
					}
					if types.AssignableTo(types.NewPointer(otherType), in) {
						implementedBy[fmt.Sprintf("$packages[\"%s\"].%s.Ptr", other.Pkg().Path(), other.Name())] = true
					}
				default:
					if types.AssignableTo(otherType, in) {
						implementedBy[fmt.Sprintf("$packages[\"%s\"].%s", other.Pkg().Path(), other.Name())] = true
					}
					if types.AssignableTo(types.NewPointer(otherType), in) {
						implementedBy[fmt.Sprintf("$ptrType($packages[\"%s\"].%s)", other.Pkg().Path(), other.Name())] = true
					}
				}
			}
			list := make([]string, 0, len(implementedBy))
			for ref := range implementedBy {
				list = append(list, ref)
			}
			sort.Strings(list)
			var target string
			switch t.Name() {
			case "error":
				target = "$error"
			default:
				target = fmt.Sprintf("$packages[\"%s\"].%s", t.Pkg().Path(), t.Name())
			}
			w.Write(removeWhitespace([]byte(fmt.Sprintf("%s.implementedBy = [%s];\n", target, strings.Join(list, ", "))), minify))
		}
	}

	for _, pkg := range pkgs {
		w.Write([]byte("$packages[\"" + string(pkg.ImportPath) + "\"].init();\n"))
	}

	w.Write([]byte("$packages[\"" + string(mainPkg.ImportPath) + "\"].main();\n\n})();\n"))
}
예제 #6
0
		actual = actual.Underlying()
	}
	if actual == nil {
		// No type information available. Assume true, so we do the check.
		return true, ""
	}
	switch actual.(type) {
	case *types.Struct:
		return true, typ.String()
	default:
		return false, ""
	}
}

var (
	stringerMethodType = types.New("func() string")
	errorType          = types.New("interface{ Error() string }").(*types.Interface)
	stringerType       = types.New("interface{ String() string }").(*types.Interface)
	// One day this might work. See issue 6259.
	// formatterType   = types.New("interface{Format(f fmt.State, c rune)}")
)

// matchArgType reports an error if printf verb t is not appropriate
// for operand arg.
//
// typ is used only for recursive calls; external callers must supply nil.
//
// (Recursion arises from the compound types {map,chan,slice} which
// may be printed with %d etc. if that is appropriate for their element
// types.)
func (f *File) matchArgType(t printfArgType, typ types.Type, arg ast.Expr) bool {
예제 #7
0
package main

import (
	"go/ast"
	"go/token"

	"code.google.com/p/go.tools/go/types"
)

// imports is the canonical map of imported packages we need for typechecking.
// It is created during initialization.
var imports = make(map[string]*types.Package)

var (
	stringerMethodType = types.New("func() string")
	errorType          = types.New("error").Underlying().(*types.Interface)
	stringerType       = types.New("interface{ String() string }").(*types.Interface)
	formatterType      *types.Interface
)

func init() {
	typ := importType("fmt", "Formatter")
	if typ != nil {
		formatterType = typ.Underlying().(*types.Interface)
	}
}

// importType returns the type denoted by the qualified identifier
// path.name, and adds the respective package to the imports map
// as a side effect.