<commit_before>extern crate piston;
extern crate graphics;
extern crate sdl2_window;
extern crate gfx_device_gl;
extern crate gfx_graphics;

use std::path::Path;
use std::rc::Rc;
use std::cell::RefCell;
use piston::window::{ Window, WindowSettings, Size, OpenGLWindow };
use gfx_graphics::gfx::traits::*;
use gfx_graphics::{ Gfx2d, Texture, gfx, TextureSettings };
use sdl2_window::{ Sdl2Window, OpenGL };

fn main() {
    use graphics::draw_state::BlendPreset;

    println!("Press A to change blending");

    let mut window = Sdl2Window::new(
        OpenGL::_3_2,
        WindowSettings::new(
            "gfx_graphics: draw_state_test".to_string(),
            Size { width: 300, height: 300 }
        )
        .exit_on_esc(true)
    );

    let (mut device, mut factory) = gfx_device_gl::create(|s| window.get_proc_address(s));
    let size = window.size();
    let frame = gfx::Frame::new(size.width as u16, size.height as u16);
    let mut renderer = factory.create_renderer();

    let rust_logo = Texture::from_path(&mut factory,
                                       &Path::new("./assets/rust.png"),
                                       &TextureSettings::new()).unwrap();
    let mut g2d = Gfx2d::new(&mut device, &mut factory);
    let mut blend = BlendPreset::Alpha;
    let window = Rc::new(RefCell::new(window));
    for e in piston::events(window) {
        use piston::event::*;
        use piston::input::*;

        if let Some(_) = e.render_args() {
            use graphics::*;

            g2d.draw(&mut renderer, &frame, |c, g| {
                let transform = c.transform.trans(100.0, 100.0);

                clear([0.8, 0.8, 0.8, 1.0], g);
                Rectangle::new([1.0, 0.0, 0.0, 1.0])
                    .draw([0.0, 0.0, 100.0, 100.0],
                          &c.draw_state,
                          c.transform,
                          g);

                let draw_state = c.draw_state.blend(blend);
                Rectangle::new([0.5, 1.0, 0.0, 0.3])
                    .draw([50.0, 50.0, 100.0, 100.0],
                          &draw_state,
                          c.transform,
                          g);

                let clipped = c.draw_state.scissor(100, 100, 100, 100);
                Image::new().draw(&rust_logo, &clipped, transform, g);
            });

            device.submit(renderer.as_buffer());
            renderer.reset();
        }

        if let Some(Button::Keyboard(Key::A)) = e.press_args() {
            blend = match blend {
                BlendPreset::Alpha => BlendPreset::Add,
                BlendPreset::Add => BlendPreset::Multiply,
                BlendPreset::Multiply => BlendPreset::Invert,
                BlendPreset::Invert => BlendPreset::Alpha,
            };
            println!("Changed blending to {:?}", blend);
        }

        if let Some(_) = e.after_render_args() {
            device.after_frame();
            factory.cleanup();
        }
    }
}
<commit_msg>Fixed scissor clipping<commit_after>extern crate piston;
extern crate graphics;
extern crate sdl2_window;
extern crate gfx_device_gl;
extern crate gfx_graphics;

use std::path::Path;
use std::rc::Rc;
use std::cell::RefCell;
use piston::window::{ Window, WindowSettings, Size, OpenGLWindow };
use gfx_graphics::gfx::traits::*;
use gfx_graphics::{ Gfx2d, Texture, gfx, TextureSettings };
use sdl2_window::{ Sdl2Window, OpenGL };

fn main() {
    use graphics::draw_state::BlendPreset;

    println!("Press A to change blending");

    let mut window = Sdl2Window::new(
        OpenGL::_3_2,
        WindowSettings::new(
            "gfx_graphics: draw_state_test".to_string(),
            Size { width: 600, height: 600 }
        )
        .exit_on_esc(true)
    );

    let (mut device, mut factory) = gfx_device_gl::create(|s| window.get_proc_address(s));
    let size = window.size();
    let frame = gfx::Frame::new(size.width as u16, size.height as u16);
    let mut renderer = factory.create_renderer();

    let rust_logo = Texture::from_path(&mut factory,
                                       &Path::new("./assets/rust.png"),
                                       &TextureSettings::new()).unwrap();
    let mut g2d = Gfx2d::new(&mut device, &mut factory);
    let mut blend = BlendPreset::Alpha;
    let window = Rc::new(RefCell::new(window));
    for e in piston::events(window) {
        use piston::event::*;
        use piston::input::*;

        if let Some(args) = e.render_args() {
            use graphics::*;

            g2d.draw(&mut renderer, &frame, |c, g| {
                clear([0.8, 0.8, 0.8, 1.0], g);
                Rectangle::new([1.0, 0.0, 0.0, 1.0])
                    .draw([0.0, 0.0, 100.0, 100.0],
                          &c.draw_state,
                          c.transform,
                          g);

                let draw_state = c.draw_state.blend(blend);
                Rectangle::new([0.5, 1.0, 0.0, 0.3])
                    .draw([50.0, 50.0, 100.0, 100.0],
                          &draw_state,
                          c.transform,
                          g);

                let transform = c.transform.trans(100.0, 100.0);
                // Compute clip rectangle from upper left corner.
                let (clip_x, clip_y, clip_w, clip_h) = (100, 100, 100, 100);
                let (clip_x, clip_y, clip_w, clip_h) =
                    (clip_x, args.height as u16 - clip_y - clip_h, clip_w, clip_h);
                let clipped = c.draw_state.scissor(clip_x, clip_y, clip_w, clip_h);
                Image::new().draw(&rust_logo, &clipped, transform, g);

                let transform = c.transform.trans(200.0, 200.0);
                Ellipse::new([1.0, 0.0, 0.0, 1.0])
                    .draw([0.0, 0.0, 50.0, 50.0],
                          clip_draw_state(),
                          transform,
                          g);
                Image::new().draw(&rust_logo, inside_draw_state(), transform, g);
            });

            device.submit(renderer.as_buffer());
            renderer.reset();
        }

        if let Some(Button::Keyboard(Key::A)) = e.press_args() {
            blend = match blend {
                BlendPreset::Alpha => BlendPreset::Add,
                BlendPreset::Add => BlendPreset::Multiply,
                BlendPreset::Multiply => BlendPreset::Invert,
                BlendPreset::Invert => BlendPreset::Alpha,
            };
            println!("Changed blending to {:?}", blend);
        }

        if let Some(_) = e.after_render_args() {
            device.after_frame();
            factory.cleanup();
        }
    }
}
<|endoftext|>


<commit_before>use na::Identity;
use utils::data::uid_remap::{UidRemap, FastKey};
use geometry::bounding_volume::BoundingVolume;
use geometry::ray::{Ray, RayCast};
use geometry::point::PointQuery;
use broad_phase::BroadPhase;
use math::{Point, Vector};

/// A broad phase testing explicitly all bounding volume pairs.
///
/// Use this for debugging purposes only.
pub struct BruteForceBroadPhase<BV, T> {
    proxies:   UidRemap<(BV, T)>,
    to_remove: Vec<usize>,
    to_add:    Vec<(usize, BV, T)>,
    to_update: Vec<(FastKey, BV)>
}

impl<BV, T> BruteForceBroadPhase<BV, T> {
    /// Creates a new brute-force broad phase.
    pub fn new() -> BruteForceBroadPhase<BV, T> {
        BruteForceBroadPhase {
            proxies:   UidRemap::new(false),
            to_remove: Vec::new(),
            to_add:    Vec::new(),
            to_update: Vec::new()
        }
    }
}

impl<P: Point, BV, T> BroadPhase<P, BV, T> for BruteForceBroadPhase<BV, T> where
    BV: 'static + BoundingVolume<<P::Vect as Vector>::Scalar> +
        RayCast<P, Identity> + PointQuery<P, Identity> + Clone {
    fn deferred_add(&mut self, uid: usize, bv: BV, data: T) {
        // XXX: should not be inserted now!
        let (key, _) = self.proxies.insert(uid, (bv.clone(), data));

        self.to_update.push((key, bv))
    }

    fn deferred_remove(&mut self, uid: usize) {
        if self.proxies.get_fast_key(uid).is_some() {
            self.to_remove.push(uid);
        }
    }

    fn deferred_set_bounding_volume(&mut self, uid: usize, bv: BV) {
        if let Some(key) = self.proxies.get_fast_key(uid) {
            self.to_update.push((key, bv));
        }
    }

    fn deferred_recompute_all_proximities(&mut self) {
        for proxy in self.proxies.iter() {
            self.to_update.push((proxy.0, (proxy.1).0.clone()));
        }
    }

    fn update(&mut self, allow_proximity: &mut FnMut(&T, &T) -> bool, proximity_handler: &mut FnMut(&T, &T, bool)) {
        for (uid, bv, data) in self.to_add.drain(..) {
            let key = self.proxies.insert(uid, (bv.clone(), data));
            self.to_update.push((key.0, bv))
        }

        for rm in self.to_remove.drain(..) {
            let _ = self.proxies.remove(rm);
        }

        for new_proxy in self.to_update.iter() {
            if let Some(proxy) = self.proxies.get_fast_mut(&new_proxy.0) {
                proxy.0 = new_proxy.1.clone();
            }
        }

        for proxy1_key in self.to_update.drain(..) {
            if let Some(proxy1) = self.proxies.get_fast(&proxy1_key.0) {
                for proxy2 in self.proxies.values() {
                    if allow_proximity(&proxy1.1, &proxy2.1) {
                        proximity_handler(&proxy1.1, &proxy2.1, proxy1.0.intersects(&proxy2.0))
                    }
                }
            }
        }
    }

    fn interferences_with_bounding_volume<'a>(&'a self, bv: &BV, out: &mut Vec<&'a T>) {
        for proxy in self.proxies.values() {
            if proxy.0.intersects(bv) {
                out.push(&proxy.1)
            }
        }
    }

    fn interferences_with_ray<'a>(&'a self, ray: &Ray<P>, out: &mut Vec<&'a T>) {
        for proxy in self.proxies.values() {
            if proxy.0.intersects_ray(&Identity::new(), ray) {
                out.push(&proxy.1)
            }
        }
    }

    fn interferences_with_point<'a>(&'a self, point: &P, out: &mut Vec<&'a T>) {
        for proxy in self.proxies.values() {
            if proxy.0.contains_point(&Identity::new(), point) {
                out.push(&proxy.1)
            }
        }
    }
}
<commit_msg>Add a loosening marging to the brute force broad phase.<commit_after>use na::Identity;
use utils::data::uid_remap::{UidRemap, FastKey};
use geometry::bounding_volume::BoundingVolume;
use geometry::ray::{Ray, RayCast};
use geometry::point::PointQuery;
use broad_phase::BroadPhase;
use math::{Point, Vector};

