<commit_before><commit_msg>Add tests for macro-based impls<commit_after>// 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.

#[derive(Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct Array<T> {
    f00: [T; 00],
    f01: [T; 01],
    f02: [T; 02],
    f03: [T; 03],
    f04: [T; 04],
    f05: [T; 05],
    f06: [T; 06],
    f07: [T; 07],
    f08: [T; 08],
    f09: [T; 09],
    f10: [T; 10],
    f11: [T; 11],
    f12: [T; 12],
    f13: [T; 13],
    f14: [T; 14],
    f15: [T; 15],
    f16: [T; 16],
    f17: [T; 17],
    f18: [T; 18],
    f19: [T; 19],
    f20: [T; 20],
    f21: [T; 21],
    f22: [T; 22],
    f23: [T; 23],
    f24: [T; 24],
    f25: [T; 25],
    f26: [T; 26],
    f27: [T; 27],
    f28: [T; 28],
    f29: [T; 29],
    f30: [T; 30],
    f31: [T; 31],
    f32: [T; 32],
}

// FIXME(#7622): merge with `Array` once `[T; N]: Clone` where `T: Clone`
#[derive(Clone, Copy)]
struct CopyArray<T: Copy> {
    f00: [T; 00],
    f01: [T; 01],
    f02: [T; 02],
    f03: [T; 03],
    f04: [T; 04],
    f05: [T; 05],
    f06: [T; 06],
    f07: [T; 07],
    f08: [T; 08],
    f09: [T; 09],
    f10: [T; 10],
    f11: [T; 11],
    f12: [T; 12],
    f13: [T; 13],
    f14: [T; 14],
    f15: [T; 15],
    f16: [T; 16],
    f17: [T; 17],
    f18: [T; 18],
    f19: [T; 19],
    f20: [T; 20],
    f21: [T; 21],
    f22: [T; 22],
    f23: [T; 23],
    f24: [T; 24],
    f25: [T; 25],
    f26: [T; 26],
    f27: [T; 27],
    f28: [T; 28],
    f29: [T; 29],
    f30: [T; 30],
    f31: [T; 31],
    f32: [T; 32],
}

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct Fn<A, B, C, D, E, F, G, H, I, J, K, L> {
    f00: fn(),
    f01: fn(A),
    f02: fn(A, B),
    f03: fn(A, B, C),
    f04: fn(A, B, C, D),
    f05: fn(A, B, C, D, E),
    f06: fn(A, B, C, D, E, F),
    f07: fn(A, B, C, D, E, F, G),
    f08: fn(A, B, C, D, E, F, G, H),
    f09: fn(A, B, C, D, E, F, G, H, I),
    f10: fn(A, B, C, D, E, F, G, H, I, J),
    f11: fn(A, B, C, D, E, F, G, H, I, J, K),
    f12: fn(A, B, C, D, E, F, G, H, I, J, K, L),
}

#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct Tuple<A, B, C, D, E, F, G, H, I, J, K, L> {
    f00: (),
    f01: (A),
    f02: (A, B),
    f03: (A, B, C),
    f04: (A, B, C, D),
    f05: (A, B, C, D, E),
    f06: (A, B, C, D, E, F),
    f07: (A, B, C, D, E, F, G),
    f08: (A, B, C, D, E, F, G, H),
    f09: (A, B, C, D, E, F, G, H, I),
    f10: (A, B, C, D, E, F, G, H, I, J),
    f11: (A, B, C, D, E, F, G, H, I, J, K),
    f12: (A, B, C, D, E, F, G, H, I, J, K, L),
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #50505 - Aaronepower:add-test, r=oli-obk<commit_after>// Copyright 2018 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.

type Func = fn(usize, usize) -> usize;

fn foo(a: usize, b: usize) -> usize { a + b }
fn bar(a: usize, b: usize) -> usize { a * b }
fn test(x: usize) -> Func {
    if x % 2 == 0 { foo }
    else { bar }
}

const FOO: Func = foo;
const BAR: Func = bar;

fn main() {
    match test(std::env::consts::ARCH.len()) {
        FOO => println!("foo"),
        BAR => println!("bar"),
        _ => unreachable!(),
    }
}
<|endoftext|>


<commit_before><commit_msg>there can never be too many tests<commit_after>#[repr(C)]
pub enum Foo {
    A, B, C, D
}

fn main() {
    let f = unsafe { std::mem::transmute::<i32, Foo>(42) };
    match f {
        Foo::A => {}, //~ ERROR invalid enum discriminant value read
        Foo::B => {},
        Foo::C => {},
        Foo::D => {},
    }
}
<|endoftext|>


<commit_before><commit_msg>basic structure<commit_after>extern crate core;

use core::num::FromPrimitive;
use core::fmt;

use Direction::{SpinUp, SpinDown, SpinSuper};
use Plan::{Trival, OddBall};

#[derive(Copy)]
#[derive(Show)]
enum Direction {
    SpinUp,
    SpinDown,
    SpinSuper,
}

impl fmt::String for Direction {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let r = match self {
            &SpinUp => "SpinUp",
            &SpinDown => "SpinDown",
            &SpinSuper => "SpinSuper"
        };
        write!(f, "{}", r)
    }
}

struct Pair<T> {
    lhs: T,
    rhs: T
}

struct Particle {
    spin: Direction
}

enum Plan {
    Trivial, // up-up-up -> down-down-down
    OddBall  // up-down-up -> down-up-down
}

enum Detector {
    D12, // 12 o'clock
    D3, // 3 o'clock
    D9, // 9 o' clock
}

impl Particle {
    fn new_pair () -> Pair<Particle> {
        let d1 = SpinSuper;
        let d2 = SpinSuper;
        let p1 = Particle{spin: d1};
        let p2 = Particle{spin: d2};

        return Pair{lhs: p1, rhs: p2};
    }

    pub fn measure (&mut self, theta: int) {
        // TODO theta = 60degrees use 3/4th and 1/4th
        // TODO theta = 0 SpinUp
        // TODO theta = 180 SpinDown
    }

    // NOTE on spooky and premeditated only if measured in the same
    // direction must the spins be opposite

    // measure with with a message
    pub fn spooky (&mut self, friend: &mut Particle) -> Pair<Direction> {

        let spin = match self.spin {
            SpinUp => SpinDown,
            SpinDown => SpinUp,
            SpinSuper => SpinUp
        };
        friend.spin = spin;

        let spin = match friend.spin {
            SpinUp => SpinDown,
            SpinDown => SpinUp,
            _ => panic!("broke the universe")
        };
        self.spin = spin;

        return Pair{lhs: self.spin, rhs: friend.spin};
    }

    pub fn premeditated (&mut self, friend: &mut Particle, theta: int, plan: Plan) -> Pair<Direction> {

        // TODO: Use plan
        friend.spin = SpinUp;

        let spin = match friend.spin {
            SpinUp => SpinDown,
            SpinDown => SpinUp,
            _ => panic!("broke the universe")
        };
        self.spin = spin;

        return Pair{lhs: self.spin, rhs: friend.spin};
    }
}

fn main () {

    let particles = Particle::new_pair();

    let mut lhs = particles.lhs;
    let mut rhs = particles.rhs;

    lhs.spooky(&mut rhs);

    println!("lhs.spin {}, rhs.spin {}", lhs.spin, rhs.spin);

    // premeditated should give +55.6% difference, spooky would give 50%
}
<|endoftext|>


<commit_before><commit_msg>Still insert items one at a time, but at least parse in a seperate thread.<commit_after><|endoftext|>


<commit_before><commit_msg>Added a repeater example demonstrating message throttling.<commit_after>extern crate irc;

use std::default::Default;
use irc::client::prelude::*;

fn main() {
    let config = Config {
        nickname: Some("repeater".to_owned()),
        alt_nicks: Some(vec!["blaster".to_owned(), "smg".to_owned()]),
        server: Some("irc.mozilla.org".to_owned()),
        use_ssl: Some(true),
        channels: Some(vec!["#rust-spam".to_owned()]),
        burst_window_length: Some(4),
        max_messages_in_burst: Some(4),
        ..Default::default()
    };

    let server = IrcServer::from_config(config).unwrap();
    server.identify().unwrap();

    server.for_each_incoming(|message| {
        print!("{}", message);
        match message.command {
            Command::PRIVMSG(ref target, ref msg) => {
                if msg.starts_with(server.current_nickname()) {
                    let tokens: Vec<_> = msg.split(" ").collect();
                    if tokens.len() > 2 {
                        let n = tokens[0].len() + tokens[1].len() + 2;
                        if let Ok(count) = tokens[1].parse::<u8>() {
                            for _ in 0..count {
                                server.send_privmsg(
                                    message.response_target().unwrap_or(target),
                                    &msg[n..]
                                ).unwrap();
                            }
                        }
                    }
                }
            }
            _ => (),
        }
    }).unwrap()
}
<|endoftext|>


<commit_before><commit_msg>Add a test for #38273<commit_after>// Copyright 2016 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.

// compile-flags: --emit=metadata
// no-prefer-dynamic
// must-compile-successfully

#[deny(warnings)]

// Test that we don't get warnings for non-pub main when only emitting metadata.
// (#38273)

fn main() {
}
<|endoftext|>


<commit_before><commit_msg>the minimal test for two-phase borrows: the core example from niko's blog post on it.<commit_after>// Copyright 2017 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.

// revisions: lxl nll
//[lxl]compile-flags: -Z borrowck=mir -Z two-phase-borrows
//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows -Z nll

// This is the "goto example" for why we want two phase borrows.

fn main() {
    let mut v = vec![0, 1, 2];
    v.push(v.len());
    assert_eq!(v, [0, 1, 2, 3]);
}
<|endoftext|>


<commit_before><commit_msg>regression test for issue #88583.<commit_after>// check-pass

#![allow(non_camel_case_types)]

struct union;

impl union {
    pub fn new() -> Self {
        union { }
    }
}

fn main() {
    let _u = union::new();
}
<|endoftext|>


<commit_before><commit_msg>Benchmark pattern and exception parsing<commit_after>#![feature(test)]

#[macro_use]
extern crate lazy_static;
extern crate test;

use std::path::PathBuf;
use test::Bencher;

extern crate hyphenation;
use hyphenation::{load, Language};
use hyphenation::exception::{Exceptions};
use hyphenation::pattern::{Patterns};

lazy_static! {
    static ref DATAPATH: PathBuf = {
        let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
        path.push("patterns");

        path
    };
}

#[bench]
fn parse_patterns_en_us(bench: &mut Bencher) {
    hyphenation::set_pattern_folder(DATAPATH.as_path());

    let by_line = load::patterns(Language::English_US).unwrap();
    let v: Vec<_> = by_line.collect();

    let mut ps = Patterns::empty();
    bench.iter(|| {
        for p in &v {
            for val in p { ps.insert(&*val) };
        }
    });
}

#[bench]
fn parse_exceptions_en_us(bench: &mut Bencher) {
    hyphenation::set_pattern_folder(DATAPATH.as_path());

    let by_line = load::exceptions(Language::English_US).unwrap();
    let v: Vec<_> = by_line.collect();

    let mut exs = Exceptions::empty();
    bench.iter(|| {
        for ex in &v {
            for val in ex { exs.insert(&*val) };
        }
    });
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::iter::Iterator;
use std::rc::Rc;
use std::ops::Deref;

use storage::file::File;

pub trait FilePrinter {

    fn new(verbose: bool, debug: bool) -> Self;

    /*
     * Print a single file
     */
    fn print_file(&self, Rc<RefCell<File>>);

    /*
     * Print a list of files
     */
    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        for file in files {
            self.print_file(file);
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        info!("{}", f(file).join(" "));
    }

    fn print_files_custom<F, I>(&self, files: I, f: &F)
        where I: Iterator<Item = Rc<RefCell<File>>>,
              F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        for file in files {
            self.print_file_custom(file, f);
        }
    }

}

struct DebugPrinter {
    debug: bool,
}

impl FilePrinter for DebugPrinter {

    fn new(_: bool, debug: bool) -> DebugPrinter {
        DebugPrinter {
            debug: debug,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f);
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f(file).join(" "));
        }
    }

}

struct SimplePrinter {
    verbose:    bool,
    debug:      bool,
}

impl FilePrinter for SimplePrinter {

    fn new(verbose: bool, debug: bool) -> SimplePrinter {
        SimplePrinter {
            debug:      debug,
            verbose:    verbose,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("{:?}", f);
        } else if self.verbose {
            info!("{}", &*f.deref().borrow());
        } else {
            info!("[File]: {}", f.deref().borrow().id());
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        let s = f(file).join(" ");
        if self.debug {
            debug!("{:?}", s);
        } else if self.verbose {
            info!("{}", s);
        } else {
            info!("[File]: {}", s);
        }
    }

}

pub struct TablePrinter {
    verbose:    bool,
    debug:      bool,
    sp:         SimplePrinter,
}

impl FilePrinter for TablePrinter {

    fn new(verbose: bool, debug: bool) -> TablePrinter {
        TablePrinter {
            debug:      debug,
            verbose:    verbose,
            sp:         SimplePrinter::new(verbose, debug),
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        self.sp.print_file(f);
    }

    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["File#", "Owner", "ID"];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.deref().borrow().owner_name())[..]);

            let id : String = file.deref().borrow().id().clone().into();
            let cell_id = Cell::new(&id[..]);
            let row = Row::new(vec![cell_i, cell_o, cell_id]);
            tab.add_row(row);
        }

        if i != 0 {
            debug!("Printing {} table entries", i);
            tab.printstd();
        } else {
            debug!("Not printing table because there are zero entries");
        }
    }

    fn print_files_custom<F, I>(&self, files: I, f: &F)
        where I: Iterator<Item = Rc<RefCell<File>>>,
              F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["#", "Module", "ID", "..."];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.deref().borrow().owner_name())[..]);

            let id : String = file.deref().borrow().id().clone().into();
            let cell_id = Cell::new(&id[..]);

            let mut row = Row::new(vec![cell_i, cell_o, cell_id]);

            for cell in f(file).iter() {
                debug!("Adding custom cell: {:?}", cell);
                row.add_cell(Cell::new(&cell[..]))
            }

            tab.add_row(row);
        }

        if i != 0 {
            debug!("Printing {} table entries", i);
            tab.printstd();
        } else {
            debug!("Not printing table because there are zero entries");
        }
    }

}
<commit_msg>Add docs to ui/file.rs<commit_after>use std::cell::RefCell;
use std::iter::Iterator;
use std::rc::Rc;
use std::ops::Deref;

use storage::file::File;

/**
 * Trait for a printer which can be used to print data from files
 */
pub trait FilePrinter {

    fn new(verbose: bool, debug: bool) -> Self;

    /*
     * Print a single file
     */
    fn print_file(&self, Rc<RefCell<File>>);

    /*
     * Print a list of files
     */
    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        for file in files {
            self.print_file(file);
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        info!("{}", f(file).join(" "));
    }

    fn print_files_custom<F, I>(&self, files: I, f: &F)
        where I: Iterator<Item = Rc<RefCell<File>>>,
              F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        for file in files {
            self.print_file_custom(file, f);
        }
    }

}

/**
 * Printer which prints in debug mode if enabled
 */
struct DebugPrinter {
    debug: bool,
}

impl FilePrinter for DebugPrinter {

    fn new(_: bool, debug: bool) -> DebugPrinter {
        DebugPrinter {
            debug: debug,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f);
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f(file).join(" "));
        }
    }

}

/**
 * Simple printer, which just uses the info!() macro or debug!() macro if in debug mode.
 */
struct SimplePrinter {
    verbose:    bool,
    debug:      bool,
}

impl FilePrinter for SimplePrinter {

    fn new(verbose: bool, debug: bool) -> SimplePrinter {
        SimplePrinter {
            debug:      debug,
            verbose:    verbose,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("{:?}", f);
        } else if self.verbose {
            info!("{}", &*f.deref().borrow());
        } else {
            info!("[File]: {}", f.deref().borrow().id());
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        let s = f(file).join(" ");
        if self.debug {
            debug!("{:?}", s);
        } else if self.verbose {
            info!("{}", s);
        } else {
            info!("[File]: {}", s);
        }
    }

}

/**
 * Table printer to print file information in a nice ASCII-table
 */
pub struct TablePrinter {
    verbose:    bool,
    debug:      bool,
    sp:         SimplePrinter,
}

impl FilePrinter for TablePrinter {

    fn new(verbose: bool, debug: bool) -> TablePrinter {
        TablePrinter {
            debug:      debug,
            verbose:    verbose,
            sp:         SimplePrinter::new(verbose, debug),
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        self.sp.print_file(f);
    }

    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["File#", "Owner", "ID"];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.deref().borrow().owner_name())[..]);

            let id : String = file.deref().borrow().id().clone().into();
            let cell_id = Cell::new(&id[..]);
            let row = Row::new(vec![cell_i, cell_o, cell_id]);
            tab.add_row(row);
        }

        if i != 0 {
            debug!("Printing {} table entries", i);
            tab.printstd();
        } else {
            debug!("Not printing table because there are zero entries");
        }
    }

    fn print_files_custom<F, I>(&self, files: I, f: &F)
        where I: Iterator<Item = Rc<RefCell<File>>>,
              F: Fn(Rc<RefCell<File>>) -> Vec<String>
    {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["#", "Module", "ID", "..."];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.deref().borrow().owner_name())[..]);

            let id : String = file.deref().borrow().id().clone().into();
            let cell_id = Cell::new(&id[..]);

            let mut row = Row::new(vec![cell_i, cell_o, cell_id]);

            for cell in f(file).iter() {
                debug!("Adding custom cell: {:?}", cell);
                row.add_cell(Cell::new(&cell[..]))
            }

            tab.add_row(row);
        }

        if i != 0 {
            debug!("Printing {} table entries", i);
            tab.printstd();
        } else {
            debug!("Not printing table because there are zero entries");
        }
    }

}
<|endoftext|>


<commit_before><commit_msg>add test for changing pub inherent method body<commit_after>// Copyright 2014 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.

// Test where we change the body of a private method in an impl.
// We then test what sort of functions must be rebuilt as a result.

// revisions:rpass1 rpass2
// compile-flags: -Z query-dep-graph

#![feature(rustc_attrs)]
#![feature(stmt_expr_attributes)]
#![allow(dead_code)]

#![rustc_partition_translated(module="struct_point-point", cfg="rpass2")]

// FIXME(#35078) -- this gets recompiled because we don't separate sig from body
#![rustc_partition_translated(module="struct_point-fn_calls_changed_method", cfg="rpass2")]
// FIXME(#36349) -- this gets recompiled because we don't separate items from impl
#![rustc_partition_translated(module="struct_point-fn_calls_another_method", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_make_struct", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_read_field", cfg="rpass2")]
#![rustc_partition_reused(module="struct_point-fn_write_field", cfg="rpass2")]

mod point {
    pub struct Point {
        pub x: f32,
        pub y: f32,
    }

    impl Point {
        pub fn distance_from_origin(&self) -> f32 {
            #[cfg(rpass1)]
            return self.x * self.x + self.y * self.y;

            #[cfg(rpass2)]
            return (self.x * self.x + self.y * self.y).sqrt();
        }

        pub fn x(&self) -> f32 {
            self.x
        }
    }
}

/// A fn item that calls (public) methods on `Point` from the same impl which changed
mod fn_calls_changed_method {
    use point::Point;

    // FIXME(#35078) -- this gets recompiled because we don't separate sig from body
    #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
    pub fn check() {
        let p = Point { x: 2.0, y: 2.0 };
        p.distance_from_origin();
    }
}

/// A fn item that calls (public) methods on `Point` from the same impl which changed
mod fn_calls_another_method {
    use point::Point;

    // FIXME(#36349) -- this gets recompiled because we don't separate items from impl
    #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")]
    pub fn check() {
        let p = Point { x: 2.0, y: 2.0 };
        p.x();
    }
}

/// A fn item that makes an instance of `Point` but does not invoke methods
mod fn_make_struct {
    use point::Point;

    #[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
    pub fn make_origin() -> Point {
        Point { x: 2.0, y: 2.0 }
    }
}

/// A fn item that reads fields from `Point` but does not invoke methods
mod fn_read_field {
    use point::Point;

    #[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
    pub fn get_x(p: Point) -> f32 {
        p.x
    }
}

/// A fn item that writes to a field of `Point` but does not invoke methods
mod fn_write_field {
    use point::Point;

    #[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
    pub fn inc_x(p: &mut Point) {
        p.x += 1.0;
    }
}

fn main() {
}
<|endoftext|>


<commit_before><commit_msg>Refactor: cleanup printing<commit_after><|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::WebSocketBinding;
use dom::bindings::codegen::Bindings::WebSocketBinding::WebSocketMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::InheritTypes::EventTargetCast;
use dom::bindings::codegen::InheritTypes::EventCast;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::error::Error::{InvalidAccess, Syntax};
use dom::bindings::global::{GlobalField, GlobalRef};
use dom::bindings::js::Root;
use dom::bindings::refcounted::Trusted;
use dom::bindings::str::USVString;
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::reflect_dom_object;
use dom::closeevent::CloseEvent;
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
use script_task::Runnable;
use script_task::ScriptMsg;
use std::cell::{Cell, RefCell};
use std::borrow::ToOwned;
use util::str::DOMString;

use hyper::header::Host;
use websocket::Message;
use websocket::ws::sender::Sender as Sender_Object;
use websocket::client::sender::Sender;
use websocket::client::receiver::Receiver;
use websocket::stream::WebSocketStream;
use websocket::client::request::Url;
use websocket::Client;
use websocket::header::Origin;
use websocket::result::WebSocketResult;
use websocket::ws::util::url::parse_url;

#[derive(JSTraceable, PartialEq, Copy, Clone)]
enum WebSocketRequestState {
    Connecting = 0,
    Open = 1,
    Closing = 2,
    Closed = 3,
}

no_jsmanaged_fields!(Sender<WebSocketStream>);
no_jsmanaged_fields!(Receiver<WebSocketStream>);

#[dom_struct]
pub struct WebSocket {
    eventtarget: EventTarget,
    url: Url,
    global: GlobalField,
    ready_state: Cell<WebSocketRequestState>,
    sender: RefCell<Option<Sender<WebSocketStream>>>,
    receiver: RefCell<Option<Receiver<WebSocketStream>>>,
    failed: Cell<bool>, //Flag to tell if websocket was closed due to failure
    full: Cell<bool>, //Flag to tell if websocket queue is full
    clean_close: Cell<bool>, //Flag to tell if the websocket closed cleanly (not due to full or fail)
    code: Cell<u16>, //Closing code
    reason: DOMRefCell<DOMString>, //Closing reason
    data: DOMRefCell<DOMString>, //Data from send - TODO: Remove after buffer is added.
    sendCloseFrame: Cell<bool>
}

/// *Establish a WebSocket Connection* as defined in RFC 6455.
fn establish_a_websocket_connection(url: (Host, String, bool), origin: String)
    -> WebSocketResult<(Sender<WebSocketStream>, Receiver<WebSocketStream>)> {
    let mut request = try!(Client::connect(url));
    request.headers.set(Origin(origin));

    let response = try!(request.send());
    try!(response.validate());

    Ok(response.begin().split())
}

impl WebSocket {
    pub fn new_inherited(global: GlobalRef, url: Url) -> WebSocket {
        WebSocket {
            eventtarget: EventTarget::new_inherited(EventTargetTypeId::WebSocket),
            url: url,
            global: GlobalField::from_rooted(&global),
            ready_state: Cell::new(WebSocketRequestState::Connecting),
            failed: Cell::new(false),
            sender: RefCell::new(None),
            receiver: RefCell::new(None),
            full: Cell::new(false),
            clean_close: Cell::new(true),
            code: Cell::new(0),
            reason: DOMRefCell::new("".to_owned()),
            data: DOMRefCell::new("".to_owned()),
            sendCloseFrame: Cell::new(false)
        }

    }

    pub fn new(global: GlobalRef, url: DOMString) -> Fallible<Root<WebSocket>> {
        // Step 1.
        let parsed_url = try!(Url::parse(&url).map_err(|_| Error::Syntax));
        let url = try!(parse_url(&parsed_url).map_err(|_| Error::Syntax));

        /*TODO: This constructor is only a prototype, it does not accomplish the specs
          defined here:
          http://html.spec.whatwg.org
          The remaining 8 items must be satisfied.
          TODO: This constructor should be responsible for spawning a thread for the
          receive loop after ws.r().Open() - See comment
        */
        let ws = reflect_dom_object(box WebSocket::new_inherited(global, parsed_url),
                                    global,
                                    WebSocketBinding::Wrap);

        let channel = establish_a_websocket_connection(url, global.get_url().serialize());
        let (temp_sender, temp_receiver) = match channel {
            Ok(channel) => channel,
            Err(e) => {
                debug!("Failed to establish a WebSocket connection: {:?}", e);
                let global_root = ws.r().global.root();
                let address = Trusted::new(global_root.r().get_cx(), ws.r(), global_root.r().script_chan().clone());
                let task = box WebSocketTaskHandler::new(address, WebSocketTask::Close);
                global_root.r().script_chan().send(ScriptMsg::RunnableMsg(task)).unwrap();
                return Ok(ws);
            }
        };

        *ws.r().sender.borrow_mut() = Some(temp_sender);
        *ws.r().receiver.borrow_mut() = Some(temp_receiver);

        //Create everything necessary for starting the open asynchronous task, then begin the task.
        let global_root = ws.r().global.root();
        let addr: Trusted<WebSocket> =
            Trusted::new(global_root.r().get_cx(), ws.r(), global_root.r().script_chan().clone());
        let open_task = box WebSocketTaskHandler::new(addr, WebSocketTask::ConnectionEstablished);
        global_root.r().script_chan().send(ScriptMsg::RunnableMsg(open_task)).unwrap();
        //TODO: Spawn thread here for receive loop
        /*TODO: Add receive loop here and make new thread run this
          Receive is an infinite loop "similiar" the one shown here:
          https://github.com/cyderize/rust-websocket/blob/master/examples/client.rs#L64
          TODO: The receive loop however does need to follow the spec. These are outlined here
          under "WebSocket message has been received" items 1-5:
          https://github.com/cyderize/rust-websocket/blob/master/examples/client.rs#L64
          TODO: The receive loop also needs to dispatch an asynchronous event as stated here:
          https://github.com/cyderize/rust-websocket/blob/master/examples/client.rs#L64
          TODO: When the receive loop receives a close message from the server,
          it confirms the websocket is now closed. This requires the close event
          to be fired (dispatch_close fires the close event - see implementation below)
        */
        Ok(ws)
    }

    pub fn Constructor(global: GlobalRef, url: DOMString) -> Fallible<Root<WebSocket>> {
        WebSocket::new(global, url)
    }
}

impl<'a> WebSocketMethods for &'a WebSocket {
    event_handler!(open, GetOnopen, SetOnopen);
    event_handler!(close, GetOnclose, SetOnclose);
    event_handler!(error, GetOnerror, SetOnerror);

    fn Url(self) -> DOMString {
        self.url.serialize()
    }

    fn ReadyState(self) -> u16 {
        self.ready_state.get() as u16
    }

    fn Send(self, data: Option<USVString>) -> Fallible<()> {
        if self.ready_state.get() == WebSocketRequestState::Connecting {
            return Err(Error::InvalidState);
        }

        /*TODO: This is not up to spec see http://html.spec.whatwg.org/multipage/comms.html search for
                "If argument is a string"
          TODO: Need to buffer data
          TODO: bufferedAmount attribute returns the size of the buffer in bytes -
                this is a required attribute defined in the websocket.webidl file
          TODO: The send function needs to flag when full by using the following
          self.full.set(true). This needs to be done when the buffer is full
        */
        let mut other_sender = self.sender.borrow_mut();
        let my_sender = other_sender.as_mut().unwrap();
        if self.sendCloseFrame.get() { //TODO: Also check if the buffer is full
            self.sendCloseFrame.set(false);
            let _ = my_sender.send_message(Message::Close(None));
            return Ok(());
        }
        let _ = my_sender.send_message(Message::Text(data.unwrap().0));
        return Ok(())
    }

    fn Close(self, code: Option<u16>, reason: Option<USVString>) -> Fallible<()>{
        if let Some(code) = code {
            //Check code is NOT 1000 NOR in the range of 3000-4999 (inclusive)
            if  code != 1000 && (code < 3000 || code > 4999) {
                return Err(Error::InvalidAccess);
            }
        }
        if let Some(ref reason) = reason {
            if reason.0.as_bytes().len() > 123 { //reason cannot be larger than 123 bytes
                return Err(Error::Syntax);
            }
        }

        match self.ready_state.get() {
            WebSocketRequestState::Closing | WebSocketRequestState::Closed  => {} //Do nothing
            WebSocketRequestState::Connecting => { //Connection is not yet established
                /*By setting the state to closing, the open function
                  will abort connecting the websocket*/
                self.ready_state.set(WebSocketRequestState::Closing);
                self.failed.set(true);
                self.sendCloseFrame.set(true);
                //Dispatch send task to send close frame
                //TODO: Sending here is just empty string, though no string is really needed. Another send, empty
                //      send, could be used.
                let _ = self.Send(None);
                //Note: After sending the close message, the receive loop confirms a close message from the server and
                //      must fire a close event
            }
            WebSocketRequestState::Open => {
                //Closing handshake not started - still in open
                //Start the closing by setting the code and reason if they exist
                if let Some(code) = code {
                    self.code.set(code);
                }
                if let Some(reason) = reason {
                    *self.reason.borrow_mut() = reason.0;
                }
                self.ready_state.set(WebSocketRequestState::Closing);
                self.sendCloseFrame.set(true);
                //Dispatch send task to send close frame
                let _ = self.Send(None);
                //Note: After sending the close message, the receive loop confirms a close message from the server and
                //      must fire a close event
            }
        }
        Ok(()) //Return Ok
    }
}

pub enum WebSocketTask {
    /// Task queued when *the WebSocket connection is established*.
    ConnectionEstablished,
    Close,
}

pub struct WebSocketTaskHandler {
    addr: Trusted<WebSocket>,
    task: WebSocketTask,
}

impl WebSocketTaskHandler {
    pub fn new(addr: Trusted<WebSocket>, task: WebSocketTask) -> WebSocketTaskHandler {
        WebSocketTaskHandler {
            addr: addr,
            task: task,
        }
    }

    fn connection_established(&self) {
        /*TODO: Items 1, 3, 4, & 5 under "WebSocket connection is established" as specified here:
          https://html.spec.whatwg.org/multipage/#feedback-from-the-protocol
        */
        let ws = self.addr.root();

        // Step 1: Protocols.

        // Step 2.
        ws.ready_state.set(WebSocketRequestState::Open);

        // Step 3: Extensions.
        // Step 4: Protocols.
        // Step 5: Cookies.

        // Step 6.
        let global = ws.global.root();
        let event = Event::new(global.r(), "open".to_owned(),
                               EventBubbles::DoesNotBubble,
                               EventCancelable::NotCancelable);
        event.fire(EventTargetCast::from_ref(ws.r()));
    }

    fn dispatch_close(&self) {
        let ws = self.addr.root();
        let ws = ws.r();
        let global = ws.global.root();
        ws.ready_state.set(WebSocketRequestState::Closed);
        //If failed or full, fire error event
        if ws.failed.get() || ws.full.get() {
            ws.failed.set(false);
            ws.full.set(false);
            //A Bad close
            ws.clean_close.set(false);
            let event = Event::new(global.r(),
                                   "error".to_owned(),
                                   EventBubbles::DoesNotBubble,
                                   EventCancelable::Cancelable);
            let target = EventTargetCast::from_ref(ws);
            event.r().fire(target);
        }
        let rsn = ws.reason.borrow();
        let rsn_clone = rsn.clone();
        /*In addition, we also have to fire a close even if error event fired
         https://html.spec.whatwg.org/multipage/#closeWebSocket
        */
        let close_event = CloseEvent::new(global.r(),
                                          "close".to_owned(),
                                          EventBubbles::DoesNotBubble,
                                          EventCancelable::NotCancelable,
                                          ws.clean_close.get(),
                                          ws.code.get(),
                                          rsn_clone);
        let target = EventTargetCast::from_ref(ws);
        let event = EventCast::from_ref(close_event.r());
        event.fire(target);
    }
}

impl Runnable for WebSocketTaskHandler {
    fn handler(self: Box<WebSocketTaskHandler>) {
        match self.task {
            WebSocketTask::ConnectionEstablished => {
                self.connection_established();
            }
            WebSocketTask::Close => {
                self.dispatch_close();
            }
        }
    }
}

<commit_msg>Remove WebSocket::sendCloseFrame.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::WebSocketBinding;
use dom::bindings::codegen::Bindings::WebSocketBinding::WebSocketMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::InheritTypes::EventTargetCast;
use dom::bindings::codegen::InheritTypes::EventCast;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::error::Error::{InvalidAccess, Syntax};
use dom::bindings::global::{GlobalField, GlobalRef};
use dom::bindings::js::Root;
use dom::bindings::refcounted::Trusted;
use dom::bindings::str::USVString;
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::reflect_dom_object;
use dom::closeevent::CloseEvent;
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
use script_task::Runnable;
use script_task::ScriptMsg;
use std::cell::{Cell, RefCell};
use std::borrow::ToOwned;
use util::str::DOMString;

use hyper::header::Host;
use websocket::Message;
use websocket::ws::sender::Sender as Sender_Object;
use websocket::client::sender::Sender;
use websocket::client::receiver::Receiver;
use websocket::stream::WebSocketStream;
use websocket::client::request::Url;
use websocket::Client;
use websocket::header::Origin;
use websocket::result::WebSocketResult;
use websocket::ws::util::url::parse_url;

#[derive(JSTraceable, PartialEq, Copy, Clone)]
enum WebSocketRequestState {
    Connecting = 0,
    Open = 1,
    Closing = 2,
    Closed = 3,
}

no_jsmanaged_fields!(Sender<WebSocketStream>);
no_jsmanaged_fields!(Receiver<WebSocketStream>);

#[dom_struct]
pub struct WebSocket {
    eventtarget: EventTarget,
    url: Url,
    global: GlobalField,
    ready_state: Cell<WebSocketRequestState>,
    sender: RefCell<Option<Sender<WebSocketStream>>>,
    receiver: RefCell<Option<Receiver<WebSocketStream>>>,
    failed: Cell<bool>, //Flag to tell if websocket was closed due to failure
    full: Cell<bool>, //Flag to tell if websocket queue is full
    clean_close: Cell<bool>, //Flag to tell if the websocket closed cleanly (not due to full or fail)
    code: Cell<u16>, //Closing code
    reason: DOMRefCell<DOMString>, //Closing reason
    data: DOMRefCell<DOMString>, //Data from send - TODO: Remove after buffer is added.
}

/// *Establish a WebSocket Connection* as defined in RFC 6455.
fn establish_a_websocket_connection(url: (Host, String, bool), origin: String)
    -> WebSocketResult<(Sender<WebSocketStream>, Receiver<WebSocketStream>)> {
    let mut request = try!(Client::connect(url));
    request.headers.set(Origin(origin));

    let response = try!(request.send());
    try!(response.validate());

    Ok(response.begin().split())
}

impl WebSocket {
    pub fn new_inherited(global: GlobalRef, url: Url) -> WebSocket {
        WebSocket {
            eventtarget: EventTarget::new_inherited(EventTargetTypeId::WebSocket),
            url: url,
            global: GlobalField::from_rooted(&global),
            ready_state: Cell::new(WebSocketRequestState::Connecting),
            failed: Cell::new(false),
            sender: RefCell::new(None),
            receiver: RefCell::new(None),
            full: Cell::new(false),
            clean_close: Cell::new(true),
            code: Cell::new(0),
            reason: DOMRefCell::new("".to_owned()),
            data: DOMRefCell::new("".to_owned()),
        }

    }

    pub fn new(global: GlobalRef, url: DOMString) -> Fallible<Root<WebSocket>> {
        // Step 1.
        let parsed_url = try!(Url::parse(&url).map_err(|_| Error::Syntax));
        let url = try!(parse_url(&parsed_url).map_err(|_| Error::Syntax));

        /*TODO: This constructor is only a prototype, it does not accomplish the specs
          defined here:
          http://html.spec.whatwg.org
          The remaining 8 items must be satisfied.
          TODO: This constructor should be responsible for spawning a thread for the
          receive loop after ws.r().Open() - See comment
        */
        let ws = reflect_dom_object(box WebSocket::new_inherited(global, parsed_url),
                                    global,
                                    WebSocketBinding::Wrap);

        let channel = establish_a_websocket_connection(url, global.get_url().serialize());
        let (temp_sender, temp_receiver) = match channel {
            Ok(channel) => channel,
            Err(e) => {
                debug!("Failed to establish a WebSocket connection: {:?}", e);
                let global_root = ws.r().global.root();
                let address = Trusted::new(global_root.r().get_cx(), ws.r(), global_root.r().script_chan().clone());
                let task = box WebSocketTaskHandler::new(address, WebSocketTask::Close);
                global_root.r().script_chan().send(ScriptMsg::RunnableMsg(task)).unwrap();
                return Ok(ws);
            }
        };

        *ws.r().sender.borrow_mut() = Some(temp_sender);
        *ws.r().receiver.borrow_mut() = Some(temp_receiver);

        //Create everything necessary for starting the open asynchronous task, then begin the task.
        let global_root = ws.r().global.root();
        let addr: Trusted<WebSocket> =
            Trusted::new(global_root.r().get_cx(), ws.r(), global_root.r().script_chan().clone());
        let open_task = box WebSocketTaskHandler::new(addr, WebSocketTask::ConnectionEstablished);
        global_root.r().script_chan().send(ScriptMsg::RunnableMsg(open_task)).unwrap();
        //TODO: Spawn thread here for receive loop
        /*TODO: Add receive loop here and make new thread run this
          Receive is an infinite loop "similiar" the one shown here:
          https://github.com/cyderize/rust-websocket/blob/master/examples/client.rs#L64
          TODO: The receive loop however does need to follow the spec. These are outlined here
          under "WebSocket message has been received" items 1-5:
          https://github.com/cyderize/rust-websocket/blob/master/examples/client.rs#L64
          TODO: The receive loop also needs to dispatch an asynchronous event as stated here:
          https://github.com/cyderize/rust-websocket/blob/master/examples/client.rs#L64
          TODO: When the receive loop receives a close message from the server,
          it confirms the websocket is now closed. This requires the close event
          to be fired (dispatch_close fires the close event - see implementation below)
        */
        Ok(ws)
    }

    pub fn Constructor(global: GlobalRef, url: DOMString) -> Fallible<Root<WebSocket>> {
        WebSocket::new(global, url)
    }
}

impl<'a> WebSocketMethods for &'a WebSocket {
    event_handler!(open, GetOnopen, SetOnopen);
    event_handler!(close, GetOnclose, SetOnclose);
    event_handler!(error, GetOnerror, SetOnerror);

    fn Url(self) -> DOMString {
        self.url.serialize()
    }

    fn ReadyState(self) -> u16 {
        self.ready_state.get() as u16
    }

    fn Send(self, data: Option<USVString>) -> Fallible<()> {
        if self.ready_state.get() == WebSocketRequestState::Connecting {
            return Err(Error::InvalidState);
        }

        /*TODO: This is not up to spec see http://html.spec.whatwg.org/multipage/comms.html search for
                "If argument is a string"
          TODO: Need to buffer data
          TODO: bufferedAmount attribute returns the size of the buffer in bytes -
                this is a required attribute defined in the websocket.webidl file
          TODO: The send function needs to flag when full by using the following
          self.full.set(true). This needs to be done when the buffer is full
        */
        let mut other_sender = self.sender.borrow_mut();
        let my_sender = other_sender.as_mut().unwrap();
        let _ = my_sender.send_message(Message::Text(data.unwrap().0));
        return Ok(())
    }

