1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use driver::session::Session;
12
13 use syntax::ast;
14 use syntax::codemap::Span;
15 use syntax::visit::Visitor;
16 use syntax::visit;
17
18 #[deriving(Clone, Eq)]
19 enum Context {
20 Normal, Loop, Closure
21 }
22
23 struct CheckLoopVisitor<'a> {
24 sess: &'a Session,
25 }
26
27 pub fn check_crate(sess: &Session, krate: &ast::Crate) {
28 visit::walk_crate(&mut CheckLoopVisitor { sess: sess }, krate, Normal)
29 }
30
31 impl<'a> Visitor<Context> for CheckLoopVisitor<'a> {
32 fn visit_item(&mut self, i: &ast::Item, _cx: Context) {
33 visit::walk_item(self, i, Normal);
34 }
35
36 fn visit_expr(&mut self, e: &ast::Expr, cx:Context) {
37 match e.node {
38 ast::ExprWhile(e, b) => {
39 self.visit_expr(e, cx);
40 self.visit_block(b, Loop);
41 }
42 ast::ExprLoop(b, _) => {
43 self.visit_block(b, Loop);
44 }
45 ast::ExprFnBlock(_, b) | ast::ExprProc(_, b) => {
46 self.visit_block(b, Closure);
47 }
48 ast::ExprBreak(_) => self.require_loop("break", cx, e.span),
49 ast::ExprAgain(_) => self.require_loop("continue", cx, e.span),
50 _ => visit::walk_expr(self, e, cx)
51 }
52 }
53 }
54
55 impl<'a> CheckLoopVisitor<'a> {
56 fn require_loop(&self, name: &str, cx: Context, span: Span) {
57 match cx {
58 Loop => {}
59 Closure => {
60 self.sess.span_err(span, format!("`{}` inside of a closure", name));
61 }
62 Normal => {
63 self.sess.span_err(span, format!("`{}` outside of loop", name));
64 }
65 }
66 }
67 }
librustc/middle/check_loop.rs:22:1-22:1 -struct- definition:
struct CheckLoopVisitor<'a> {
sess: &'a Session,
}
references:- 327: pub fn check_crate(sess: &Session, krate: &ast::Crate) {
28: visit::walk_crate(&mut CheckLoopVisitor { sess: sess }, krate, Normal)
29: }
31: impl<'a> Visitor<Context> for CheckLoopVisitor<'a> {
32: fn visit_item(&mut self, i: &ast::Item, _cx: Context) {
--
55: impl<'a> CheckLoopVisitor<'a> {
56: fn require_loop(&self, name: &str, cx: Context, span: Span) {
librustc/middle/check_loop.rs:18:23-18:23 -enum- definition:
enum Context {
Normal, Loop, Closure
}
references:- 919: enum Context {
--
36: fn visit_expr(&mut self, e: &ast::Expr, cx:Context) {
37: match e.node {
--
55: impl<'a> CheckLoopVisitor<'a> {
56: fn require_loop(&self, name: &str, cx: Context, span: Span) {
57: match cx {