/// A broad phase testing explicitly all bounding volume pairs.
///
/// Use this for debugging purposes only.
pub struct BruteForceBroadPhase<N, BV, T> {
    proxies:   UidRemap<(BV, T)>,
    margin:    N, // The margin added to each bounding volume.
    to_remove: Vec<usize>,
    to_add:    Vec<(usize, BV, T)>,
    to_update: Vec<(FastKey, BV)>
}

impl<N, BV, T> BruteForceBroadPhase<N, BV, T> {
    /// Creates a new brute-force broad phase.
    pub fn new(margin: N, small_keys: bool) -> BruteForceBroadPhase<N, BV, T> {
        BruteForceBroadPhase {
            proxies:   UidRemap::new(small_keys),
            margin:    margin,
            to_remove: Vec::new(),
            to_add:    Vec::new(),
            to_update: Vec::new()
        }
    }
}

impl<P: Point, BV, T> BroadPhase<P, BV, T> for BruteForceBroadPhase<<P::Vect as Vector>::Scalar, BV, T> where
    BV: 'static + BoundingVolume<<P::Vect as Vector>::Scalar> +
        RayCast<P, Identity> + PointQuery<P, Identity> + Clone {
    fn deferred_add(&mut self, uid: usize, bv: BV, data: T) {
        // XXX: should not be inserted now!
        let (key, _) = self.proxies.insert(uid, (bv.clone(), data));

        self.to_update.push((key, bv))
    }

    fn deferred_remove(&mut self, uid: usize) {
        if self.proxies.get_fast_key(uid).is_some() {
            self.to_remove.push(uid);
        }
    }

    fn deferred_set_bounding_volume(&mut self, uid: usize, bv: BV) {
        if let Some(key) = self.proxies.get_fast_key(uid) {
            if !self.proxies[key].0.contains(&bv) {
                self.to_update.push((key, bv.loosened(self.margin)));
            }
        }
    }

    fn deferred_recompute_all_proximities(&mut self) {
        for proxy in self.proxies.iter() {
            self.to_update.push((proxy.0, (proxy.1).0.clone()));
        }
    }

    fn update(&mut self, allow_proximity: &mut FnMut(&T, &T) -> bool, proximity_handler: &mut FnMut(&T, &T, bool)) {
        for (uid, bv, data) in self.to_add.drain(..) {
            let lbv = bv.loosened(self.margin.clone());
            let key = self.proxies.insert(uid, (lbv.clone(), data));
            self.to_update.push((key.0, lbv))
        }

        for rm in self.to_remove.drain(..) {
            let _ = self.proxies.remove(rm);
        }

        for new_proxy in self.to_update.iter() {
            if let Some(proxy) = self.proxies.get_fast_mut(&new_proxy.0) {
                proxy.0 = new_proxy.1.clone();
            }
        }

        for proxy1_key in self.to_update.drain(..) {
            if let Some(proxy1) = self.proxies.get_fast(&proxy1_key.0) {
                for proxy2 in self.proxies.values() {
                    if allow_proximity(&proxy1.1, &proxy2.1) {
                        proximity_handler(&proxy1.1, &proxy2.1, proxy1.0.intersects(&proxy2.0))
                    }
                }
            }
        }
    }

    fn interferences_with_bounding_volume<'a>(&'a self, bv: &BV, out: &mut Vec<&'a T>) {
        for proxy in self.proxies.values() {
            if proxy.0.intersects(bv) {
                out.push(&proxy.1)
            }
        }
    }

    fn interferences_with_ray<'a>(&'a self, ray: &Ray<P>, out: &mut Vec<&'a T>) {
        for proxy in self.proxies.values() {
            if proxy.0.intersects_ray(&Identity::new(), ray) {
                out.push(&proxy.1)
            }
        }
    }

    fn interferences_with_point<'a>(&'a self, point: &P, out: &mut Vec<&'a T>) {
        for proxy in self.proxies.values() {
            if proxy.0.contains_point(&Identity::new(), point) {
                out.push(&proxy.1)
            }
        }
    }
}
<|endoftext|>


<commit_before>#[derive(Debug, Clone, RustcEncodable)]
pub struct Country {
    link: String,
    name: String,
    num_events: i32,
    num_fatalities: i32,
}
<commit_msg>started typescript conversion<commit_after><|endoftext|>


<commit_before>
<commit_msg>remove empty file<commit_after><|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Function_composition
#[cfg(not(test))]
use std::f32::consts;

#[cfg(not(test))]
fn main() {
    fn f(x: uint) -> String { x.to_string() }
    fn g(x: f32) -> uint { x as uint }

    // just a silly example
    // turn PI to a uint and then
    // the uint to a String
    // via function composition
    let comp = compose(f, g);
    println!("{}", comp(consts::PI));
}

// the future unboxed closures should
// allow to compose closures, not just bare functions (so that environment can be captured)
// Also returning a proc has the limitation that the composed function can only be called once
fn compose<A, B, C>(f: fn(A) -> B, g: fn(C) -> A) -> proc(C) -> B {
    proc(x: C) {f(g(x))}
}

#[test]
fn test_compose() {
    fn inc(x: uint) -> uint { x + 1 }
    fn mul(x: uint) -> uint { x * 3 }

    let comp = compose(inc, mul);
    assert_eq!(comp(3), 10);
}
<commit_msg>Fix function_composition<commit_after>// http://rosettacode.org/wiki/Function_composition
#[cfg(not(test))]
use std::f32::consts;

#[cfg(not(test))]
fn main() {
    fn f(x: uint) -> String { x.to_string() }
    fn g(x: f32) -> uint { x as uint }

    // just a silly example
    // turn PI to a uint and then
    // the uint to a String
    // via function composition
    let comp = compose(f, g);
    println!("{}", comp(consts::PI));
}

// the future unboxed closures should
// allow to compose closures, not just bare functions (so that environment can be captured)
// Also returning a proc has the limitation that the composed function can only be called once
fn compose<A, B, C>(f: fn(A) -> B, g: fn(C) -> A) -> proc(C): 'static -> B {
    proc(x: C) {f(g(x))}
}

#[test]
fn test_compose() {
    fn inc(x: uint) -> uint { x + 1 }
    fn mul(x: uint) -> uint { x * 3 }

    let comp = compose(inc, mul);
    assert_eq!(comp(3), 10);
}
<|endoftext|>


<commit_before>//! Operator norms of matrices

use lapack::c;
use lapack::c::Layout::ColumnMajor as cm;

use layout::MatrixLayout;
use types::*;

use super::NormType;

pub trait OperatorNorm_: AssociatedReal {
    unsafe fn opnorm(NormType, MatrixLayout, &[Self]) -> Self::Real;
}

macro_rules! impl_opnorm {
    ($scalar:ty, $lange:path) => {
impl OperatorNorm_ for $scalar {
    unsafe fn opnorm(t: NormType, l: MatrixLayout, a: &[Self]) -> Self::Real {
        match l {
            MatrixLayout::F((col, lda)) => $lange(cm, t as u8, lda, col, a, lda),
            MatrixLayout::C((row, lda)) => $lange(cm, t.transpose() as u8, lda, row, a, lda),
        }
    }
}
}} // impl_opnorm!

impl_opnorm!(f64, c::dlange);
impl_opnorm!(f32, c::slange);
impl_opnorm!(c64, c::zlange);
impl_opnorm!(c32, c::clange);
<commit_msg>Make pub lapack_traits::opnorm::NormType #90<commit_after>//! Operator norms of matrices

use lapack::c;
use lapack::c::Layout::ColumnMajor as cm;

use layout::MatrixLayout;
use types::*;

pub use super::NormType;

pub trait OperatorNorm_: AssociatedReal {
    unsafe fn opnorm(NormType, MatrixLayout, &[Self]) -> Self::Real;
}

macro_rules! impl_opnorm {
    ($scalar:ty, $lange:path) => {
impl OperatorNorm_ for $scalar {
    unsafe fn opnorm(t: NormType, l: MatrixLayout, a: &[Self]) -> Self::Real {
        match l {
            MatrixLayout::F((col, lda)) => $lange(cm, t as u8, lda, col, a, lda),
            MatrixLayout::C((row, lda)) => $lange(cm, t.transpose() as u8, lda, row, a, lda),
        }
    }
}
}} // impl_opnorm!

impl_opnorm!(f64, c::dlange);
impl_opnorm!(f32, c::slange);
impl_opnorm!(c64, c::zlange);
impl_opnorm!(c32, c::clange);
<|endoftext|>


<commit_before>/// The version of the call operator that takes an immutable receiver.
///
/// Instances of `Fn` can be called repeatedly without mutating state.
///
/// *This trait (`Fn`) is not to be confused with [function pointers]
/// (`fn`).*
///
/// `Fn` is implemented automatically by closures which only take immutable
/// references to captured variables or don't capture anything at all, as well
/// as (safe) [function pointers] (with some caveats, see their documentation
/// for more details). Additionally, for any type `F` that implements `Fn`, `&F`
/// implements `Fn`, too.
///
/// Since both [`FnMut`] and [`FnOnce`] are supertraits of `Fn`, any
/// instance of `Fn` can be used as a parameter where a [`FnMut`] or [`FnOnce`]
/// is expected.
///
/// Use `Fn` as a bound when you want to accept a parameter of function-like
/// type and need to call it repeatedly and without mutating state (e.g., when
/// calling it concurrently). If you do not need such strict requirements, use
/// [`FnMut`] or [`FnOnce`] as bounds.
///
/// See the [chapter on closures in *The Rust Programming Language*][book] for
/// some more information on this topic.
///
/// Also of note is the special syntax for `Fn` traits (e.g.
/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
///
/// [book]: ../../book/ch13-01-closures.html
/// [`FnMut`]: trait.FnMut.html
/// [`FnOnce`]: trait.FnOnce.html
/// [function pointers]: ../../std/primitive.fn.html
/// [nomicon]: ../../nomicon/hrtb.html
///
/// # Examples
///
/// ## Calling a closure
///
/// ```
/// let square = |x| x * x;
/// assert_eq!(square(5), 25);
/// ```
///
/// ## Using a `Fn` parameter
///
/// ```
/// fn call_with_one<F>(func: F) -> usize
///     where F: Fn(usize) -> usize {
///     func(1)
/// }
///
/// let double = |x| x * 2;
/// assert_eq!(call_with_one(double), 2);
/// ```
#[lang = "fn"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
    on(
        Args = "()",
        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
    ),
    message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
    label = "expected an `Fn<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