    fn Close(self, code: Option<u16>, reason: Option<USVString>) -> Fallible<()>{
        fn send_close(this: &WebSocket) {
            this.ready_state.set(WebSocketRequestState::Closing);

            let mut sender = this.sender.borrow_mut();
            //TODO: Also check if the buffer is full
            let _ = sender.as_mut().unwrap().send_message(Message::Close(None));
        }

        if let Some(code) = code {
            //Check code is NOT 1000 NOR in the range of 3000-4999 (inclusive)
            if  code != 1000 && (code < 3000 || code > 4999) {
                return Err(Error::InvalidAccess);
            }
        }
        if let Some(ref reason) = reason {
            if reason.0.as_bytes().len() > 123 { //reason cannot be larger than 123 bytes
                return Err(Error::Syntax);
            }
        }

        match self.ready_state.get() {
            WebSocketRequestState::Closing | WebSocketRequestState::Closed  => {} //Do nothing
            WebSocketRequestState::Connecting => { //Connection is not yet established
                /*By setting the state to closing, the open function
                  will abort connecting the websocket*/
                self.failed.set(true);
                send_close(self);
                //Note: After sending the close message, the receive loop confirms a close message from the server and
                //      must fire a close event
            }
            WebSocketRequestState::Open => {
                //Closing handshake not started - still in open
                //Start the closing by setting the code and reason if they exist
                if let Some(code) = code {
                    self.code.set(code);
                }
                if let Some(reason) = reason {
                    *self.reason.borrow_mut() = reason.0;
                }
                send_close(self);
                //Note: After sending the close message, the receive loop confirms a close message from the server and
                //      must fire a close event
            }
        }
        Ok(()) //Return Ok
    }
}

pub enum WebSocketTask {
    /// Task queued when *the WebSocket connection is established*.
    ConnectionEstablished,
    Close,
}

pub struct WebSocketTaskHandler {
    addr: Trusted<WebSocket>,
    task: WebSocketTask,
}

impl WebSocketTaskHandler {
    pub fn new(addr: Trusted<WebSocket>, task: WebSocketTask) -> WebSocketTaskHandler {
        WebSocketTaskHandler {
            addr: addr,
            task: task,
        }
    }

    fn connection_established(&self) {
        /*TODO: Items 1, 3, 4, & 5 under "WebSocket connection is established" as specified here:
          https://html.spec.whatwg.org/multipage/#feedback-from-the-protocol
        */
        let ws = self.addr.root();

        // Step 1: Protocols.

        // Step 2.
        ws.ready_state.set(WebSocketRequestState::Open);

        // Step 3: Extensions.
        // Step 4: Protocols.
        // Step 5: Cookies.

        // Step 6.
        let global = ws.global.root();
        let event = Event::new(global.r(), "open".to_owned(),
                               EventBubbles::DoesNotBubble,
                               EventCancelable::NotCancelable);
        event.fire(EventTargetCast::from_ref(ws.r()));
    }

    fn dispatch_close(&self) {
        let ws = self.addr.root();
        let ws = ws.r();
        let global = ws.global.root();
        ws.ready_state.set(WebSocketRequestState::Closed);
        //If failed or full, fire error event
        if ws.failed.get() || ws.full.get() {
            ws.failed.set(false);
            ws.full.set(false);
            //A Bad close
            ws.clean_close.set(false);
            let event = Event::new(global.r(),
                                   "error".to_owned(),
                                   EventBubbles::DoesNotBubble,
                                   EventCancelable::Cancelable);
            let target = EventTargetCast::from_ref(ws);
            event.r().fire(target);
        }
        let rsn = ws.reason.borrow();
        let rsn_clone = rsn.clone();
        /*In addition, we also have to fire a close even if error event fired
         https://html.spec.whatwg.org/multipage/#closeWebSocket
        */
        let close_event = CloseEvent::new(global.r(),
                                          "close".to_owned(),
                                          EventBubbles::DoesNotBubble,
                                          EventCancelable::NotCancelable,
                                          ws.clean_close.get(),
                                          ws.code.get(),
                                          rsn_clone);
        let target = EventTargetCast::from_ref(ws);
        let event = EventCast::from_ref(close_event.r());
        event.fire(target);
    }
}

impl Runnable for WebSocketTaskHandler {
    fn handler(self: Box<WebSocketTaskHandler>) {
        match self.task {
            WebSocketTask::ConnectionEstablished => {
                self.connection_established();
            }
            WebSocketTask::Close => {
                self.dispatch_close();
            }
        }
    }
}

<|endoftext|>


<commit_before><commit_msg>test: Add an interior-vec test case, XFAIL'd for now because of leaks in the compiler<commit_after>// xfail-stage0
// xfail-stage1
// xfail-stage2
// xfail-stage3

// works, but leaks in the compiler :(

import rusti::ivec_len;

native "rust-intrinsic" mod rusti {
    fn ivec_len[T](&T[] v) -> uint;
}

fn main() {
    let int[] v = ~[];
    assert (ivec_len(v) == 0u);     // zero-length
    auto x = ~[ 1, 2 ];
    assert (ivec_len(x) == 2u);     // on stack
    auto y = ~[ 1, 2, 3, 4, 5 ];
    assert (ivec_len(y) == 5u);     // on heap

    v += ~[];
    assert (ivec_len(v) == 0u);     // zero-length append
    x += ~[ 3 ];
    assert (ivec_len(x) == 3u);     // on-stack append
    y += ~[ 6, 7, 8, 9 ];
    assert (ivec_len(y) == 9u);     // on-heap append

    auto vv = v + v;
    assert (ivec_len(vv) == 0u);     // zero-length add
    auto xx = x + ~[ 4 ];
    assert (ivec_len(xx) == 4u);     // on-stack add
    auto yy = y + ~[ 10, 11 ];
    assert (ivec_len(yy) == 11u);    // on-heap add
}

<|endoftext|>


<commit_before>// Copyright 2012-2013 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.

use infer::InferCtxt;
use infer::lexical_region_resolve::RegionResolutionError;
use infer::lexical_region_resolve::RegionResolutionError::*;
use syntax::codemap::Span;
use ty::{self, TyCtxt};
use util::common::ErrorReported;

mod different_lifetimes;
mod find_anon_type;
mod named_anon_conflict;
mod util;

impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
    pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool {
        let (span, sub, sup) = match *error {
            ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
            SubSupConflict(_, ref origin, sub, _, sup) => (origin.span(), sub, sup),
            _ => return false, // inapplicable
        };

        if let Some(tables) = self.in_progress_tables {
            let tables = tables.borrow();
            NiceRegionError::new(self.tcx, span, sub, sup, Some(&tables)).try_report().is_some()
        } else {
            NiceRegionError::new(self.tcx, span, sub, sup, None).try_report().is_some()
        }
    }
}

pub struct NiceRegionError<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
    span: Span,
    sub: ty::Region<'tcx>,
    sup: ty::Region<'tcx>,
    tables: Option<&'cx ty::TypeckTables<'tcx>>,
}

impl<'cx, 'gcx, 'tcx> NiceRegionError<'cx, 'gcx, 'tcx> {
    pub fn new(
        tcx: TyCtxt<'cx, 'gcx, 'tcx>,
        span: Span,
        sub: ty::Region<'tcx>,
        sup: ty::Region<'tcx>,
        tables: Option<&'cx ty::TypeckTables<'tcx>>,
    ) -> Self {
        Self { tcx, span, sub, sup, tables }
    }

    pub fn try_report(&self) -> Option<ErrorReported> {
        self.try_report_anon_anon_conflict()
            .or_else(|| self.try_report_named_anon_conflict())
    }
}
<commit_msg>give precedence to `try_report_named_anon_conflict` method<commit_after>// Copyright 2012-2013 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.

use infer::InferCtxt;
use infer::lexical_region_resolve::RegionResolutionError;
use infer::lexical_region_resolve::RegionResolutionError::*;
use syntax::codemap::Span;
use ty::{self, TyCtxt};
use util::common::ErrorReported;

mod different_lifetimes;
mod find_anon_type;
mod named_anon_conflict;
mod util;

impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
    pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool {
        let (span, sub, sup) = match *error {
            ConcreteFailure(ref origin, sub, sup) => (origin.span(), sub, sup),
            SubSupConflict(_, ref origin, sub, _, sup) => (origin.span(), sub, sup),
            _ => return false, // inapplicable
        };

        if let Some(tables) = self.in_progress_tables {
            let tables = tables.borrow();
            NiceRegionError::new(self.tcx, span, sub, sup, Some(&tables)).try_report().is_some()
        } else {
            NiceRegionError::new(self.tcx, span, sub, sup, None).try_report().is_some()
        }
    }
}

pub struct NiceRegionError<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
    tcx: TyCtxt<'cx, 'gcx, 'tcx>,
    span: Span,
    sub: ty::Region<'tcx>,
    sup: ty::Region<'tcx>,
    tables: Option<&'cx ty::TypeckTables<'tcx>>,
}

impl<'cx, 'gcx, 'tcx> NiceRegionError<'cx, 'gcx, 'tcx> {
    pub fn new(
        tcx: TyCtxt<'cx, 'gcx, 'tcx>,
        span: Span,
        sub: ty::Region<'tcx>,
        sup: ty::Region<'tcx>,
        tables: Option<&'cx ty::TypeckTables<'tcx>>,
    ) -> Self {
        Self { tcx, span, sub, sup, tables }
    }

