2012-12-03 16:48:01 -08:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2012-07-16 17:27:04 -07:00
|
|
|
/// Correctness for protocols
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
This section of code makes sure the protocol is likely to generate
|
|
|
|
correct code. The correctness criteria include:
|
|
|
|
|
|
|
|
* No protocols transition to states that don't exist.
|
|
|
|
* Messages step to states with the right number of type parameters.
|
|
|
|
|
|
|
|
In addition, this serves as a lint pass. Lint warns for the following
|
|
|
|
things.
|
|
|
|
|
|
|
|
* States with no messages, it's better to step to !.
|
|
|
|
|
|
|
|
It would also be nice to warn about unreachable states, but the
|
|
|
|
visitor infrastructure for protocols doesn't currently work well for
|
|
|
|
that.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2013-01-08 19:37:25 -08:00
|
|
|
use core::prelude::*;
|
|
|
|
|
2012-12-23 17:41:37 -05:00
|
|
|
use ast;
|
2013-01-08 19:37:25 -08:00
|
|
|
use codemap::span;
|
2012-09-04 11:37:29 -07:00
|
|
|
use ext::base::ext_ctxt;
|
2012-12-13 13:05:22 -08:00
|
|
|
use ext::pipes::proto::{state, protocol, next_state};
|
2012-12-23 17:41:37 -05:00
|
|
|
use ext::pipes::proto;
|
2012-07-16 17:27:04 -07:00
|
|
|
|
2013-02-14 21:17:26 -08:00
|
|
|
pub impl proto::visitor<(), (), ()> for ext_ctxt {
|
2013-02-17 02:51:55 -05:00
|
|
|
fn visit_proto(&self, _proto: protocol,
|
2012-07-16 17:27:04 -07:00
|
|
|
_states: &[()]) { }
|
|
|
|
|
2013-02-17 02:51:55 -05:00
|
|
|
fn visit_state(&self, state: state, _m: &[()]) {
|
2012-07-16 17:27:04 -07:00
|
|
|
if state.messages.len() == 0 {
|
|
|
|
self.span_warn(
|
2012-07-24 16:58:48 -07:00
|
|
|
state.span, // use a real span!
|
2012-08-22 17:24:52 -07:00
|
|
|
fmt!("state %s contains no messages, \
|
2012-07-16 17:27:04 -07:00
|
|
|
consider stepping to a terminal state instead",
|
2012-08-22 17:24:52 -07:00
|
|
|
state.name))
|
2012-07-16 17:27:04 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-17 02:51:55 -05:00
|
|
|
fn visit_message(&self, name: ~str, _span: span, _tys: &[@ast::Ty],
|
2013-01-17 08:55:28 -08:00
|
|
|
this: state, next: Option<next_state>) {
|
2012-08-06 12:34:08 -07:00
|
|
|
match next {
|
2013-02-17 10:59:09 -08:00
|
|
|
Some(ref next_state) => {
|
2012-07-17 12:51:24 -07:00
|
|
|
let proto = this.proto;
|
2013-02-17 10:59:09 -08:00
|
|
|
if !proto.has_state(next_state.state) {
|
2012-07-17 12:51:24 -07:00
|
|
|
// This should be a span fatal, but then we need to
|
|
|
|
// track span information.
|
2012-07-16 17:27:04 -07:00
|
|
|
self.span_err(
|
2013-02-17 10:59:09 -08:00
|
|
|
proto.get_state(next_state.state).span,
|
2012-08-22 17:24:52 -07:00
|
|
|
fmt!("message %s steps to undefined state, %s",
|
2013-02-17 10:59:09 -08:00
|
|
|
name, next_state.state));
|
2012-07-17 12:51:24 -07:00
|
|
|
}
|
|
|
|
else {
|
2013-02-17 10:59:09 -08:00
|
|
|
let next = proto.get_state(next_state.state);
|
2012-07-17 12:51:24 -07:00
|
|
|
|
2013-02-17 10:59:09 -08:00
|
|
|
if next.ty_params.len() != next_state.tys.len() {
|
2012-07-17 12:51:24 -07:00
|
|
|
self.span_err(
|
2012-07-24 16:58:48 -07:00
|
|
|
next.span, // use a real span
|
2012-08-22 17:24:52 -07:00
|
|
|
fmt!("message %s target (%s) \
|
2012-07-17 12:51:24 -07:00
|
|
|
needs %u type parameters, but got %u",
|
2012-07-18 16:18:02 -07:00
|
|
|
name, next.name,
|
2012-07-17 12:51:24 -07:00
|
|
|
next.ty_params.len(),
|
2013-02-17 10:59:09 -08:00
|
|
|
next_state.tys.len()));
|
2012-07-17 12:51:24 -07:00
|
|
|
}
|
2012-07-16 17:27:04 -07:00
|
|
|
}
|
|
|
|
}
|
2012-08-20 12:23:37 -07:00
|
|
|
None => ()
|
2012-07-16 17:27:04 -07:00
|
|
|
}
|
|
|
|
}
|
2012-10-15 14:56:42 -07:00
|
|
|
}
|
2013-01-29 13:54:06 -08:00
|
|
|
|