pub trait Fn<Args>: FnMut<Args> {
    /// Performs the call operation.
    #[unstable(feature = "fn_traits", issue = "29625")]
    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}

/// The version of the call operator that takes a mutable receiver.
///
/// Instances of `FnMut` can be called repeatedly and may mutate state.
///
/// `FnMut` is implemented automatically by closures which take mutable
/// references to captured variables, as well as all types that implement
/// [`Fn`], e.g., (safe) [function pointers] (since `FnMut` is a supertrait of
/// [`Fn`]). Additionally, for any type `F` that implements `FnMut`, `&mut F`
/// implements `FnMut`, too.
///
/// Since [`FnOnce`] is a supertrait of `FnMut`, any instance of `FnMut` can be
/// used where a [`FnOnce`] is expected, and since [`Fn`] is a subtrait of
/// `FnMut`, any instance of [`Fn`] can be used where `FnMut` is expected.
///
/// Use `FnMut` as a bound when you want to accept a parameter of function-like
/// type and need to call it repeatedly, while allowing it to mutate state.
/// If you don't want the parameter to mutate state, use [`Fn`] as a
/// bound; if you don't need to call it repeatedly, use [`FnOnce`].
///
/// See the [chapter on closures in *The Rust Programming Language*][book] for
/// some more information on this topic.
///
/// Also of note is the special syntax for `Fn` traits (e.g.
/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
///
/// [book]: ../../book/ch13-01-closures.html
/// [`Fn`]: trait.Fn.html
/// [`FnOnce`]: trait.FnOnce.html
/// [function pointers]: ../../std/primitive.fn.html
/// [nomicon]: ../../nomicon/hrtb.html
///
/// # Examples
///
/// ## Calling a mutably capturing closure
///
/// ```
/// let mut x = 5;
/// {
///     let mut square_x = || x *= x;
///     square_x();
/// }
/// assert_eq!(x, 25);
/// ```
///
/// ## Using a `FnMut` parameter
///
/// ```
/// fn do_twice<F>(mut func: F)
///     where F: FnMut()
/// {
///     func();
///     func();
/// }
///
/// let mut x: usize = 1;
/// {
///     let add_two_to_x = || x += 2;
///     do_twice(add_two_to_x);
/// }
///
/// assert_eq!(x, 5);
/// ```
#[lang = "fn_mut"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
    on(
        Args = "()",
        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
    ),
    message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
    label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
pub trait FnMut<Args>: FnOnce<Args> {
    /// Performs the call operation.
    #[unstable(feature = "fn_traits", issue = "29625")]
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

/// The version of the call operator that takes a by-value receiver.
///
/// Instances of `FnOnce` can be called, but might not be callable multiple
/// times. Because of this, if the only thing known about a type is that it
/// implements `FnOnce`, it can only be called once.
///
/// `FnOnce` is implemented automatically by closure that might consume captured
/// variables, as well as all types that implement [`FnMut`], e.g., (safe)
/// [function pointers] (since `FnOnce` is a supertrait of [`FnMut`]).
///
/// Since both [`Fn`] and [`FnMut`] are subtraits of `FnOnce`, any instance of
/// [`Fn`] or [`FnMut`] can be used where a `FnOnce` is expected.
///
/// Use `FnOnce` as a bound when you want to accept a parameter of function-like
/// type and only need to call it once. If you need to call the parameter
/// repeatedly, use [`FnMut`] as a bound; if you also need it to not mutate
/// state, use [`Fn`].
///
/// See the [chapter on closures in *The Rust Programming Language*][book] for
/// some more information on this topic.
///
/// Also of note is the special syntax for `Fn` traits (e.g.
/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
///
/// [book]: ../../book/ch13-01-closures.html
/// [`Fn`]: trait.Fn.html
/// [`FnMut`]: trait.FnMut.html
/// [function pointers]: ../../std/primitive.fn.html
/// [nomicon]: ../../nomicon/hrtb.html
///
/// # Examples
///
/// ## Using a `FnOnce` parameter
///
/// ```
/// fn consume_with_relish<F>(func: F)
///     where F: FnOnce() -> String
/// {
///     // `func` consumes its captured variables, so it cannot be run more
///     // than once.
///     println!("Consumed: {}", func());
///
///     println!("Delicious!");
///
///     // Attempting to invoke `func()` again will throw a `use of moved
///     // value` error for `func`.
/// }
///
/// let x = String::from("x");
/// let consume_and_return_x = move || x;
/// consume_with_relish(consume_and_return_x);
///
/// // `consume_and_return_x` can no longer be invoked at this point
/// ```
#[lang = "fn_once"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
    on(
        Args = "()",
        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
    ),
    message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
    label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
pub trait FnOnce<Args> {
    /// The returned type after the call operator is used.
    #[lang = "fn_once_output"]
    #[stable(feature = "fn_once_output", since = "1.12.0")]
    type Output;

