Commit 2e5116bd authored by Robert Griesemer's avatar Robert Griesemer

[dev.typealias] go/ast, go/parser, go/printer, go/types: initial type alias support

Parsing and printing support for type aliases complete.
go/types recognizes them an issues an "unimplemented" error for now.

For #18130.

Change-Id: I9f2f7b1971b527276b698d9347bcd094ef0012ee
Reviewed-on: https://go-review.googlesource.com/34986
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent ffedff7e
...@@ -848,6 +848,7 @@ type ( ...@@ -848,6 +848,7 @@ type (
TypeSpec struct { TypeSpec struct {
Doc *CommentGroup // associated documentation; or nil Doc *CommentGroup // associated documentation; or nil
Name *Ident // type name Name *Ident // type name
Assign token.Pos // position of '=', if any
Type Expr // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes Type Expr // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
Comment *CommentGroup // line comments; or nil Comment *CommentGroup // line comments; or nil
} }
......
...@@ -2327,7 +2327,10 @@ func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast. ...@@ -2327,7 +2327,10 @@ func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.
// (Global identifiers are resolved in a separate phase after parsing.) // (Global identifiers are resolved in a separate phase after parsing.)
spec := &ast.TypeSpec{Doc: doc, Name: ident} spec := &ast.TypeSpec{Doc: doc, Name: ident}
p.declare(spec, nil, p.topScope, ast.Typ, ident) p.declare(spec, nil, p.topScope, ast.Typ, ident)
if p.tok == token.ASSIGN {
spec.Assign = p.pos
p.next()
}
spec.Type = p.parseType() spec.Type = p.parseType()
p.expectSemi() // call before accessing p.linecomment p.expectSemi() // call before accessing p.linecomment
spec.Comment = p.lineComment spec.Comment = p.lineComment
......
...@@ -46,6 +46,8 @@ var valids = []string{ ...@@ -46,6 +46,8 @@ var valids = []string{
`package p; const (x = 0; y; z)`, // issue 9639 `package p; const (x = 0; y; z)`, // issue 9639
`package p; var _ = map[P]int{P{}:0, {}:1}`, `package p; var _ = map[P]int{P{}:0, {}:1}`,
`package p; var _ = map[*P]int{&P{}:0, {}:1}`, `package p; var _ = map[*P]int{&P{}:0, {}:1}`,
`package p; type T = int`,
`package p; type (T = p.T; _ = struct{}; x = *T)`,
} }
func TestValid(t *testing.T) { func TestValid(t *testing.T) {
......
...@@ -1445,6 +1445,9 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool) { ...@@ -1445,6 +1445,9 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
} else { } else {
p.print(vtab) p.print(vtab)
} }
if s.Assign.IsValid() {
p.print(token.ASSIGN, blank)
}
p.expr(s.Type) p.expr(s.Type)
p.setComment(s.Comment) p.setComment(s.Comment)
......
...@@ -985,3 +985,18 @@ func _(struct { ...@@ -985,3 +985,18 @@ func _(struct {
x int x int
y int y int
}) // no extra comma between } and ) }) // no extra comma between } and )
// alias declarations
type c0 struct{}
type c1 = C
type c2 = struct{ x int }
type c3 = p.C
type (
s struct{}
a = A
b = A
c = foo
d = interface{}
ddd = p.Foo
)
...@@ -999,3 +999,18 @@ func _(struct { ...@@ -999,3 +999,18 @@ func _(struct {
x int x int
y int y int
}) // no extra comma between } and ) }) // no extra comma between } and )
// alias declarations
type c0 struct{}
type c1 = C
type c2 = struct{ x int}
type c3 = p.C
type (
s struct{}
a = A
b = A
c = foo
d = interface{}
ddd = p.Foo
)
\ No newline at end of file
...@@ -534,6 +534,9 @@ func (check *Checker) declStmt(decl ast.Decl) { ...@@ -534,6 +534,9 @@ func (check *Checker) declStmt(decl ast.Decl) {
} }
case *ast.TypeSpec: case *ast.TypeSpec:
if s.Assign.IsValid() {
check.errorf(s.Assign, "type alias declarations not yet implemented")
}
obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
// spec: "The scope of a type identifier declared inside a function // spec: "The scope of a type identifier declared inside a function
// begins at the identifier in the TypeSpec and ends at the end of // begins at the identifier in the TypeSpec and ends at the end of
......
...@@ -346,6 +346,9 @@ func (check *Checker) collectObjects() { ...@@ -346,6 +346,9 @@ func (check *Checker) collectObjects() {
} }
case *ast.TypeSpec: case *ast.TypeSpec:
if s.Assign.IsValid() {
check.errorf(s.Assign, "type alias declarations not yet implemented")
}
obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil) obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
check.declarePkgObj(s.Name, obj, &declInfo{file: fileScope, typ: s.Type}) check.declarePkgObj(s.Name, obj, &declInfo{file: fileScope, typ: s.Type})
......
...@@ -208,3 +208,11 @@ func (BlankT) _() {} ...@@ -208,3 +208,11 @@ func (BlankT) _() {}
func (BlankT) _(int) {} func (BlankT) _(int) {}
func (BlankT) _() int { return 0 } func (BlankT) _() int { return 0 }
func (BlankT) _(int) int { return 0} func (BlankT) _(int) int { return 0}
// type alias declarations
// TODO(gri) complete this
type (
__ = /* ERROR not yet implemented */ int
a0 = /* ERROR not yet implemented */ int
a1 = /* ERROR not yet implemented */ struct{}
)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment