Beispiel #1
0
func TestExportedType(t *testing.T) {
	tests := []struct {
		typString string
		exp       bool
	}{
		{"int", true},
		{"string", false}, // references the shadowed builtin "string"
		{"T", true},
		{"t", false},
		{"*T", true},
		{"*t", false},
		{"map[int]complex128", true},
	}
	for _, test := range tests {
		src := `package foo; type T int; type t int; type string struct{}`
		fset := token.NewFileSet()
		file, err := parser.ParseFile(fset, "foo.go", src, 0)
		if err != nil {
			t.Fatalf("Parsing %q: %v", src, err)
		}
		// use the package name as package path
		pkg, err := types.Check(file.Name.Name, fset, []*ast.File{file})
		if err != nil {
			t.Fatalf("Type checking %q: %v", src, err)
		}
		tv, err := types.Eval(fset, pkg, token.NoPos, test.typString)
		if err != nil {
			t.Errorf("types.Eval(%q): %v", test.typString, err)
			continue
		}
		if got := exportedType(tv.Type); got != test.exp {
			t.Errorf("exportedType(%v) = %t, want %t", tv.Type, got, test.exp)
		}
	}
}
Beispiel #2
0
func TestDemo(ot *testing.T) {
	importPath := "github.com/bronze1man/kmg/kmgGoSource"
	kmgCmd.MustRun("kmg go test -i " + importPath)
	pkgDir := kmgConfig.DefaultEnv().MustGetPathFromImportPath(importPath)
	fset := token.NewFileSet()
	astPkgMap, err := parser.ParseDir(fset, pkgDir, nil, 0)
	if err != nil {
		panic(err)
	}
	astPkg := astPkgMap["kmgGoSource_test"]
	astFileList := []*ast.File{}
	for _, file := range astPkg.Files {
		astFileList = append(astFileList, file)
	}
	//os.Chdir(kmgConfig.DefaultEnv().ProjectPath)
	pkg, err := types.Check(pkgDir, fset, astFileList)
	if err != nil {
		panic(err)
	}
	funcA := pkg.Scope().Lookup("FuncA")
	recvPkg := types.NewPackage("github.com/bronze1man/kmg/kmgGoSource", "kmgGoSource")
	kmgDebug.Println(types.TypeString(recvPkg, funcA.Type()))
	funTypParams := funcA.Type().(*types.Signature).Params()
	for i := 0; i < funTypParams.Len(); i++ {
		kmgDebug.Println(funTypParams.At(i).Name())
		kmgDebug.Println(funTypParams.At(i).Type().String())
	}
	//for _,p:=range funcA.Type().(*types.Signature).Params().
	//kmgDebug.Println(funcA.Type().(*types.Signature).Params().String())
}
Beispiel #3
0
func ParsePackage(name, dir string) (*types.Package, *token.FileSet) {
	fset := token.NewFileSet()
	pkgs, err := parser.ParseDir(fset, dir, fileFilter, parser.DeclarationErrors)
	astFiles := []*ast.File{}
	for _, pkg := range pkgs {
		for _, f := range pkg.Files {
			astFiles = append(astFiles, f)
		}
	}
	tPackage, err := types.Check(name, fset, astFiles)
	if err != nil {
		log.Fatal(err)
	}
	if !tPackage.Complete() {
		log.Fatal("Parsing of package incomplete.")
	}
	return tPackage, fset
}
Beispiel #4
0
func gotypes(data []byte) (err error) {
	defer func() {
		x := recover()
		if x != nil {
			if str, ok := x.(string); ok && strings.Contains(str, "not an Int") {
				// https://github.com/golang/go/issues/11325
				err = errors.New(str)
				return
			}
			panic(x)
		}
	}()
	fset := token.NewFileSet()
	var f *ast.File
	f, err = parser.ParseFile(fset, "src.go", data, parser.ParseComments|parser.DeclarationErrors|parser.AllErrors)
	if err != nil {
		return
	}
	_, err = types.Check("pkg", fset, []*ast.File{f})
	if err != nil {
		return
	}
	return
}
Beispiel #5
0
func (w *World) CompilePackage(fset *token.FileSet, files []*ast.File, pkgpath string) (Code, error) {
	pkgFiles := make(map[string]*ast.File)
	for _, f := range files {
		pkgFiles[f.Name.Name] = f
	}
	//pkg, err := ast.NewPackage(fset, pkgFiles, srcImporter, types.Universe)
	pkg, err := types.Check(files[0].Name.String(), fset, files)
	if err != nil {
		return nil, err
	}
	if pkg == nil {
		return nil, errors.New("could not create an AST package out of ast.Files")
	}

	switch g_visiting[pkgpath] {
	case done:
		return &pkgCode{w, make(code, 0)}, nil
	case visiting:
		//fmt.Printf("** package dependency cycle **\n")
		return nil, errors.New("package dependency cycle")
	}
	g_visiting[pkgpath] = visiting
	// create a new scope in which to process this new package
	imports := []*ast.ImportSpec{}
	for _, f := range files {
		imports = append(imports, f.Imports...)
	}

	for _, imp := range imports {
		path, _ := strconv.Unquote(imp.Path.Value)
		if _, ok := universe.pkgs[path]; ok {
			// already compiled
			continue
		}
		imp_files, err := findPkgFiles(path)
		if err != nil {
			return nil, errors.New(fmt.Sprintf("could not find files for package [%s]", path))
		}
		code, err := w.CompilePackage(fset, imp_files, path)
		if err != nil {
			return nil, err
		}
		_, err = code.Run()
		if err != nil {
			return nil, err
		}
	}

	prev_scope := w.scope
	w.scope = w.scope.ChildScope()
	w.scope.global = true
	defer func() {
		g_visiting[pkgpath] = done
		// add this scope (the package's scope) to the lookup-table of packages
		universe.pkgs[pkgpath] = w.scope
		// restore the previous scope
		w.scope.exit()
		if pkgpath != "main" {
			w.scope = prev_scope
		}
	}()

	decls := make([]ast.Decl, 0)
	for _, f := range files {
		decls = append(decls, f.Decls...)
	}
	code, err := w.CompileDeclList(fset, decls)
	if err != nil {
		return nil, err
	}
	_, err = code.Run()
	if err != nil {
		return nil, err
	}

	//FIXME: make sure all the imports are used at this point.

	{
		// store the init function (if any) for later use
		init_code, init_err := w.Compile(fset, "init()")
		if init_code != nil {
			if init_err == nil || init_err != nil {
				w.inits = append(w.inits, init_code)
			}
		}
	}
	return code, err
}