LEFT | RIGHT |
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 // A parser for Go source files. Input may be provided in a variety of | 5 // A parser for Go source files. Input may be provided in a variety of |
6 // forms (see the various Parse* functions); the output is an abstract | 6 // forms (see the various Parse* functions); the output is an abstract |
7 // syntax tree (AST) representing the Go source. The parser is invoked | 7 // syntax tree (AST) representing the Go source. The parser is invoked |
8 // through one of the Parse* functions. | 8 // through one of the Parse* functions. |
9 // | 9 // |
10 package parser | 10 package parser |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 | 132 |
133 | 133 |
134 func (p *parser) declare(decl interface{}, scope *ast.Scope, kind ast.ObjKind, i
dents ...*ast.Ident) { | 134 func (p *parser) declare(decl interface{}, scope *ast.Scope, kind ast.ObjKind, i
dents ...*ast.Ident) { |
135 for _, ident := range idents { | 135 for _, ident := range idents { |
136 assert(ident.Obj == nil, "identifier already declared or resolve
d") | 136 assert(ident.Obj == nil, "identifier already declared or resolve
d") |
137 if ident.Name != "_" { | 137 if ident.Name != "_" { |
138 obj := ast.NewObj(kind, ident.Name) | 138 obj := ast.NewObj(kind, ident.Name) |
139 // remember the corresponding declaration for redeclarat
ion | 139 // remember the corresponding declaration for redeclarat
ion |
140 // errors and global variable resolution/typechecking ph
ase | 140 // errors and global variable resolution/typechecking ph
ase |
141 obj.Decl = decl | 141 obj.Decl = decl |
142 » » » alt := scope.Insert(obj) | 142 » » » if alt := scope.Insert(obj); alt != nil && p.mode&Declar
ationErrors != 0 { |
143 » » » if alt != obj && p.mode&DeclarationErrors != 0 { | |
144 prevDecl := "" | 143 prevDecl := "" |
145 if pos := alt.Pos(); pos.IsValid() { | 144 if pos := alt.Pos(); pos.IsValid() { |
146 prevDecl = fmt.Sprintf("\n\tprevious dec
laration at %s", p.file.Position(pos)) | 145 prevDecl = fmt.Sprintf("\n\tprevious dec
laration at %s", p.file.Position(pos)) |
147 } | 146 } |
148 p.error(ident.Pos(), fmt.Sprintf("%s redeclared
in this block%s", ident.Name, prevDecl)) | 147 p.error(ident.Pos(), fmt.Sprintf("%s redeclared
in this block%s", ident.Name, prevDecl)) |
149 } | 148 } |
150 ident.Obj = obj | 149 ident.Obj = obj |
151 } | 150 } |
152 } | 151 } |
153 } | 152 } |
154 | 153 |
155 | 154 |
156 func (p *parser) shortVarDecl(idents []*ast.Ident) { | 155 func (p *parser) shortVarDecl(idents []*ast.Ident) { |
157 // Go spec: A short variable declaration may redeclare variables | 156 // Go spec: A short variable declaration may redeclare variables |
158 // provided they were originally declared in the same block with | 157 // provided they were originally declared in the same block with |
159 // the same type, and at least one of the non-blank variables is new. | 158 // the same type, and at least one of the non-blank variables is new. |
160 n := 0 // number of new variables | 159 n := 0 // number of new variables |
161 for _, ident := range idents { | 160 for _, ident := range idents { |
162 assert(ident.Obj == nil, "identifier already declared or resolve
d") | 161 assert(ident.Obj == nil, "identifier already declared or resolve
d") |
163 if ident.Name != "_" { | 162 if ident.Name != "_" { |
164 obj := ast.NewObj(ast.Var, ident.Name) | 163 obj := ast.NewObj(ast.Var, ident.Name) |
165 // short var declarations cannot have redeclaration erro
rs | 164 // short var declarations cannot have redeclaration erro
rs |
166 // and are not global => no need to remember the respect
ive | 165 // and are not global => no need to remember the respect
ive |
167 // declaration | 166 // declaration |
168 alt := p.topScope.Insert(obj) | 167 alt := p.topScope.Insert(obj) |
169 » » » if alt == obj { | 168 » » » if alt == nil { |
170 n++ // new declaration | 169 n++ // new declaration |
| 170 alt = obj |
171 } | 171 } |
172 ident.Obj = alt | 172 ident.Obj = alt |
173 } | 173 } |
174 } | 174 } |
175 if n == 0 && p.mode&DeclarationErrors != 0 { | 175 if n == 0 && p.mode&DeclarationErrors != 0 { |
176 p.error(idents[0].Pos(), "no new variables on left side of :=") | 176 p.error(idents[0].Pos(), "no new variables on left side of :=") |
177 } | 177 } |
178 } | 178 } |
179 | 179 |
180 | 180 |
(...skipping 955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 | 1136 |
1137 func (p *parser) parseElement(keyOk bool) ast.Expr { | 1137 func (p *parser) parseElement(keyOk bool) ast.Expr { |
1138 if p.trace { | 1138 if p.trace { |
1139 defer un(trace(p, "Element")) | 1139 defer un(trace(p, "Element")) |
1140 } | 1140 } |
1141 | 1141 |
1142 if p.tok == token.LBRACE { | 1142 if p.tok == token.LBRACE { |
1143 return p.parseLiteralValue(nil) | 1143 return p.parseLiteralValue(nil) |
1144 } | 1144 } |
1145 | 1145 |
1146 » x := p.parseRhs() | 1146 » x := p.parseExpr(keyOk) // don't resolve if map key |
1147 » if keyOk && p.tok == token.COLON { | 1147 » if keyOk { |
1148 » » colon := p.pos | 1148 » » if p.tok == token.COLON { |
1149 » » p.next() | 1149 » » » colon := p.pos |
1150 » » x = &ast.KeyValueExpr{x, colon, p.parseElement(false)} | 1150 » » » p.next() |
1151 » } | 1151 » » » return &ast.KeyValueExpr{x, colon, p.parseElement(false)
} |
| 1152 » » } |
| 1153 » » p.resolve(x) // not a map key |
| 1154 » } |
| 1155 |
1152 return x | 1156 return x |
1153 } | 1157 } |
1154 | 1158 |
1155 | 1159 |
1156 func (p *parser) parseElementList() (list []ast.Expr) { | 1160 func (p *parser) parseElementList() (list []ast.Expr) { |
1157 if p.trace { | 1161 if p.trace { |
1158 defer un(trace(p, "ElementList")) | 1162 defer un(trace(p, "ElementList")) |
1159 } | 1163 } |
1160 | 1164 |
1161 for p.tok != token.RBRACE && p.tok != token.EOF { | 1165 for p.tok != token.RBRACE && p.tok != token.EOF { |
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2232 // i <= index for current ident | 2236 // i <= index for current ident |
2233 assert(ident.Obj == unresolved, "object already resolved") | 2237 assert(ident.Obj == unresolved, "object already resolved") |
2234 ident.Obj = p.pkgScope.Lookup(ident.Name) // also removes unreso
lved sentinel | 2238 ident.Obj = p.pkgScope.Lookup(ident.Name) // also removes unreso
lved sentinel |
2235 if ident.Obj == nil { | 2239 if ident.Obj == nil { |
2236 p.unresolved[i] = ident | 2240 p.unresolved[i] = ident |
2237 i++ | 2241 i++ |
2238 } | 2242 } |
2239 } | 2243 } |
2240 | 2244 |
2241 // TODO(gri): store p.imports in AST | 2245 // TODO(gri): store p.imports in AST |
2242 » return &ast.File{doc, pos, ident, decls, p.pkgScope, p.unresolved[0:i],
p.comments} | 2246 » return &ast.File{doc, pos, ident, decls, p.pkgScope, p.imports, p.unreso
lved[0:i], p.comments} |
2243 } | 2247 } |
LEFT | RIGHT |