mirror of
https://github.com/golang/go
synced 2024-11-22 00:34:40 -07:00
support for ...T parameters (go/* packages)
R=rsc CC=golang-dev https://golang.org/cl/194126
This commit is contained in:
parent
4967f857d5
commit
8fedbb8c3d
@ -379,7 +379,7 @@ func (p *parser) parseArrayType(ellipsisOk bool) ast.Expr {
|
|||||||
lbrack := p.expect(token.LBRACK)
|
lbrack := p.expect(token.LBRACK)
|
||||||
var len ast.Expr
|
var len ast.Expr
|
||||||
if ellipsisOk && p.tok == token.ELLIPSIS {
|
if ellipsisOk && p.tok == token.ELLIPSIS {
|
||||||
len = &ast.Ellipsis{p.pos}
|
len = &ast.Ellipsis{p.pos, nil}
|
||||||
p.next()
|
p.next()
|
||||||
} else if p.tok != token.RBRACK {
|
} else if p.tok != token.RBRACK {
|
||||||
len = p.parseExpr()
|
len = p.parseExpr()
|
||||||
@ -499,11 +499,11 @@ func (p *parser) tryParameterType(ellipsisOk bool) ast.Expr {
|
|||||||
if ellipsisOk && p.tok == token.ELLIPSIS {
|
if ellipsisOk && p.tok == token.ELLIPSIS {
|
||||||
pos := p.pos
|
pos := p.pos
|
||||||
p.next()
|
p.next()
|
||||||
|
typ := p.tryType()
|
||||||
if p.tok != token.RPAREN {
|
if p.tok != token.RPAREN {
|
||||||
// "..." always must be at the very end of a parameter list
|
p.Error(pos, "can use '...' for last parameter only")
|
||||||
p.Error(pos, "expected type, found '...'")
|
|
||||||
}
|
}
|
||||||
return &ast.Ellipsis{pos}
|
return &ast.Ellipsis{pos, typ}
|
||||||
}
|
}
|
||||||
return p.tryType()
|
return p.tryType()
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,8 @@ type (
|
|||||||
// parameter list or the "..." length in an array type.
|
// parameter list or the "..." length in an array type.
|
||||||
//
|
//
|
||||||
Ellipsis struct {
|
Ellipsis struct {
|
||||||
token.Position // position of "..."
|
token.Position // position of "..."
|
||||||
|
Elt Expr // ellipsis element type (parameter lists only)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A BasicLit node represents a literal of basic type.
|
// A BasicLit node represents a literal of basic type.
|
||||||
|
@ -164,7 +164,7 @@ func ParseDir(path string, filter func(*os.Dir) bool, mode uint) (map[string]*as
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
scope := ast.NewScope(nil)
|
var scope *ast.Scope = nil // for now tracking of declarations is disabled
|
||||||
pkgs := make(map[string]*ast.Package)
|
pkgs := make(map[string]*ast.Package)
|
||||||
for i := 0; i < len(list); i++ {
|
for i := 0; i < len(list); i++ {
|
||||||
entry := &list[i]
|
entry := &list[i]
|
||||||
|
@ -81,10 +81,7 @@ func (p *parser) init(filename string, src []byte, scope *ast.Scope, mode uint)
|
|||||||
p.mode = mode
|
p.mode = mode
|
||||||
p.trace = mode&Trace != 0 // for convenience (p.trace is used frequently)
|
p.trace = mode&Trace != 0 // for convenience (p.trace is used frequently)
|
||||||
if scope != nil {
|
if scope != nil {
|
||||||
// Disabled for now. Causes error with "godoc http":
|
p.checkDecl = true
|
||||||
// parser.parseDir: src/pkg/http/server.go:159:16: 'Write' declared already at src/pkg/http/request.go:140:21 (and 4 more errors)
|
|
||||||
|
|
||||||
// p.checkDecl = true
|
|
||||||
} else {
|
} else {
|
||||||
scope = ast.NewScope(nil) // provide a dummy scope
|
scope = ast.NewScope(nil) // provide a dummy scope
|
||||||
}
|
}
|
||||||
@ -480,7 +477,7 @@ func (p *parser) parseArrayType(ellipsisOk bool) ast.Expr {
|
|||||||
lbrack := p.expect(token.LBRACK)
|
lbrack := p.expect(token.LBRACK)
|
||||||
var len ast.Expr
|
var len ast.Expr
|
||||||
if ellipsisOk && p.tok == token.ELLIPSIS {
|
if ellipsisOk && p.tok == token.ELLIPSIS {
|
||||||
len = &ast.Ellipsis{p.pos}
|
len = &ast.Ellipsis{p.pos, nil}
|
||||||
p.next()
|
p.next()
|
||||||
} else if p.tok != token.RBRACK {
|
} else if p.tok != token.RBRACK {
|
||||||
len = p.parseExpr()
|
len = p.parseExpr()
|
||||||
@ -600,11 +597,11 @@ func (p *parser) tryParameterType(ellipsisOk bool) ast.Expr {
|
|||||||
if ellipsisOk && p.tok == token.ELLIPSIS {
|
if ellipsisOk && p.tok == token.ELLIPSIS {
|
||||||
pos := p.pos
|
pos := p.pos
|
||||||
p.next()
|
p.next()
|
||||||
|
typ := p.tryType()
|
||||||
if p.tok != token.RPAREN {
|
if p.tok != token.RPAREN {
|
||||||
// "..." always must be at the very end of a parameter list
|
p.Error(pos, "can use '...' for last parameter only")
|
||||||
p.Error(pos, "expected type, found '...'")
|
|
||||||
}
|
}
|
||||||
return &ast.Ellipsis{pos}
|
return &ast.Ellipsis{pos, typ}
|
||||||
}
|
}
|
||||||
return p.tryType()
|
return p.tryType()
|
||||||
}
|
}
|
||||||
@ -1824,6 +1821,9 @@ func parseImportSpec(p *parser, doc *ast.CommentGroup) ast.Spec {
|
|||||||
p.next()
|
p.next()
|
||||||
} else if p.tok == token.IDENT {
|
} else if p.tok == token.IDENT {
|
||||||
ident = p.parseIdent(ast.Pkg)
|
ident = p.parseIdent(ast.Pkg)
|
||||||
|
// TODO(gri) Make sure the ident is not already declared in the
|
||||||
|
// package scope. Also, cannot add the same name to
|
||||||
|
// the package scope later.
|
||||||
p.declIdent(p.fileScope, ident)
|
p.declIdent(p.fileScope, ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ var validPrograms = []interface{}{
|
|||||||
`package main; func main() { _ = (<-chan int)(x) }` + "\n",
|
`package main; func main() { _ = (<-chan int)(x) }` + "\n",
|
||||||
`package main; func main() { _ = (<-chan <-chan int)(x) }` + "\n",
|
`package main; func main() { _ = (<-chan <-chan int)(x) }` + "\n",
|
||||||
`package main; func f(func() func() func())` + "\n",
|
`package main; func f(func() func() func())` + "\n",
|
||||||
|
`package main; func f(...)` + "\n",
|
||||||
|
`package main; func f(float, ...int)` + "\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -759,6 +759,9 @@ func (p *printer) expr1(expr ast.Expr, prec1, depth int, ctxt exprContext, multi
|
|||||||
|
|
||||||
case *ast.Ellipsis:
|
case *ast.Ellipsis:
|
||||||
p.print(token.ELLIPSIS)
|
p.print(token.ELLIPSIS)
|
||||||
|
if x.Elt != nil {
|
||||||
|
p.expr(x.Elt, multiLine)
|
||||||
|
}
|
||||||
|
|
||||||
case *ast.ArrayType:
|
case *ast.ArrayType:
|
||||||
p.print(token.LBRACK)
|
p.print(token.LBRACK)
|
||||||
|
24
src/pkg/go/printer/testdata/declarations.golden
vendored
24
src/pkg/go/printer/testdata/declarations.golden
vendored
@ -547,3 +547,27 @@ func _() { // opening "{" must move up
|
|||||||
|
|
||||||
var _ = x // comment
|
var _ = x // comment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ellipsis parameters
|
||||||
|
func _(...)
|
||||||
|
func _(...int)
|
||||||
|
func _(...*int)
|
||||||
|
func _(...[]int)
|
||||||
|
func _(...struct{})
|
||||||
|
func _(bool, ...interface{})
|
||||||
|
func _(bool, ...func())
|
||||||
|
func _(bool, ...func(...))
|
||||||
|
func _(bool, ...map[string]int)
|
||||||
|
func _(bool, ...chan int)
|
||||||
|
|
||||||
|
func _(b bool, x ...)
|
||||||
|
func _(b bool, x ...int)
|
||||||
|
func _(b bool, x ...*int)
|
||||||
|
func _(b bool, x ...[]int)
|
||||||
|
func _(b bool, x ...struct{})
|
||||||
|
func _(x ...interface{})
|
||||||
|
func _(x ...func())
|
||||||
|
func _(x ...func(...))
|
||||||
|
func _(x ...map[string]int)
|
||||||
|
func _(x ...chan int)
|
||||||
|
24
src/pkg/go/printer/testdata/declarations.input
vendored
24
src/pkg/go/printer/testdata/declarations.input
vendored
@ -551,3 +551,27 @@ func _() // opening "{" must move up
|
|||||||
var _ // comment
|
var _ // comment
|
||||||
= x;
|
= x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ellipsis parameters
|
||||||
|
func _(...)
|
||||||
|
func _(...int)
|
||||||
|
func _(...*int)
|
||||||
|
func _(...[]int)
|
||||||
|
func _(...struct{})
|
||||||
|
func _(bool, ...interface{})
|
||||||
|
func _(bool, ...func())
|
||||||
|
func _(bool, ...func(...))
|
||||||
|
func _(bool, ...map[string]int)
|
||||||
|
func _(bool, ...chan int)
|
||||||
|
|
||||||
|
func _(b bool, x ...)
|
||||||
|
func _(b bool, x ...int)
|
||||||
|
func _(b bool, x ...*int)
|
||||||
|
func _(b bool, x ...[]int)
|
||||||
|
func _(b bool, x ...struct{})
|
||||||
|
func _(x ...interface{})
|
||||||
|
func _(x ...func())
|
||||||
|
func _(x ...func(...))
|
||||||
|
func _(x ...map[string]int)
|
||||||
|
func _(x ...chan int)
|
||||||
|
Loading…
Reference in New Issue
Block a user