Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1227)

Delta Between Two Patch Sets: src/pkg/go/parser/parser.go

Issue 6585063: code review 6585063: go/ast: track position of <- for channel types (Closed)
Left Patch Set: Created 11 years, 5 months ago
Right Patch Set: diff -r c763565f31ff https://code.google.com/p/go Created 11 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/go/ast/ast.go ('k') | src/pkg/go/parser/short_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Package parser implements a parser for Go source files. Input may be 5 // Package parser implements a parser for Go source files. Input may be
6 // provided in a variety of forms (see the various Parse* functions); the 6 // provided in a variety of forms (see the various Parse* functions); the
7 // output is an abstract syntax tree (AST) representing the Go source. The 7 // output is an abstract syntax tree (AST) representing the Go source. The
8 // parser is invoked through one of the Parse* functions. 8 // parser is invoked through one of the Parse* functions.
9 // 9 //
10 package parser 10 package parser
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 return &ast.MapType{Map: pos, Key: key, Value: value} 917 return &ast.MapType{Map: pos, Key: key, Value: value}
918 } 918 }
919 919
920 func (p *parser) parseChanType() *ast.ChanType { 920 func (p *parser) parseChanType() *ast.ChanType {
921 if p.trace { 921 if p.trace {
922 defer un(trace(p, "ChanType")) 922 defer un(trace(p, "ChanType"))
923 } 923 }
924 924
925 pos := p.pos 925 pos := p.pos
926 dir := ast.SEND | ast.RECV 926 dir := ast.SEND | ast.RECV
927 var arrow token.Pos
927 if p.tok == token.CHAN { 928 if p.tok == token.CHAN {
928 p.next() 929 p.next()
929 if p.tok == token.ARROW { 930 if p.tok == token.ARROW {
931 arrow = p.pos
930 p.next() 932 p.next()
931 dir = ast.SEND 933 dir = ast.SEND
932 } 934 }
933 } else { 935 } else {
934 » » p.expect(token.ARROW) 936 » » arrow = p.expect(token.ARROW)
935 p.expect(token.CHAN) 937 p.expect(token.CHAN)
936 dir = ast.RECV 938 dir = ast.RECV
937 } 939 }
938 value := p.parseType() 940 value := p.parseType()
939 941
940 » return &ast.ChanType{Begin: pos, Dir: dir, Value: value} 942 » return &ast.ChanType{Begin: pos, Arrow: arrow, Dir: dir, Value: value}
941 } 943 }
942 944
943 // If the result is an identifier, it is not resolved. 945 // If the result is an identifier, it is not resolved.
944 func (p *parser) tryIdentOrType(ellipsisOk bool) ast.Expr { 946 func (p *parser) tryIdentOrType(ellipsisOk bool) ast.Expr {
945 switch p.tok { 947 switch p.tok {
946 case token.IDENT: 948 case token.IDENT:
947 return p.parseTypeName() 949 return p.parseTypeName()
948 case token.LBRACK: 950 case token.LBRACK:
949 return p.parseArrayType(ellipsisOk) 951 return p.parseArrayType(ellipsisOk)
950 case token.STRUCT: 952 case token.STRUCT:
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 1392
1391 switch p.tok { 1393 switch p.tok {
1392 case token.ADD, token.SUB, token.NOT, token.XOR, token.AND: 1394 case token.ADD, token.SUB, token.NOT, token.XOR, token.AND:
1393 pos, op := p.pos, p.tok 1395 pos, op := p.pos, p.tok
1394 p.next() 1396 p.next()
1395 x := p.parseUnaryExpr(false) 1397 x := p.parseUnaryExpr(false)
1396 return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)} 1398 return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)}
1397 1399
1398 case token.ARROW: 1400 case token.ARROW:
1399 // channel type or receive expression 1401 // channel type or receive expression
1400 » » pos := p.pos 1402 » » arrow := p.pos
1401 p.next() 1403 p.next()
1402 1404
1403 // If the next token is token.CHAN we still don't know if it 1405 // If the next token is token.CHAN we still don't know if it
1404 // is a channel type or a receive operation - we only know 1406 // is a channel type or a receive operation - we only know
1405 // once we have found the end of the unary expression. There 1407 // once we have found the end of the unary expression. There
1406 // are two cases: 1408 // are two cases:
1407 // 1409 //
1408 // <- type => (<-type) must be channel type 1410 // <- type => (<-type) must be channel type
1409 // <- expr => <-(expr) is a receive from an expression 1411 // <- expr => <-(expr) is a receive from an expression
1410 // 1412 //
1411 // In the first case, the arrow must be re-associated with 1413 // In the first case, the arrow must be re-associated with
1412 // the channel type parsed already: 1414 // the channel type parsed already:
1413 // 1415 //
1414 // <- (chan type) => (<-chan type) 1416 // <- (chan type) => (<-chan type)
1415 // <- (chan<- type) => (<-chan (<-type)) 1417 // <- (chan<- type) => (<-chan (<-type))
1416 1418
1417 x := p.parseUnaryExpr(false) 1419 x := p.parseUnaryExpr(false)
1418 1420
1419 // determine which case we have 1421 // determine which case we have
1420 if typ, ok := x.(*ast.ChanType); ok { 1422 if typ, ok := x.(*ast.ChanType); ok {
1421 // (<-type) 1423 // (<-type)
1422 1424
1423 // re-associate position info and <- 1425 // re-associate position info and <-
1424 » » » arrow := true 1426 » » » dir := ast.SEND
1425 » » » for ok && arrow { 1427 » » » for ok && dir == ast.SEND {
1426 » » » » begin := typ.Begin
1427 if typ.Dir == ast.RECV { 1428 if typ.Dir == ast.RECV {
1428 // error: (<-type) is (<-(<-chan T)) 1429 // error: (<-type) is (<-(<-chan T))
1429 » » » » » p.errorExpected(begin, "'chan'") 1430 » » » » » p.errorExpected(typ.Arrow, "'chan'")
1430 } 1431 }
1431 » » » » arrow = typ.Dir == ast.SEND 1432 » » » » arrow, typ.Begin, typ.Arrow = typ.Arrow, arrow, arrow
1432 » » » » typ.Begin = pos 1433 » » » » dir, typ.Dir = typ.Dir, ast.RECV
1433 » » » » typ.Dir = ast.RECV
1434 typ, ok = typ.Value.(*ast.ChanType) 1434 typ, ok = typ.Value.(*ast.ChanType)
1435 » » » » // TODO(gri) ast.ChanType should store exact <- position 1435 » » » }
1436 » » » » pos = begin // estimate (we don't have the exact position of <- for send channels) 1436 » » » if dir == ast.SEND {
1437 » » » } 1437 » » » » p.errorExpected(arrow, "channel type")
1438 » » » if arrow {
1439 » » » » p.errorExpected(pos, "'chan'")
1440 } 1438 }
1441 1439
1442 return x 1440 return x
1443 } 1441 }
1444 1442
1445 // <-(expr) 1443 // <-(expr)
1446 » » return &ast.UnaryExpr{OpPos: pos, Op: token.ARROW, X: p.checkExp r(x)} 1444 » » return &ast.UnaryExpr{OpPos: arrow, Op: token.ARROW, X: p.checkE xpr(x)}
1447 1445
1448 case token.MUL: 1446 case token.MUL:
1449 // pointer type or unary "*" expression 1447 // pointer type or unary "*" expression
1450 pos := p.pos 1448 pos := p.pos
1451 p.next() 1449 p.next()
1452 x := p.parseUnaryExpr(false) 1450 x := p.parseUnaryExpr(false)
1453 return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)} 1451 return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)}
1454 } 1452 }
1455 1453
1456 return p.parsePrimaryExpr(lhs) 1454 return p.parsePrimaryExpr(lhs)
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after
2381 Doc: doc, 2379 Doc: doc,
2382 Package: pos, 2380 Package: pos,
2383 Name: ident, 2381 Name: ident,
2384 Decls: decls, 2382 Decls: decls,
2385 Scope: p.pkgScope, 2383 Scope: p.pkgScope,
2386 Imports: p.imports, 2384 Imports: p.imports,
2387 Unresolved: p.unresolved[0:i], 2385 Unresolved: p.unresolved[0:i],
2388 Comments: p.comments, 2386 Comments: p.comments,
2389 } 2387 }
2390 } 2388 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b