Precondition: T is not a method signature (*Signature with Recv()!=nil). Recursive case: skip => don't create methods for T. EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu)
(T Type, skip bool)
| 151 | // EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) |
| 152 | // |
| 153 | func (prog *Program) needMethods(T Type, skip bool) { |
| 154 | // Each package maintains its own set of types it has visited. |
| 155 | if prevSkip, ok := prog.runtimeTypes.At(T).(bool); ok { |
| 156 | // needMethods(T) was previously called |
| 157 | if !prevSkip || skip { |
| 158 | return // already seen, with same or false 'skip' value |
| 159 | } |
| 160 | } |
| 161 | prog.runtimeTypes.Set(T, skip) |
| 162 | |
| 163 | tmset := prog.MethodSets.MethodSet(T) |
| 164 | |
| 165 | if !skip && !isInterface(T) && tmset.Len() > 0 { |
| 166 | // Create methods of T. |
| 167 | mset := prog.createMethodSet(T) |
| 168 | if !mset.complete { |
| 169 | mset.complete = true |
| 170 | n := tmset.Len() |
| 171 | for i := 0; i < n; i++ { |
| 172 | prog.addMethod(mset, tmset.At(i)) |
| 173 | } |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | // Recursion over signatures of each method. |
| 178 | for i := 0; i < tmset.Len(); i++ { |
| 179 | sig := tmset.At(i).Type().(*Signature) |
| 180 | prog.needMethods(sig.Params(), false) |
| 181 | prog.needMethods(sig.Results(), false) |
| 182 | } |
| 183 | |
| 184 | switch t := T.(type) { |
| 185 | case *Basic: |
| 186 | // nop |
| 187 | |
| 188 | case *Interface, *TypeParam: |
| 189 | // nop---handled by recursion over method set. |
| 190 | |
| 191 | case *Pointer: |
| 192 | prog.needMethods(t.Elem(), false) |
| 193 | |
| 194 | case *Slice: |
| 195 | prog.needMethods(t.Elem(), false) |
| 196 | |
| 197 | case *Chan: |
| 198 | prog.needMethods(t.Elem(), false) |
| 199 | |
| 200 | case *Map: |
| 201 | prog.needMethods(t.Key(), false) |
| 202 | prog.needMethods(t.Elem(), false) |
| 203 | |
| 204 | case *Signature: |
| 205 | if t.Recv() != nil { |
| 206 | panic(fmt.Sprintf("Signature %s has Recv %s", t, t.Recv())) |
| 207 | } |
| 208 | prog.needMethods(t.Params(), false) |
| 209 | prog.needMethods(t.Results(), false) |
| 210 |
no test coverage detected