    pub fn try_report(&self) -> Option<ErrorReported> {
        self.try_report_named_anon_conflict()
            .or_else(|| self.try_report_anon_anon_conflict())
    }
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #88194 - spastorino:test-tait-assoc-impl-trait, r=oli-obk<commit_after>// check-pass

#![feature(type_alias_impl_trait)]
#![allow(dead_code)]

type Foo = impl Iterator<Item = impl Send>;

fn make_foo() -> Foo {
    vec![1, 2].into_iter()
}

type Bar = impl Send;
type Baz = impl Iterator<Item = Bar>;

fn make_baz() -> Baz {
    vec!["1", "2"].into_iter()
}

fn main() {}
<|endoftext|>


<commit_before>use std::io;

use docopt;
use tabwriter::TabWriter;

use types::{CliError, CsvConfig, Delimiter};
use util;

docopt!(Args, "
Prints flattened records such that fields are labeled separated
by a new line. This mode is particularly useful for viewing one
record at a time.

There is also a condensed view (-c or --condensed) that will shorten
the contents of each field to provide a summary view.

Usage:
    xcsv flatten [options] [<input>]

flatten options:
    -c, --condensed <arg>  Limits the length (in bytes) of each field to the
                           value specified.
    -s, --separator <arg>  A string of characters to write after each record.
                           When non-empty, a new line is automatically
                           appended to the separator.
                           [default: #]

Common options:
    -h, --help             Display this message
    -n, --no-headers       When set, the first row will not be interpreted
                           as headers. (i.e., They are not searched, analyzed,
                           sliced, etc.)
    -d, --delimiter <arg>  The field delimiter for reading CSV data.
                           Must be a single character. [default: ,]
", arg_input: Option<String>, flag_delimiter: Delimiter)

pub fn main() -> Result<(), CliError> {
    let args: Args = try!(util::get_args());
    let rconfig = CsvConfig::new(args.arg_input.clone())
                            .delimiter(args.flag_delimiter)
                            .no_headers(args.flag_no_headers);
    let mut rdr = try!(io| rconfig.reader());
    let headers = try!(csv| rdr.byte_headers());

    let mut wtr: Box<Writer> =
        if false {
            box io::stdout() as Box<Writer>
        } else {
            box TabWriter::new(io::stdout()) as Box<Writer>
        };
    let mut first = true;
    for r in rdr.byte_records() {
        if !first && !args.flag_separator.is_empty() {
            try!(io| wtr.write_str(args.flag_separator.as_slice()));
            try!(io| wtr.write_u8(b'\n'));
        }
        first = false;
        for (header, field) in headers.iter().zip(try!(csv| r).into_iter()) {
            try!(io| wtr.write(header[]));
            try!(io| wtr.write_u8(b'\t'));
            try!(io| wtr.write(field[]));
            try!(io| wtr.write_u8(b'\n'));
        }
    }
    try!(io| wtr.flush());
    Ok(())
}
<commit_msg>Add "condense" feature to flatten command.<commit_after>use std::io;

use docopt;
use tabwriter::TabWriter;

use types::{CliError, CsvConfig, Delimiter};
use util;

docopt!(Args, "
Prints flattened records such that fields are labeled separated
by a new line. This mode is particularly useful for viewing one
record at a time.

There is also a condensed view (-c or --condensed) that will shorten
the contents of each field to provide a summary view.

Usage:
    xcsv flatten [options] [<input>]

flatten options:
    -c, --condensed <arg>  Limits the length (in bytes) of each field to the
                           value specified.
    -s, --separator <arg>  A string of characters to write after each record.
                           When non-empty, a new line is automatically
                           appended to the separator.
                           [default: #]

Common options:
    -h, --help             Display this message
    -n, --no-headers       When set, the first row will not be interpreted
                           as headers. (i.e., They are not searched, analyzed,
                           sliced, etc.)
    -d, --delimiter <arg>  The field delimiter for reading CSV data.
                           Must be a single character. [default: ,]
", arg_input: Option<String>, flag_delimiter: Delimiter,
   flag_condensed: Option<uint>)

pub fn main() -> Result<(), CliError> {
    let args: Args = try!(util::get_args());
    let rconfig = CsvConfig::new(args.arg_input.clone())
                            .delimiter(args.flag_delimiter)
                            .no_headers(args.flag_no_headers);
    let mut rdr = try!(io| rconfig.reader());
    let headers = try!(csv| rdr.byte_headers());

    let mut wtr: Box<Writer> =
        if false {
            box io::stdout() as Box<Writer>
        } else {
            box TabWriter::new(io::stdout()) as Box<Writer>
        };
    let mut first = true;
    for r in rdr.byte_records() {
        if !first && !args.flag_separator.is_empty() {
            try!(io| wtr.write_str(args.flag_separator.as_slice()));
            try!(io| wtr.write_u8(b'\n'));
        }
        first = false;
        for (header, field) in headers.iter().zip(try!(csv| r).into_iter()) {
            try!(io| wtr.write(header[]));
            try!(io| wtr.write_u8(b'\t'));
            match args.flag_condensed {
                Some(n) if n < field.len() => {
                    try!(io| wtr.write(field[..n]));
                    try!(io| wtr.write_str("..."));
                }
                _ => try!(io| wtr.write(field[])),
            }
            try!(io| wtr.write_u8(b'\n'));
        }
    }
    try!(io| wtr.flush());
    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>rollup merge of #17062 : nathantypanski/generic-lifetime-trait-impl<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// This code used to produce an ICE on the definition of trait Bar
// with the following message:
//
// Type parameter out of range when substituting in region 'a (root
// type=fn(Self) -> 'astr) (space=FnSpace, index=0)
//
// Regression test for issue #16218.

trait Bar<'a> {}

trait Foo<'a> {
    fn bar<'a, T: Bar<'a>>(self) -> &'a str;
}

impl<'a> Foo<'a> for &'a str {
    fn bar<T: Bar<'a>>(self) -> &'a str { fail!() } //~ ERROR lifetime
}

fn main() {
}
<|endoftext|>


<commit_before><commit_msg>Add ICE regression test with unboxed closures<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
// This code used to produce the following ICE:
//
//    error: internal compiler error: get_unique_type_id_of_type() -
//    unexpected type: closure,
//    ty_unboxed_closure(syntax::ast::DefId{krate: 0u32, node: 66u32},
//    ReScope(63u32))
//
// This is a regression test for issue #17021.

#![feature(unboxed_closures, overloaded_calls)]

use std::ptr;

pub fn replace_map<'a, T, F>(src: &mut T, prod: F)
where F: |: T| -> T {
    unsafe { *src = prod(ptr::read(src as *mut T as *const T)); }
}

pub fn main() {
    let mut a = 7u;
    let b = &mut a;
    replace_map(b, |: x: uint| x * 2);
    assert_eq!(*b, 14u);
}
<|endoftext|>


<commit_before>// Copyright 2016 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.

// run-pass

#[repr(u32)]
enum Tag { I, F }

#[repr(C)]
union U {
    i: i32,
    f: f32,
}

#[repr(C)]
struct Value {
    tag: Tag,
    u: U,
}

fn is_zero(v: Value) -> bool {
    unsafe {
        match v {
            Value { tag: Tag::I, u: U { i: 0 } } => true,
            Value { tag: Tag::F, u: U { f: 0.0 } } => true,
            _ => false,
        }
    }
}

union W {
    a: u8,
    b: u8,
}

fn refut(w: W) {
    unsafe {
        match w {
            W { a: 10 } => {
                panic!();
            }
            W { b } => {
                assert_eq!(b, 11);
            }
        }
    }
}

fn main() {
    let v = Value { tag: Tag::I, u: U { i: 1 } };
    assert_eq!(is_zero(v), false);

    let w = W { a: 11 };
    refut(w);
}
<commit_msg>Allow illegal_floating_point_literal_pattern. These will need to be updated at some point.<commit_after>// Copyright 2016 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.

// run-pass
#![allow(illegal_floating_point_literal_pattern)]

#[repr(u32)]
enum Tag { I, F }

#[repr(C)]
union U {
    i: i32,
    f: f32,
}

#[repr(C)]
struct Value {
    tag: Tag,
    u: U,
}

fn is_zero(v: Value) -> bool {
    unsafe {
        match v {
            Value { tag: Tag::I, u: U { i: 0 } } => true,
            Value { tag: Tag::F, u: U { f: 0.0 } } => true,
            _ => false,
        }
    }
}

union W {
    a: u8,
    b: u8,
}

fn refut(w: W) {
    unsafe {
        match w {
            W { a: 10 } => {
                panic!();
            }
            W { b } => {
                assert_eq!(b, 11);
            }
        }
    }
}

fn main() {
    let v = Value { tag: Tag::I, u: U { i: 1 } };
    assert_eq!(is_zero(v), false);

    let w = W { a: 11 };
    refut(w);
}
<|endoftext|>


<commit_before><commit_msg>Write to db from thread pool.<commit_after><|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A windowing implementation using GLFW.

use windowing::{ApplicationMethods, WindowEvent, WindowMethods};
use windowing::{IdleWindowEvent, ResizeWindowEvent, LoadUrlWindowEvent, MouseWindowEventClass,  MouseWindowMoveEventClass};
use windowing::{ScrollWindowEvent, ZoomWindowEvent, NavigationWindowEvent, FinishedWindowEvent};
use windowing::{QuitWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent};
use windowing::RefreshWindowEvent;
use windowing::{Forward, Back};

use alert::{Alert, AlertMethods};
use extra::time::Timespec;
use extra::time;
use std::cell::RefCell;
use std::libc::{exit, c_int};
use std::local_data;
use std::rc::Rc;

use geom::point::Point2D;
use geom::size::Size2D;
use servo_msg::compositor_msg::{IdleRenderState, RenderState, RenderingRenderState};
use servo_msg::compositor_msg::{FinishedLoading, Blank, Loading, PerformingLayout, ReadyState};

use glfw;

/// A structure responsible for setting up and tearing down the entire windowing system.
pub struct Application;

impl ApplicationMethods for Application {
    fn new() -> Application {
        // Per GLFW docs it's safe to set the error callback before calling
        // glfwInit(), and this way we notice errors from init too.
        glfw::set_error_callback(~glfw::LogErrorHandler);

        if glfw::init().is_err() {
            // handles things like inability to connect to X
            // cannot simply fail, since the runtime isn't up yet (causes a nasty abort)
            println!("GLFW initialization failed");
            unsafe { exit(1); }
        }

        Application
    }
}

impl Drop for Application {
    fn drop(&mut self) {
        drop_local_window();
        glfw::terminate();
    }
}

macro_rules! glfw_callback(
    (
        $callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr
    ) => ({
        struct GlfwCallback;
        impl $callback for GlfwCallback {
            fn call(&self $(, $arg: $arg_ty)*) {
                $block
            }
        }
        ~GlfwCallback
    });

    (
        [$($state:ident: $state_ty:ty),*],
        $callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr
    ) => ({
        struct GlfwCallback {
            $($state: $state_ty,)*
        }
        impl $callback for GlfwCallback {
            fn call(&self $(, $arg: $arg_ty)*) {
                $block
            }
        }
        ~GlfwCallback {
            $($state: $state,)*
        }
    });
)

/// The type of a window.
pub struct Window {
    glfw_window: glfw::Window,

    event_queue: RefCell<~[WindowEvent]>,

    drag_origin: Point2D<c_int>,

    mouse_down_button: RefCell<Option<glfw::MouseButton>>,
    mouse_down_point: RefCell<Point2D<c_int>>,

    ready_state: RefCell<ReadyState>,
    render_state: RefCell<RenderState>,

    last_title_set_time: RefCell<Timespec>,
}

impl WindowMethods<Application> for Window {
    /// Creates a new window.
    fn new(_: &Application) -> Rc<Window> {
        // Create the GLFW window.
        let glfw_window = glfw::Window::create(800, 600, "Servo", glfw::Windowed)
            .expect("Failed to create GLFW window");
        glfw_window.make_context_current();

        // Create our window object.
        let window = Window {
            glfw_window: glfw_window,

            event_queue: RefCell::new(~[]),

            drag_origin: Point2D(0 as c_int, 0),

            mouse_down_button: RefCell::new(None),
            mouse_down_point: RefCell::new(Point2D(0 as c_int, 0)),

            ready_state: RefCell::new(Blank),
            render_state: RefCell::new(IdleRenderState),

            last_title_set_time: RefCell::new(Timespec::new(0, 0)),
        };

        // Register event handlers.
        window.glfw_window.set_framebuffer_size_callback(
            glfw_callback!(glfw::FramebufferSizeCallback(_win: &glfw::Window, width: i32, height: i32) {
                let tmp = local_window();
                tmp.borrow().event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint)));
            }));
        window.glfw_window.set_refresh_callback(
            glfw_callback!(glfw::WindowRefreshCallback(_win: &glfw::Window) {
                let tmp = local_window();
                tmp.borrow().event_queue.with_mut(|queue| queue.push(RefreshWindowEvent));
            }));
        window.glfw_window.set_key_callback(
            glfw_callback!(glfw::KeyCallback(_win: &glfw::Window, key: glfw::Key, _scancode: c_int,
                                             action: glfw::Action, mods: glfw::Modifiers) {
                if action == glfw::Press {
                    let tmp = local_window();
                    tmp.borrow().handle_key(key, mods)
                }
            }));
        window.glfw_window.set_mouse_button_callback(
            glfw_callback!(glfw::MouseButtonCallback(win: &glfw::Window, button: glfw::MouseButton,
                                                     action: glfw::Action, _mods: glfw::Modifiers) {
                let (x, y) = win.get_cursor_pos();
                //handle hidpi displays, since GLFW returns non-hi-def coordinates.
                let (backing_size, _) = win.get_framebuffer_size();
                let (window_size, _) = win.get_size();
                let hidpi = (backing_size as f32) / (window_size as f32);
                let x = x as f32 * hidpi;
                let y = y as f32 * hidpi;
                if button == glfw::MouseButtonLeft || button == glfw::MouseButtonRight {
                    let tmp = local_window();
                    tmp.borrow().handle_mouse(button, action, x as i32, y as i32);
                }
            }));
        window.glfw_window.set_cursor_pos_callback(
            glfw_callback!(glfw::CursorPosCallback(_win: &glfw::Window, xpos: f64, ypos: f64) {
                let tmp = local_window();
                tmp.borrow().event_queue.with_mut(|queue| queue.push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32))));
            }));
        window.glfw_window.set_scroll_callback(
            glfw_callback!(glfw::ScrollCallback(win: &glfw::Window, xpos: f64, ypos: f64) {
                let dx = (xpos as f32) * 30.0;
                let dy = (ypos as f32) * 30.0;

                let (x, y) = win.get_cursor_pos();
                //handle hidpi displays, since GLFW returns non-hi-def coordinates.
                let (backing_size, _) = win.get_framebuffer_size();
                let (window_size, _) = win.get_size();
                let hidpi = (backing_size as f32) / (window_size as f32);
                let x = x as f32 * hidpi;
                let y = y as f32 * hidpi;

                let tmp = local_window();
                tmp.borrow().event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32))));
            }));

        let wrapped_window = Rc::from_send(window);

        install_local_window(wrapped_window.clone());

        wrapped_window
    }

    /// Returns the size of the window.
    fn size(&self) -> Size2D<f32> {
        let (width, height) = self.glfw_window.get_framebuffer_size();
        Size2D(width as f32, height as f32)
    }

    /// Presents the window to the screen (perhaps by page flipping).
    fn present(&self) {
        self.glfw_window.swap_buffers();
    }

    fn recv(&self) -> WindowEvent {
        if !self.event_queue.with_mut(|queue| queue.is_empty()) {
            return self.event_queue.with_mut(|queue| queue.shift())
        }
        glfw::poll_events();

        if self.glfw_window.should_close() {
            QuitWindowEvent
        } else if !self.event_queue.with_mut(|queue| queue.is_empty()) {
            self.event_queue.with_mut(|queue| queue.shift())
        } else {
            IdleWindowEvent
        }
    }

    /// Sets the ready state.
    fn set_ready_state(&self, ready_state: ReadyState) {
        self.ready_state.set(ready_state);
        self.update_window_title()
    }

    /// Sets the render state.
    fn set_render_state(&self, render_state: RenderState) {
        if self.ready_state.get() == FinishedLoading &&
            self.render_state.get() == RenderingRenderState &&
            render_state == IdleRenderState {
            // page loaded
            self.event_queue.with_mut(|queue| queue.push(FinishedWindowEvent));
        }

        self.render_state.set(render_state);
        self.update_window_title()
    }

    fn hidpi_factor(&self) -> f32 {
        let (backing_size, _) = self.glfw_window.get_framebuffer_size();
        let (window_size, _) = self.glfw_window.get_size();
        (backing_size as f32) / (window_size as f32)
    }
}

