librustc: Port the pretty printer annotation infrastructure to use traits instead of garbage collected functions.

This commit is contained in:
Patrick Walton 2013-08-29 15:24:33 -07:00
parent 33993535ef
commit 15ce791ff5
3 changed files with 143 additions and 98 deletions

View File

@ -439,15 +439,70 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
phase_6_link_output(sess, &trans, outputs);
}
pub fn pretty_print_input(sess: Session, cfg: ast::CrateConfig, input: &input,
ppm: PpMode) {
struct IdentifiedAnnotation {
contents: (),
}
fn ann_paren_for_expr(node: pprust::ann_node) {
impl pprust::pp_ann for IdentifiedAnnotation {
fn pre(&self, node: pprust::ann_node) {
match node {
pprust::node_expr(s, _) => pprust::popen(s),
_ => ()
pprust::node_expr(s, _) => pprust::popen(s),
_ => ()
}
}
fn post(&self, node: pprust::ann_node) {
match node {
pprust::node_item(s, item) => {
pp::space(s.s);
pprust::synth_comment(s, item.id.to_str());
}
pprust::node_block(s, ref blk) => {
pp::space(s.s);
pprust::synth_comment(s, ~"block " + blk.id.to_str());
}
pprust::node_expr(s, expr) => {
pp::space(s.s);
pprust::synth_comment(s, expr.id.to_str());
pprust::pclose(s);
}
pprust::node_pat(s, pat) => {
pp::space(s.s);
pprust::synth_comment(s, ~"pat " + pat.id.to_str());
}
}
}
}
struct TypedAnnotation {
analysis: CrateAnalysis,
}
impl pprust::pp_ann for TypedAnnotation {
fn pre(&self, node: pprust::ann_node) {
match node {
pprust::node_expr(s, _) => pprust::popen(s),
_ => ()
}
}
fn post(&self, node: pprust::ann_node) {
let tcx = self.analysis.ty_cx;
match node {
pprust::node_expr(s, expr) => {
pp::space(s.s);
pp::word(s.s, "as");
pp::space(s.s);
pp::word(s.s, ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr)));
pprust::pclose(s);
}
_ => ()
}
}
}
pub fn pretty_print_input(sess: Session,
cfg: ast::CrateConfig,
input: &input,
ppm: PpMode) {
fn ann_typed_post(tcx: ty::ctxt, node: pprust::ann_node) {
match node {
pprust::node_expr(s, expr) => {
@ -460,28 +515,6 @@ pub fn pretty_print_input(sess: Session, cfg: ast::CrateConfig, input: &input,
_ => ()
}
}
fn ann_identified_post(node: pprust::ann_node) {
match node {
pprust::node_item(s, item) => {
pp::space(s.s);
pprust::synth_comment(s, item.id.to_str());
}
pprust::node_block(s, ref blk) => {
pp::space(s.s);
pprust::synth_comment(
s, ~"block " + blk.id.to_str());
}
pprust::node_expr(s, expr) => {
pp::space(s.s);
pprust::synth_comment(s, expr.id.to_str());
pprust::pclose(s);
}
pprust::node_pat(s, pat) => {
pp::space(s.s);
pprust::synth_comment(s, ~"pat " + pat.id.to_str());
}
}
}
let crate = phase_1_parse_input(sess, cfg.clone(), input);
@ -494,28 +527,30 @@ pub fn pretty_print_input(sess: Session, cfg: ast::CrateConfig, input: &input,
let annotation = match ppm {
PpmIdentified | PpmExpandedIdentified => {
pprust::pp_ann {
pre: ann_paren_for_expr,
post: ann_identified_post
}
@IdentifiedAnnotation {
contents: (),
} as @pprust::pp_ann
}
PpmTyped => {
let analysis = phase_3_run_analysis_passes(sess, crate);
pprust::pp_ann {
pre: ann_paren_for_expr,
post: |a| ann_typed_post(analysis.ty_cx, a)
}
@TypedAnnotation {
analysis: analysis
} as @pprust::pp_ann
}
_ => pprust::no_ann()
_ => @pprust::no_ann::new() as @pprust::pp_ann,
};
let src = sess.codemap.get_filemap(source_name(input)).src;
do io::with_str_reader(src) |rdr| {
pprust::print_crate(sess.codemap, token::get_ident_interner(),
sess.span_diagnostic, crate,
pprust::print_crate(sess.codemap,
token::get_ident_interner(),
sess.span_diagnostic,
crate,
source_name(input),
rdr, io::stdout(),
annotation, is_expanded);
rdr,
io::stdout(),
annotation,
is_expanded);
}
}

View File

@ -87,6 +87,42 @@ struct LoopScope<'self> {
break_bits: ~[uint]
}
impl<O:DataFlowOperator> pprust::pp_ann for DataFlowContext<O> {
fn pre(&self, node: pprust::ann_node) {
let (ps, id) = match node {
pprust::node_expr(ps, expr) => (ps, expr.id),
pprust::node_block(ps, blk) => (ps, blk.id),
pprust::node_item(ps, _) => (ps, 0),
pprust::node_pat(ps, pat) => (ps, pat.id)
};
if self.nodeid_to_bitset.contains_key(&id) {
let (start, end) = self.compute_id_range_frozen(id);
let on_entry = self.on_entry.slice(start, end);
let entry_str = bits_to_str(on_entry);
let gens = self.gens.slice(start, end);
let gens_str = if gens.iter().any(|&u| u != 0) {
fmt!(" gen: %s", bits_to_str(gens))
} else {
~""
};
let kills = self.kills.slice(start, end);
let kills_str = if kills.iter().any(|&u| u != 0) {
fmt!(" kill: %s", bits_to_str(kills))
} else {
~""
};
let comment_str = fmt!("id %d: %s%s%s",
id, entry_str, gens_str, kills_str);
pprust::synth_comment(ps, comment_str);
pp::space(ps.s);
}
}
}
impl<O:DataFlowOperator> DataFlowContext<O> {
pub fn new(tcx: ty::ctxt,
method_map: typeck::method_map,
@ -319,46 +355,9 @@ impl<O:DataFlowOperator+Clone+'static> DataFlowContext<O> {
}
fn pretty_print_to(@self, wr: @io::Writer, blk: &ast::Block) {
let pre: @fn(pprust::ann_node) = |node| {
let (ps, id) = match node {
pprust::node_expr(ps, expr) => (ps, expr.id),
pprust::node_block(ps, blk) => (ps, blk.id),
pprust::node_item(ps, _) => (ps, 0),
pprust::node_pat(ps, pat) => (ps, pat.id)
};
if self.nodeid_to_bitset.contains_key(&id) {
let (start, end) = self.compute_id_range_frozen(id);
let on_entry = self.on_entry.slice(start, end);
let entry_str = bits_to_str(on_entry);
let gens = self.gens.slice(start, end);
let gens_str = if gens.iter().any(|&u| u != 0) {
fmt!(" gen: %s", bits_to_str(gens))
} else {
~""
};
let kills = self.kills.slice(start, end);
let kills_str = if kills.iter().any(|&u| u != 0) {
fmt!(" kill: %s", bits_to_str(kills))
} else {
~""
};
let comment_str = fmt!("id %d: %s%s%s",
id, entry_str, gens_str, kills_str);
pprust::synth_comment(ps, comment_str);
pp::space(ps.s);
}
};
let post: @fn(pprust::ann_node) = |_| {
};
let ps = pprust::rust_printer_annotated(
wr, self.tcx.sess.intr(),
pprust::pp_ann {pre:pre, post:post});
let ps = pprust::rust_printer_annotated(wr,
self.tcx.sess.intr(),
self as @pprust::pp_ann);
pprust::cbox(ps, pprust::indent_unit);
pprust::ibox(ps, 0u);
pprust::print_block(ps, blk);

View File

@ -37,16 +37,26 @@ pub enum ann_node<'self> {
node_expr(@ps, &'self ast::Expr),
node_pat(@ps, &'self ast::Pat),
}
pub struct pp_ann {
pre: @fn(ann_node),
post: @fn(ann_node)
pub trait pp_ann {
fn pre(&self, _node: ann_node) {}
fn post(&self, _node: ann_node) {}
}
pub fn no_ann() -> pp_ann {
fn ignore(_node: ann_node) { }
return pp_ann {pre: ignore, post: ignore};
pub struct no_ann {
contents: (),
}
impl no_ann {
pub fn new() -> no_ann {
no_ann {
contents: (),
}
}
}
impl pp_ann for no_ann {}
pub struct CurrentCommentAndLiteral {
cur_cmnt: uint,
cur_lit: uint,
@ -60,7 +70,7 @@ pub struct ps {
literals: Option<~[comments::lit]>,
cur_cmnt_and_lit: @mut CurrentCommentAndLiteral,
boxes: @mut ~[pp::breaks],
ann: pp_ann
ann: @pp_ann
}
pub fn ibox(s: @ps, u: uint) {
@ -74,12 +84,13 @@ pub fn end(s: @ps) {
}
pub fn rust_printer(writer: @io::Writer, intr: @ident_interner) -> @ps {
return rust_printer_annotated(writer, intr, no_ann());
return rust_printer_annotated(writer, intr, @no_ann::new() as @pp_ann);
}
pub fn rust_printer_annotated(writer: @io::Writer,
intr: @ident_interner,
ann: pp_ann) -> @ps {
ann: @pp_ann)
-> @ps {
return @ps {
s: pp::mk_printer(writer, default_columns),
cm: None::<@CodeMap>,
@ -109,7 +120,7 @@ pub fn print_crate(cm: @CodeMap,
filename: @str,
input: @io::Reader,
out: @io::Writer,
ann: pp_ann,
ann: @pp_ann,
is_expanded: bool) {
let (cmnts, lits) = comments::gather_comments_and_literals(
span_diagnostic,
@ -484,7 +495,7 @@ pub fn print_item(s: @ps, item: &ast::item) {
maybe_print_comment(s, item.span.lo);
print_outer_attributes(s, item.attrs);
let ann_node = node_item(s, item);
(s.ann.pre)(ann_node);
s.ann.pre(ann_node);
match item.node {
ast::item_static(ref ty, m, expr) => {
head(s, visibility_qualified(item.vis, "static"));
@ -635,7 +646,7 @@ pub fn print_item(s: @ps, item: &ast::item) {
end(s);
}
}
(s.ann.post)(ann_node);
s.ann.post(ann_node);
}
fn print_trait_ref(s: @ps, t: &ast::trait_ref) {
@ -958,7 +969,7 @@ pub fn print_possibly_embedded_block_(s: @ps,
}
maybe_print_comment(s, blk.span.lo);
let ann_node = node_block(s, blk);
(s.ann.pre)(ann_node);
s.ann.pre(ann_node);
match embedded {
block_block_fn => end(s),
block_normal => bopen(s)
@ -979,7 +990,7 @@ pub fn print_possibly_embedded_block_(s: @ps,
_ => ()
}
bclose_maybe_open(s, blk.span, indented, close_box);
(s.ann.post)(ann_node);
s.ann.post(ann_node);
}
pub fn print_if(s: @ps, test: &ast::Expr, blk: &ast::Block,
@ -1121,7 +1132,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
maybe_print_comment(s, expr.span.lo);
ibox(s, indent_unit);
let ann_node = node_expr(s, expr);
(s.ann.pre)(ann_node);
s.ann.pre(ann_node);
match expr.node {
ast::ExprVstore(e, v) => {
print_expr_vstore(s, v);
@ -1456,7 +1467,7 @@ pub fn print_expr(s: @ps, expr: &ast::Expr) {
pclose(s);
}
}
(s.ann.post)(ann_node);
s.ann.post(ann_node);
end(s);
}
@ -1578,7 +1589,7 @@ pub fn print_bounded_path(s: @ps, path: &ast::Path,
pub fn print_pat(s: @ps, pat: &ast::Pat) {
maybe_print_comment(s, pat.span.lo);
let ann_node = node_pat(s, pat);
(s.ann.pre)(ann_node);
s.ann.pre(ann_node);
/* Pat isn't normalized, but the beauty of it
is that it doesn't matter */
match pat.node {
@ -1678,7 +1689,7 @@ pub fn print_pat(s: @ps, pat: &ast::Pat) {
word(s.s, "]");
}
}
(s.ann.post)(ann_node);
s.ann.post(ann_node);
}
pub fn explicit_self_to_str(explicit_self: &ast::explicit_self_, intr: @ident_interner) -> ~str {