| 154 | } |
| 155 | |
| 156 | func (p *Parser) parseTypes(fset *token.FileSet, fs []*ast.File) (map[string]types.Type, map[*types.Struct]ast.Expr) { |
| 157 | conf := &types.Config{ |
| 158 | Importer: p.Importer, |
| 159 | // Adding a NO-OP error function ignores errors and performs best-effort |
| 160 | // type checking. https://godoc.org/golang.org/x/tools/go/types#Config |
| 161 | Error: func(error) {}, |
| 162 | } |
| 163 | ti := &types.Info{ |
| 164 | Types: make(map[ast.Expr]types.TypeAndValue), |
| 165 | } |
| 166 | // Note: conf.Check can fail, but since Info is not required data, it's ok. |
| 167 | conf.Check("", fset, fs, ti) |
| 168 | ul := make(map[string]types.Type) |
| 169 | el := make(map[*types.Struct]ast.Expr) |
| 170 | for e, t := range ti.Types { |
| 171 | // Collect the underlying types. |
| 172 | ul[t.Type.String()] = t.Type.Underlying() |
| 173 | // Collect structs to determine the fields of a receiver. |
| 174 | if v, ok := t.Type.(*types.Struct); ok { |
| 175 | el[v] = e |
| 176 | } |
| 177 | } |
| 178 | return ul, el |
| 179 | } |
| 180 | |
| 181 | // extractFunctionBody extracts the source code of a function body including the braces. |
| 182 | func extractFunctionBody(fset *token.FileSet, fDecl *ast.FuncDecl, src []byte) string { |