impl Window {
    /// Helper function to set the window title in accordance with the ready state.
    fn update_window_title(&self) {
        let now = time::get_time();
        if now.sec == self.last_title_set_time.get().sec {
            return
        }
        self.last_title_set_time.set(now);

        match self.ready_state.get() {
            Blank => {
                self.glfw_window.set_title("blank — Servo")
            }
            Loading => {
                self.glfw_window.set_title("Loading — Servo")
            }
            PerformingLayout => {
                self.glfw_window.set_title("Performing Layout — Servo")
            }
            FinishedLoading => {
                match self.render_state.get() {
                    RenderingRenderState => {
                        self.glfw_window.set_title("Rendering — Servo")
                    }
                    IdleRenderState => {
                        self.glfw_window.set_title("Servo")
                    }
                }
            }
        }
    }

    /// Helper function to handle keyboard events.
    fn handle_key(&self, key: glfw::Key, mods: glfw::Modifiers) {
        match key {
            glfw::KeyEscape => self.glfw_window.set_should_close(true),
            glfw::KeyL if mods.contains(glfw::Control) => self.load_url(), // Ctrl+L
            glfw::KeyEqual if mods.contains(glfw::Control) => { // Ctrl-+
                self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(1.1)));
            }
            glfw::KeyMinus if mods.contains(glfw::Control) => { // Ctrl--
                self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(0.90909090909)));
            }
            glfw::KeyBackspace if mods.contains(glfw::Shift) => { // Shift-Backspace
                self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Forward)));
            }
            glfw::KeyBackspace => { // Backspace
                self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Back)));
            }
            _ => {}
        }
    }

    /// Helper function to handle a click
    fn handle_mouse(&self, button: glfw::MouseButton, action: glfw::Action, x: c_int, y: c_int) {
        // FIXME(tkuehn): max pixel dist should be based on pixel density
        let max_pixel_dist = 10f64;
        let event = match action {
            glfw::Press => {
                self.mouse_down_point.set(Point2D(x, y));
                self.mouse_down_button.set(Some(button));
                MouseWindowMouseDownEvent(button as uint, Point2D(x as f32, y as f32))
            }
            glfw::Release => {
                match self.mouse_down_button.get() {
                    None => (),
                    Some(but) if button == but => {
                        let pixel_dist = self.mouse_down_point.get() - Point2D(x, y);
                        let pixel_dist = ((pixel_dist.x * pixel_dist.x +
                                           pixel_dist.y * pixel_dist.y) as f64).sqrt();
                        if pixel_dist < max_pixel_dist {
                            let click_event = MouseWindowClickEvent(button as uint,
                                                                    Point2D(x as f32, y as f32));
                            self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(click_event)));
                        }
                    }
                    Some(_) => (),
                }
                MouseWindowMouseUpEvent(button as uint, Point2D(x as f32, y as f32))
            }
            _ => fail!("I cannot recognize the type of mouse action that occured. :-(")
        };
        self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(event)));
    }

    /// Helper function to pop up an alert box prompting the user to load a URL.
    fn load_url(&self) {
        let mut alert: Alert = AlertMethods::new("Navigate to:");
        alert.add_prompt();
        alert.run();
        let value = alert.prompt_value();
        if "" == value {    // To avoid crashing on Linux.
            self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(~"http://purple.com/")))
        } else {
            self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(value.clone())))
        }
    }
}

static TLS_KEY: local_data::Key<Rc<Window>> = &local_data::Key;

fn install_local_window(window: Rc<Window>) {
    local_data::set(TLS_KEY, window);
}

fn drop_local_window() {
    local_data::pop(TLS_KEY);
}

fn local_window() -> Rc<Window> {
    local_data::get(TLS_KEY, |v| v.unwrap().clone())
}
<commit_msg>RefCell->Cell<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A windowing implementation using GLFW.

use windowing::{ApplicationMethods, WindowEvent, WindowMethods};
use windowing::{IdleWindowEvent, ResizeWindowEvent, LoadUrlWindowEvent, MouseWindowEventClass,  MouseWindowMoveEventClass};
use windowing::{ScrollWindowEvent, ZoomWindowEvent, NavigationWindowEvent, FinishedWindowEvent};
use windowing::{QuitWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent};
use windowing::RefreshWindowEvent;
use windowing::{Forward, Back};

use alert::{Alert, AlertMethods};
use extra::time::Timespec;
use extra::time;
use std::cell::{Cell, RefCell};
use std::libc::{exit, c_int};
use std::local_data;
use std::rc::Rc;

use geom::point::Point2D;
use geom::size::Size2D;
use servo_msg::compositor_msg::{IdleRenderState, RenderState, RenderingRenderState};
use servo_msg::compositor_msg::{FinishedLoading, Blank, Loading, PerformingLayout, ReadyState};

use glfw;

/// A structure responsible for setting up and tearing down the entire windowing system.
pub struct Application;

impl ApplicationMethods for Application {
    fn new() -> Application {
        // Per GLFW docs it's safe to set the error callback before calling
        // glfwInit(), and this way we notice errors from init too.
        glfw::set_error_callback(~glfw::LogErrorHandler);

        if glfw::init().is_err() {
            // handles things like inability to connect to X
            // cannot simply fail, since the runtime isn't up yet (causes a nasty abort)
            println!("GLFW initialization failed");
            unsafe { exit(1); }
        }

        Application
    }
}

