// Copyright 2015 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.

//! An experimental pass that scources for `#[rustc_mir]` attributes,
//! builds the resulting MIR, and dumps it out into a file for inspection.
//!
//! The attribute formats that are currently accepted are:
//!
//! - `#[rustc_mir(graphviz="file.gv")]`
//! - `#[rustc_mir(pretty="file.mir")]`

extern crate syntax;
extern crate rustc;
extern crate rustc_front;

use build;
use graphviz;
use pretty;
use transform::*;
use rustc::dep_graph::DepNode;
use rustc::mir::repr::Mir;
use hair::cx::Cx;
use std::fs::File;

use self::rustc::middle::infer;
use self::rustc::middle::region::CodeExtentData;
use self::rustc::middle::ty::{self, Ty};
use self::rustc::util::common::ErrorReported;
use self::rustc::util::nodemap::NodeMap;
use self::rustc_front::hir;
use self::rustc_front::intravisit::{self, Visitor};
use self::syntax::ast;
use self::syntax::attr::AttrMetaMethods;
use self::syntax::codemap::Span;

pub type MirMap<'tcx> = NodeMap<Mir<'tcx>>;

pub fn build_mir_for_crate<'tcx>(tcx: &ty::ctxt<'tcx>) -> MirMap<'tcx> {
    let mut map = NodeMap();
    {
        let mut dump = OuterDump {
            tcx: tcx,
            map: &mut map,
        };
        tcx.visit_all_items_in_krate(DepNode::MirMapConstruction, &mut dump);
    }
    map
}

///////////////////////////////////////////////////////////////////////////
// OuterDump -- walks a crate, looking for fn items and methods to build MIR from

struct OuterDump<'a, 'tcx: 'a> {
    tcx: &'a ty::ctxt<'tcx>,
    map: &'a mut MirMap<'tcx>,
}

impl<'a, 'tcx> OuterDump<'a, 'tcx> {
    fn visit_mir<OP>(&mut self, attributes: &'a [ast::Attribute], mut walk_op: OP)
        where OP: for<'m> FnMut(&mut InnerDump<'a, 'm, 'tcx>)
    {
        let mut closure_dump = InnerDump {
            tcx: self.tcx,
            attr: None,
            map: &mut *self.map,
        };
        for attr in attributes {
            if attr.check_name("rustc_mir") {
                closure_dump.attr = Some(attr);
            }
        }
        walk_op(&mut closure_dump);
    }
}


impl<'a, 'tcx> Visitor<'tcx> for OuterDump<'a, 'tcx> {
    fn visit_item(&mut self, item: &'tcx hir::Item) {
        self.visit_mir(&item.attrs, |c| intravisit::walk_item(c, item));
        intravisit::walk_item(self, item);
    }

    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
        match trait_item.node {
            hir::MethodTraitItem(_, Some(_)) => {
                self.visit_mir(&trait_item.attrs, |c| intravisit::walk_trait_item(c, trait_item));
            }
            hir::MethodTraitItem(_, None) |
            hir::ConstTraitItem(..) |
            hir::TypeTraitItem(..) => {}
        }
        intravisit::walk_trait_item(self, trait_item);
    }

    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
        match impl_item.node {
            hir::ImplItemKind::Method(..) => {
                self.visit_mir(&impl_item.attrs, |c| intravisit::walk_impl_item(c, impl_item));
            }
            hir::ImplItemKind::Const(..) | hir::ImplItemKind::Type(..) => {}
        }
        intravisit::walk_impl_item(self, impl_item);
    }
}

///////////////////////////////////////////////////////////////////////////
// InnerDump -- dumps MIR for a single fn and its contained closures

struct InnerDump<'a, 'm, 'tcx: 'a + 'm> {
    tcx: &'a ty::ctxt<'tcx>,
    map: &'m mut MirMap<'tcx>,
    attr: Option<&'a ast::Attribute>,
}

