mirror of
https://github.com/golang/go
synced 2024-11-21 19:04:44 -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)
|
||||
var len ast.Expr
|
||||
if ellipsisOk && p.tok == token.ELLIPSIS {
|
||||
len = &ast.Ellipsis{p.pos}
|
||||
len = &ast.Ellipsis{p.pos, nil}
|
||||
p.next()
|
||||
} else if p.tok != token.RBRACK {
|
||||
len = p.parseExpr()
|
||||
@ -499,11 +499,11 @@ func (p *parser) tryParameterType(ellipsisOk bool) ast.Expr {
|
||||
if ellipsisOk && p.tok == token.ELLIPSIS {
|
||||
pos := p.pos
|
||||
p.next()
|
||||
typ := p.tryType()
|
||||
if p.tok != token.RPAREN {
|
||||
// "..." always must be at the very end of a parameter list
|
||||
p.Error(pos, "expected type, found '...'")
|
||||
p.Error(pos, "can use '...' for last parameter only")
|
||||
}
|
||||
return &ast.Ellipsis{pos}
|
||||
return &ast.Ellipsis{pos, typ}
|
||||
}
|
||||
return p.tryType()
|
||||
}
|
||||
|
@ -126,6 +126,7 @@ type (
|
||||
//
|
||||
Ellipsis struct {
|
||||
token.Position // position of "..."
|
||||
Elt Expr // ellipsis element type (parameter lists only)
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
scope := ast.NewScope(nil)
|
||||
var scope *ast.Scope = nil // for now tracking of declarations is disabled
|
||||
pkgs := make(map[string]*ast.Package)
|
||||
for i := 0; i < len(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.trace = mode&Trace != 0 // for convenience (p.trace is used frequently)
|
||||
if scope != nil {
|
||||
// Disabled for now. Causes error with "godoc http":
|
||||
// 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
|
||||
p.checkDecl = true
|
||||
} else {
|
||||
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)
|
||||
var len ast.Expr
|
||||
if ellipsisOk && p.tok == token.ELLIPSIS {
|
||||
len = &ast.Ellipsis{p.pos}
|
||||
len = &ast.Ellipsis{p.pos, nil}
|
||||
p.next()
|
||||
} else if p.tok != token.RBRACK {
|
||||
len = p.parseExpr()
|
||||
@ -600,11 +597,11 @@ func (p *parser) tryParameterType(ellipsisOk bool) ast.Expr {
|
||||
if ellipsisOk && p.tok == token.ELLIPSIS {
|
||||
pos := p.pos
|
||||
p.next()
|
||||
typ := p.tryType()
|
||||
if p.tok != token.RPAREN {
|
||||
// "..." always must be at the very end of a parameter list
|
||||
p.Error(pos, "expected type, found '...'")
|
||||
p.Error(pos, "can use '...' for last parameter only")
|
||||
}
|
||||
return &ast.Ellipsis{pos}
|
||||
return &ast.Ellipsis{pos, typ}
|
||||
}
|
||||
return p.tryType()
|
||||
}
|
||||
@ -1824,6 +1821,9 @@ func parseImportSpec(p *parser, doc *ast.CommentGroup) ast.Spec {
|
||||
p.next()
|
||||
} else if p.tok == token.IDENT {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,8 @@ var validPrograms = []interface{}{
|
||||
`package main; func main() { _ = (<-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(...)` + "\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:
|
||||
p.print(token.ELLIPSIS)
|
||||
if x.Elt != nil {
|
||||
p.expr(x.Elt, multiLine)
|
||||
}
|
||||
|
||||
case *ast.ArrayType:
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
= 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