package typeparams
import (
- "fmt"
"go/ast"
"go/token"
)
}
return nil
}
-
-func Get(n ast.Node) *ast.FieldList {
- switch n := n.(type) {
- case *ast.TypeSpec:
- return n.TParams
- case *ast.FuncType:
- return n.TParams
- default:
- panic(fmt.Sprintf("node type %T has no type parameters", n))
- }
-}
-
-func Set(n ast.Node, params *ast.FieldList) {
- switch n := n.(type) {
- case *ast.TypeSpec:
- n.TParams = params
- case *ast.FuncType:
- n.TParams = params
- default:
- panic(fmt.Sprintf("node type %T has no type parameters", n))
- }
-}
_, params := p.parseParameters(false)
results := p.parseResult()
idents = []*ast.Ident{ident}
- typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
- typeparams.Set(typ, tparams)
+ typ = &ast.FuncType{
+ Func: token.NoPos,
+ TParams: tparams,
+ Params: params,
+ Results: results,
+ }
} else {
// embedded instantiated type
// TODO(rfindley) should resolve all identifiers in x.
func (p *parser) parseGenericType(spec *ast.TypeSpec, openPos token.Pos, name0 *ast.Ident, closeTok token.Token) {
list := p.parseParameterList(name0, closeTok, p.parseParamDecl, true)
closePos := p.expect(closeTok)
- typeparams.Set(spec, &ast.FieldList{Opening: openPos, List: list, Closing: closePos})
+ spec.TParams = &ast.FieldList{Opening: openPos, List: list, Closing: closePos}
// Type alias cannot have type parameters. Accept them for robustness but complain.
if p.tok == token.ASSIGN {
p.error(p.pos, "generic type cannot be alias")
Name: ident,
Type: &ast.FuncType{
Func: pos,
+ TParams: tparams,
Params: params,
Results: results,
},
Body: body,
}
- typeparams.Set(decl.Type, tparams)
return decl
}
import (
"fmt"
"go/ast"
- "go/internal/typeparams"
"go/token"
)
// at the identifier in the TypeSpec and ends at the end of the innermost
// containing block.
r.declare(spec, nil, r.topScope, ast.Typ, spec.Name)
- if tparams := typeparams.Get(spec); tparams != nil {
+ if spec.TParams != nil {
r.openScope(spec.Pos())
defer r.closeScope()
- r.walkTParams(tparams)
+ r.walkTParams(spec.TParams)
}
ast.Walk(r, spec.Type)
}
// Type parameters are walked normally: they can reference each other, and
// can be referenced by normal parameters.
- if tparams := typeparams.Get(n.Type); tparams != nil {
- r.walkTParams(tparams)
+ if n.Type.TParams != nil {
+ r.walkTParams(n.Type.TParams)
// TODO(rFindley): need to address receiver type parameters.
}
// that they may be resolved in the constraint expressions held in the field
// Type.
func (r *resolver) walkTParams(list *ast.FieldList) {
- if list == nil {
- return
- }
r.declareList(list, ast.Typ)
r.resolveList(list)
}
import (
"bytes"
"go/ast"
- "go/internal/typeparams"
"go/token"
"math"
"strconv"
}
func (p *printer) signature(sig *ast.FuncType) {
- if tparams := typeparams.Get(sig); tparams != nil {
- p.parameters(tparams, true)
+ if sig.TParams != nil {
+ p.parameters(sig.TParams, true)
}
if sig.Params != nil {
p.parameters(sig.Params, false)
case *ast.TypeSpec:
p.setComment(s.Doc)
p.expr(s.Name)
- if tparams := typeparams.Get(s); tparams != nil {
- p.parameters(tparams, true)
+ if s.TParams != nil {
+ p.parameters(s.TParams, true)
}
if n == 1 {
p.print(blank)
"fmt"
"go/ast"
"go/constant"
- "go/internal/typeparams"
"go/token"
)
})
alias := tdecl.Assign.IsValid()
- if alias && typeparams.Get(tdecl) != nil {
+ if alias && tdecl.TParams.NumFields() != 0 {
// The parser will ensure this but we may still get an invalid AST.
// Complain and continue as regular type definition.
check.error(atPos(tdecl.Assign), 0, "generic type cannot be alias")
named := check.newNamed(obj, nil, nil, nil, nil)
def.setUnderlying(named)
- if tparams := typeparams.Get(tdecl); tparams != nil {
+ if tdecl.TParams != nil {
check.openScope(tdecl, "type parameters")
defer check.closeScope()
- named.tparams = check.collectTypeParams(tparams)
+ named.tparams = check.collectTypeParams(tdecl.TParams)
}
// determine underlying type of named
import (
"go/ast"
- "go/internal/typeparams"
"go/token"
)
// a receiver specification.)
if sig.tparams != nil {
var at positioner = f.Type
- if tparams := typeparams.Get(f.Type); tparams != nil {
- at = tparams
+ if ftyp, _ := f.Type.(*ast.FuncType); ftyp != nil && ftyp.TParams != nil {
+ at = ftyp.TParams
}
check.errorf(at, _Todo, "methods cannot have type parameters")
}
}
}
- if tparams := typeparams.Get(ftyp); tparams != nil {
- sig.tparams = check.collectTypeParams(tparams)
+ if ftyp.TParams != nil {
+ sig.tparams = check.collectTypeParams(ftyp.TParams)
// Always type-check method type parameters but complain that they are not allowed.
// (A separate check is needed when type-checking interface method signatures because
// they don't have a receiver specification.)
if recvPar != nil {
- check.errorf(tparams, _Todo, "methods cannot have type parameters")
+ check.errorf(ftyp.TParams, _Todo, "methods cannot have type parameters")
}
}