impl<'a, 'm, 'tcx> Visitor<'tcx> for InnerDump<'a,'m,'tcx> {
    fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem) {
        // ignore methods; the outer dump will call us for them independently
    }

    fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) {
        // ignore methods; the outer dump will call us for them independently
    }

    fn visit_fn(&mut self,
                fk: intravisit::FnKind<'tcx>,
                decl: &'tcx hir::FnDecl,
                body: &'tcx hir::Block,
                span: Span,
                id: ast::NodeId) {
        let (prefix, implicit_arg_tys) = match fk {
            intravisit::FnKind::Closure =>
                (format!("{}-", id), vec![closure_self_ty(&self.tcx, id, body.id)]),
            _ =>
                (format!(""), vec![]),
        };

        let param_env = ty::ParameterEnvironment::for_item(self.tcx, id);

        let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), true);

        match build_mir(Cx::new(&infcx), implicit_arg_tys, id, span, decl, body) {
            Ok(mut mir) => {
                simplify_cfg::SimplifyCfg::new().run_on_mir(&mut mir);

                let meta_item_list = self.attr
                                         .iter()
                                         .flat_map(|a| a.meta_item_list())
                                         .flat_map(|l| l.iter());
                for item in meta_item_list {
                    if item.check_name("graphviz") || item.check_name("pretty") {
                        match item.value_str() {
                            Some(s) => {
                                let filename = format!("{}{}", prefix, s);
                                let result = File::create(&filename).and_then(|ref mut output| {
                                    if item.check_name("graphviz") {
                                        graphviz::write_mir_graphviz(&mir, output)
                                    } else {
                                        pretty::write_mir_pretty(&mir, output)
                                    }
                                });

                                if let Err(e) = result {
                                    self.tcx.sess.span_fatal(
                                        item.span,
                                        &format!("Error writing MIR {} results to `{}`: {}",
                                                 item.name(), filename, e));
                                }
                            }
                            None => {
                                self.tcx.sess.span_err(
                                    item.span,
                                    &format!("{} attribute requires a path", item.name()));
                            }
                        }
                    }
                }

                let previous = self.map.insert(id, mir);
                assert!(previous.is_none());
            }
            Err(ErrorReported) => {}
        }

        intravisit::walk_fn(self, fk, decl, body, span);
    }
}

fn build_mir<'a,'tcx:'a>(cx: Cx<'a,'tcx>,
                         implicit_arg_tys: Vec<Ty<'tcx>>,
                         fn_id: ast::NodeId,
                         span: Span,
                         decl: &'tcx hir::FnDecl,
                         body: &'tcx hir::Block)
                         -> Result<Mir<'tcx>, ErrorReported> {
    // fetch the fully liberated fn signature (that is, all bound
    // types/lifetimes replaced)
    let fn_sig = match cx.tcx().tables.borrow().liberated_fn_sigs.get(&fn_id) {
        Some(f) => f.clone(),
        None => {
            cx.tcx().sess.span_bug(span,
                                   &format!("no liberated fn sig for {:?}", fn_id));
        }
    };

    let arguments =
        decl.inputs
            .iter()
            .enumerate()
            .map(|(index, arg)| {
                (fn_sig.inputs[index], &*arg.pat)
            })
            .collect();

    let parameter_scope =
        cx.tcx().region_maps.lookup_code_extent(
            CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.id });
    Ok(build::construct(cx,
                        span,
                        implicit_arg_tys,
                        arguments,
                        parameter_scope,
                        fn_sig.output,
                        body))
}

fn closure_self_ty<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
                             closure_expr_id: ast::NodeId,
                             body_id: ast::NodeId)
                             -> Ty<'tcx> {
    let closure_ty = tcx.node_id_to_type(closure_expr_id);

    // We're just hard-coding the idea that the signature will be
    // &self or &mut self and hence will have a bound region with
    // number 0, hokey.
    let region = ty::Region::ReFree(ty::FreeRegion {
        scope: tcx.region_maps.item_extent(body_id),
        bound_region: ty::BoundRegion::BrAnon(0),
    });
    let region = tcx.mk_region(region);

    match tcx.closure_kind(tcx.map.local_def_id(closure_expr_id)) {
        ty::ClosureKind::FnClosureKind =>
            tcx.mk_ref(region,
                       ty::TypeAndMut { ty: closure_ty,
                                        mutbl: hir::MutImmutable }),
        ty::ClosureKind::FnMutClosureKind =>
            tcx.mk_ref(region,
                       ty::TypeAndMut { ty: closure_ty,
                                        mutbl: hir::MutMutable }),
        ty::ClosureKind::FnOnceClosureKind =>
            closure_ty
    }
}
