OLD | NEW |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 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 // This file implements typechecking of statements. | 5 // This file implements typechecking of statements. |
6 | 6 |
7 package types | 7 package types |
8 | 8 |
9 import ( | 9 import ( |
10 "go/ast" | 10 "go/ast" |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 check.stmt(s) | 219 check.stmt(s) |
220 } | 220 } |
221 } | 221 } |
222 | 222 |
223 func (check *checker) stmtList(list []ast.Stmt) { | 223 func (check *checker) stmtList(list []ast.Stmt) { |
224 for _, s := range list { | 224 for _, s := range list { |
225 check.stmt(s) | 225 check.stmt(s) |
226 } | 226 } |
227 } | 227 } |
228 | 228 |
| 229 func (check *checker) call(c ast.Expr) { |
| 230 call, _ := c.(*ast.CallExpr) |
| 231 if call == nil { |
| 232 // For go/defer, the parser makes sure that we have a function c
all, |
| 233 // so if we don't, the AST was created incorrectly elsewhere. |
| 234 // TODO(gri) consider removing the checks from the parser. |
| 235 check.invalidAST(c.Pos(), "%s is not a function call", c) |
| 236 return |
| 237 } |
| 238 var x operand |
| 239 check.rawExpr(&x, call, nil, -1, false) // don't check if value is used |
| 240 // TODO(gri) If a builtin is called, the builtin must be valid in statem
ent |
| 241 // context. However, the spec doesn't say that explicitly. |
| 242 } |
| 243 |
229 // stmt typechecks statement s. | 244 // stmt typechecks statement s. |
230 func (check *checker) stmt(s ast.Stmt) { | 245 func (check *checker) stmt(s ast.Stmt) { |
231 switch s := s.(type) { | 246 switch s := s.(type) { |
232 case *ast.BadStmt, *ast.EmptyStmt: | 247 case *ast.BadStmt, *ast.EmptyStmt: |
233 // ignore | 248 // ignore |
234 | 249 |
235 case *ast.DeclStmt: | 250 case *ast.DeclStmt: |
236 check.decl(s.Decl) | 251 check.decl(s.Decl) |
237 | 252 |
238 case *ast.LabeledStmt: | 253 case *ast.LabeledStmt: |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 return | 355 return |
341 } | 356 } |
342 var x, y operand | 357 var x, y operand |
343 check.expr(&x, s.Lhs[0], nil, -1) | 358 check.expr(&x, s.Lhs[0], nil, -1) |
344 check.expr(&y, s.Rhs[0], nil, -1) | 359 check.expr(&y, s.Rhs[0], nil, -1) |
345 check.binary(&x, &y, op, nil) | 360 check.binary(&x, &y, op, nil) |
346 check.assign1to1(s.Lhs[0], nil, &x, false, -1) | 361 check.assign1to1(s.Lhs[0], nil, &x, false, -1) |
347 } | 362 } |
348 | 363 |
349 case *ast.GoStmt: | 364 case *ast.GoStmt: |
350 » » unimplemented() | 365 » » check.call(s.Call) |
351 | 366 |
352 case *ast.DeferStmt: | 367 case *ast.DeferStmt: |
353 » » unimplemented() | 368 » » check.call(s.Call) |
354 | 369 |
355 case *ast.ReturnStmt: | 370 case *ast.ReturnStmt: |
356 sig := check.functypes[len(check.functypes)-1] | 371 sig := check.functypes[len(check.functypes)-1] |
357 if n := len(sig.Results); n > 0 { | 372 if n := len(sig.Results); n > 0 { |
358 // TODO(gri) should not have to compute lhs, named every
single time - clean this up | 373 // TODO(gri) should not have to compute lhs, named every
single time - clean this up |
359 lhs := make([]ast.Expr, n) | 374 lhs := make([]ast.Expr, n) |
360 named := false // if set, function has named results | 375 named := false // if set, function has named results |
361 for i, res := range sig.Results { | 376 for i, res := range sig.Results { |
362 if len(res.Name) > 0 { | 377 if len(res.Name) > 0 { |
363 // a blank (_) result parameter is a nam
ed result parameter! | 378 // a blank (_) result parameter is a nam
ed result parameter! |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 check.optionalStmt(s.Post) | 457 check.optionalStmt(s.Post) |
443 check.stmt(s.Body) | 458 check.stmt(s.Body) |
444 | 459 |
445 case *ast.RangeStmt: | 460 case *ast.RangeStmt: |
446 unimplemented() | 461 unimplemented() |
447 | 462 |
448 default: | 463 default: |
449 check.errorf(s.Pos(), "invalid statement") | 464 check.errorf(s.Pos(), "invalid statement") |
450 } | 465 } |
451 } | 466 } |
OLD | NEW |