    /// Performs the call operation.
    #[unstable(feature = "fn_traits", issue = "29625")]
    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

mod impls {
    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> Fn<A> for &F
    where
        F: Fn<A>,
    {
        extern "rust-call" fn call(&self, args: A) -> F::Output {
            (**self).call(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnMut<A> for &F
    where
        F: Fn<A>,
    {
        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
            (**self).call(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnOnce<A> for &F
    where
        F: Fn<A>,
    {
        type Output = F::Output;

        extern "rust-call" fn call_once(self, args: A) -> F::Output {
            (*self).call(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnMut<A> for &mut F
    where
        F: FnMut<A>,
    {
        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
            (*self).call_mut(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnOnce<A> for &mut F
    where
        F: FnMut<A>,
    {
        type Output = F::Output;
        extern "rust-call" fn call_once(self, args: A) -> F::Output {
            (*self).call_mut(args)
        }
    }
}
<commit_msg>Fixed typo in `closure`<commit_after>/// The version of the call operator that takes an immutable receiver.
///
/// Instances of `Fn` can be called repeatedly without mutating state.
///
/// *This trait (`Fn`) is not to be confused with [function pointers]
/// (`fn`).*
///
/// `Fn` is implemented automatically by closures which only take immutable
/// references to captured variables or don't capture anything at all, as well
/// as (safe) [function pointers] (with some caveats, see their documentation
/// for more details). Additionally, for any type `F` that implements `Fn`, `&F`
/// implements `Fn`, too.
///
/// Since both [`FnMut`] and [`FnOnce`] are supertraits of `Fn`, any
/// instance of `Fn` can be used as a parameter where a [`FnMut`] or [`FnOnce`]
/// is expected.
///
/// Use `Fn` as a bound when you want to accept a parameter of function-like
/// type and need to call it repeatedly and without mutating state (e.g., when
/// calling it concurrently). If you do not need such strict requirements, use
/// [`FnMut`] or [`FnOnce`] as bounds.
///
/// See the [chapter on closures in *The Rust Programming Language*][book] for
/// some more information on this topic.
///
/// Also of note is the special syntax for `Fn` traits (e.g.
/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
///
/// [book]: ../../book/ch13-01-closures.html
/// [`FnMut`]: trait.FnMut.html
/// [`FnOnce`]: trait.FnOnce.html
/// [function pointers]: ../../std/primitive.fn.html
/// [nomicon]: ../../nomicon/hrtb.html
///
/// # Examples
///
/// ## Calling a closure
///
/// ```
/// let square = |x| x * x;
/// assert_eq!(square(5), 25);
/// ```
///
/// ## Using a `Fn` parameter
///
/// ```
/// fn call_with_one<F>(func: F) -> usize
///     where F: Fn(usize) -> usize {
///     func(1)
/// }
///
/// let double = |x| x * 2;
/// assert_eq!(call_with_one(double), 2);
/// ```
#[lang = "fn"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
    on(
        Args = "()",
        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
    ),
    message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
    label = "expected an `Fn<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
pub trait Fn<Args>: FnMut<Args> {
    /// Performs the call operation.
    #[unstable(feature = "fn_traits", issue = "29625")]
    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
}

/// The version of the call operator that takes a mutable receiver.
///
/// Instances of `FnMut` can be called repeatedly and may mutate state.
///
/// `FnMut` is implemented automatically by closures which take mutable
/// references to captured variables, as well as all types that implement
/// [`Fn`], e.g., (safe) [function pointers] (since `FnMut` is a supertrait of
/// [`Fn`]). Additionally, for any type `F` that implements `FnMut`, `&mut F`
/// implements `FnMut`, too.
///
/// Since [`FnOnce`] is a supertrait of `FnMut`, any instance of `FnMut` can be
/// used where a [`FnOnce`] is expected, and since [`Fn`] is a subtrait of
/// `FnMut`, any instance of [`Fn`] can be used where `FnMut` is expected.
///
/// Use `FnMut` as a bound when you want to accept a parameter of function-like
/// type and need to call it repeatedly, while allowing it to mutate state.
/// If you don't want the parameter to mutate state, use [`Fn`] as a
/// bound; if you don't need to call it repeatedly, use [`FnOnce`].
///
/// See the [chapter on closures in *The Rust Programming Language*][book] for
/// some more information on this topic.
///
/// Also of note is the special syntax for `Fn` traits (e.g.
/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
///
/// [book]: ../../book/ch13-01-closures.html
/// [`Fn`]: trait.Fn.html
/// [`FnOnce`]: trait.FnOnce.html
/// [function pointers]: ../../std/primitive.fn.html
/// [nomicon]: ../../nomicon/hrtb.html
///
/// # Examples
///
/// ## Calling a mutably capturing closure
///
/// ```
/// let mut x = 5;
/// {
///     let mut square_x = || x *= x;
///     square_x();
/// }
/// assert_eq!(x, 25);
/// ```
///
/// ## Using a `FnMut` parameter
///
/// ```
/// fn do_twice<F>(mut func: F)
///     where F: FnMut()
/// {
///     func();
///     func();
/// }
///
/// let mut x: usize = 1;
/// {
///     let add_two_to_x = || x += 2;
///     do_twice(add_two_to_x);
/// }
///
/// assert_eq!(x, 5);
/// ```
#[lang = "fn_mut"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
    on(
        Args = "()",
        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
    ),
    message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
    label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
pub trait FnMut<Args>: FnOnce<Args> {
    /// Performs the call operation.
    #[unstable(feature = "fn_traits", issue = "29625")]
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

/// The version of the call operator that takes a by-value receiver.
///
/// Instances of `FnOnce` can be called, but might not be callable multiple
/// times. Because of this, if the only thing known about a type is that it
/// implements `FnOnce`, it can only be called once.
///
/// `FnOnce` is implemented automatically by closures that might consume captured
/// variables, as well as all types that implement [`FnMut`], e.g., (safe)
/// [function pointers] (since `FnOnce` is a supertrait of [`FnMut`]).
///
/// Since both [`Fn`] and [`FnMut`] are subtraits of `FnOnce`, any instance of
/// [`Fn`] or [`FnMut`] can be used where a `FnOnce` is expected.
///
/// Use `FnOnce` as a bound when you want to accept a parameter of function-like
/// type and only need to call it once. If you need to call the parameter
/// repeatedly, use [`FnMut`] as a bound; if you also need it to not mutate
/// state, use [`Fn`].
///
/// See the [chapter on closures in *The Rust Programming Language*][book] for
/// some more information on this topic.
///
/// Also of note is the special syntax for `Fn` traits (e.g.
/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
///
/// [book]: ../../book/ch13-01-closures.html
/// [`Fn`]: trait.Fn.html
/// [`FnMut`]: trait.FnMut.html
/// [function pointers]: ../../std/primitive.fn.html
/// [nomicon]: ../../nomicon/hrtb.html
///
/// # Examples
///
/// ## Using a `FnOnce` parameter
///
/// ```
/// fn consume_with_relish<F>(func: F)
///     where F: FnOnce() -> String
/// {
///     // `func` consumes its captured variables, so it cannot be run more
///     // than once.
///     println!("Consumed: {}", func());
///
///     println!("Delicious!");
///
///     // Attempting to invoke `func()` again will throw a `use of moved
///     // value` error for `func`.
/// }
///
/// let x = String::from("x");
/// let consume_and_return_x = move || x;
/// consume_with_relish(consume_and_return_x);
///
/// // `consume_and_return_x` can no longer be invoked at this point
/// ```
#[lang = "fn_once"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
    on(
        Args = "()",
        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
    ),
    message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
    label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
)]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
pub trait FnOnce<Args> {
    /// The returned type after the call operator is used.
    #[lang = "fn_once_output"]
    #[stable(feature = "fn_once_output", since = "1.12.0")]
    type Output;

    /// Performs the call operation.
    #[unstable(feature = "fn_traits", issue = "29625")]
    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

mod impls {
    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> Fn<A> for &F
    where
        F: Fn<A>,
    {
        extern "rust-call" fn call(&self, args: A) -> F::Output {
            (**self).call(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnMut<A> for &F
    where
        F: Fn<A>,
    {
        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
            (**self).call(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnOnce<A> for &F
    where
        F: Fn<A>,
    {
        type Output = F::Output;

        extern "rust-call" fn call_once(self, args: A) -> F::Output {
            (*self).call(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnMut<A> for &mut F
    where
        F: FnMut<A>,
    {
        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
            (*self).call_mut(args)
        }
    }

    #[stable(feature = "rust1", since = "1.0.0")]
    impl<A, F: ?Sized> FnOnce<A> for &mut F
    where
        F: FnMut<A>,
    {
        type Output = F::Output;
        extern "rust-call" fn call_once(self, args: A) -> F::Output {
            (*self).call_mut(args)
        }
    }
}
<|endoftext|>


<commit_before>#[link(name = "widmannserver",
       vers = "0.1-pre",
       url = "")];

#[crate_type = "lib"];

extern mod extra;
extern mod http;
extern mod widmann;

use std::rt::io::net::ip::{SocketAddr, Ipv4Addr};
use std::rt::io::Writer;
use extra::time;

use http::server::{Config, Server, Request, ResponseWriter};
use http::headers::content_type::MediaType;
use http::status::Ok;

use widmann::application::*;
use widmann::application::response::*;

#[deriving(Clone)]
pub struct WidmannServer<T> {
  application: Application<T>
}

impl<T> WidmannServer<T> {
  pub fn new(application: Application<T>) -> WidmannServer<T> {
    WidmannServer { application: application }
  }
}

impl<T: ToResponse> Server for WidmannServer<T> {
    fn get_config(&self) -> Config {
      Config { bind_address: SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 8001 } }
    }

    fn handle_request(&self, r: &Request, w: &mut ResponseWriter) {
      let response = self.application.call(r);

      w.headers.date = Some(time::now_utc());
      w.headers.content_type = Some(MediaType {
          type_: ~"text",
          subtype: ~"plain",
          parameters: ~[(~"charset", ~"UTF-8")]
      });
      w.headers.server = Some(~"Example");

      w.headers.content_length = Some(response.body.len());

      w.status = Ok; //response.status.clone();
      w.write(response.body.as_bytes());
    }
}<commit_msg>Return correct status<commit_after>#[link(name = "widmannserver",
       vers = "0.1-pre",
       url = "")];

#[crate_type = "lib"];

extern mod extra;
extern mod http;
extern mod widmann;

use std::rt::io::net::ip::{SocketAddr, Ipv4Addr};
use std::rt::io::Writer;
use extra::time;

use http::server::{Config, Server, Request, ResponseWriter};
use http::headers::content_type::MediaType;

use widmann::application::*;
use widmann::application::response::*;

#[deriving(Clone)]
pub struct WidmannServer<T> {
  application: Application<T>
}

impl<T> WidmannServer<T> {
  pub fn new(application: Application<T>) -> WidmannServer<T> {
    WidmannServer { application: application }
  }
}

impl<T: ToResponse> Server for WidmannServer<T> {
    fn get_config(&self) -> Config {
      Config { bind_address: SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 8001 } }
    }

    fn handle_request(&self, r: &Request, w: &mut ResponseWriter) {
      let response = self.application.call(r);

      w.headers.date = Some(time::now_utc());
      w.headers.content_type = Some(MediaType {
          type_: ~"text",
          subtype: ~"plain",
          parameters: ~[(~"charset", ~"UTF-8")]
      });
      w.headers.server = Some(~"Example");

      w.headers.content_length = Some(response.body.len());

      w.status = response.status.clone();
      w.write(response.body.as_bytes());
    }
}<|endoftext|>


<commit_before>use super::File;

use futures::{Future, Poll};

use std::fs::File as StdFile;
use std::fs::Metadata;
use std::io;

const POLL_AFTER_RESOLVE: &str = "Cannot poll MetadataFuture after it resolves";

/// Future returned by `File::metadata` and resolves to a `(Metadata, File)` instance.
#[derive(Debug)]
pub struct MetadataFuture {
    file: Option<File>,
}

impl MetadataFuture {
    pub(crate) fn new(file: File) -> Self {
        MetadataFuture { file: Some(file) }
    }

    fn std(&mut self) -> &mut StdFile {
        self.file.as_mut().expect(POLL_AFTER_RESOLVE).std()
    }
}

impl Future for MetadataFuture {
    type Item = (File, Metadata);
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let metadata = try_ready!(::blocking_io(|| {
            StdFile::metadata(self.std())
        }));

        let file = self.file.take().expect(POLL_AFTER_RESOLVE);
        Ok((file, metadata).into())
    }
}
<commit_msg>fs: fix minor documentation error for MetadataFuture (#698)<commit_after>use super::File;

use futures::{Future, Poll};

use std::fs::File as StdFile;
use std::fs::Metadata;
use std::io;

const POLL_AFTER_RESOLVE: &str = "Cannot poll MetadataFuture after it resolves";

/// Future returned by `File::metadata` and resolves to a `(File, Metadata)` instance.
#[derive(Debug)]
pub struct MetadataFuture {
    file: Option<File>,
}

impl MetadataFuture {
    pub(crate) fn new(file: File) -> Self {
        MetadataFuture { file: Some(file) }
    }

    fn std(&mut self) -> &mut StdFile {
        self.file.as_mut().expect(POLL_AFTER_RESOLVE).std()
    }
}

impl Future for MetadataFuture {
    type Item = (File, Metadata);
    type Error = io::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        let metadata = try_ready!(::blocking_io(|| {
            StdFile::metadata(self.std())
        }));

        let file = self.file.take().expect(POLL_AFTER_RESOLVE);
        Ok((file, metadata).into())
    }
}
<|endoftext|>


<commit_before>use std::io::{self, BufRead};

fn main() {
    //println!("Hello, world!");
    let stdin = io::stdin();

    let mut lines = stdin.lock().lines().fuse();
    let input = match lines.next()  {
        Some(Ok(a))  => a,
        _ => panic!("Couldn t read input.")
    };

    let info = input.trim();
    let splitted = info.split(",");
    let iter = splitted.map(|a| a.to_string().parse().unwrap_or(0));

    let mut result  = 0;
    for num in iter {
        result += num;
    }
    println!("{:?}", result);
}
<commit_msg>Moved example for day 1<commit_after>use std::io::{self, BufRead};

fn code1() {
    let stdin = io::stdin();

    let mut lines = stdin.lock().lines().fuse();
    let input = match lines.next()  {
        Some(Ok(a))  => a,
        _ => panic!("Couldn t read input.")
    };

    let info = input.trim();
    let splitted = info.split(",");
    let iter = splitted.map(|a| a.to_string().parse().unwrap_or(0));

    let mut result  = 0;
    for num in iter {
        result += num;
    }
    println!("{:?}", result);
}

fn main() {
    code1();
}
<|endoftext|>


<commit_before>/*!
A Rust interface for Objective-C blocks.

For more information on the specifics of the block implementation, see
Clang's documentation: http://clang.llvm.org/docs/Block-ABI-Apple.html

# Invoking blocks

The `Block` struct is used for invoking blocks from Objective-C. For example,
consider this Objective-C function:

``` objc
int32_t sum(int32_t (^block)(int32_t, int32_t)) {
    return block(5, 8);
}
```

We could write it in Rust as the following:

```
# use objc::block::Block;
fn sum(block: &mut Block<(i32, i32), i32>) -> i32 {
    block.call((5, 8))
}
```

Note the extra parentheses in the `call` method, since the arguments must be
passed as a tuple.

# Creating blocks

Creating a block to pass to Objective-C can be done with the `ConcreteBlock`
struct. For example, to create a block that adds two `i32`s, we could write:

```
# use objc::block::ConcreteBlock;
let block = ConcreteBlock::new(|a: i32, b: i32| a + b);
let mut block = block.copy();
assert!(block.call((5, 8)) == 13);
```

It is important to copy your block to the heap (with the `copy` method) before
passing it to Objective-C; this is because our `ConcreteBlock` is only meant
to be copied once, and we can enforce this in Rust, but if Objective-C code
were to copy it twice we could have a double free.
*/

use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;
use libc::{c_int, c_ulong};

use runtime::{Class, Object};
use {EncodePtr, Id, Message};

#[link(name = "Foundation", kind = "framework")]
extern {
    static _NSConcreteStackBlock: Class;
}

/// Types that may be used as the arguments to an Objective-C block.
pub trait BlockArguments {
    /// Calls the given `Block` with self as the arguments.
    fn call_block<R>(self, block: &mut Block<Self, R>) -> R;
}

macro_rules! block_args_impl {
    ($($a:ident : $t:ident),*) => (
        impl<$($t),*> BlockArguments for ($($t,)*) {
            fn call_block<R>(self, block: &mut Block<Self, R>) -> R {
                let invoke: unsafe extern fn(*mut Block<Self, R> $(, $t)*) -> R = unsafe {
                    mem::transmute(block.invoke)
                };
                let ($($a,)*) = self;
                unsafe {
                    invoke(block $(, $a)*)
                }
            }
        }
    );
}

block_args_impl!();
block_args_impl!(a: A);
block_args_impl!(a: A, b: B);
block_args_impl!(a: A, b: B, c: C);
block_args_impl!(a: A, b: B, c: C, d: D);
block_args_impl!(a: A, b: B, c: C, d: D, e: E);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L);

/// An Objective-C block that takes arguments of `A` when called and
/// returns a value of `R`.
#[repr(C)]
pub struct Block<A, R> {
    isa: *const Class,
    flags: c_int,
    _reserved: c_int,
    invoke: unsafe extern fn(*mut Block<A, R>, ...) -> R,
}

// TODO: impl FnMut when it's possible
impl<A: BlockArguments, R> Block<A, R> where A: BlockArguments {
    /// Call self with the given arguments.
    pub fn call(&mut self, args: A) -> R {
        args.call_block(self)
    }
}

unsafe impl<A, R> Message for Block<A, R> { }

impl<A, R> EncodePtr for Block<A, R> {
    fn ptr_code() -> &'static str { "@?" }
}

/// Types that may be converted into a `ConcreteBlock`.
pub trait IntoConcreteBlock<A> where A: BlockArguments {
    /// The return type of the resulting `ConcreteBlock`.
    type Ret;

    /// Consumes self to create a `ConcreteBlock`.
    fn into_concrete_block(self) -> ConcreteBlock<A, Self::Ret, Self>;
}

macro_rules! concrete_block_impl {
    ($f:ident) => (
        concrete_block_impl!($f,);
    );
    ($f:ident, $($a:ident : $t:ident),*) => (
        impl<$($t,)* R, X> IntoConcreteBlock<($($t,)*)> for X
                where X: Fn($($t,)*) -> R {
            type Ret = R;

            fn into_concrete_block(self) -> ConcreteBlock<($($t,)*), R, X> {
                unsafe extern fn $f<$($t,)* R, X>(
                        block_ptr: *mut ConcreteBlock<($($t,)*), R, X>
                        $(, $a: $t)*) -> R
                        where X: Fn($($t,)*) -> R {
                    let block = &*block_ptr;
                    (block.closure)($($a),*)
                }

                unsafe {
                    ConcreteBlock::with_invoke(
                        mem::transmute($f::<$($t,)* R, X>), self)
                }
            }
        }
    );
}

concrete_block_impl!(concrete_block_invoke_args0);
concrete_block_impl!(concrete_block_invoke_args1, a: A);
concrete_block_impl!(concrete_block_invoke_args2, a: A, b: B);
concrete_block_impl!(concrete_block_invoke_args3, a: A, b: B, c: C);
concrete_block_impl!(concrete_block_invoke_args4, a: A, b: B, c: C, d: D);
concrete_block_impl!(concrete_block_invoke_args5, a: A, b: B, c: C, d: D, e: E);
concrete_block_impl!(concrete_block_invoke_args6, a: A, b: B, c: C, d: D, e: E, f: F);
concrete_block_impl!(concrete_block_invoke_args7, a: A, b: B, c: C, d: D, e: E, f: F, g: G);
concrete_block_impl!(concrete_block_invoke_args8, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H);
concrete_block_impl!(concrete_block_invoke_args9, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I);
concrete_block_impl!(concrete_block_invoke_args10, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J);
concrete_block_impl!(concrete_block_invoke_args11, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K);
concrete_block_impl!(concrete_block_invoke_args12, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L);

/// An Objective-C block whose size is known at compile time and may be
/// constructed on the stack.
#[repr(C)]
pub struct ConcreteBlock<A, R, F> {
    base: Block<A, R>,
    descriptor: Box<BlockDescriptor<ConcreteBlock<A, R, F>>>,
    closure: F,
}

impl<A, R, F> ConcreteBlock<A, R, F>
        where A: BlockArguments, F: IntoConcreteBlock<A, Ret=R> {
    /// Constructs a `ConcreteBlock` with the given closure.
    /// When the block is called, it will return the value that results from
    /// calling the closure.
    pub fn new(closure: F) -> Self {
        closure.into_concrete_block()
    }
}

impl<A, R, F> ConcreteBlock<A, R, F> {
    /// Constructs a `ConcreteBlock` with the given invoke function and closure.
    /// Unsafe because the caller must ensure the invoke function takes the
    /// correct arguments.
    unsafe fn with_invoke(invoke: unsafe extern fn(*mut Self, ...) -> R,
            closure: F) -> Self {
        ConcreteBlock {
            base: Block {
                isa: &_NSConcreteStackBlock,
                // 1 << 25 = BLOCK_HAS_COPY_DISPOSE
                flags: 1 << 25,
                _reserved: 0,
                invoke: mem::transmute(invoke),
            },
            descriptor: Box::new(BlockDescriptor::new()),
            closure: closure,
        }
    }
}

impl<A, R, F> ConcreteBlock<A, R, F> where F: 'static {
    /// Copy self onto the heap.
    pub fn copy(self) -> Id<Block<A, R>> {
        unsafe {
            // The copy method is declared as returning an object pointer.
            let block: *mut Object = msg_send![&self.base, copy];
            let block = block as *mut Block<A, R>;
            // At this point, our copy helper has been run so the block will
            // be moved to the heap and we can forget the original block
            // because the heap block will drop in our dispose helper.
            mem::forget(self);
            Id::from_retained_ptr(block)
        }
    }
}

impl<A, R, F> Clone for ConcreteBlock<A, R, F> where F: Clone {
    fn clone(&self) -> Self {
        unsafe {
            ConcreteBlock::with_invoke(mem::transmute(self.invoke),
                self.closure.clone())
        }
    }
}

impl<A, R, F> Deref for ConcreteBlock<A, R, F> {
    type Target = Block<A, R>;

    fn deref(&self) -> &Block<A, R> {
        &self.base
    }
}

impl<A, R, F> DerefMut for ConcreteBlock<A, R, F> {
    fn deref_mut(&mut self) -> &mut Block<A, R> {
        &mut self.base
    }
}

unsafe extern fn block_context_dispose<B>(block: &mut B) {
    // Read the block onto the stack and let it drop
    ptr::read(block);
}

unsafe extern fn block_context_copy<B>(_dst: &mut B, _src: &B) {
    // The runtime memmoves the src block into the dst block, nothing to do
}

#[repr(C)]
struct BlockDescriptor<B> {
    _reserved: c_ulong,
    block_size: c_ulong,
    copy_helper: unsafe extern fn(&mut B, &B),
    dispose_helper: unsafe extern fn(&mut B),
}

impl<B> BlockDescriptor<B> {
    fn new() -> BlockDescriptor<B> {
        BlockDescriptor {
            _reserved: 0,
            block_size: mem::size_of::<B>() as c_ulong,
            copy_helper: block_context_copy::<B>,
            dispose_helper: block_context_dispose::<B>,
        }
    }
}

#[cfg(test)]
mod tests {
    use test_utils;
    use Id;
    use super::{Block, ConcreteBlock};

    #[test]
    fn test_call_block() {
        let mut block = test_utils::get_int_block_with(13);
        assert!(block.call(()) == 13);
    }

    #[test]
    fn test_call_block_args() {
        let mut block = test_utils::get_add_block_with(13);
        assert!(block.call((2,)) == 15);
    }

    #[test]
    fn test_create_block() {
        let mut block = ConcreteBlock::new(|| 13);
        let result = test_utils::invoke_int_block(&mut block);
        assert!(result == 13);
    }

    #[test]
    fn test_create_block_args() {
        let mut block = ConcreteBlock::new(|a: i32| a + 5);
        let result = test_utils::invoke_add_block(&mut block, 6);
        assert!(result == 11);
    }

    #[test]
    fn test_concrete_block_copy() {
        let s = "Hello!".to_string();
        let expected_len = s.len() as i32;
        let mut block = ConcreteBlock::new(move || s.len() as i32);
        assert!(test_utils::invoke_int_block(&mut block) == expected_len);

        let mut copied = block.copy();
        assert!(test_utils::invoke_int_block(&mut copied) == expected_len);
    }

    #[test]
    fn test_concrete_block_stack_copy() {
        fn make_block() -> Id<Block<(), i32>> {
            let x = 7;
            let block = ConcreteBlock::new(move || x);
            block.copy()
        }

        let mut block = make_block();
        assert!(test_utils::invoke_int_block(&mut block) == 7);
    }
}
<commit_msg>Added a BlockBase struct so Block is 0-sized.<commit_after>/*!
A Rust interface for Objective-C blocks.

For more information on the specifics of the block implementation, see
Clang's documentation: http://clang.llvm.org/docs/Block-ABI-Apple.html

# Invoking blocks

The `Block` struct is used for invoking blocks from Objective-C. For example,
consider this Objective-C function:

``` objc
int32_t sum(int32_t (^block)(int32_t, int32_t)) {
    return block(5, 8);
}
```

We could write it in Rust as the following:

```
# use objc::block::Block;
fn sum(block: &mut Block<(i32, i32), i32>) -> i32 {
    block.call((5, 8))
}
```

Note the extra parentheses in the `call` method, since the arguments must be
passed as a tuple.

# Creating blocks

Creating a block to pass to Objective-C can be done with the `ConcreteBlock`
struct. For example, to create a block that adds two `i32`s, we could write:

```
# use objc::block::ConcreteBlock;
let block = ConcreteBlock::new(|a: i32, b: i32| a + b);
let mut block = block.copy();
assert!(block.call((5, 8)) == 13);
```

It is important to copy your block to the heap (with the `copy` method) before
passing it to Objective-C; this is because our `ConcreteBlock` is only meant
to be copied once, and we can enforce this in Rust, but if Objective-C code
were to copy it twice we could have a double free.
*/

use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;
use libc::{c_int, c_ulong};

use runtime::{Class, Object};
use {EncodePtr, Id, Message};

#[link(name = "Foundation", kind = "framework")]
extern {
    static _NSConcreteStackBlock: Class;
}

/// Types that may be used as the arguments to an Objective-C block.
pub trait BlockArguments {
    /// Calls the given `Block` with self as the arguments.
    fn call_block<R>(self, block: &mut Block<Self, R>) -> R;
}

macro_rules! block_args_impl {
    ($($a:ident : $t:ident),*) => (
        impl<$($t),*> BlockArguments for ($($t,)*) {
            fn call_block<R>(self, block: &mut Block<Self, R>) -> R {
                let invoke: unsafe extern fn(*mut Block<Self, R> $(, $t)*) -> R = unsafe {
                    let base = &*(block as *mut _ as *mut BlockBase<Self, R>);
                    mem::transmute(base.invoke)
                };
                let ($($a,)*) = self;
                unsafe {
                    invoke(block $(, $a)*)
                }
            }
        }
    );
}

block_args_impl!();
block_args_impl!(a: A);
block_args_impl!(a: A, b: B);
block_args_impl!(a: A, b: B, c: C);
block_args_impl!(a: A, b: B, c: C, d: D);
block_args_impl!(a: A, b: B, c: C, d: D, e: E);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K);
block_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L);

#[repr(C)]
struct BlockBase<A, R> {
    isa: *const Class,
    flags: c_int,
    _reserved: c_int,
    invoke: unsafe extern fn(*mut Block<A, R>, ...) -> R,
}

/// An Objective-C block that takes arguments of `A` when called and
/// returns a value of `R`.
#[repr(C)]
pub struct Block<A, R> {
    _base: PhantomData<BlockBase<A, R>>,
}

// TODO: impl FnMut when it's possible
impl<A: BlockArguments, R> Block<A, R> where A: BlockArguments {
    /// Call self with the given arguments.
    pub fn call(&mut self, args: A) -> R {
        args.call_block(self)
    }
}

unsafe impl<A, R> Message for Block<A, R> { }

impl<A, R> EncodePtr for Block<A, R> {
    fn ptr_code() -> &'static str { "@?" }
}

/// Types that may be converted into a `ConcreteBlock`.
pub trait IntoConcreteBlock<A> where A: BlockArguments {
    /// The return type of the resulting `ConcreteBlock`.
    type Ret;

    /// Consumes self to create a `ConcreteBlock`.
    fn into_concrete_block(self) -> ConcreteBlock<A, Self::Ret, Self>;
}

macro_rules! concrete_block_impl {
    ($f:ident) => (
        concrete_block_impl!($f,);
    );
    ($f:ident, $($a:ident : $t:ident),*) => (
        impl<$($t,)* R, X> IntoConcreteBlock<($($t,)*)> for X
                where X: Fn($($t,)*) -> R {
            type Ret = R;

            fn into_concrete_block(self) -> ConcreteBlock<($($t,)*), R, X> {
                unsafe extern fn $f<$($t,)* R, X>(
                        block_ptr: *mut ConcreteBlock<($($t,)*), R, X>
                        $(, $a: $t)*) -> R
                        where X: Fn($($t,)*) -> R {
                    let block = &*block_ptr;
                    (block.closure)($($a),*)
                }

                unsafe {
                    ConcreteBlock::with_invoke(
                        mem::transmute($f::<$($t,)* R, X>), self)
                }
            }
        }
    );
}

concrete_block_impl!(concrete_block_invoke_args0);
concrete_block_impl!(concrete_block_invoke_args1, a: A);
concrete_block_impl!(concrete_block_invoke_args2, a: A, b: B);
concrete_block_impl!(concrete_block_invoke_args3, a: A, b: B, c: C);
concrete_block_impl!(concrete_block_invoke_args4, a: A, b: B, c: C, d: D);
concrete_block_impl!(concrete_block_invoke_args5, a: A, b: B, c: C, d: D, e: E);
concrete_block_impl!(concrete_block_invoke_args6, a: A, b: B, c: C, d: D, e: E, f: F);
concrete_block_impl!(concrete_block_invoke_args7, a: A, b: B, c: C, d: D, e: E, f: F, g: G);
concrete_block_impl!(concrete_block_invoke_args8, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H);
concrete_block_impl!(concrete_block_invoke_args9, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I);
concrete_block_impl!(concrete_block_invoke_args10, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J);
concrete_block_impl!(concrete_block_invoke_args11, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K);
concrete_block_impl!(concrete_block_invoke_args12, a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L);

/// An Objective-C block whose size is known at compile time and may be
/// constructed on the stack.
#[repr(C)]
pub struct ConcreteBlock<A, R, F> {
    base: BlockBase<A, R>,
    descriptor: Box<BlockDescriptor<ConcreteBlock<A, R, F>>>,
    closure: F,
}

impl<A, R, F> ConcreteBlock<A, R, F>
        where A: BlockArguments, F: IntoConcreteBlock<A, Ret=R> {
    /// Constructs a `ConcreteBlock` with the given closure.
    /// When the block is called, it will return the value that results from
    /// calling the closure.
    pub fn new(closure: F) -> Self {
        closure.into_concrete_block()
    }
}

impl<A, R, F> ConcreteBlock<A, R, F> {
    /// Constructs a `ConcreteBlock` with the given invoke function and closure.
    /// Unsafe because the caller must ensure the invoke function takes the
    /// correct arguments.
    unsafe fn with_invoke(invoke: unsafe extern fn(*mut Self, ...) -> R,
            closure: F) -> Self {
        ConcreteBlock {
            base: BlockBase {
                isa: &_NSConcreteStackBlock,
                // 1 << 25 = BLOCK_HAS_COPY_DISPOSE
                flags: 1 << 25,
                _reserved: 0,
                invoke: mem::transmute(invoke),
            },
            descriptor: Box::new(BlockDescriptor::new()),
            closure: closure,
        }
    }
}

impl<A, R, F> ConcreteBlock<A, R, F> where F: 'static {
    /// Copy self onto the heap.
    pub fn copy(self) -> Id<Block<A, R>> {
        unsafe {
            // The copy method is declared as returning an object pointer.
            let block: *mut Object = msg_send![&*self, copy];
            let block = block as *mut Block<A, R>;
            // At this point, our copy helper has been run so the block will
            // be moved to the heap and we can forget the original block
            // because the heap block will drop in our dispose helper.
            mem::forget(self);
            Id::from_retained_ptr(block)
        }
    }
}

impl<A, R, F> Clone for ConcreteBlock<A, R, F> where F: Clone {
    fn clone(&self) -> Self {
        unsafe {
            ConcreteBlock::with_invoke(mem::transmute(self.base.invoke),
                self.closure.clone())
        }
    }
}

impl<A, R, F> Deref for ConcreteBlock<A, R, F> {
    type Target = Block<A, R>;

    fn deref(&self) -> &Block<A, R> {
        unsafe { &*(&self.base as *const _ as *const Block<A, R>) }
    }
}

impl<A, R, F> DerefMut for ConcreteBlock<A, R, F> {
    fn deref_mut(&mut self) -> &mut Block<A, R> {
        unsafe { &mut *(&mut self.base as *mut _ as *mut Block<A, R>) }
    }
}

unsafe extern fn block_context_dispose<B>(block: &mut B) {
    // Read the block onto the stack and let it drop
    ptr::read(block);
}

unsafe extern fn block_context_copy<B>(_dst: &mut B, _src: &B) {
    // The runtime memmoves the src block into the dst block, nothing to do
}

#[repr(C)]
struct BlockDescriptor<B> {
    _reserved: c_ulong,
    block_size: c_ulong,
    copy_helper: unsafe extern fn(&mut B, &B),
    dispose_helper: unsafe extern fn(&mut B),
}

impl<B> BlockDescriptor<B> {
    fn new() -> BlockDescriptor<B> {
        BlockDescriptor {
            _reserved: 0,
            block_size: mem::size_of::<B>() as c_ulong,
            copy_helper: block_context_copy::<B>,
            dispose_helper: block_context_dispose::<B>,
        }
    }
}

#[cfg(test)]
mod tests {
    use test_utils;
    use Id;
    use super::{Block, ConcreteBlock};

    #[test]
    fn test_call_block() {
        let mut block = test_utils::get_int_block_with(13);
        assert!(block.call(()) == 13);
    }

    #[test]
    fn test_call_block_args() {
        let mut block = test_utils::get_add_block_with(13);
        assert!(block.call((2,)) == 15);
    }

    #[test]
    fn test_create_block() {
        let mut block = ConcreteBlock::new(|| 13);
        let result = test_utils::invoke_int_block(&mut block);
        assert!(result == 13);
    }

    #[test]
    fn test_create_block_args() {
        let mut block = ConcreteBlock::new(|a: i32| a + 5);
        let result = test_utils::invoke_add_block(&mut block, 6);
        assert!(result == 11);
    }

    #[test]
    fn test_concrete_block_copy() {
        let s = "Hello!".to_string();
        let expected_len = s.len() as i32;
        let mut block = ConcreteBlock::new(move || s.len() as i32);
        assert!(test_utils::invoke_int_block(&mut block) == expected_len);

        let mut copied = block.copy();
        assert!(test_utils::invoke_int_block(&mut copied) == expected_len);
    }

    #[test]
    fn test_concrete_block_stack_copy() {
        fn make_block() -> Id<Block<(), i32>> {
            let x = 7;
            let block = ConcreteBlock::new(move || x);
            block.copy()
        }

        let mut block = make_block();
        assert!(test_utils::invoke_int_block(&mut block) == 7);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate rls_analysis;
extern crate rls_data as data;
extern crate serde;
#[macro_use]
extern crate serde_json;

use data::GlobalCrateId;
use rls_analysis::{AnalysisHost, AnalysisLoader};
use std::collections::HashMap;
use std::fs::{self, File};
use std::path::{Path, PathBuf};

/// A global definition id in a crate.
///
/// FIXME(emilio): This key is kind of slow, because GlobalCrateId contains a
/// String. There's a "disambiguator" field which may be more than enough for
/// our purposes.
#[derive(Clone, Hash, Debug, Eq, PartialEq)]
pub struct DefId(GlobalCrateId, u32);

/// A map from global definition ids to the actual definition.
pub struct Defs {
    map: HashMap<DefId, data::Def>,
}

impl Defs {
    fn new() -> Self {
        Self { map: HashMap::new() }
    }

    fn insert(&mut self, analysis: &data::Analysis, def: &data::Def) {
        let crate_id = analysis.prelude.as_ref().unwrap().crate_id.clone();
        let mut definition = def.clone();
        let crate_independent_qualname =
            format!("{}{}", crate_id.name, def.qualname);
        definition.qualname = crate_independent_qualname;

        let index = definition.id.index;
        let previous = self.map.insert(DefId(crate_id, index), definition);
        if let Some(previous) = previous {
            // This shouldn't happen, but as of right now it can happen with
            // some builtin definitions when highly generic types are involved.
            // This is probably a rust bug, just ignore it for now.
            eprintln!(
                "Found a definition with the same ID twice? {:?}, {:?}",
                previous,
                def,
            );
        }
    }

    /// Getter for a given local id, which takes care of converting to a global
    /// ID and returning the definition if present.
    fn get(&self, analysis: &data::Analysis, id: data::Id) -> Option<data::Def> {
        let prelude = analysis.prelude.as_ref().unwrap();
        let krate_id = if id.krate == 0 {
            prelude.crate_id.clone()
        } else {
            // TODO(emilio): This escales with the number of crates in this
            // particular crate, but it's probably not too bad, since it should
            // be a pretty fast linear search.
            let krate = prelude.external_crates.iter().find(|krate| {
                krate.num == id.krate
            });

            let krate = match krate {
                Some(k) => k,
                None => {
                    eprintln!("Crate not found: {:?}", id);
                    return None;
                }
            };

            krate.id.clone()
        };

        let id = DefId(krate_id, id.index);
        self.map.get(&id).cloned()
    }
}

#[derive(Clone)]
pub struct Loader {
    deps_dir: PathBuf,
}

impl Loader {
    pub fn new(deps_dir: PathBuf) -> Self {
        Self { deps_dir }
    }
}

impl AnalysisLoader for Loader {
    fn needs_hard_reload(&self, _: &Path) -> bool {
        true
    }

    fn fresh_host(&self) -> AnalysisHost<Self> {
        AnalysisHost::new_with_loader(self.clone())
    }

    fn set_path_prefix(&mut self, _: &Path) {}

    fn abs_path_prefix(&self) -> Option<PathBuf> {
        None
    }
    fn search_directories(&self) -> Vec<PathBuf> {
        vec![self.deps_dir.clone()]
    }
}

// Searchfox uses 1-indexed lines, 0-indexed columns.
fn span_to_string(span: &data::SpanData) -> String {
    // Rust spans are multi-line... So we just set the start column if it spans
    // multiple rows, searchfox has fallback code to handle this.
    if span.line_start != span.line_end {
        return format!("{}:{}", span.line_start.0, span.column_start.0 - 1);
    }
    if span.column_start == span.column_end {
        return format!("{}:{}", span.line_start.0, span.column_start.0 - 1);
    }
    format!("{}:{}-{}", span.line_start.0, span.column_start.zero_indexed().0, span.column_end.zero_indexed().0)
}

fn visit(
    file: &mut File,
    kind: &'static str,
    location: &data::SpanData,
    qualname: &str,
    context: Option<&str>,
) {
    use serde_json::map::Map;
    use serde_json::value::Value;
    use std::io::Write;

    let mut out = Map::new();
    out.insert("loc".into(), Value::String(span_to_string(location)));
    out.insert("target".into(), json!(1));
    out.insert("kind".into(), Value::String(kind.into()));
    out.insert("pretty".into(), Value::String(qualname.into()));
    out.insert("sym".into(), Value::String(qualname.into()));
    if let Some(context) = context {
        out.insert("context".into(), Value::String(context.into()));
        out.insert("contextsym".into(), Value::String(context.into()));
    }

    let object = serde_json::to_string(&Value::Object(out)).unwrap();
    file.write_all(object.as_bytes()).unwrap();
    write!(file, "\n").unwrap();

    let mut out = Map::new();
    out.insert("loc".into(), Value::String(span_to_string(location)));
    out.insert("source".into(), json!(1));
    out.insert("kind".into(), Value::String(kind.into()));
    out.insert("pretty".into(), Value::String(qualname.into()));
    out.insert("sym".into(), Value::String(qualname.into()));

    let object = serde_json::to_string(&Value::Object(out)).unwrap();
    file.write_all(object.as_bytes()).unwrap();
    write!(file, "\n").unwrap();
}

fn analyze_file(
    file_name: &PathBuf,
    defs: &Defs,
    file_analysis: &data::Analysis,
    src_dir: &Path,
    output_dir: &Path,
) {
    let file = match file_name.strip_prefix(src_dir) {
        Ok(f) => f,
        Err(..) => {
            eprintln!("File not in the source directory: {}", file_name.display());
            return;
        }
    };

    let output_file = output_dir.join(file);
    let mut output_dir = output_file.clone();
    output_dir.pop();
    if let Err(err) = fs::create_dir_all(output_dir) {
        eprintln!(
            "Couldn't create dir for: {}, {:?}",
            output_file.display(),
            err
        );
        return;
    }
    let mut file = match File::create(&output_file) {
        Ok(f) => f,
        Err(err) => {
            eprintln!(
                "Couldn't open output file: {}, {:?}",
                output_file.display(),
                err
            );
            return;
        }
    };

    for import in &file_analysis.imports {
        let id = match import.ref_id {
            Some(id) => id,
            None => {
                eprintln!("Dropping import {} ({:?}): {}, no ref", import.name, import.kind, import.value);
                continue;
            }
        };

        let def = match defs.get(file_analysis, id) {
            Some(def) => def,
            None => {
                eprintln!("Dropping import {} ({:?}): {}, no def for ref {:?}", import.name, import.kind, import.value, id);
                continue;
            }
        };

        visit(&mut file, "use", &import.span, &def.qualname, None)
    }

    for def in &file_analysis.defs {
        let parent = def.parent
            .and_then(|parent_id| defs.get(file_analysis, parent_id).map(|d| d.qualname));

        let crate_name = &file_analysis.prelude.as_ref().unwrap().crate_id.name;
        let qualname = format!("{}{}", crate_name, def.qualname);
        visit(&mut file, "def", &def.span, &qualname, parent.as_ref().map(|p| &**p))
    }

    for ref_ in &file_analysis.refs {
        let def = match defs.get(file_analysis, ref_.ref_id) {
            Some(d) => d,
            None => {
                eprintln!("Dropping ref {:?}, kind {:?}, no def", ref_.ref_id, ref_.kind);
                continue;
            }
        };
        visit(
            &mut file,
            "use",
            &ref_.span,
            &def.qualname,
            /* context = */ None, // TODO
        )
    }
}

fn analyze_crate(
    analysis: &data::Analysis,
    defs: &Defs,
    src_dir: &Path,
    output_dir: &Path,
) {
    let mut per_file = HashMap::new();

    println!("Analyzing crate: {:?}", analysis.prelude);

    macro_rules! flat_map_per_file {
        ($field:ident) => {
            for item in &analysis.$field {
                let mut file_analysis =
                    per_file.entry(item.span.file_name.clone())
                        .or_insert_with(|| {
                            let prelude = analysis.prelude.clone();
                            let mut analysis = data::Analysis::new(analysis.config.clone());
                            analysis.prelude = prelude;
                            analysis
                        });
                file_analysis.$field.push(item.clone());
            }
        }
    }

    flat_map_per_file!(imports);
    flat_map_per_file!(defs);
    flat_map_per_file!(impls);
    flat_map_per_file!(refs);
    flat_map_per_file!(macro_refs);
    flat_map_per_file!(relations);

    for (mut name, analysis) in per_file.drain() {
        if name.is_relative() {
            name = src_dir.join(name);
        }
        analyze_file(&name, defs, &analysis, src_dir, output_dir);
    }
}

fn main() {
    let matches = app_from_crate!()
        .args_from_usage(
            "<src>    'Points to the source root'
             <input>  'Points to the deps/save-analysis directory'
             <output> 'Points to the directory where searchfox metadata should go'",
        )
        .get_matches();

    let src_dir = Path::new(matches.value_of("src").unwrap());
    let input_dir = Path::new(matches.value_of("input").unwrap());
    let output_dir = Path::new(matches.value_of("output").unwrap());

    let loader = Loader::new(PathBuf::from(input_dir));

    let crates = rls_analysis::read_analysis_from_files(&loader, Default::default(), &[]);

    let mut defs = Defs::new();
    for krate in &crates {
        for def in &krate.analysis.defs {
            println!("Indexing def: {:?}", def);
            defs.insert(&krate.analysis, def);
        }
    }

    for krate in crates {
        analyze_crate(&krate.analysis, &defs, &src_dir, &output_dir);
    }
}
<commit_msg>rust-indexer: Handle better trait function impls.<commit_after>#[macro_use]
extern crate clap;
extern crate rls_analysis;
extern crate rls_data as data;
extern crate serde;
#[macro_use]
extern crate serde_json;

use data::GlobalCrateId;
use data::DefKind;
use rls_analysis::{AnalysisHost, AnalysisLoader};
use std::collections::HashMap;
use std::fs::{self, File};
use std::path::{Path, PathBuf};

/// A global definition id in a crate.
///
/// FIXME(emilio): This key is kind of slow, because GlobalCrateId contains a
/// String. There's a "disambiguator" field which may be more than enough for
/// our purposes.
#[derive(Clone, Hash, Debug, Eq, PartialEq)]
pub struct DefId(GlobalCrateId, u32);

/// A map from global definition ids to the actual definition.
pub struct Defs {
    map: HashMap<DefId, data::Def>,
}

impl Defs {
    fn new() -> Self {
        Self { map: HashMap::new() }
    }

    fn insert(&mut self, analysis: &data::Analysis, def: &data::Def) {
        let crate_id = analysis.prelude.as_ref().unwrap().crate_id.clone();
        let mut definition = def.clone();
        let crate_independent_qualname =
            format!("{}{}", crate_id.name, def.qualname);
        definition.qualname = crate_independent_qualname;

        let index = definition.id.index;
        let previous = self.map.insert(DefId(crate_id, index), definition);
        if let Some(previous) = previous {
            // This shouldn't happen, but as of right now it can happen with
            // some builtin definitions when highly generic types are involved.
            // This is probably a rust bug, just ignore it for now.
            eprintln!(
                "Found a definition with the same ID twice? {:?}, {:?}",
                previous,
                def,
            );
        }
    }

    /// Getter for a given local id, which takes care of converting to a global
    /// ID and returning the definition if present.
    fn get(&self, analysis: &data::Analysis, id: data::Id) -> Option<data::Def> {
        let prelude = analysis.prelude.as_ref().unwrap();
        let krate_id = if id.krate == 0 {
            prelude.crate_id.clone()
        } else {
            // TODO(emilio): This escales with the number of crates in this
            // particular crate, but it's probably not too bad, since it should
            // be a pretty fast linear search.
            let krate = prelude.external_crates.iter().find(|krate| {
                krate.num == id.krate
            });

            let krate = match krate {
                Some(k) => k,
                None => {
                    eprintln!("Crate not found: {:?}", id);
                    return None;
                }
            };

            krate.id.clone()
        };

        let id = DefId(krate_id, id.index);
        self.map.get(&id).cloned()
    }
}

#[derive(Clone)]
pub struct Loader {
    deps_dir: PathBuf,
}

impl Loader {
    pub fn new(deps_dir: PathBuf) -> Self {
        Self { deps_dir }
    }
}

impl AnalysisLoader for Loader {
    fn needs_hard_reload(&self, _: &Path) -> bool {
        true
    }

    fn fresh_host(&self) -> AnalysisHost<Self> {
        AnalysisHost::new_with_loader(self.clone())
    }

    fn set_path_prefix(&mut self, _: &Path) {}

    fn abs_path_prefix(&self) -> Option<PathBuf> {
        None
    }
    fn search_directories(&self) -> Vec<PathBuf> {
        vec![self.deps_dir.clone()]
    }
}

// Searchfox uses 1-indexed lines, 0-indexed columns.
fn span_to_string(span: &data::SpanData) -> String {
    // Rust spans are multi-line... So we just set the start column if it spans
    // multiple rows, searchfox has fallback code to handle this.
    if span.line_start != span.line_end {
        return format!("{}:{}", span.line_start.0, span.column_start.0 - 1);
    }
    if span.column_start == span.column_end {
        return format!("{}:{}", span.line_start.0, span.column_start.0 - 1);
    }
    format!("{}:{}-{}", span.line_start.0, span.column_start.zero_indexed().0, span.column_end.zero_indexed().0)
}

fn visit(
    file: &mut File,
    kind: &'static str,
    location: &data::SpanData,
    qualname: &str,
    context: Option<&str>,
) {
    use serde_json::map::Map;
    use serde_json::value::Value;
    use std::io::Write;

    let mut out = Map::new();
    out.insert("loc".into(), Value::String(span_to_string(location)));
    out.insert("target".into(), json!(1));
    out.insert("kind".into(), Value::String(kind.into()));
    out.insert("pretty".into(), Value::String(qualname.into()));
    out.insert("sym".into(), Value::String(qualname.into()));
    if let Some(context) = context {
        out.insert("context".into(), Value::String(context.into()));
        out.insert("contextsym".into(), Value::String(context.into()));
    }

    let object = serde_json::to_string(&Value::Object(out)).unwrap();
    file.write_all(object.as_bytes()).unwrap();
    write!(file, "\n").unwrap();

    let mut out = Map::new();
    out.insert("loc".into(), Value::String(span_to_string(location)));
    out.insert("source".into(), json!(1));
    out.insert("kind".into(), Value::String(kind.into()));
    out.insert("pretty".into(), Value::String(qualname.into()));
    out.insert("sym".into(), Value::String(qualname.into()));

    let object = serde_json::to_string(&Value::Object(out)).unwrap();
    file.write_all(object.as_bytes()).unwrap();
    write!(file, "\n").unwrap();
}

fn analyze_file(
    file_name: &PathBuf,
    defs: &Defs,
    file_analysis: &data::Analysis,
    src_dir: &Path,
    output_dir: &Path,
) {
    let file = match file_name.strip_prefix(src_dir) {
        Ok(f) => f,
        Err(..) => {
            eprintln!("File not in the source directory: {}", file_name.display());
            return;
        }
    };

    let output_file = output_dir.join(file);
    let mut output_dir = output_file.clone();
    output_dir.pop();
    if let Err(err) = fs::create_dir_all(output_dir) {
        eprintln!(
            "Couldn't create dir for: {}, {:?}",
            output_file.display(),
            err
        );
        return;
    }
    let mut file = match File::create(&output_file) {
        Ok(f) => f,
        Err(err) => {
            eprintln!(
                "Couldn't open output file: {}, {:?}",
                output_file.display(),
                err
            );
            return;
        }
    };

    for import in &file_analysis.imports {
        let id = match import.ref_id {
            Some(id) => id,
            None => {
                eprintln!("Dropping import {} ({:?}): {}, no ref", import.name, import.kind, import.value);
                continue;
            }
        };

        let def = match defs.get(file_analysis, id) {
            Some(def) => def,
            None => {
                eprintln!("Dropping import {} ({:?}): {}, no def for ref {:?}", import.name, import.kind, import.value, id);
                continue;
            }
        };

        visit(&mut file, "use", &import.span, &def.qualname, None)
    }

    for def in &file_analysis.defs {
        let parent =
            def.parent.and_then(|parent_id| defs.get(file_analysis, parent_id));

        if let Some(ref parent) = parent {
            if parent.kind == DefKind::Trait {
                let trait_dependent_name =
                    format!("{}::{}", parent.qualname, def.name);
                visit(
                    &mut file,
                    "def",
                    &def.span,
                    &trait_dependent_name,
                    Some(&parent.qualname),
                )
            }
        }

        let crate_name = &file_analysis.prelude.as_ref().unwrap().crate_id.name;
        let qualname = format!("{}{}", crate_name, def.qualname);
        visit(&mut file, "def", &def.span, &qualname, parent.as_ref().map(|p| &*p.qualname))
    }

    for ref_ in &file_analysis.refs {
        let def = match defs.get(file_analysis, ref_.ref_id) {
            Some(d) => d,
            None => {
                eprintln!("Dropping ref {:?}, kind {:?}, no def", ref_.ref_id, ref_.kind);
                continue;
            }
        };
        visit(
            &mut file,
            "use",
            &ref_.span,
            &def.qualname,
            /* context = */ None, // TODO
        )
    }
}

fn analyze_crate(
    analysis: &data::Analysis,
    defs: &Defs,
    src_dir: &Path,
    output_dir: &Path,
) {
    let mut per_file = HashMap::new();

    println!("Analyzing crate: {:?}", analysis.prelude);

    macro_rules! flat_map_per_file {
        ($field:ident) => {
            for item in &analysis.$field {
                let mut file_analysis =
                    per_file.entry(item.span.file_name.clone())
                        .or_insert_with(|| {
                            let prelude = analysis.prelude.clone();
                            let mut analysis = data::Analysis::new(analysis.config.clone());
                            analysis.prelude = prelude;
                            analysis
                        });
                file_analysis.$field.push(item.clone());
            }
        }
    }

    flat_map_per_file!(imports);
    flat_map_per_file!(defs);
    flat_map_per_file!(impls);
    flat_map_per_file!(refs);
    flat_map_per_file!(macro_refs);
    flat_map_per_file!(relations);

    for (mut name, analysis) in per_file.drain() {
        if name.is_relative() {
            name = src_dir.join(name);
        }
        analyze_file(&name, defs, &analysis, src_dir, output_dir);
    }
}

fn main() {
    let matches = app_from_crate!()
        .args_from_usage(
            "<src>    'Points to the source root'
             <input>  'Points to the deps/save-analysis directory'
             <output> 'Points to the directory where searchfox metadata should go'",
        )
        .get_matches();

    let src_dir = Path::new(matches.value_of("src").unwrap());
    let input_dir = Path::new(matches.value_of("input").unwrap());
    let output_dir = Path::new(matches.value_of("output").unwrap());

    let loader = Loader::new(PathBuf::from(input_dir));

    let crates = rls_analysis::read_analysis_from_files(&loader, Default::default(), &[]);

    let mut defs = Defs::new();
    for krate in &crates {
        for def in &krate.analysis.defs {
            println!("Indexing def: {:?}", def);
            defs.insert(&krate.analysis, def);
        }
    }

    for krate in crates {
        analyze_crate(&krate.analysis, &defs, &src_dir, &output_dir);
    }
}
<|endoftext|>