Ejemplo n.º 1
0
func findRouteTableAST(file *ast.File) (routeTableAST *ast.CompositeLit) {
	defer func() {
		if err := recover(); err != nil && err != ErrRouteTableASTIsFound {
			panic(err)
		}
	}()
	ast.Inspect(file, func(node ast.Node) bool {
		switch aType := node.(type) {
		case *ast.GenDecl:
			if aType.Tok != token.VAR {
				return false
			}
			ast.Inspect(aType, func(n ast.Node) bool {
				switch typ := n.(type) {
				case *ast.CompositeLit:
					switch t := typ.Type.(type) {
					case *ast.Ident:
						if t.Name == routeTableTypeName {
							routeTableAST = typ
							panic(ErrRouteTableASTIsFound)
						}
					}
				}
				return true
			})
		}
		return true
	})
	return routeTableAST
}
Ejemplo n.º 2
0
func rewriteConflictingNames(fn *ast.FuncDecl) {
	for _, fieldList := range []*ast.FieldList{fn.Recv, fn.Type.Params, fn.Type.Results} {
		if fieldList == nil {
			continue
		}
		for _, f := range fieldList.List {
			for _, name := range f.Names {
				if name.Name == fn.Name.Name {
					oldName := name.Name
					newName := createConflictFreeNameCheckIdents(name.Name, fn)
					rewriteFn := func(node ast.Node) bool {
						if ident, ok := node.(*ast.Ident); ok && ident.Name == oldName {
							ident.Name = newName
						}
						return true
					}
					// Instead of walking all of fn, walk fn.Recv, fn.Type, and fn.Body.
					// If we walked all of fn we would rewrite the name of the function itself
					// in addition to the parameter we are rewriting.
					if fn.Recv != nil && fn.Recv.List != nil {
						ast.Inspect(fn.Recv, rewriteFn)
					}
					if fn.Type != nil {
						ast.Inspect(fn.Type, rewriteFn)
					}
					if fn.Body != nil {
						ast.Inspect(fn.Body, rewriteFn)
					}
					return // at most one parameter can share a name with the function
				}
			}
		}
	}
}
Ejemplo n.º 3
0
// GetPublicFunctions lists all public functions (not methods) from a golang source file.
func GetPublicFunctions(filePath string) ([]string, error) {
	var functionNames []string

	// Create the AST by parsing src.
	fset := token.NewFileSet() // positions are relative to fset
	f, err := parser.ParseFile(fset, filePath, nil, 0)
	if err != nil {
		return nil, fmt.Errorf("failed parse file to list functions: %v", err)
	}

	// Inspect the AST and print all identifiers and literals.
	ast.Inspect(f, func(n ast.Node) bool {
		var s string
		switch x := n.(type) {
		case *ast.FuncDecl:
			s = x.Name.Name
			// It's a function (not method), and is public, record it.
			if x.Recv == nil && isPublic(s) {
				functionNames = append(functionNames, s)
			}
		}
		return true
	})

	return functionNames, nil
}
Ejemplo n.º 4
0
// Build constructs a control flow graph,
// filtered to include only interesting nodes.
func Build(fset *token.FileSet, body *ast.BlockStmt, interesting func(ast.Node) bool) *Graph {
	start := &ast.Ident{Name: "_cfg_start_"}
	end := &ast.Ident{Name: "_cfg_end_"}
	b := &builder{
		interesting:  interesting,
		followCache:  make(map[ast.Node][]ast.Node),
		end:          end,
		need:         make(map[ast.Node]bool),
		trimmed:      make(map[ast.Node]bool),
		followed:     make(map[ast.Node]bool),
		brkLabel:     make(map[string][]ast.Node),
		contLabel:    make(map[string][]ast.Node),
		gotoLabel:    make(map[string]ast.Node),
		isGotoTarget: make(map[string]bool),
		stmtLabel:    make(map[ast.Stmt]string),
	}

	ast.Inspect(body, b.scanGoto)
	b.followCache[start] = b.trimList(b.follow(body, []ast.Node{end}))
	return &Graph{
		FileSet: fset,
		Start:   start,
		End:     end,
		Follow:  b.followCache,
	}
}
Ejemplo n.º 5
0
// Scan app source code for calls to X.Y(), where X is of type *Validation.
//
// Recognize these scenarios:
// - "Y" = "Validation" and is a member of the receiver.
//   (The common case for inline validation)
// - "X" is passed in to the func as a parameter.
//   (For structs implementing Validated)
//
// The line number to which a validation call is attributed is that of the
// surrounding ExprStmt.  This is so that it matches what runtime.Callers()
// reports.
//
// The end result is that we can set the default validation key for each call to
// be the same as the local variable.
func getValidationKeys(fset *token.FileSet, funcDecl *ast.FuncDecl, imports map[string]string) map[int]string {
	var (
		lineKeys = make(map[int]string)

		// Check the func parameters and the receiver's members for the *revel.Validation type.
		validationParam = getValidationParameter(funcDecl, imports)
	)

	ast.Inspect(funcDecl.Body, func(node ast.Node) bool {
		// e.g. c.Validation.Required(arg) or v.Required(arg)
		callExpr, ok := node.(*ast.CallExpr)
		if !ok {
			return true
		}

		// e.g. c.Validation.Required or v.Required
		funcSelector, ok := callExpr.Fun.(*ast.SelectorExpr)
		if !ok {
			return true
		}

		switch x := funcSelector.X.(type) {
		case *ast.SelectorExpr: // e.g. c.Validation
			if x.Sel.Name != "Validation" {
				return true
			}

		case *ast.Ident: // e.g. v
			if validationParam == nil || x.Obj != validationParam {
				return true
			}

		default:
			return true
		}

		if len(callExpr.Args) == 0 {
			return true
		}

		// If the argument is a binary expression, take the first expression.
		// (e.g. c.Validation.Required(myName != ""))
		arg := callExpr.Args[0]
		if binExpr, ok := arg.(*ast.BinaryExpr); ok {
			arg = binExpr.X
		}

		// If it's a literal, skip it.
		if _, ok = arg.(*ast.BasicLit); ok {
			return true
		}

		if typeExpr := NewTypeExpr("", arg); typeExpr.Valid {
			lineKeys[fset.Position(callExpr.End()).Line] = typeExpr.TypeName("")
		}
		return true
	})

	return lineKeys
}
Ejemplo n.º 6
0
func init() {
	act(Action{
		Path: "/imports",
		Doc:  "",
		Func: func(r Request) (data, error) {
			res := ImportsResult{}

			a := ImportsArgs{
				Toggle:    []ImportDeclArg{},
				TabWidth:  8,
				TabIndent: true,
			}

			if err := r.Decode(&a); err != nil {
				return res, err
			}

			fset, af, err := parseAstFile(a.Fn, a.Src, parser.ImportsOnly|parser.ParseComments)
			if err == nil {
				ast.Inspect(af, func(n ast.Node) bool {
					if n != nil {
						tp := fset.Position(n.End())
						if tp.Line > res.LineRef {
							res.LineRef = tp.Line
						}
					}
					return true
				})
				af = imp(fset, af, a.Toggle)
				res.Src, err = printSrc(fset, af, a.TabIndent, a.TabWidth)
			}
			return res, err
		},
	})
}
Ejemplo n.º 7
0
func StructFuncs(f *ast.File) map[string]funcs {

	structFuncs := map[string]funcs{}

	ast.Inspect(f, func(n ast.Node) bool {

		f, ok := n.(*ast.FuncDecl)

		if !ok {
			return true
		}

		recv, ok := findRecv(f.Recv)
		if !ok {
			return true
		}

		fn := funcType{
			Recv:     recv,
			Name:     f.Name.Name,
			Comments: findComments(f.Doc),
		}

		structFuncs[recv] = append(structFuncs[recv], fn)
		return false
	})

	return structFuncs
}
func (sms *ShowMissingStrings) extractString(f *ast.File, fset *token.FileSet, filename string) error {
	ast.Inspect(f, func(n ast.Node) bool {
		switch x := n.(type) {
		case *ast.CallExpr:
			switch x.Fun.(type) {
			case *ast.Ident:
				funName := x.Fun.(*ast.Ident).Name

				if funName == "T" || funName == "t" {
					if stringArg, ok := x.Args[0].(*ast.BasicLit); ok {
						translatedString, err := strconv.Unquote(stringArg.Value)
						if err != nil {
							panic(err.Error())
						}

						sms.Println("Adding to translated strings:", translatedString)
						sms.TranslatedStrings = append(sms.TranslatedStrings, filename+": "+translatedString)
					}
				}
			default:
				//Skip!
			}
		}
		return true
	})

	return nil
}
Ejemplo n.º 9
0
// checkRangeLoop walks the body of the provided range statement, checking if
// its index or value variables are used unsafely inside goroutines or deferred
// function literals.
func checkRangeLoop(f *File, node ast.Node) {
	n := node.(*ast.RangeStmt)
	key, _ := n.Key.(*ast.Ident)
	val, _ := n.Value.(*ast.Ident)
	if key == nil && val == nil {
		return
	}
	sl := n.Body.List
	if len(sl) == 0 {
		return
	}
	var last *ast.CallExpr
	switch s := sl[len(sl)-1].(type) {
	case *ast.GoStmt:
		last = s.Call
	case *ast.DeferStmt:
		last = s.Call
	default:
		return
	}
	lit, ok := last.Fun.(*ast.FuncLit)
	if !ok {
		return
	}
	ast.Inspect(lit.Body, func(n ast.Node) bool {
		id, ok := n.(*ast.Ident)
		if !ok || id.Obj == nil {
			return true
		}
		if key != nil && id.Obj == key.Obj || val != nil && id.Obj == val.Obj {
			f.Bad(id.Pos(), "range variable", id.Name, "captured by func literal")
		}
		return true
	})
}
Ejemplo n.º 10
0
func lintCheckFlagParse(fset *token.FileSet, af *ast.File, res []AcLintReport) []AcLintReport {
	reps := []AcLintReport{}
	foundParse := false
	ast.Inspect(af, func(node ast.Node) bool {
		switch c := node.(type) {
		case *ast.CallExpr:
			if sel, ok := c.Fun.(*ast.SelectorExpr); ok {
				if id, ok := sel.X.(*ast.Ident); ok && id.Name == "flag" {
					if sel.Sel.String() == "Parse" {
						foundParse = true
					} else if !foundParse && c != nil {
						tp := fset.Position(c.Pos())
						if tp.IsValid() {
							reps = append(reps, AcLintReport{
								Row: tp.Line - 1,
								Col: tp.Column - 1,
								Msg: "Cannot find corresponding call to flag.Parse()",
							})
						}
					}
				}
			}
		}
		return !foundParse
	})

	if !foundParse {
		res = append(res, reps...)
	}

	return res
}
Ejemplo n.º 11
0
func (f *file) checkFileContent() {
	if f.isTest() {
		return
	}

	if f.config.PackageName {
		f.checkPkgName(f.ast.Name)
	}

	for _, v := range f.ast.Decls {
		switch decl := v.(type) {
		case *ast.FuncDecl:
			f.checkFunctionDeclare(decl)
			if decl.Body == nil {
				break
			}
			ast.Inspect(decl.Body, func(node ast.Node) bool {
				switch decl2 := node.(type) {
				case *ast.GenDecl:
					f.checkGenDecl(decl2, false)
				case *ast.FuncDecl:
					f.checkFunctionDeclare(decl2)
				case *ast.AssignStmt:
					f.checkAssign(decl2)
				case *ast.StructType:
					f.checkStruct(decl2)
				}
				return true
			})
		case *ast.GenDecl:
			f.checkGenDecl(decl, true)
		}
	}
}
Ejemplo n.º 12
0
func (f *file) checkValueName(decl *ast.GenDecl, kind string, top bool) {
	for _, spec := range decl.Specs {
		if vSpec, ok := spec.(*ast.ValueSpec); ok {
			for _, name := range vSpec.Names {
				f.checkName(name, kind, !top)
			}
		} else if tSpec, ok := spec.(*ast.TypeSpec); ok {
			f.checkName(tSpec.Name, kind, false)
			ast.Inspect(tSpec.Type, func(node ast.Node) bool {
				switch decl2 := node.(type) {
				case *ast.GenDecl:
					f.checkGenDecl(decl2, false)
				case *ast.FuncDecl:
					f.checkFunctionDeclare(decl2)
				case *ast.StructType:
					f.checkStruct(decl2)
				case *ast.InterfaceType:
					f.checkInterface(decl2)
				}
				return true
			})
		} else if iSpec, ok := spec.(*ast.ImportSpec); ok && iSpec.Name != nil {
			f.checkName(iSpec.Name, "import", true)
		}
	}
}
Ejemplo n.º 13
0
func enumerateAstNodesInPackage(iterator func(filename string, node ast.Node) bool) error {
	packageRoot, err := getPackageFolderPath()
	if err != nil {
		return err
	}

	files, err := ioutil.ReadDir(packageRoot)
	if err != nil {
		return fmt.Errorf("Error listing package root: %v", err)
	}

	fileSet := token.NewFileSet()

	for _, f := range files {
		if strings.HasSuffix(f.Name(), ".go") {
			contents, err := ioutil.ReadFile(filepath.Join(packageRoot, f.Name()))
			if err != nil {
				return fmt.Errorf("Error reading contents of go file in package: %v", err)
			}

			parsed, err := parser.ParseFile(fileSet, f.Name(), contents, 0)
			if err != nil {
				return fmt.Errorf("Error parsing source file %s: %v", f.Name(), err)
			}

			ast.Inspect(parsed, func(n ast.Node) bool {
				return iterator(f.Name(), n)
			})
		}
	}

	return nil
}
Ejemplo n.º 14
0
func printNode(n ast.Node) {
	ast.Inspect(n, func(n ast.Node) bool {
		fmt.Printf("%T: %v\n", n, n)

		return true
	})
}
Ejemplo n.º 15
0
func (fix *Fixup) inspectFile(file string) (translatedStrings []string, err error) {
	fset := token.NewFileSet()
	astFile, err := parser.ParseFile(fset, file, nil, parser.AllErrors)
	if err != nil {
		fix.Println(err)
		return
	}

	ast.Inspect(astFile, func(n ast.Node) bool {
		switch x := n.(type) {
		case *ast.CallExpr:
			switch x.Fun.(type) {
			case *ast.Ident:
				funName := x.Fun.(*ast.Ident).Name

				if funName == "T" || funName == "t" {
					if stringArg, ok := x.Args[0].(*ast.BasicLit); ok {
						translatedString, err := strconv.Unquote(stringArg.Value)
						if err != nil {
							panic(err.Error())
						}
						translatedStrings = append(translatedStrings, translatedString)
					}
				}
			default:
				//Skip!
			}
		}
		return true
	})

	return
}
Ejemplo n.º 16
0
func main() {
	fset := token.NewFileSet()

	f, err := parser.ParseFile(fset, "example_test.go", nil, 0)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, s := range f.Imports {
		fmt.Println(s.Path.Value)
	}

	for _, decl := range f.Decls {
		ast.Inspect(decl, func(node ast.Node) bool {
			fn, ok := node.(*ast.FuncDecl)
			if !ok {
				return false
			}
			fnName := fn.Name.Name
			for _, param := range fn.Type.Params.List {
				typeName := param.Type.(*ast.Ident).Name
				for _, name := range param.Names {
					println(fnName, name.Name, typeName)
				}
			}
			return false
		})
	}
}
Ejemplo n.º 17
0
// This function checks that all the functions using the tests
// defined in indextest, namely:
// TestIndex_, TestPathOfSignerTarget_, TestFiles_
// do exist in the provided test file.
func hasAllRequiredTests(name string, t *testing.T) error {
	tests := make(map[string]bool)
	for _, v := range requiredTests {
		tests[v] = false
	}

	if !strings.HasSuffix(name, "_test.go") || skipFromList(name) {
		return nil
	}
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, name, nil, 0)
	if err != nil {
		t.Fatalf("%v: %v", name, err)
	}
	ast.Inspect(f, func(n ast.Node) bool {
		switch x := n.(type) {
		case *ast.FuncDecl:
			name := x.Name.Name
			for k, _ := range tests {
				if strings.HasPrefix(name, k) {
					tests[k] = true
				}
			}
		}
		return true
	})

	for k, v := range tests {
		if !v {
			return fmt.Errorf("%v not implemented in %v", k, name)
		}
	}
	return nil
}
Ejemplo n.º 18
0
// getTaggedComments walks the AST and returns types which have directive comment
// returns a map of TypeSpec to directive
func getTaggedComments(pkg *ast.Package, directive string) map[*ast.TypeSpec]*ast.Comment {
	specs := make(map[*ast.TypeSpec]*ast.Comment)

	ast.Inspect(pkg, func(n ast.Node) bool {
		g, ok := n.(*ast.GenDecl)

		// is it a type?
		// http://golang.org/pkg/go/ast/#GenDecl
		if !ok || g.Tok != token.TYPE {
			// never mind, move on
			return true
		}

		if g.Lparen == 0 {
			// not parenthesized, copy GenDecl.Doc into TypeSpec.Doc
			g.Specs[0].(*ast.TypeSpec).Doc = g.Doc
		}

		for _, s := range g.Specs {
			t := s.(*ast.TypeSpec)

			if c := findAnnotation(t.Doc, directive); c != nil {
				specs[t] = c
			}
		}

		// no need to keep walking, we don't care about TypeSpec's children
		return false
	})

	return specs
}
Ejemplo n.º 19
0
func processFile(filename string) []Function {
	var res []Function
	fset := token.NewFileSet() // positions are relative to fset
	f, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
	if err != nil {
		panic(err)
	}

	cmap := ast.NewCommentMap(fset, f, f.Comments)
	ast.Inspect(f, func(n ast.Node) bool {
		switch x := n.(type) {
		case *ast.FuncDecl:
			fun := Function{Begin: fset.Position(x.Pos()).Line,
				Package:  f.Name.String(),
				Name:     x.Name.String(),
				End:      fset.Position(x.End()).Line,
				Filepath: fset.Position(x.Pos()).Filename}

			fun.getTSpec(cmap[n])
			res = append(res, fun)
		}
		return true
	})
	return res
}
Ejemplo n.º 20
0
// TestIncompleteSelection ensures that an incomplete selector
// expression is parsed as a (blank) *ast.SelectorExpr, not a
// *ast.BadExpr.
func TestIncompleteSelection(t *testing.T) {
	for _, src := range []string{
		"package p; var _ = fmt.",             // at EOF
		"package p; var _ = fmt.\ntype X int", // not at EOF
	} {
		fset := token.NewFileSet()
		f, err := ParseFile(fset, "", src, 0)
		if err == nil {
			t.Errorf("ParseFile(%s) succeeded unexpectedly", src)
			continue
		}

		const wantErr = "expected selector or type assertion"
		if !strings.Contains(err.Error(), wantErr) {
			t.Errorf("ParseFile returned wrong error %q, want %q", err, wantErr)
		}

		var sel *ast.SelectorExpr
		ast.Inspect(f, func(n ast.Node) bool {
			if n, ok := n.(*ast.SelectorExpr); ok {
				sel = n
			}
			return true
		})
		if sel == nil {
			t.Error("found no *ast.SelectorExpr")
			continue
		}
		const wantSel = "&{fmt _}"
		if fmt.Sprint(sel) != wantSel {
			t.Errorf("found selector %s, want %s", sel, wantSel)
			continue
		}
	}
}
Ejemplo n.º 21
0
func AnotatedStructs(f *ast.File, anotation string) structs {

	structs := structs{}

	pkg := f.Name.Name
	ast.Inspect(f, func(n ast.Node) bool {

		g, ok := n.(*ast.GenDecl)

		if !ok || g.Tok != token.TYPE {
			return true
		}

		comments := findComments(g.Doc)
		if !isMarked(comments, anotation) {
			return true
		}

		st, ok := findStruct(g.Specs)
		if !ok {
			return true
		}

		st.Comments = comments
		st.Package = pkg

		structs = append(structs, st)
		return false
	})

	return structs
}
Ejemplo n.º 22
0
func main() {
	f, err := parser.ParseFile(fset, "hello.go", input, 0)
	if err != nil {
		log.Fatal(err) // parse error
	}

	conf := types.Config{Importer: importer.Default()}
	info := &types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
	if _, err := conf.Check("cmd/hello", fset, []*ast.File{f}, info); err != nil {
		log.Fatal(err) // type error
	}

	//!+inspect
	// f is a parsed, type-checked *ast.File.
	ast.Inspect(f, func(n ast.Node) bool {
		if expr, ok := n.(ast.Expr); ok {
			if tv, ok := info.Types[expr]; ok {
				fmt.Printf("%-24s\tmode:  %s\n", nodeString(expr), mode(tv))
				fmt.Printf("\t\t\t\ttype:  %v\n", tv.Type)
				if tv.Value != nil {
					fmt.Printf("\t\t\t\tvalue: %v\n", tv.Value)
				}
			}
		}
		return true
	})
	//!-inspect
}
Ejemplo n.º 23
0
func (pkg *PackageInfo) TypeInfos() TypeInfos {
	var types TypeInfos
	for _, file := range pkg.Files {
		if file == nil {
			continue
		}
		ast.Inspect(file.AstFile(), func(node ast.Node) bool {
			decl, ok := node.(*ast.GenDecl)
			if !ok || decl.Tok != token.TYPE {
				return true
			}
			found := false
			for _, spec := range decl.Specs {
				ts, ok := spec.(*ast.TypeSpec)
				if !ok {
					continue
				}
				types = append(types, &TypeInfo{
					FileInfo: file,
					GenDecl:  decl,
					TypeSpec: ts,
				})
				found = true
			}
			return !found
		})
	}
	return types
}
Ejemplo n.º 24
0
func main() {
	flag.Parse()

	importPaths := gotool.ImportPaths(flag.Args())
	if len(importPaths) == 0 {
		return
	}

	var conf loader.Config
	conf.Fset = fset
	for _, importPath := range importPaths {
		conf.Import(importPath)
	}
	prog, err := conf.Load()
	if err != nil {
		log.Fatal(err)
	}

	for _, pkg := range prog.InitialPackages() {
		for _, file := range pkg.Files {
			ast.Inspect(file, func(node ast.Node) bool {
				if s, ok := node.(*ast.StructType); ok {
					malign(node.Pos(), pkg.Types[s].Type.(*types.Struct))
				}
				return true
			})
		}
	}
}
Ejemplo n.º 25
0
func main() {
	outputFile := flag.String("o", "", "Output file, blank for stdout")
	flag.Parse()
	fname := flag.Arg(0)

	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, fname, nil, parser.ParseComments)
	if err != nil {
		log.Fatal(err)
	}

	var structs []structInfo
	i := inspector(&structs)
	ast.Inspect(f, i)

	var output io.Writer = os.Stdout
	if *outputFile != "" {
		fd, err := os.Create(*outputFile)
		if err != nil {
			log.Fatal(err)
		}
		output = fd
	}

	headerTpl.Execute(output, map[string]string{"Package": f.Name.Name})
	for _, s := range structs {
		fmt.Fprintf(output, "\n/*\n\n")
		generateDiagram(output, s)
		generateXdr(output, s)
		fmt.Fprintf(output, "*/\n")
		generateCode(output, s)
	}
}
Ejemplo n.º 26
0
func varIdentsDeclaredWithin(nodes []ast.Node) map[string]*ast.Ident {
	result := make(map[string]*ast.Ident)
	for _, node := range nodes {
		ast.Inspect(node, func(node ast.Node) bool {
			switch typedNode := node.(type) {
			case *ast.ValueSpec:
				for _, name := range typedNode.Names {
					result[name.Name] = name
				}

			case *ast.AssignStmt:
				if typedNode.Tok.String() == ":=" {
					for i := range typedNode.Lhs {
						result[typedNode.Lhs[i].(*ast.Ident).Name] = typedNode.Lhs[i].(*ast.Ident)
					}
				}

			case *ast.RangeStmt:
				if typedNode.Tok.String() == ":=" {
					result[typedNode.Key.(*ast.Ident).Name] = typedNode.Key.(*ast.Ident)
					if typedNode.Value != nil {
						result[typedNode.Value.(*ast.Ident).Name] = typedNode.Value.(*ast.Ident)
					}
				}
			}
			return true
		})
	}
	return result
}
Ejemplo n.º 27
0
func PrintHugeParams(fset *token.FileSet, info *types.Info, files []*ast.File) {
	checkTuple := func(descr string, tuple *types.Tuple) {
		for i := 0; i < tuple.Len(); i++ {
			v := tuple.At(i)
			if sz := sizeof(v.Type()); sz > int64(*bytesFlag) {
				fmt.Printf("%s: %q %s: %s = %d bytes\n",
					fset.Position(v.Pos()),
					v.Name(), descr, v.Type(), sz)
			}
		}
	}
	checkSig := func(sig *types.Signature) {
		checkTuple("parameter", sig.Params())
		checkTuple("result", sig.Results())
	}
	for _, file := range files {
		ast.Inspect(file, func(n ast.Node) bool {
			switch n := n.(type) {
			case *ast.FuncDecl:
				checkSig(info.Defs[n.Name].Type().(*types.Signature))
			case *ast.FuncLit:
				checkSig(info.Types[n.Type].Type.(*types.Signature))
			}
			return true
		})
	}
}
Ejemplo n.º 28
0
func removeCommentsFrom(decls []ast.Decl) {
	for _, decl := range decls {
		ast.Inspect(decl, func(n ast.Node) bool {
			switch d := n.(type) {
			case *ast.GenDecl:
				d.Doc = nil
				for _, spec := range d.Specs {
					switch s := spec.(type) {
					case *ast.ImportSpec:
						s.Doc = nil
						s.Comment = nil
					case *ast.ValueSpec:
						s.Doc = nil
						s.Comment = nil
					case *ast.TypeSpec:
						s.Doc = nil
						s.Comment = nil
					}
				}
			case *ast.FuncDecl:
				d.Doc = nil
			case *ast.StructType:
				for _, field := range d.Fields.List {
					field.Doc = nil
					field.Comment = nil
				}
			}
			return true
		})
	}
}
Ejemplo n.º 29
0
func stripParens(x ast.Expr) ast.Expr {
	if px, strip := x.(*ast.ParenExpr); strip {
		// parentheses must not be stripped if there are any
		// unparenthesized composite literals starting with
		// a type name
		ast.Inspect(px.X, func(node interface{}) bool {
			switch x := node.(type) {
			case *ast.ParenExpr:
				// parentheses protect enclosed composite literals
				return false
			case *ast.CompositeLit:
				if isTypeName(x.Type) {
					strip = false // do not strip parentheses
				}
				return false
			}
			// in all other cases, keep inspecting
			return true
		})
		if strip {
			return stripParens(px.X)
		}
	}
	return x
}
Ejemplo n.º 30
0
func (es *extractStrings) extractString(f *ast.File, fset *token.FileSet) error {
	shouldProcessBasicLit := true
	ast.Inspect(f, func(n ast.Node) bool {
		switch x := n.(type) {
		case *ast.BasicLit:
			if shouldProcessBasicLit {
				es.processBasicLit(x, n, fset)
			}
			shouldProcessBasicLit = true
		case *ast.IndexExpr:
			_, ok := x.Index.(*ast.BasicLit)
			if ok {
				shouldProcessBasicLit = false
			}
		case *ast.KeyValueExpr:
			_, ok := x.Key.(*ast.BasicLit)
			if ok {
				shouldProcessBasicLit = false
			}
		}
		return true
	})

	return nil
}