status-go/vendor/go.uber.org/mock/mockgen/generic_go118.go

131 lines
2.9 KiB
Go

// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build go1.18
// +build go1.18
package main
import (
"errors"
"fmt"
"go/ast"
"go/token"
"strings"
"go.uber.org/mock/mockgen/model"
)
func getTypeSpecTypeParams(ts *ast.TypeSpec) []*ast.Field {
if ts == nil || ts.TypeParams == nil {
return nil
}
return ts.TypeParams.List
}
func (p *fileParser) parseGenericType(pkg string, typ ast.Expr, tps map[string]model.Type) (model.Type, error) {
switch v := typ.(type) {
case *ast.IndexExpr:
m, err := p.parseType(pkg, v.X, tps)
if err != nil {
return nil, err
}
nm, ok := m.(*model.NamedType)
if !ok {
return m, nil
}
t, err := p.parseType(pkg, v.Index, tps)
if err != nil {
return nil, err
}
nm.TypeParams = &model.TypeParametersType{TypeParameters: []model.Type{t}}
return m, nil
case *ast.IndexListExpr:
m, err := p.parseType(pkg, v.X, tps)
if err != nil {
return nil, err
}
nm, ok := m.(*model.NamedType)
if !ok {
return m, nil
}
var ts []model.Type
for _, expr := range v.Indices {
t, err := p.parseType(pkg, expr, tps)
if err != nil {
return nil, err
}
ts = append(ts, t)
}
nm.TypeParams = &model.TypeParametersType{TypeParameters: ts}
return m, nil
}
return nil, nil
}
func getIdentTypeParams(decl any) string {
if decl == nil {
return ""
}
ts, ok := decl.(*ast.TypeSpec)
if !ok {
return ""
}
if ts.TypeParams == nil || len(ts.TypeParams.List) == 0 {
return ""
}
var sb strings.Builder
sb.WriteString("[")
for i, v := range ts.TypeParams.List {
if i != 0 {
sb.WriteString(", ")
}
sb.WriteString(v.Names[0].Name)
}
sb.WriteString("]")
return sb.String()
}
func (p *fileParser) parseGenericMethod(field *ast.Field, it *namedInterface, iface *model.Interface, pkg string, tps map[string]model.Type) ([]*model.Method, error) {
var indices []ast.Expr
var typ ast.Expr
switch v := field.Type.(type) {
case *ast.IndexExpr:
indices = []ast.Expr{v.Index}
typ = v.X
case *ast.IndexListExpr:
indices = v.Indices
typ = v.X
case *ast.UnaryExpr:
if v.Op == token.TILDE {
return nil, errConstraintInterface
}
return nil, fmt.Errorf("~T may only appear as constraint for %T", field.Type)
case *ast.BinaryExpr:
if v.Op == token.OR {
return nil, errConstraintInterface
}
return nil, fmt.Errorf("A|B may only appear as constraint for %T", field.Type)
default:
return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type)
}
nf := &ast.Field{
Doc: field.Comment,
Names: field.Names,
Type: typ,
Tag: field.Tag,
Comment: field.Comment,
}
it.embeddedInstTypeParams = indices
return p.parseMethod(nf, it, iface, pkg, tps)
}
var errConstraintInterface = errors.New("interface contains constraints")