 6a979fb40d
			
		
	
	
		6a979fb40d
		
			
		
	
	
	
	
		
			
			* update staticcheck Don't fork staticcheck: use the upstream version. Remove unneeded SSA loading. * Cache go/analysis facts Don't load unneeded packages for go/analysis. Repeated run of go/analysis linters now 10x faster (2s vs 20s on this repo) than before.
		
			
				
	
	
		
			83 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			83 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package unused
 | |
| 
 | |
| import "go/types"
 | |
| 
 | |
| // lookupMethod returns the index of and method with matching package and name, or (-1, nil).
 | |
| func lookupMethod(T *types.Interface, pkg *types.Package, name string) (int, *types.Func) {
 | |
| 	if name != "_" {
 | |
| 		for i := 0; i < T.NumMethods(); i++ {
 | |
| 			m := T.Method(i)
 | |
| 			if sameId(m, pkg, name) {
 | |
| 				return i, m
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return -1, nil
 | |
| }
 | |
| 
 | |
| func sameId(obj types.Object, pkg *types.Package, name string) bool {
 | |
| 	// spec:
 | |
| 	// "Two identifiers are different if they are spelled differently,
 | |
| 	// or if they appear in different packages and are not exported.
 | |
| 	// Otherwise, they are the same."
 | |
| 	if name != obj.Name() {
 | |
| 		return false
 | |
| 	}
 | |
| 	// obj.Name == name
 | |
| 	if obj.Exported() {
 | |
| 		return true
 | |
| 	}
 | |
| 	// not exported, so packages must be the same (pkg == nil for
 | |
| 	// fields in Universe scope; this can only happen for types
 | |
| 	// introduced via Eval)
 | |
| 	if pkg == nil || obj.Pkg() == nil {
 | |
| 		return pkg == obj.Pkg()
 | |
| 	}
 | |
| 	// pkg != nil && obj.pkg != nil
 | |
| 	return pkg.Path() == obj.Pkg().Path()
 | |
| }
 | |
| 
 | |
| func (g *Graph) implements(V types.Type, T *types.Interface, msV *types.MethodSet) ([]*types.Selection, bool) {
 | |
| 	// fast path for common case
 | |
| 	if T.Empty() {
 | |
| 		return nil, true
 | |
| 	}
 | |
| 
 | |
| 	if ityp, _ := V.Underlying().(*types.Interface); ityp != nil {
 | |
| 		// TODO(dh): is this code reachable?
 | |
| 		for i := 0; i < T.NumMethods(); i++ {
 | |
| 			m := T.Method(i)
 | |
| 			_, obj := lookupMethod(ityp, m.Pkg(), m.Name())
 | |
| 			switch {
 | |
| 			case obj == nil:
 | |
| 				return nil, false
 | |
| 			case !types.Identical(obj.Type(), m.Type()):
 | |
| 				return nil, false
 | |
| 			}
 | |
| 		}
 | |
| 		return nil, true
 | |
| 	}
 | |
| 
 | |
| 	// A concrete type implements T if it implements all methods of T.
 | |
| 	var sels []*types.Selection
 | |
| 	for i := 0; i < T.NumMethods(); i++ {
 | |
| 		m := T.Method(i)
 | |
| 		sel := msV.Lookup(m.Pkg(), m.Name())
 | |
| 		if sel == nil {
 | |
| 			return nil, false
 | |
| 		}
 | |
| 
 | |
| 		f, _ := sel.Obj().(*types.Func)
 | |
| 		if f == nil {
 | |
| 			return nil, false
 | |
| 		}
 | |
| 
 | |
| 		if !types.Identical(f.Type(), m.Type()) {
 | |
| 			return nil, false
 | |
| 		}
 | |
| 
 | |
| 		sels = append(sels, sel)
 | |
| 	}
 | |
| 	return sels, true
 | |
| }
 |