typecheck type checks the AST f assuming the information in cfg. It returns two maps with type information: typeof maps AST nodes to type information in gofmt string form. assign maps type strings to lists of expressions that were assigned to values of another type that were assigned to that type.
(cfg *TypeConfig, f *ast.File)
| 133 | // assign maps type strings to lists of expressions that were assigned |
| 134 | // to values of another type that were assigned to that type. |
| 135 | func typecheck(cfg *TypeConfig, f *ast.File) (typeof map[interface{}]string, assign map[string][]interface{}) { |
| 136 | typeof = make(map[interface{}]string) |
| 137 | assign = make(map[string][]interface{}) |
| 138 | cfg1 := &TypeConfig{} |
| 139 | *cfg1 = *cfg // make copy so we can add locally |
| 140 | copied := false |
| 141 | |
| 142 | // gather function declarations |
| 143 | for _, decl := range f.Decls { |
| 144 | fn, ok := decl.(*ast.FuncDecl) |
| 145 | if !ok { |
| 146 | continue |
| 147 | } |
| 148 | typecheck1(cfg, fn.Type, typeof, assign) |
| 149 | t := typeof[fn.Type] |
| 150 | if fn.Recv != nil { |
| 151 | // The receiver must be a type. |
| 152 | rcvr := typeof[fn.Recv] |
| 153 | if !isType(rcvr) { |
| 154 | if len(fn.Recv.List) != 1 { |
| 155 | continue |
| 156 | } |
| 157 | rcvr = mkType(gofmt(fn.Recv.List[0].Type)) |
| 158 | typeof[fn.Recv.List[0].Type] = rcvr |
| 159 | } |
| 160 | rcvr = getType(rcvr) |
| 161 | if rcvr != "" && rcvr[0] == '*' { |
| 162 | rcvr = rcvr[1:] |
| 163 | } |
| 164 | typeof[rcvr+"."+fn.Name.Name] = t |
| 165 | } else { |
| 166 | if isType(t) { |
| 167 | t = getType(t) |
| 168 | } else { |
| 169 | t = gofmt(fn.Type) |
| 170 | } |
| 171 | typeof[fn.Name] = t |
| 172 | |
| 173 | // Record typeof[fn.Name.Obj] for future references to fn.Name. |
| 174 | typeof[fn.Name.Obj] = t |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | // gather struct declarations |
| 179 | for _, decl := range f.Decls { |
| 180 | d, ok := decl.(*ast.GenDecl) |
| 181 | if ok { |
| 182 | for _, s := range d.Specs { |
| 183 | switch s := s.(type) { |
| 184 | case *ast.TypeSpec: |
| 185 | if cfg1.Type[s.Name.Name] != nil { |
| 186 | break |
| 187 | } |
| 188 | if !copied { |
| 189 | copied = true |
| 190 | // Copy map lazily: it's time. |
| 191 | cfg1.Type = make(map[string]*Type) |
| 192 | for k, v := range cfg.Type { |
nothing calls this directly
no test coverage detected