// Copyright 2021 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package typeparams import ( "go/ast" "go/token" ) func PackIndexExpr(x ast.Expr, lbrack token.Pos, exprs []ast.Expr, rbrack token.Pos) ast.Expr { switch len(exprs) { case 0: panic("internal error: PackIndexExpr with empty expr slice") case 1: return &ast.IndexExpr{ X: x, Lbrack: lbrack, Index: exprs[0], Rbrack: rbrack, } default: return &ast.IndexListExpr{ X: x, Lbrack: lbrack, Indices: exprs, Rbrack: rbrack, } } } // IndexExpr wraps an ast.IndexExpr or ast.IndexListExpr. // // Orig holds the original ast.Expr from which this IndexExpr was derived. // // Note: IndexExpr (intentionally) does not wrap ast.Expr, as that leads to // accidental misuse such as encountered in golang/go#63933. // // TODO(rfindley): remove this helper, in favor of just having a helper // function that returns indices. type IndexExpr struct { Orig ast.Expr // the wrapped expr, which may be distinct from the IndexListExpr below. X ast.Expr // expression Lbrack token.Pos // position of "[" Indices []ast.Expr // index expressions Rbrack token.Pos // position of "]" } func (x *IndexExpr) Pos() token.Pos { return x.Orig.Pos() } func UnpackIndexExpr(n ast.Node) *IndexExpr { switch e := n.(type) { case *ast.IndexExpr: return &IndexExpr{ Orig: e, X: e.X, Lbrack: e.Lbrack, Indices: []ast.Expr{e.Index}, Rbrack: e.Rbrack, } case *ast.IndexListExpr: return &IndexExpr{ Orig: e, X: e.X, Lbrack: e.Lbrack, Indices: e.Indices, Rbrack: e.Rbrack, } } return nil }