impl Drop for Application {
    fn drop(&mut self) {
        drop_local_window();
        glfw::terminate();
    }
}

macro_rules! glfw_callback(
    (
        $callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr
    ) => ({
        struct GlfwCallback;
        impl $callback for GlfwCallback {
            fn call(&self $(, $arg: $arg_ty)*) {
                $block
            }
        }
        ~GlfwCallback
    });

    (
        [$($state:ident: $state_ty:ty),*],
        $callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr
    ) => ({
        struct GlfwCallback {
            $($state: $state_ty,)*
        }
        impl $callback for GlfwCallback {
            fn call(&self $(, $arg: $arg_ty)*) {
                $block
            }
        }
        ~GlfwCallback {
            $($state: $state,)*
        }
    });
)

/// The type of a window.
pub struct Window {
    glfw_window: glfw::Window,

    event_queue: RefCell<~[WindowEvent]>,

    drag_origin: Point2D<c_int>,

    mouse_down_button: Cell<Option<glfw::MouseButton>>,
    mouse_down_point: Cell<Point2D<c_int>>,

    ready_state: Cell<ReadyState>,
    render_state: Cell<RenderState>,

    last_title_set_time: Cell<Timespec>,
}

impl WindowMethods<Application> for Window {
    /// Creates a new window.
    fn new(_: &Application) -> Rc<Window> {
        // Create the GLFW window.
        let glfw_window = glfw::Window::create(800, 600, "Servo", glfw::Windowed)
            .expect("Failed to create GLFW window");
        glfw_window.make_context_current();

        // Create our window object.
        let window = Window {
            glfw_window: glfw_window,

            event_queue: RefCell::new(~[]),

            drag_origin: Point2D(0 as c_int, 0),

            mouse_down_button: Cell::new(None),
            mouse_down_point: Cell::new(Point2D(0 as c_int, 0)),

            ready_state: Cell::new(Blank),
            render_state: Cell::new(IdleRenderState),

            last_title_set_time: Cell::new(Timespec::new(0, 0)),
        };

        // Register event handlers.
        window.glfw_window.set_framebuffer_size_callback(
            glfw_callback!(glfw::FramebufferSizeCallback(_win: &glfw::Window, width: i32, height: i32) {
                let tmp = local_window();
                tmp.borrow().event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint)));
            }));
        window.glfw_window.set_refresh_callback(
            glfw_callback!(glfw::WindowRefreshCallback(_win: &glfw::Window) {
                let tmp = local_window();
                tmp.borrow().event_queue.with_mut(|queue| queue.push(RefreshWindowEvent));
            }));
        window.glfw_window.set_key_callback(
            glfw_callback!(glfw::KeyCallback(_win: &glfw::Window, key: glfw::Key, _scancode: c_int,
                                             action: glfw::Action, mods: glfw::Modifiers) {
                if action == glfw::Press {
                    let tmp = local_window();
                    tmp.borrow().handle_key(key, mods)
                }
            }));
        window.glfw_window.set_mouse_button_callback(
            glfw_callback!(glfw::MouseButtonCallback(win: &glfw::Window, button: glfw::MouseButton,
                                                     action: glfw::Action, _mods: glfw::Modifiers) {
                let (x, y) = win.get_cursor_pos();
                //handle hidpi displays, since GLFW returns non-hi-def coordinates.
                let (backing_size, _) = win.get_framebuffer_size();
                let (window_size, _) = win.get_size();
                let hidpi = (backing_size as f32) / (window_size as f32);
                let x = x as f32 * hidpi;
                let y = y as f32 * hidpi;
                if button == glfw::MouseButtonLeft || button == glfw::MouseButtonRight {
                    let tmp = local_window();
                    tmp.borrow().handle_mouse(button, action, x as i32, y as i32);
                }
            }));
        window.glfw_window.set_cursor_pos_callback(
            glfw_callback!(glfw::CursorPosCallback(_win: &glfw::Window, xpos: f64, ypos: f64) {
                let tmp = local_window();
                tmp.borrow().event_queue.with_mut(|queue| queue.push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32))));
            }));
        window.glfw_window.set_scroll_callback(
            glfw_callback!(glfw::ScrollCallback(win: &glfw::Window, xpos: f64, ypos: f64) {
                let dx = (xpos as f32) * 30.0;
                let dy = (ypos as f32) * 30.0;

                let (x, y) = win.get_cursor_pos();
                //handle hidpi displays, since GLFW returns non-hi-def coordinates.
                let (backing_size, _) = win.get_framebuffer_size();
                let (window_size, _) = win.get_size();
                let hidpi = (backing_size as f32) / (window_size as f32);
                let x = x as f32 * hidpi;
                let y = y as f32 * hidpi;

                let tmp = local_window();
                tmp.borrow().event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32))));
            }));

        let wrapped_window = Rc::from_send(window);

        install_local_window(wrapped_window.clone());

        wrapped_window
    }

    /// Returns the size of the window.
    fn size(&self) -> Size2D<f32> {
        let (width, height) = self.glfw_window.get_framebuffer_size();
        Size2D(width as f32, height as f32)
    }

    /// Presents the window to the screen (perhaps by page flipping).
    fn present(&self) {
        self.glfw_window.swap_buffers();
    }

    fn recv(&self) -> WindowEvent {
        if !self.event_queue.with_mut(|queue| queue.is_empty()) {
            return self.event_queue.with_mut(|queue| queue.shift())
        }
        glfw::poll_events();

        if self.glfw_window.should_close() {
            QuitWindowEvent
        } else if !self.event_queue.with_mut(|queue| queue.is_empty()) {
            self.event_queue.with_mut(|queue| queue.shift())
        } else {
            IdleWindowEvent
        }
    }

    /// Sets the ready state.
    fn set_ready_state(&self, ready_state: ReadyState) {
        self.ready_state.set(ready_state);
        self.update_window_title()
    }

    /// Sets the render state.
    fn set_render_state(&self, render_state: RenderState) {
        if self.ready_state.get() == FinishedLoading &&
            self.render_state.get() == RenderingRenderState &&
            render_state == IdleRenderState {
            // page loaded
            self.event_queue.with_mut(|queue| queue.push(FinishedWindowEvent));
        }

        self.render_state.set(render_state);
        self.update_window_title()
    }

    fn hidpi_factor(&self) -> f32 {
        let (backing_size, _) = self.glfw_window.get_framebuffer_size();
        let (window_size, _) = self.glfw_window.get_size();
        (backing_size as f32) / (window_size as f32)
    }
}

impl Window {
    /// Helper function to set the window title in accordance with the ready state.
    fn update_window_title(&self) {
        let now = time::get_time();
        if now.sec == self.last_title_set_time.get().sec {
            return
        }
        self.last_title_set_time.set(now);

        match self.ready_state.get() {
            Blank => {
                self.glfw_window.set_title("blank — Servo")
            }
            Loading => {
                self.glfw_window.set_title("Loading — Servo")
            }
            PerformingLayout => {
                self.glfw_window.set_title("Performing Layout — Servo")
            }
            FinishedLoading => {
                match self.render_state.get() {
                    RenderingRenderState => {
                        self.glfw_window.set_title("Rendering — Servo")
                    }
                    IdleRenderState => {
                        self.glfw_window.set_title("Servo")
                    }
                }
            }
        }
    }

    /// Helper function to handle keyboard events.
    fn handle_key(&self, key: glfw::Key, mods: glfw::Modifiers) {
        match key {
            glfw::KeyEscape => self.glfw_window.set_should_close(true),
            glfw::KeyL if mods.contains(glfw::Control) => self.load_url(), // Ctrl+L
            glfw::KeyEqual if mods.contains(glfw::Control) => { // Ctrl-+
                self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(1.1)));
            }
            glfw::KeyMinus if mods.contains(glfw::Control) => { // Ctrl--
                self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(0.90909090909)));
            }
            glfw::KeyBackspace if mods.contains(glfw::Shift) => { // Shift-Backspace
                self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Forward)));
            }
            glfw::KeyBackspace => { // Backspace
                self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Back)));
            }
            _ => {}
        }
    }

    /// Helper function to handle a click
    fn handle_mouse(&self, button: glfw::MouseButton, action: glfw::Action, x: c_int, y: c_int) {
        // FIXME(tkuehn): max pixel dist should be based on pixel density
        let max_pixel_dist = 10f64;
        let event = match action {
            glfw::Press => {
                self.mouse_down_point.set(Point2D(x, y));
                self.mouse_down_button.set(Some(button));
                MouseWindowMouseDownEvent(button as uint, Point2D(x as f32, y as f32))
            }
            glfw::Release => {
                match self.mouse_down_button.get() {
                    None => (),
                    Some(but) if button == but => {
                        let pixel_dist = self.mouse_down_point.get() - Point2D(x, y);
                        let pixel_dist = ((pixel_dist.x * pixel_dist.x +
                                           pixel_dist.y * pixel_dist.y) as f64).sqrt();
                        if pixel_dist < max_pixel_dist {
                            let click_event = MouseWindowClickEvent(button as uint,
                                                                    Point2D(x as f32, y as f32));
                            self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(click_event)));
                        }
                    }
                    Some(_) => (),
                }
                MouseWindowMouseUpEvent(button as uint, Point2D(x as f32, y as f32))
            }
            _ => fail!("I cannot recognize the type of mouse action that occured. :-(")
        };
        self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(event)));
    }

    /// Helper function to pop up an alert box prompting the user to load a URL.
    fn load_url(&self) {
        let mut alert: Alert = AlertMethods::new("Navigate to:");
        alert.add_prompt();
        alert.run();
        let value = alert.prompt_value();
        if "" == value {    // To avoid crashing on Linux.
            self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(~"http://purple.com/")))
        } else {
            self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(value.clone())))
        }
    }
}

static TLS_KEY: local_data::Key<Rc<Window>> = &local_data::Key;

fn install_local_window(window: Rc<Window>) {
    local_data::set(TLS_KEY, window);
}

fn drop_local_window() {
    local_data::pop(TLS_KEY);
}

fn local_window() -> Rc<Window> {
    local_data::get(TLS_KEY, |v| v.unwrap().clone())
}
<|endoftext|>


<commit_before><commit_msg>chore: OO<commit_after><|endoftext|>