<commit_before>use super::respan::respan;
use proc_macro2::{Group, Spacing, Span, TokenStream, TokenTree};
use quote::{quote, quote_spanned};
use std::{iter::FromIterator, mem};
use syn::{
    parse_quote,
    punctuated::Punctuated,
    visit_mut::{self, VisitMut},
    DeriveInput, ExprPath, Macro, Path, PathArguments, QSelf, Type, TypePath,
};

pub fn replace_receiver(input: &mut DeriveInput) {
    let ident = &input.ident;
    let ty_generics = input.generics.split_for_impl().1;
    let self_ty = parse_quote!(#ident #ty_generics);
    let mut visitor = ReplaceReceiver(&self_ty);
    visitor.visit_generics_mut(&mut input.generics);
    visitor.visit_data_mut(&mut input.data);
}

struct ReplaceReceiver<'a>(&'a TypePath);

impl ReplaceReceiver<'_> {
    fn self_ty(&self, span: Span) -> TypePath {
        respan(self.0, span)
    }

    fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
        if path.leading_colon.is_some() {
            return;
        }

        let first = &path.segments[0];
        if first.ident != "Self" || !first.arguments.is_empty() {
            return;
        }

        if path.segments.len() == 1 {
            self.self_to_expr_path(path);
            return;
        }

        let span = first.ident.span();
        *qself = Some(QSelf {
            lt_token: Token![<](span),
            ty: Box::new(self.self_ty(span).into()),
            position: 0,
            as_token: None,
            gt_token: Token![>](span),
        });

        path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap());

        let segments = mem::replace(&mut path.segments, Punctuated::new());
        path.segments = segments.into_pairs().skip(1).collect();
    }

    fn self_to_expr_path(&self, path: &mut Path) {
        if path.leading_colon.is_some() {
            return;
        }

        let first = &path.segments[0];
        if first.ident != "Self" || !first.arguments.is_empty() {
            return;
        }

        let self_ty = self.self_ty(first.ident.span());
        let variant = mem::replace(path, self_ty.path);
        for segment in &mut path.segments {
            if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
                if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() {
                    bracketed.colon2_token = Some(<Token![::]>::default());
                }
            }
        }
        if variant.segments.len() > 1 {
            path.segments.push_punct(<Token![::]>::default());
            path.segments.extend(variant.segments.into_pairs().skip(1));
        }
    }

    fn visit_token_stream(&self, tokens: &mut TokenStream) -> bool {
        let mut out = Vec::new();
        let mut modified = false;
        let mut iter = tokens.clone().into_iter().peekable();
        while let Some(tt) = iter.next() {
            match tt {
                TokenTree::Ident(ident) => {
                    if ident == "Self" {
                        modified = true;
                        let self_ty = self.self_ty(ident.span());
                        match iter.peek() {
                            Some(TokenTree::Punct(p))
                                if p.as_char() == ':' && p.spacing() == Spacing::Joint =>
                            {
                                let next = iter.next().unwrap();
                                match iter.peek() {
                                    Some(TokenTree::Punct(p)) if p.as_char() == ':' => {
                                        let span = ident.span();
                                        out.extend(quote_spanned!(span=> <#self_ty>));
                                    }
                                    _ => out.extend(quote!(#self_ty)),
                                }
                                out.push(next);
                            }
                            _ => out.extend(quote!(#self_ty)),
                        }
                    } else {
                        out.push(TokenTree::Ident(ident));
                    }
                }
                TokenTree::Group(group) => {
                    let mut content = group.stream();
                    modified |= self.visit_token_stream(&mut content);
                    let mut new = Group::new(group.delimiter(), content);
                    new.set_span(group.span());
                    out.push(TokenTree::Group(new));
                }
                other => out.push(other),
            }
        }
        if modified {
            *tokens = TokenStream::from_iter(out);
        }
        modified
    }
}

impl VisitMut for ReplaceReceiver<'_> {
    // `Self` -> `Receiver`
    fn visit_type_mut(&mut self, ty: &mut Type) {
        if let Type::Path(node) = ty {
            if node.qself.is_none() && node.path.is_ident("Self") {
                *ty = self.self_ty(node.path.segments[0].ident.span()).into();
            } else {
                self.visit_type_path_mut(node);
            }
        } else {
            visit_mut::visit_type_mut(self, ty);
        }
    }

    // `Self::Assoc` -> `<Receiver>::Assoc`
    fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
        if ty.qself.is_none() {
            self.self_to_qself(&mut ty.qself, &mut ty.path);
        }
        visit_mut::visit_type_path_mut(self, ty);
    }

    // `Self::method` -> `<Receiver>::method`
    fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) {
        if expr.qself.is_none() {
            self.self_to_qself(&mut expr.qself, &mut expr.path);
        }
        visit_mut::visit_expr_path_mut(self, expr);
    }

    fn visit_macro_mut(&mut self, mac: &mut Macro) {
        // We can't tell in general whether `self` inside a macro invocation
        // refers to the self in the argument list or a different self
        // introduced within the macro. Heuristic: if the macro input contains
        // `fn`, then `self` is more likely to refer to something other than the
        // outer function's self argument.
        if !contains_fn(mac.tokens.clone()) {
            self.visit_token_stream(&mut mac.tokens);
        }
    }
}

fn contains_fn(tokens: TokenStream) -> bool {
    tokens.into_iter().any(|tt| match tt {
        TokenTree::Ident(ident) => ident == "fn",
        TokenTree::Group(group) => contains_fn(group.stream()),
        _ => false,
    })
}
<commit_msg>Make AST borrow checker happy<commit_after>use super::respan::respan;
use proc_macro2::{Group, Spacing, Span, TokenStream, TokenTree};
use quote::{quote, quote_spanned};
use std::{iter::FromIterator, mem};
use syn::{
    parse_quote,
    punctuated::Punctuated,
    visit_mut::{self, VisitMut},
    DeriveInput, ExprPath, Macro, Path, PathArguments, QSelf, Type, TypePath,
};

pub fn replace_receiver(input: &mut DeriveInput) {
    let self_ty = {
        let ident = &input.ident;
        let ty_generics = input.generics.split_for_impl().1;
        parse_quote!(#ident #ty_generics)
    };
    let mut visitor = ReplaceReceiver(&self_ty);
    visitor.visit_generics_mut(&mut input.generics);
    visitor.visit_data_mut(&mut input.data);
}

struct ReplaceReceiver<'a>(&'a TypePath);

impl ReplaceReceiver<'_> {
    fn self_ty(&self, span: Span) -> TypePath {
        respan(self.0, span)
    }

    fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
        if path.leading_colon.is_some() {
            return;
        }

        // Make borrow checker happy
        {
            let first = &path.segments[0];
            if first.ident != "Self" || !first.arguments.is_empty() {
                return;
            }
        }

        if path.segments.len() == 1 {
            self.self_to_expr_path(path);
            return;
        }

        let span = path.segments[0].ident.span();
        *qself = Some(QSelf {
            lt_token: Token![<](span),
            ty: Box::new(self.self_ty(span).into()),
            position: 0,
            as_token: None,
            gt_token: Token![>](span),
        });

        path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap());

        let segments = mem::replace(&mut path.segments, Punctuated::new());
        path.segments = segments.into_pairs().skip(1).collect();
    }

    fn self_to_expr_path(&self, path: &mut Path) {
        if path.leading_colon.is_some() {
            return;
        }

        // Make borrow checker happy
        {
            let first = &path.segments[0];
            if first.ident != "Self" || !first.arguments.is_empty() {
                return;
            }
        }

        let self_ty = self.self_ty(path.segments[0].ident.span());
        let variant = mem::replace(path, self_ty.path);
        for segment in &mut path.segments {
            if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
                if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() {
                    bracketed.colon2_token = Some(<Token![::]>::default());
                }
            }
        }
        if variant.segments.len() > 1 {
            path.segments.push_punct(<Token![::]>::default());
            path.segments.extend(variant.segments.into_pairs().skip(1));
        }
    }

    fn visit_token_stream(&self, tokens: &mut TokenStream) -> bool {
        let mut out = Vec::new();
        let mut modified = false;
        let mut iter = tokens.clone().into_iter().peekable();
        while let Some(tt) = iter.next() {
            match tt {
                TokenTree::Ident(ident) => {
                    if ident == "Self" {
                        modified = true;
                        let self_ty = self.self_ty(ident.span());
                        match iter.peek() {
                            Some(TokenTree::Punct(p))
                                if p.as_char() == ':' && p.spacing() == Spacing::Joint => {}
                            _ => {
                                out.extend(quote!(#self_ty));
                                continue;
                            }
                        }
                        let next = iter.next().unwrap();
                        match iter.peek() {
                            Some(TokenTree::Punct(p)) if p.as_char() == ':' => {
                                let span = ident.span();
                                out.extend(quote_spanned!(span=> <#self_ty>));
                            }
                            _ => out.extend(quote!(#self_ty)),
                        }
                        out.push(next);
                    } else {
                        out.push(TokenTree::Ident(ident));
                    }
                }
                TokenTree::Group(group) => {
                    let mut content = group.stream();
                    modified |= self.visit_token_stream(&mut content);
                    let mut new = Group::new(group.delimiter(), content);
                    new.set_span(group.span());
                    out.push(TokenTree::Group(new));
                }
                other => out.push(other),
            }
        }
        if modified {
            *tokens = TokenStream::from_iter(out);
        }
        modified
    }
}

impl VisitMut for ReplaceReceiver<'_> {
    // `Self` -> `Receiver`
    fn visit_type_mut(&mut self, ty: &mut Type) {
        let span = if let Type::Path(node) = ty {
            if node.qself.is_none() && node.path.is_ident("Self") {
                node.path.segments[0].ident.span()
            } else {
                self.visit_type_path_mut(node);
                return;
            }
        } else {
            visit_mut::visit_type_mut(self, ty);
            return;
        };
        *ty = self.self_ty(span).into();
    }

    // `Self::Assoc` -> `<Receiver>::Assoc`
    fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
        if ty.qself.is_none() {
            self.self_to_qself(&mut ty.qself, &mut ty.path);
        }
        visit_mut::visit_type_path_mut(self, ty);
    }

    // `Self::method` -> `<Receiver>::method`
    fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) {
        if expr.qself.is_none() {
            self.self_to_qself(&mut expr.qself, &mut expr.path);
        }
        visit_mut::visit_expr_path_mut(self, expr);
    }

    fn visit_macro_mut(&mut self, mac: &mut Macro) {
        // We can't tell in general whether `self` inside a macro invocation
        // refers to the self in the argument list or a different self
        // introduced within the macro. Heuristic: if the macro input contains
        // `fn`, then `self` is more likely to refer to something other than the
        // outer function's self argument.
        if !contains_fn(mac.tokens.clone()) {
            self.visit_token_stream(&mut mac.tokens);
        }
    }
}

fn contains_fn(tokens: TokenStream) -> bool {
    tokens.into_iter().any(|tt| match tt {
        TokenTree::Ident(ident) => ident == "fn",
        TokenTree::Group(group) => contains_fn(group.stream()),
        _ => false,
    })
}
<|endoftext|>


<commit_before>use super::diagnostics::Error;
use super::item::ItemInfo;
use super::Parser;

use crate::{new_sub_parser_from_file, DirectoryOwnership};

use rustc_ast::ast::{self, Attribute, Crate, Ident, ItemKind, Mod};
use rustc_ast::attr;
use rustc_ast::token::{self, TokenKind};
use rustc_errors::PResult;
use rustc_span::source_map::{FileName, SourceMap, Span, DUMMY_SP};
use rustc_span::symbol::sym;

use std::path::{self, Path, PathBuf};

/// Information about the path to a module.
// Public for rustfmt usage.
pub struct ModulePath {
    name: String,
    path_exists: bool,
    pub result: Result<ModulePathSuccess, Error>,
}

// Public for rustfmt usage.
pub struct ModulePathSuccess {
    pub path: PathBuf,
    pub directory_ownership: DirectoryOwnership,
}

impl<'a> Parser<'a> {
    /// Parses a source module as a crate. This is the main entry point for the parser.
    pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> {
        let lo = self.token.span;
        let krate = Ok(ast::Crate {
            attrs: self.parse_inner_attributes()?,
            module: self.parse_mod_items(&token::Eof, lo)?,
            span: lo.to(self.token.span),
            // Filled in by proc_macro_harness::inject()
            proc_macros: Vec::new(),
        });
        krate
    }

    /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
    pub(super) fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
        let in_cfg = crate::config::process_configure_mod(self.sess, self.cfg_mods, attrs);

        let id = self.parse_ident()?;
        let (module, mut inner_attrs) = if self.eat(&token::Semi) {
            if in_cfg && self.recurse_into_file_modules {
                // This mod is in an external file. Let's go get it!
                let ModulePathSuccess { path, directory_ownership } =
                    self.submod_path(id, &attrs)?;
                self.eval_src_mod(path, directory_ownership, id.to_string(), id.span)?
            } else {
                (ast::Mod { inner: DUMMY_SP, items: Vec::new(), inline: false }, Vec::new())
            }
        } else {
            let old_directory = self.directory.clone();
            self.push_directory(id, &attrs);

            self.expect(&token::OpenDelim(token::Brace))?;
            let mod_inner_lo = self.token.span;
            let inner_attrs = self.parse_inner_attributes()?;
            let module = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;

            self.directory = old_directory;
            (module, inner_attrs)
        };
        attrs.append(&mut inner_attrs);
        Ok((id, ItemKind::Mod(module)))
    }

    /// Given a termination token, parses all of the items in a module.
    fn parse_mod_items(&mut self, term: &TokenKind, inner_lo: Span) -> PResult<'a, Mod> {
        let mut items = vec![];
        while let Some(item) = self.parse_item()? {
            items.push(item);
            self.maybe_consume_incorrect_semicolon(&items);
        }

        if !self.eat(term) {
            let token_str = super::token_descr(&self.token);
            if !self.maybe_consume_incorrect_semicolon(&items) {
                let msg = &format!("expected item, found {}", token_str);
                let mut err = self.struct_span_err(self.token.span, msg);
                err.span_label(self.token.span, "expected item");
                return Err(err);
            }
        }

        let hi = if self.token.span.is_dummy() { inner_lo } else { self.prev_token.span };

        Ok(Mod { inner: inner_lo.to(hi), items, inline: true })
    }

    fn submod_path(
        &mut self,
        id: ast::Ident,
        outer_attrs: &[Attribute],
    ) -> PResult<'a, ModulePathSuccess> {
        if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
            let directory_ownership = match path.file_name().and_then(|s| s.to_str()) {
                // All `#[path]` files are treated as though they are a `mod.rs` file.
                // This means that `mod foo;` declarations inside `#[path]`-included
                // files are siblings,
                //
                // Note that this will produce weirdness when a file named `foo.rs` is
                // `#[path]` included and contains a `mod foo;` declaration.
                // If you encounter this, it's your own darn fault :P
                Some(_) => DirectoryOwnership::Owned { relative: None },
                _ => DirectoryOwnership::UnownedViaMod,
            };
            return Ok(ModulePathSuccess { directory_ownership, path });
        }

        let relative = match self.directory.ownership {
            DirectoryOwnership::Owned { relative } => relative,
            DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaMod => None,
        };
        let paths =
            Parser::default_submod_path(id, relative, &self.directory.path, self.sess.source_map());

        match self.directory.ownership {
            DirectoryOwnership::Owned { .. } => {
                paths.result.map_err(|err| self.span_fatal_err(id.span, err))
            }
            DirectoryOwnership::UnownedViaBlock => self.error_decl_mod_in_block(id.span, paths),
            DirectoryOwnership::UnownedViaMod => self.error_cannot_declare_mod_here(id.span, paths),
        }
    }

    fn error_decl_mod_in_block<T>(&self, id_sp: Span, paths: ModulePath) -> PResult<'a, T> {
        let msg =
            "Cannot declare a non-inline module inside a block unless it has a path attribute";
        let mut err = self.struct_span_err(id_sp, msg);
        if paths.path_exists {
            let msg = format!("Maybe `use` the module `{}` instead of redeclaring it", paths.name);
            err.span_note(id_sp, &msg);
        }
        Err(err)
    }

    fn error_cannot_declare_mod_here<T>(&self, id_sp: Span, paths: ModulePath) -> PResult<'a, T> {
        let mut err = self.struct_span_err(id_sp, "cannot declare a new module at this location");
        if !id_sp.is_dummy() {
            if let FileName::Real(src_path) = self.sess.source_map().span_to_filename(id_sp) {
                if let Some(stem) = src_path.file_stem() {
                    let mut dest_path = src_path.clone();
                    dest_path.set_file_name(stem);
                    dest_path.push("mod.rs");
                    err.span_note(
                        id_sp,
                        &format!(
                            "maybe move this module `{}` to its own \
                                    directory via `{}`",
                            src_path.display(),
                            dest_path.display()
                        ),
                    );
                }
            }
        }
        if paths.path_exists {
            err.span_note(
                id_sp,
                &format!(
                    "... or maybe `use` the module `{}` instead \
                                of possibly redeclaring it",
                    paths.name
                ),
            );
        }
        Err(err)
    }

    /// Derive a submodule path from the first found `#[path = "path_string"]`.
    /// The provided `dir_path` is joined with the `path_string`.
    // Public for rustfmt usage.
    pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
        // Extract path string from first `#[path = "path_string"]` attribute.
        let path_string = attr::first_attr_value_str_by_name(attrs, sym::path)?;
        let path_string = path_string.as_str();

        // On windows, the base path might have the form
        // `\\?\foo\bar` in which case it does not tolerate
        // mixed `/` and `\` separators, so canonicalize
        // `/` to `\`.
        #[cfg(windows)]
        let path_string = path_string.replace("/", "\\");

        Some(dir_path.join(&*path_string))
    }

    /// Returns a path to a module.
    // Public for rustfmt usage.
    pub fn default_submod_path(
        id: ast::Ident,
        relative: Option<ast::Ident>,
        dir_path: &Path,
        source_map: &SourceMap,
    ) -> ModulePath {
        // If we're in a foo.rs file instead of a mod.rs file,
        // we need to look for submodules in
        // `./foo/<id>.rs` and `./foo/<id>/mod.rs` rather than
        // `./<id>.rs` and `./<id>/mod.rs`.
        let relative_prefix_string;
        let relative_prefix = if let Some(ident) = relative {
            relative_prefix_string = format!("{}{}", ident.name, path::MAIN_SEPARATOR);
            &relative_prefix_string
        } else {
            ""
        };

        let mod_name = id.name.to_string();
        let default_path_str = format!("{}{}.rs", relative_prefix, mod_name);
        let secondary_path_str =
            format!("{}{}{}mod.rs", relative_prefix, mod_name, path::MAIN_SEPARATOR);
        let default_path = dir_path.join(&default_path_str);
        let secondary_path = dir_path.join(&secondary_path_str);
        let default_exists = source_map.file_exists(&default_path);
        let secondary_exists = source_map.file_exists(&secondary_path);

        let result = match (default_exists, secondary_exists) {
            (true, false) => Ok(ModulePathSuccess {
                path: default_path,
                directory_ownership: DirectoryOwnership::Owned { relative: Some(id) },
            }),
            (false, true) => Ok(ModulePathSuccess {
                path: secondary_path,
                directory_ownership: DirectoryOwnership::Owned { relative: None },
            }),
            (false, false) => {
                Err(Error::FileNotFoundForModule { mod_name: mod_name.clone(), default_path })
            }
            (true, true) => Err(Error::DuplicatePaths {
                mod_name: mod_name.clone(),
                default_path: default_path_str,
                secondary_path: secondary_path_str,
            }),
        };

        ModulePath { name: mod_name, path_exists: default_exists || secondary_exists, result }
    }

    /// Reads a module from a source file.
    fn eval_src_mod(
        &mut self,
        path: PathBuf,
        directory_ownership: DirectoryOwnership,
        name: String,
        id_sp: Span,
    ) -> PResult<'a, (Mod, Vec<Attribute>)> {
        let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
        if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
            let mut err = String::from("circular modules: ");
            let len = included_mod_stack.len();
            for p in &included_mod_stack[i..len] {
                err.push_str(&p.to_string_lossy());
                err.push_str(" -> ");
            }
            err.push_str(&path.to_string_lossy());
            return Err(self.struct_span_err(id_sp, &err[..]));
        }
        included_mod_stack.push(path.clone());
        drop(included_mod_stack);

        let mut p0 =
            new_sub_parser_from_file(self.sess, &path, directory_ownership, Some(name), id_sp);
        p0.cfg_mods = self.cfg_mods;
        let mod_inner_lo = p0.token.span;
        let mod_attrs = p0.parse_inner_attributes()?;
        let mut m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?;
        m0.inline = false;
        self.sess.included_mod_stack.borrow_mut().pop();
        Ok((m0, mod_attrs))
    }

    fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
        if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) {
            self.directory.path.push(&*path.as_str());
            self.directory.ownership = DirectoryOwnership::Owned { relative: None };
        } else {
            // We have to push on the current module name in the case of relative
            // paths in order to ensure that any additional module paths from inline
            // `mod x { ... }` come after the relative extension.
            //
            // For example, a `mod z { ... }` inside `x/y.rs` should set the current
            // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
            if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership {
                if let Some(ident) = relative.take() {
                    // remove the relative offset
                    self.directory.path.push(&*ident.as_str());
                }
            }
            self.directory.path.push(&*id.as_str());
        }
    }
}
<commit_msg>extract parse_mod<commit_after>use super::diagnostics::Error;
use super::item::ItemInfo;
use super::Parser;

use crate::{new_sub_parser_from_file, DirectoryOwnership};

use rustc_ast::ast::{self, Attribute, Crate, Ident, ItemKind, Mod};
use rustc_ast::attr;
use rustc_ast::token::{self, TokenKind};
use rustc_errors::PResult;
use rustc_span::source_map::{FileName, SourceMap, Span, DUMMY_SP};
use rustc_span::symbol::sym;

use std::path::{self, Path, PathBuf};

/// Information about the path to a module.
// Public for rustfmt usage.
pub struct ModulePath {
    name: String,
    path_exists: bool,
    pub result: Result<ModulePathSuccess, Error>,
}

// Public for rustfmt usage.
pub struct ModulePathSuccess {
    pub path: PathBuf,
    pub directory_ownership: DirectoryOwnership,
}

impl<'a> Parser<'a> {
    /// Parses a source module as a crate. This is the main entry point for the parser.
    pub fn parse_crate_mod(&mut self) -> PResult<'a, Crate> {
        let lo = self.token.span;
        let (module, attrs) = self.parse_mod(&token::Eof)?;
        let span = lo.to(self.token.span);
        let proc_macros = Vec::new(); // Filled in by `proc_macro_harness::inject()`.
        Ok(ast::Crate { attrs, module, span, proc_macros })
    }

    /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
    pub(super) fn parse_item_mod(&mut self, attrs: &mut Vec<Attribute>) -> PResult<'a, ItemInfo> {
        let in_cfg = crate::config::process_configure_mod(self.sess, self.cfg_mods, attrs);

        let id = self.parse_ident()?;
        let (module, mut inner_attrs) = if self.eat(&token::Semi) {
            if in_cfg && self.recurse_into_file_modules {
                // This mod is in an external file. Let's go get it!
                let ModulePathSuccess { path, directory_ownership } =
                    self.submod_path(id, &attrs)?;
                self.eval_src_mod(path, directory_ownership, id.to_string(), id.span)?
            } else {
                (ast::Mod { inner: DUMMY_SP, items: Vec::new(), inline: false }, Vec::new())
            }
        } else {
            let old_directory = self.directory.clone();
            self.push_directory(id, &attrs);

            self.expect(&token::OpenDelim(token::Brace))?;
            let module = self.parse_mod(&token::CloseDelim(token::Brace))?;

            self.directory = old_directory;
            module
        };
        attrs.append(&mut inner_attrs);
        Ok((id, ItemKind::Mod(module)))
    }

    /// Parses the contents of a module (inner attributes followed by module items).
    fn parse_mod(&mut self, term: &TokenKind) -> PResult<'a, (Mod, Vec<Attribute>)> {
        let lo = self.token.span;
        let attrs = self.parse_inner_attributes()?;
        let module = self.parse_mod_items(term, lo)?;
        Ok((module, attrs))
    }

    /// Given a termination token, parses all of the items in a module.
    fn parse_mod_items(&mut self, term: &TokenKind, inner_lo: Span) -> PResult<'a, Mod> {
        let mut items = vec![];
        while let Some(item) = self.parse_item()? {
            items.push(item);
            self.maybe_consume_incorrect_semicolon(&items);
        }

        if !self.eat(term) {
            let token_str = super::token_descr(&self.token);
            if !self.maybe_consume_incorrect_semicolon(&items) {
                let msg = &format!("expected item, found {}", token_str);
                let mut err = self.struct_span_err(self.token.span, msg);
                err.span_label(self.token.span, "expected item");
                return Err(err);
            }
        }

        let hi = if self.token.span.is_dummy() { inner_lo } else { self.prev_token.span };

        Ok(Mod { inner: inner_lo.to(hi), items, inline: true })
    }

    fn submod_path(
        &mut self,
        id: ast::Ident,
        outer_attrs: &[Attribute],
    ) -> PResult<'a, ModulePathSuccess> {
        if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
            let directory_ownership = match path.file_name().and_then(|s| s.to_str()) {
                // All `#[path]` files are treated as though they are a `mod.rs` file.
                // This means that `mod foo;` declarations inside `#[path]`-included
                // files are siblings,
                //
                // Note that this will produce weirdness when a file named `foo.rs` is
                // `#[path]` included and contains a `mod foo;` declaration.
                // If you encounter this, it's your own darn fault :P
                Some(_) => DirectoryOwnership::Owned { relative: None },
                _ => DirectoryOwnership::UnownedViaMod,
            };
            return Ok(ModulePathSuccess { directory_ownership, path });
        }

        let relative = match self.directory.ownership {
            DirectoryOwnership::Owned { relative } => relative,
            DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaMod => None,
        };
        let paths =
            Parser::default_submod_path(id, relative, &self.directory.path, self.sess.source_map());

        match self.directory.ownership {
            DirectoryOwnership::Owned { .. } => {
                paths.result.map_err(|err| self.span_fatal_err(id.span, err))
            }
            DirectoryOwnership::UnownedViaBlock => self.error_decl_mod_in_block(id.span, paths),
            DirectoryOwnership::UnownedViaMod => self.error_cannot_declare_mod_here(id.span, paths),
        }
    }

    fn error_decl_mod_in_block<T>(&self, id_sp: Span, paths: ModulePath) -> PResult<'a, T> {
        let msg =
            "Cannot declare a non-inline module inside a block unless it has a path attribute";
        let mut err = self.struct_span_err(id_sp, msg);
        if paths.path_exists {
            let msg = format!("Maybe `use` the module `{}` instead of redeclaring it", paths.name);
            err.span_note(id_sp, &msg);
        }
        Err(err)
    }

    fn error_cannot_declare_mod_here<T>(&self, id_sp: Span, paths: ModulePath) -> PResult<'a, T> {
        let mut err = self.struct_span_err(id_sp, "cannot declare a new module at this location");
        if !id_sp.is_dummy() {
            if let FileName::Real(src_path) = self.sess.source_map().span_to_filename(id_sp) {
                if let Some(stem) = src_path.file_stem() {
                    let mut dest_path = src_path.clone();
                    dest_path.set_file_name(stem);
                    dest_path.push("mod.rs");
                    err.span_note(
                        id_sp,
                        &format!(
                            "maybe move this module `{}` to its own \
                                    directory via `{}`",
                            src_path.display(),
                            dest_path.display()
                        ),
                    );
                }
            }
        }
        if paths.path_exists {
            err.span_note(
                id_sp,
                &format!(
                    "... or maybe `use` the module `{}` instead \
                                of possibly redeclaring it",
                    paths.name
                ),
            );
        }
        Err(err)
    }

    /// Derive a submodule path from the first found `#[path = "path_string"]`.
    /// The provided `dir_path` is joined with the `path_string`.
    // Public for rustfmt usage.
    pub fn submod_path_from_attr(attrs: &[Attribute], dir_path: &Path) -> Option<PathBuf> {
        // Extract path string from first `#[path = "path_string"]` attribute.
        let path_string = attr::first_attr_value_str_by_name(attrs, sym::path)?;
        let path_string = path_string.as_str();

        // On windows, the base path might have the form
        // `\\?\foo\bar` in which case it does not tolerate
        // mixed `/` and `\` separators, so canonicalize
        // `/` to `\`.
        #[cfg(windows)]
        let path_string = path_string.replace("/", "\\");

        Some(dir_path.join(&*path_string))
    }

    /// Returns a path to a module.
    // Public for rustfmt usage.
    pub fn default_submod_path(
        id: ast::Ident,
        relative: Option<ast::Ident>,
        dir_path: &Path,
        source_map: &SourceMap,
    ) -> ModulePath {
        // If we're in a foo.rs file instead of a mod.rs file,
        // we need to look for submodules in
        // `./foo/<id>.rs` and `./foo/<id>/mod.rs` rather than
        // `./<id>.rs` and `./<id>/mod.rs`.
        let relative_prefix_string;
        let relative_prefix = if let Some(ident) = relative {
            relative_prefix_string = format!("{}{}", ident.name, path::MAIN_SEPARATOR);
            &relative_prefix_string
        } else {
            ""
        };

        let mod_name = id.name.to_string();
        let default_path_str = format!("{}{}.rs", relative_prefix, mod_name);
        let secondary_path_str =
            format!("{}{}{}mod.rs", relative_prefix, mod_name, path::MAIN_SEPARATOR);
        let default_path = dir_path.join(&default_path_str);
        let secondary_path = dir_path.join(&secondary_path_str);
        let default_exists = source_map.file_exists(&default_path);
        let secondary_exists = source_map.file_exists(&secondary_path);

        let result = match (default_exists, secondary_exists) {
            (true, false) => Ok(ModulePathSuccess {
                path: default_path,
                directory_ownership: DirectoryOwnership::Owned { relative: Some(id) },
            }),
            (false, true) => Ok(ModulePathSuccess {
                path: secondary_path,
                directory_ownership: DirectoryOwnership::Owned { relative: None },
            }),
            (false, false) => {
                Err(Error::FileNotFoundForModule { mod_name: mod_name.clone(), default_path })
            }
            (true, true) => Err(Error::DuplicatePaths {
                mod_name: mod_name.clone(),
                default_path: default_path_str,
                secondary_path: secondary_path_str,
            }),
        };

        ModulePath { name: mod_name, path_exists: default_exists || secondary_exists, result }
    }

    /// Reads a module from a source file.
    fn eval_src_mod(
        &mut self,
        path: PathBuf,
        directory_ownership: DirectoryOwnership,
        name: String,
        id_sp: Span,
    ) -> PResult<'a, (Mod, Vec<Attribute>)> {
        let mut included_mod_stack = self.sess.included_mod_stack.borrow_mut();
        if let Some(i) = included_mod_stack.iter().position(|p| *p == path) {
            let mut err = String::from("circular modules: ");
            let len = included_mod_stack.len();
            for p in &included_mod_stack[i..len] {
                err.push_str(&p.to_string_lossy());
                err.push_str(" -> ");
            }
            err.push_str(&path.to_string_lossy());
            return Err(self.struct_span_err(id_sp, &err[..]));
        }
        included_mod_stack.push(path.clone());
        drop(included_mod_stack);

        let mut p0 =
            new_sub_parser_from_file(self.sess, &path, directory_ownership, Some(name), id_sp);
        p0.cfg_mods = self.cfg_mods;
        let mut module = p0.parse_mod(&token::Eof)?;
        module.0.inline = false;

        self.sess.included_mod_stack.borrow_mut().pop();
        Ok(module)
    }

    fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
        if let Some(path) = attr::first_attr_value_str_by_name(attrs, sym::path) {
            self.directory.path.push(&*path.as_str());
            self.directory.ownership = DirectoryOwnership::Owned { relative: None };
        } else {
            // We have to push on the current module name in the case of relative
            // paths in order to ensure that any additional module paths from inline
            // `mod x { ... }` come after the relative extension.
            //
            // For example, a `mod z { ... }` inside `x/y.rs` should set the current
            // directory path to `/x/y/z`, not `/x/z` with a relative offset of `y`.
            if let DirectoryOwnership::Owned { relative } = &mut self.directory.ownership {
                if let Some(ident) = relative.take() {
                    // remove the relative offset
                    self.directory.path.push(&*ident.as_str());
                }
            }
            self.directory.path.push(&*id.as_str());
        }
    }
}
<|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 ast::{MetaItem, Item, Expr};
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
use ext::deriving::generic::*;
use ext::deriving::generic::ty::*;
use parse::token::InternedString;

use std::gc::Gc;

pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                             span: Span,
                             mitem: Gc<MetaItem>,
                             item: Gc<Item>,
                             push: |Gc<Item>|) {
    let inline = cx.meta_word(span, InternedString::new("inline"));
    let attrs = vec!(cx.attribute(span, inline));
    let trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: Path::new(vec!("std", "clone", "Clone")),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        methods: vec!(
            MethodDef {
                name: "clone",
                generics: LifetimeBounds::empty(),
                explicit_self: borrowed_explicit_self(),
                args: Vec::new(),
                ret_ty: Self,
                attributes: attrs,
                combine_substructure: combine_substructure(|c, s, sub| {
                    cs_clone("Clone", c, s, sub)
                }),
            }
        )
    };

    trait_def.expand(cx, mitem, item, push)
}

fn cs_clone(
    name: &str,
    cx: &mut ExtCtxt, trait_span: Span,
    substr: &Substructure) -> Gc<Expr> {
    let clone_ident = substr.method_ident;
    let ctor_ident;
    let all_fields;
    let subcall = |field: &FieldInfo|
        cx.expr_method_call(field.span, field.self_, clone_ident, Vec::new());

    match *substr.fields {
        Struct(ref af) => {
            ctor_ident = substr.type_ident;
            all_fields = af;
        }
        EnumMatching(_, variant, ref af) => {
            ctor_ident = variant.node.name;
            all_fields = af;
        },
        EnumNonMatchingCollapsed (..) => {
            cx.span_bug(trait_span,
                        format!("non-matching enum variants in \
                                 `deriving({})`",
                                name).as_slice())
        }
        StaticEnum(..) | StaticStruct(..) => {
            cx.span_bug(trait_span,
                        format!("static method in `deriving({})`",
                                name).as_slice())
        }
    }

    if all_fields.len() >= 1 && all_fields.get(0).name.is_none() {
        // enum-like
        let subcalls = all_fields.iter().map(subcall).collect();
        cx.expr_call_ident(trait_span, ctor_ident, subcalls)
    } else {
        // struct-like
        let fields = all_fields.iter().map(|field| {
            let ident = match field.name {
                Some(i) => i,
                None => {
                    cx.span_bug(trait_span,
                                format!("unnamed field in normal struct in \
                                         `deriving({})`",
                                        name).as_slice())
                }
            };
            cx.field_imm(field.span, ident, subcall(field))
        }).collect::<Vec<_>>();

        if fields.is_empty() {
            // no fields, so construct like `None`
            cx.expr_ident(trait_span, ctor_ident)
        } else {
            cx.expr_struct_ident(trait_span, ctor_ident, fields)
        }
    }
}
<commit_msg>syntax: minor cleanup of #[deriving(Clone)]<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 ast::{MetaItem, Item, Expr};
use codemap::Span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
use ext::deriving::generic::*;
use ext::deriving::generic::ty::*;
use parse::token::InternedString;

use std::gc::Gc;

pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                             span: Span,
                             mitem: Gc<MetaItem>,
                             item: Gc<Item>,
                             push: |Gc<Item>|) {
    let inline = cx.meta_word(span, InternedString::new("inline"));
    let attrs = vec!(cx.attribute(span, inline));
    let trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: Path::new(vec!("std", "clone", "Clone")),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        methods: vec!(
            MethodDef {
                name: "clone",
                generics: LifetimeBounds::empty(),
                explicit_self: borrowed_explicit_self(),
                args: Vec::new(),
                ret_ty: Self,
                attributes: attrs,
                combine_substructure: combine_substructure(|c, s, sub| {
                    cs_clone(c, s, sub)
                }),
            }
        )
    };

    trait_def.expand(cx, mitem, item, push)
}

fn cs_clone(
    cx: &mut ExtCtxt,
    trait_span: Span,
    substr: &Substructure) -> Gc<Expr> {
    let clone_ident = substr.method_ident;
    let ctor_ident;
    let all_fields;
    let subcall = |field: &FieldInfo| {
        cx.expr_method_call(field.span, field.self_, clone_ident, Vec::new())
    };

    match *substr.fields {
        Struct(ref af) => {
            ctor_ident = substr.type_ident;
            all_fields = af;
        }
        EnumMatching(_, variant, ref af) => {
            ctor_ident = variant.node.name;
            all_fields = af;
        },
        EnumNonMatchingCollapsed(..) => {
            cx.span_bug(trait_span, "non-matching enum variants in `#[deriving(Clone)]`")
        }
        StaticEnum(..) | StaticStruct(..) => {
            cx.span_bug(trait_span, "static method in `#[deriving(Clone)]`")
        }
    }

    if all_fields.len() >= 1 && all_fields.get(0).name.is_none() {
        // enum-like
        let subcalls = all_fields.iter().map(subcall).collect();
        cx.expr_call_ident(trait_span, ctor_ident, subcalls)
    } else {
        // struct-like
        let fields = all_fields.iter().map(|field| {
            let ident = match field.name {
                Some(i) => i,
                None => {
                    cx.span_bug(trait_span, "unnamed field in normal struct in \
                                             `#[deriving(Clone)]`")
                }
            };
            cx.field_imm(field.span, ident, subcall(field))
        }).collect::<Vec<_>>();

        if fields.is_empty() {
            // no fields, so construct like `None`
            cx.expr_ident(trait_span, ctor_ident)
        } else {
            cx.expr_struct_ident(trait_span, ctor_ident, fields)
        }
    }
}
<|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::HTMLMetaElementBinding;
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{Root, RootedReference};
use dom::document::Document;
use dom::element::Element;
use dom::htmlelement::HTMLElement;
use dom::node::{Node, document_from_node};
use dom::virtualmethods::VirtualMethods;
use std::ascii::AsciiExt;
use std::sync::Arc;
use string_cache::Atom;
use style::servo::Stylesheet;
use style::stylesheets::{CSSRule, Origin};
use style::viewport::ViewportRule;
use util::str::{DOMString, HTML_SPACE_CHARACTERS};

#[dom_struct]
pub struct HTMLMetaElement {
    htmlelement: HTMLElement,
    stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
}

impl HTMLMetaElement {
    fn new_inherited(localName: Atom,
                     prefix: Option<DOMString>,
                     document: &Document) -> HTMLMetaElement {
        HTMLMetaElement {
            htmlelement: HTMLElement::new_inherited(localName, prefix, document),
            stylesheet: DOMRefCell::new(None),
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: Atom,
               prefix: Option<DOMString>,
               document: &Document) -> Root<HTMLMetaElement> {
        let element = HTMLMetaElement::new_inherited(localName, prefix, document);
        Node::reflect_node(box element, document, HTMLMetaElementBinding::Wrap)
    }

    pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
        self.stylesheet.borrow().clone()
    }

    fn process_attributes(&self) {
        let element = self.upcast::<Element>();
        if let Some(name) = element.get_attribute(&ns!(), &atom!("name")).r() {
            let name = name.value().to_ascii_lowercase();
            let name = name.trim_matches(HTML_SPACE_CHARACTERS);

            if name == "viewport" {
                self.apply_viewport();
            }
        }
    }

    fn apply_viewport(&self) {
        if !::util::prefs::get_pref("layout.viewport.enabled").as_boolean().unwrap_or(false) {
            return;
        }
        let element = self.upcast::<Element>();
        if let Some(content) = element.get_attribute(&ns!(), &atom!("content")).r() {
            let content = content.value();
            if !content.is_empty() {
                if let Some(translated_rule) = ViewportRule::from_meta(&**content) {
                    *self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet {
                        rules: vec![CSSRule::Viewport(translated_rule)],
                        origin: Origin::Author,
                        media: None,
                        // Viewport constraints are always recomputed on resize; they don't need to
                        // force all styles to be recomputed.
                        dirty_on_viewport_size_change: false,
                    }));
                    let doc = document_from_node(self);
                    doc.invalidate_stylesheets();
                }
            }
        }
    }
}

impl HTMLMetaElementMethods for HTMLMetaElement {
    // https://html.spec.whatwg.org/multipage/#dom-meta-name
    make_getter!(Name, "name");

    // https://html.spec.whatwg.org/multipage/#dom-meta-name
    make_setter!(SetName, "name");

    // https://html.spec.whatwg.org/multipage/#dom-meta-content
    make_getter!(Content, "content");

    // https://html.spec.whatwg.org/multipage/#dom-meta-content
    make_setter!(SetContent, "content");
}

impl VirtualMethods for HTMLMetaElement {
    fn super_type(&self) -> Option<&VirtualMethods> {
        Some(self.upcast::<HTMLElement>() as &VirtualMethods)
    }

    fn bind_to_tree(&self, tree_in_doc: bool) {
        if let Some(ref s) = self.super_type() {
            s.bind_to_tree(tree_in_doc);
        }

        if tree_in_doc {
            self.process_attributes();
        }
    }
}
<commit_msg>Overrode parse_plain_attribute of VirtualMethods for HTMLMetaElement to pass  as an Atom<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::attr::AttrValue;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding;
use dom::bindings::codegen::Bindings::HTMLMetaElementBinding::HTMLMetaElementMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{Root, RootedReference};
use dom::document::Document;
use dom::element::Element;
use dom::htmlelement::HTMLElement;
use dom::node::{Node, document_from_node};
use dom::virtualmethods::VirtualMethods;
use std::ascii::AsciiExt;
use std::sync::Arc;
use string_cache::Atom;
use style::servo::Stylesheet;
use style::stylesheets::{CSSRule, Origin};
use style::viewport::ViewportRule;
use util::str::{DOMString, HTML_SPACE_CHARACTERS};

#[dom_struct]
pub struct HTMLMetaElement {
    htmlelement: HTMLElement,
    stylesheet: DOMRefCell<Option<Arc<Stylesheet>>>,
}

impl HTMLMetaElement {
    fn new_inherited(localName: Atom,
                     prefix: Option<DOMString>,
                     document: &Document) -> HTMLMetaElement {
        HTMLMetaElement {
            htmlelement: HTMLElement::new_inherited(localName, prefix, document),
            stylesheet: DOMRefCell::new(None),
        }
    }

    #[allow(unrooted_must_root)]
    pub fn new(localName: Atom,
               prefix: Option<DOMString>,
               document: &Document) -> Root<HTMLMetaElement> {
        let element = HTMLMetaElement::new_inherited(localName, prefix, document);
        Node::reflect_node(box element, document, HTMLMetaElementBinding::Wrap)
    }

    pub fn get_stylesheet(&self) -> Option<Arc<Stylesheet>> {
        self.stylesheet.borrow().clone()
    }

    fn process_attributes(&self) {
        let element = self.upcast::<Element>();
        if let Some(name) = element.get_attribute(&ns!(), &atom!("name")).r() {
            let name = name.value().to_ascii_lowercase();
            let name = name.trim_matches(HTML_SPACE_CHARACTERS);

            if name == "viewport" {
                self.apply_viewport();
            }
        }
    }

    fn apply_viewport(&self) {
        if !::util::prefs::get_pref("layout.viewport.enabled").as_boolean().unwrap_or(false) {
            return;
        }
        let element = self.upcast::<Element>();
        if let Some(content) = element.get_attribute(&ns!(), &atom!("content")).r() {
            let content = content.value();
            if !content.is_empty() {
                if let Some(translated_rule) = ViewportRule::from_meta(&**content) {
                    *self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet {
                        rules: vec![CSSRule::Viewport(translated_rule)],
                        origin: Origin::Author,
                        media: None,
                        // Viewport constraints are always recomputed on resize; they don't need to
                        // force all styles to be recomputed.
                        dirty_on_viewport_size_change: false,
                    }));
                    let doc = document_from_node(self);
                    doc.invalidate_stylesheets();
                }
            }
        }
    }
}

impl HTMLMetaElementMethods for HTMLMetaElement {
    // https://html.spec.whatwg.org/multipage/#dom-meta-name
    make_getter!(Name, "name");

    // https://html.spec.whatwg.org/multipage/#dom-meta-name
    make_atomic_setter!(SetName, "name");

    // https://html.spec.whatwg.org/multipage/#dom-meta-content
    make_getter!(Content, "content");

    // https://html.spec.whatwg.org/multipage/#dom-meta-content
    make_setter!(SetContent, "content");
}

impl VirtualMethods for HTMLMetaElement {
    fn super_type(&self) -> Option<&VirtualMethods> {
        Some(self.upcast::<HTMLElement>() as &VirtualMethods)
    }

    fn bind_to_tree(&self, tree_in_doc: bool) {
        if let Some(ref s) = self.super_type() {
            s.bind_to_tree(tree_in_doc);
        }

        if tree_in_doc {
            self.process_attributes();
        }
    }

    fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue {
        match name {
            &atom!("name") => AttrValue::from_atomic(value),
            _ => self.super_type().unwrap().parse_plain_attribute(name, value),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright © 2016 Cormac O'Brien
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

use std::sync::{Once, ONCE_INIT};

use glium::{DrawParameters, IndexBuffer, Frame, Program, Surface, Texture2d, VertexBuffer};
use glium::backend::Facade;
use glium::program::ProgramCreationInput;
use glium::uniforms::Sampler;

static FULLSCREEN_TEXTURE_VERTICES: [f32; 16] = [
    -1.0,  1.0, 0.0, 1.0,  // Top left
     1.0,  1.0, 0.0, 1.0,  // Top right
    -1.0, -1.0, 0.0, 1.0,  // Bottom left
     1.0, -1.0, 0.0, 1.0]; // Bottom right

static FULLSCREEN_TEXTURE_INDICES: [u32; 6] = [0, 2, 3, 0, 1, 3];

static FULLSCREEN_TEXTURE_COORDINATES: [f32; 8] = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0];

static FULLSCREEN_TEXTURE_VERTEX_SHADER: &'static str = r#"
#version 330

layout(location = 0) in vec4 pos;
layout(location = 1) in vec2 texcoord;

out vec2 Texcoord;

void main() {
    Texcoord = texcoord;
    gl_Position = pos;
}

"#;

static FULLSCREEN_TEXTURE_FRAGMENT_SHADER: &'static str = r#"
#version 330

in vec2 Texcoord;

out vec4 color;

uniform sampler2D tex;

void main() {
    color = texture(tex, Texcoord);
}
"#;

static INIT: Once = ONCE_INIT;

fn fullscreen_texture_program<F>(facade: &F) -> Program where F: Facade {
    let program = match Program::new(facade, ProgramCreationInput::SourceCode {
        vertex_shader: FULLSCREEN_TEXTURE_VERTEX_SHADER,
        tessellation_control_shader: None,
        tessellation_evaluation_shader: None,
        geometry_shader: None,
        fragment_shader: FULLSCREEN_TEXTURE_FRAGMENT_SHADER,
        outputs_srgb: false,
        uses_point_size: false,
        transform_feedback_varyings: None,
    }) {
        Err(why) => panic!("{}", why),
        Ok(p) => p,
    };
}

fn fullscreen_texture(target: &Frame, program: &Program, sampler: &Sampler<Texture2d>) {
    INIT.call_once(|| {
        DEFAULT_DRAW_PARAMS: = DrawParameters::default();

    });
    static FULLSCREEN_TEXTURE_VERTEX_BUFFER: VertexBuffer<f32> = VertexBuffer::new(FULLSCREEN_TEXTURE_INDICES);
    static FULLSCREEN_TEXTURE_INDEX_BUFFER: IndexBuffer<u32> = IndexBuffer::new(FULLSCREEN_TEXTURE_INDICES);

    let uniforms = uniform! {
        tex: *sampler,
    };

    target.draw(&FULLSCREEN_TEXTURE_VERTEX_BUFFER,
                &FULLSCREEN_TEXTURE_INDEX_BUFFER,
                &program,
                &uniforms,
                &DEFAULT_DRAW_PARAMS);
}
<commit_msg>Remove debug.rs<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/. */

extern crate std;

pub struct Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    pub value: T,
    index: usize,
}

// TODO implement std::num::Float
impl <T, CT> std::num::Float for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn nan() -> Self {
        unimplemented!();
    }

    fn infinity() -> Self {
        unimplemented!();
    }

    fn neg_infinity() -> Self {
        unimplemented!();
    }

    fn zero() -> Self {
        unimplemented!();
    }

    fn neg_zero() -> Self {
        unimplemented!();
    }

    fn one() -> Self {
        unimplemented!();
    }

    fn mantissa_digits(unused_self: Option<Self>) -> usize {
        unimplemented!();
    }

    fn digits(unused_self: Option<Self>) -> usize {
        unimplemented!();
    }

    fn epsilon() -> Self {
        unimplemented!();
    }

    fn min_exp(unused_self: Option<Self>) -> isize {
        unimplemented!();
    }

    fn max_exp(unused_self: Option<Self>) -> isize {
        unimplemented!();
    }

    fn min_10_exp(unused_self: Option<Self>) -> isize {
        unimplemented!();
    }

    fn max_10_exp(unused_self: Option<Self>) -> isize {
        unimplemented!();
    }

    fn min_value() -> Self {
        unimplemented!();
    }

    fn min_pos_value(unused_self: Option<Self>) -> Self {
        unimplemented!();
    }

    fn max_value() -> Self {
        unimplemented!();
    }

    fn is_nan(self) -> bool {
        self.value.is_nan()
    }

    fn is_infinite(self) -> bool {
        self.value.is_infinite()
    }

    fn is_finite(self) -> bool {
        self.value.is_finite()
    }

    fn is_normal(self) -> bool {
        self.value.is_normal()
    }

    fn classify(self) -> std::num::FpCategory {
        self.value.classify()
    }

    fn integer_decode(self) -> (u64, i16, i8) {
        self.value.integer_decode()
    }

    fn floor(self) -> Self {
        unimplemented!();
    }

    fn ceil(self) -> Self {
        unimplemented!();
    }

    fn round(self) -> Self {
        unimplemented!();
    }

    fn trunc(self) -> Self {
        unimplemented!();
    }

    fn fract(self) -> Self {
        unimplemented!();
    }

    fn abs(self) -> Self {
        unimplemented!();
    }

    fn signum(self) -> Self {
        unimplemented!();
    }

    fn is_positive(self) -> bool {
        self.value.is_positive()
    }

    fn is_negative(self) -> bool {
        self.value.is_negative()
    }

    fn mul_add(self, a: Self, b: Self) -> Self {
        unimplemented!();
    }

    fn recip(self) -> Self {
        unimplemented!();
    }

    fn powi(self, n: i32) -> Self {
        unimplemented!();
    }

    fn powf(self, n: Self) -> Self {
        unimplemented!();
    }

    fn sqrt(self) -> Self {
        let one = <T as std::num::Float>::one();
        let two = one + one;
        let sqrt_value = self.value.sqrt();
        Float{value: sqrt_value,
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(
                  (two * sqrt_value).recip(), self.index)}
    }

    fn rsqrt(self) -> Self {
        unimplemented!();
    }

    fn exp(self) -> Self {
        let exp_value = self.value.exp();
        Float{value: exp_value,
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(
                  exp_value, self.index)}
    }

    fn exp2(self) -> Self {
        unimplemented!();
    }

    fn ln(self) -> Self {
        unimplemented!();
    }

    fn log(self, base: Self) -> Self {
        unimplemented!();
    }

    fn log2(self) -> Self {
        unimplemented!();
    }

    fn log10(self) -> Self {
        unimplemented!();
    }

    fn to_degrees(self) -> Self {
        unimplemented!();
    }

    fn to_radians(self) -> Self {
        unimplemented!();
    }

    fn ldexp(x: Self, exp: isize) -> Self {
        unimplemented!();
    }

    fn frexp(self) -> (Self, isize) {
        unimplemented!();
    }

    fn next_after(self, other: Self) -> Self {
        unimplemented!();
    }

    fn max(self, other: Self) -> Self {
        unimplemented!();
    }

    fn min(self, other: Self) -> Self {
        unimplemented!();
    }

    fn abs_sub(self, other: Self) -> Self {
        unimplemented!();
    }

    fn cbrt(self) -> Self {
        unimplemented!();
    }

    fn hypot(self, other: Self) -> Self {
        unimplemented!();
    }

    fn sin(self) -> Self {
        Float{value: self.value.sin(),
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(
                  self.value.cos(), self.index)}
    }

    fn cos(self) -> Self {
        Float{value: self.value.cos(),
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(
                  -self.value.sin(), self.index)}
    }

    fn tan(self) -> Self {
        unimplemented!();
    }

    fn asin(self) -> Self {
        unimplemented!();
    }

    fn acos(self) -> Self {
        unimplemented!();
    }

    fn atan(self) -> Self {
        unimplemented!();
    }

    fn atan2(self, other: Self) -> Self {
        unimplemented!();
    }

    fn sin_cos(self) -> (Self, Self) {
        unimplemented!();
    }

    fn exp_m1(self) -> Self {
        unimplemented!();
    }

    fn ln_1p(self) -> Self {
        unimplemented!();
    }

    fn sinh(self) -> Self {
        unimplemented!();
    }

    fn cosh(self) -> Self {
        unimplemented!();
    }

    fn tanh(self) -> Self {
        unimplemented!();
    }

    fn asinh(self) -> Self {
        unimplemented!();
    }

    fn acosh(self) -> Self {
        unimplemented!();
    }

    fn atanh(self) -> Self {
        unimplemented!();
    }
}

impl <T, CT> std::clone::Clone for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn clone(&self) -> Self {
        Float{value: self.value, index: self.index}
    }
}

impl <T, CT> std::num::ToPrimitive for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn to_i64(&self) -> Option<i64> { self.value.to_i64() }

    fn to_u64(&self) -> Option<u64> { self.value.to_u64() }
    //TODO implement the rest optional function.
}

impl <T, CT> std::num::NumCast for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn from<TP>(n: TP) -> Option<Self> where TP: std::num::ToPrimitive {
        None
    }
}

impl <T, CT> std::ops::Neg for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn neg(self) -> Float<T, CT> {
        // TODO rust doesn't have T::one() yet.
        let one: T = std::num::Float::one();
        Float{value: -self.value,
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(one.neg(), self.index)}
    }
}

// TODO adjoints of 1 can be optimized out, i.e., not multiplying. Should we?
// TODO implement operations with underlying type.
impl <T, CT> std::ops::Add<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn add(self, rhs: Float<T, CT>) -> Float<T, CT> {
        Float{value: self.value + rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[std::num::Float::one(), std::num::Float::one()],
                  &[self.index, rhs.index])}
    }
}

impl <T, CT> std::ops::Sub<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn sub(self, rhs: Float<T, CT>) -> Float<T, CT> {
        let one: T = std::num::Float::one();
        Float{value: self.value - rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[one, -one],
                  &[self.index, rhs.index])}
    }
}

impl <T, CT> std::ops::Mul<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn mul(self, rhs: Float<T, CT>) -> Float<T, CT> {
        Float{value: self.value * rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[rhs.value, self.value],
                  &[self.index, rhs.index])}
    }
}

impl <T, CT> std::ops::Div<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn div(self, rhs: Float<T, CT>) -> Float<T, CT> {
        Float{value: self.value / rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[rhs.value.recip(), -((self.value * self.value).recip())],
                  &[self.index, rhs.index])}
    }
}

// TODO 1. Does it make sense to support % operator between two Floats ?
//      2. If so, should we record rhs even though the multiplier is 0?
impl <T, CT> std::ops::Rem<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn rem(self, rhs: Float<T, CT>) -> Float<T, CT> {
        // TODO add this kind of assert everywhere.
        // assert!(( self . context as * const super::context::Context < T >
        //         ) == (
        //         rhs . context as * const super::context::Context < T > ));
        Float{value: self.value % rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[std::num::Float::one(), std::num::Float::zero()],
                  &[self.index, rhs.index])}
    }
}

impl <T, CT> std::cmp::PartialEq for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn eq(&self, other: &Float<T, CT>) -> bool { self.value == other.value }
}

impl <T, CT> std::cmp::PartialOrd for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn partial_cmp(&self, other: &Float<T, CT>) -> Option<std::cmp::Ordering> {
        self.value.partial_cmp(&other.value)
    }
}

impl <T, CT> std::marker::Copy for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
}

// Crate private functions

pub trait FloatCratePrivate<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn new(value: T, index: usize) ->Self;
    fn float_get_index(&self) -> usize;
}

impl <T, CT> FloatCratePrivate<T, CT> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn new(value: T, index: usize) -> Self {
        Float{value: value, index: index}
    }

    fn float_get_index(&self) -> usize {
        self.index
    }
}
<commit_msg>Add an expression template implementation TODO.<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/. */

extern crate std;

// TODO Using expression template will give better performance.
//      e.g., http://www.met.reading.ac.uk/clouds/adept/

pub struct Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    pub value: T,
    index: usize,
}

// TODO implement std::num::Float
impl <T, CT> std::num::Float for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn nan() -> Self {
        unimplemented!();
    }

    fn infinity() -> Self {
        unimplemented!();
    }

    fn neg_infinity() -> Self {
        unimplemented!();
    }

    fn zero() -> Self {
        unimplemented!();
    }

    fn neg_zero() -> Self {
        unimplemented!();
    }

    fn one() -> Self {
        unimplemented!();
    }

    fn mantissa_digits(unused_self: Option<Self>) -> usize {
        unimplemented!();
    }

    fn digits(unused_self: Option<Self>) -> usize {
        unimplemented!();
    }

    fn epsilon() -> Self {
        unimplemented!();
    }

    fn min_exp(unused_self: Option<Self>) -> isize {
        unimplemented!();
    }

    fn max_exp(unused_self: Option<Self>) -> isize {
        unimplemented!();
    }

    fn min_10_exp(unused_self: Option<Self>) -> isize {
        unimplemented!();
    }

    fn max_10_exp(unused_self: Option<Self>) -> isize {
        unimplemented!();
    }

    fn min_value() -> Self {
        unimplemented!();
    }

    fn min_pos_value(unused_self: Option<Self>) -> Self {
        unimplemented!();
    }

    fn max_value() -> Self {
        unimplemented!();
    }

    fn is_nan(self) -> bool {
        self.value.is_nan()
    }

    fn is_infinite(self) -> bool {
        self.value.is_infinite()
    }

    fn is_finite(self) -> bool {
        self.value.is_finite()
    }

    fn is_normal(self) -> bool {
        self.value.is_normal()
    }

    fn classify(self) -> std::num::FpCategory {
        self.value.classify()
    }

    fn integer_decode(self) -> (u64, i16, i8) {
        self.value.integer_decode()
    }

    fn floor(self) -> Self {
        unimplemented!();
    }

    fn ceil(self) -> Self {
        unimplemented!();
    }

    fn round(self) -> Self {
        unimplemented!();
    }

    fn trunc(self) -> Self {
        unimplemented!();
    }

    fn fract(self) -> Self {
        unimplemented!();
    }

    fn abs(self) -> Self {
        unimplemented!();
    }

    fn signum(self) -> Self {
        unimplemented!();
    }

    fn is_positive(self) -> bool {
        self.value.is_positive()
    }

    fn is_negative(self) -> bool {
        self.value.is_negative()
    }

    fn mul_add(self, a: Self, b: Self) -> Self {
        unimplemented!();
    }

    fn recip(self) -> Self {
        unimplemented!();
    }

    fn powi(self, n: i32) -> Self {
        unimplemented!();
    }

    fn powf(self, n: Self) -> Self {
        unimplemented!();
    }

    fn sqrt(self) -> Self {
        let one = <T as std::num::Float>::one();
        let two = one + one;
        let sqrt_value = self.value.sqrt();
        Float{value: sqrt_value,
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(
                  (two * sqrt_value).recip(), self.index)}
    }

    fn rsqrt(self) -> Self {
        unimplemented!();
    }

    fn exp(self) -> Self {
        let exp_value = self.value.exp();
        Float{value: exp_value,
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(
                  exp_value, self.index)}
    }

    fn exp2(self) -> Self {
        unimplemented!();
    }

    fn ln(self) -> Self {
        unimplemented!();
    }

    fn log(self, base: Self) -> Self {
        unimplemented!();
    }

    fn log2(self) -> Self {
        unimplemented!();
    }

    fn log10(self) -> Self {
        unimplemented!();
    }

    fn to_degrees(self) -> Self {
        unimplemented!();
    }

    fn to_radians(self) -> Self {
        unimplemented!();
    }

    fn ldexp(x: Self, exp: isize) -> Self {
        unimplemented!();
    }

    fn frexp(self) -> (Self, isize) {
        unimplemented!();
    }

    fn next_after(self, other: Self) -> Self {
        unimplemented!();
    }

    fn max(self, other: Self) -> Self {
        unimplemented!();
    }

    fn min(self, other: Self) -> Self {
        unimplemented!();
    }

    fn abs_sub(self, other: Self) -> Self {
        unimplemented!();
    }

    fn cbrt(self) -> Self {
        unimplemented!();
    }

    fn hypot(self, other: Self) -> Self {
        unimplemented!();
    }

    fn sin(self) -> Self {
        Float{value: self.value.sin(),
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(
                  self.value.cos(), self.index)}
    }

    fn cos(self) -> Self {
        Float{value: self.value.cos(),
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(
                  -self.value.sin(), self.index)}
    }

    fn tan(self) -> Self {
        unimplemented!();
    }

    fn asin(self) -> Self {
        unimplemented!();
    }

    fn acos(self) -> Self {
        unimplemented!();
    }

    fn atan(self) -> Self {
        unimplemented!();
    }

    fn atan2(self, other: Self) -> Self {
        unimplemented!();
    }

    fn sin_cos(self) -> (Self, Self) {
        unimplemented!();
    }

    fn exp_m1(self) -> Self {
        unimplemented!();
    }

    fn ln_1p(self) -> Self {
        unimplemented!();
    }

    fn sinh(self) -> Self {
        unimplemented!();
    }

    fn cosh(self) -> Self {
        unimplemented!();
    }

    fn tanh(self) -> Self {
        unimplemented!();
    }

    fn asinh(self) -> Self {
        unimplemented!();
    }

    fn acosh(self) -> Self {
        unimplemented!();
    }

    fn atanh(self) -> Self {
        unimplemented!();
    }
}

impl <T, CT> std::clone::Clone for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn clone(&self) -> Self {
        Float{value: self.value, index: self.index}
    }
}

impl <T, CT> std::num::ToPrimitive for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn to_i64(&self) -> Option<i64> { self.value.to_i64() }

    fn to_u64(&self) -> Option<u64> { self.value.to_u64() }
    //TODO implement the rest optional function.
}

impl <T, CT> std::num::NumCast for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn from<TP>(n: TP) -> Option<Self> where TP: std::num::ToPrimitive {
        None
    }
}

impl <T, CT> std::ops::Neg for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn neg(self) -> Float<T, CT> {
        // TODO rust doesn't have T::one() yet.
        let one: T = std::num::Float::one();
        Float{value: -self.value,
              index: <CT as super::context::ContextCratePrivate<T>>::unary_operation(one.neg(), self.index)}
    }
}

// TODO adjoints of 1 can be optimized out, i.e., not multiplying. Should we?
// TODO implement operations with underlying type.
impl <T, CT> std::ops::Add<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn add(self, rhs: Float<T, CT>) -> Float<T, CT> {
        Float{value: self.value + rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[std::num::Float::one(), std::num::Float::one()],
                  &[self.index, rhs.index])}
    }
}

impl <T, CT> std::ops::Sub<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn sub(self, rhs: Float<T, CT>) -> Float<T, CT> {
        let one: T = std::num::Float::one();
        Float{value: self.value - rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[one, -one],
                  &[self.index, rhs.index])}
    }
}

impl <T, CT> std::ops::Mul<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn mul(self, rhs: Float<T, CT>) -> Float<T, CT> {
        Float{value: self.value * rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[rhs.value, self.value],
                  &[self.index, rhs.index])}
    }
}

impl <T, CT> std::ops::Div<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn div(self, rhs: Float<T, CT>) -> Float<T, CT> {
        Float{value: self.value / rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[rhs.value.recip(), -((self.value * self.value).recip())],
                  &[self.index, rhs.index])}
    }
}

// TODO 1. Does it make sense to support % operator between two Floats ?
//      2. If so, should we record rhs even though the multiplier is 0?
impl <T, CT> std::ops::Rem<Float<T, CT>> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    type Output = Float<T, CT>;
    fn rem(self, rhs: Float<T, CT>) -> Float<T, CT> {
        // TODO add this kind of assert everywhere.
        // assert!(( self . context as * const super::context::Context < T >
        //         ) == (
        //         rhs . context as * const super::context::Context < T > ));
        Float{value: self.value % rhs.value,
              index: <CT as super::context::ContextCratePrivate<T>>::binary_operation(
                  &[std::num::Float::one(), std::num::Float::zero()],
                  &[self.index, rhs.index])}
    }
}

impl <T, CT> std::cmp::PartialEq for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn eq(&self, other: &Float<T, CT>) -> bool { self.value == other.value }
}

impl <T, CT> std::cmp::PartialOrd for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn partial_cmp(&self, other: &Float<T, CT>) -> Option<std::cmp::Ordering> {
        self.value.partial_cmp(&other.value)
    }
}

impl <T, CT> std::marker::Copy for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
}

// Crate private functions

pub trait FloatCratePrivate<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn new(value: T, index: usize) ->Self;
    fn float_get_index(&self) -> usize;
}

impl <T, CT> FloatCratePrivate<T, CT> for Float<T, CT> where T: std::num::Float, CT: super::context::Context<T> {
    fn new(value: T, index: usize) -> Self {
        Float{value: value, index: index}
    }

    fn float_get_index(&self) -> usize {
        self.index
    }
}
<|endoftext|>


<commit_before>//use std::cmp::min;
//const INF: i32 = 0x3f3f3f3f;

pub struct DisjointSets {
    parent: Vec<usize>
}

impl DisjointSets {
    pub fn new(size: usize) -> DisjointSets {
        DisjointSets { parent: (0..size).collect() }
    }

    pub fn find(&mut self, u: usize) -> usize {
        let par_u = self.parent[u];
        if par_u != u { self.parent[u] = self.find(par_u); }
        self.parent[u]
    }

    pub fn union(&mut self, u: usize, v: usize) {
        let (pu, pv) = (self.find(u), self.find(v));
        if pu != pv { self.parent[pu] = pv; }
    }
}

#[derive(Clone)]
pub struct Vertex<V> {
    pub first: Option<usize>,
    pub data: V
}

pub struct Edge<E> {
    pub endp: usize,
    pub next: Option<usize>,
    pub data: E
}

pub struct Graph<V, E> {
    pub verts: Vec<Vertex<V>>,
    pub edges: Vec<Edge<E>>,
}

impl<V, E> Graph<V, E> where V: Clone {
    pub fn new(vmax: usize, emax: usize, vdata: V) -> Graph<V, E> {
        Graph {
            verts: vec![Vertex{ first: None, data: vdata }; vmax],
            edges: Vec::with_capacity(2 * emax)
        }
    }

    pub fn add_edge(&mut self, a: usize, b: usize, data: E, rdata: E) {
        self.edges.push(Edge{
            endp: a,
            next: self.verts[a].first,
            data: data
        });
        self.verts[a].first = Some(self.edges.len() - 1);
        self.edges.push(Edge{
            endp: b,
            next: self.verts[b].first,
            data: rdata
        });
        self.verts[b].first = Some(self.edges.len() - 1);
    }

    pub fn adj_list(&self, u: usize) -> Vec<(usize, usize)> {
        let mut adj = Vec::new();
        let mut next_e = self.verts[u].first;
        while let Some(e) = next_e {
            let v = self.edges[e ^ 1].endp;
            next_e = self.edges[e].next;
            adj.push((e, v));
        }
        adj
    }
}

#[derive(Clone)]
struct VFlowData {
    lev: Option<usize>,
    cur: Option<usize>
}

pub struct EFlowData {
    pub flow: i64,
    pub cap: i64,
    pub cost: i64
}

pub struct FlowGraph {
    graph: Graph<VFlowData, EFlowData>
}

impl FlowGraph {
    pub fn new(vmax: usize, emax: usize) -> FlowGraph {
        let data = VFlowData { lev: None, cur: None };
        let graph = Graph::new(vmax, emax, data);
        FlowGraph { graph: graph }
    }

    pub fn add_edge(&mut self, a: usize, b: usize, cap: i64, cost: i64) {
        let data = EFlowData { flow: 0, cap: cap, cost: cost };
        let rdata = EFlowData { cost: -cost, ..data };
        self.graph.add_edge(a, b, data, rdata);
    }

    fn bfs(&mut self, s: usize, t: usize) -> bool {
        let g = &mut self.graph;
        for v in &mut g.verts { v.data.lev = None; }
        let mut q = ::std::collections::VecDeque::<usize>::new();
        q.push_back(s);
        g.verts[s].data.lev = Some(0);
        while let Some(u) = q.pop_front() {
            g.verts[u].data.cur = g.verts[u].first;
            for (e, v) in g.adj_list(u) {
                let edge = &g.edges[e];
                if g.verts[v].data.lev == None && edge.data.flow < edge.data.cap {
                    q.push_back(v);
                    g.verts[v].data.lev = Some(g.verts[u].data.lev.unwrap() + 1);
                }
            }
        }
        return g.verts[t].data.lev != None;
    }

    fn dfs(&mut self, u: usize, t: usize, f: i64) -> i64 {
        if u == t { return f; }
        let mut df = 0;

        while let Some(e) = self.graph.verts[u].data.cur {
            let v = self.graph.edges[e ^ 1].endp;
            if let (Some(lu), Some(lv)) = (self.graph.verts[u].data.lev, self.graph.verts[v].data.lev) {
                let rem_cap = self.graph.edges[e].data.cap
                            - self.graph.edges[e].data.flow;
                if rem_cap > 0 && lv == lu + 1 {
                    let cf = self.dfs(v, t, ::std::cmp::min(rem_cap, f - df));
                    self.graph.edges[e].data.flow += cf;
                    self.graph.edges[e ^ 1].data.flow -= cf;
                    df += cf;
                    if df == f { break; }
                }
            }
            self.graph.verts[u].data.cur = self.graph.edges[e].next;
        }
        return df;
    }

    // Dinic's fast maximum flow: V^2E in general,
    // min(V^(2/3),sqrt(E))E on unit caps, sqrt(V)E on bipartite
    pub fn dinic(&mut self, s: usize, t: usize) -> i64 {
        let mut flow = 0;
        while self.bfs(s, t) {
            flow += self.dfs(s, t, 0x3f3f3f3f);
        }
        flow
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_basic_flow()
    {
        let mut graph = FlowGraph::new(3, 2);
        graph.add_edge(0, 1, 4, 1);
        graph.add_edge(1, 2, 3, 1);
        let flow = graph.dinic(0, 2);
        assert_eq!(flow, 3);
    }
}
<commit_msg>Iterator version of Graph.adj_list<commit_after>//use std::cmp::min;
//const INF: i32 = 0x3f3f3f3f;

pub struct DisjointSets {
    parent: Vec<usize>
}

impl DisjointSets {
    pub fn new(size: usize) -> DisjointSets {
        DisjointSets { parent: (0..size).collect() }
    }

    pub fn find(&mut self, u: usize) -> usize {
        let par_u = self.parent[u];
        if par_u != u { self.parent[u] = self.find(par_u); }
        self.parent[u]
    }

    pub fn union(&mut self, u: usize, v: usize) {
        let (pu, pv) = (self.find(u), self.find(v));
        if pu != pv { self.parent[pu] = pv; }
    }
}

#[derive(Clone)]
pub struct Vertex<V> {
    pub first: Option<usize>,
    pub data: V
}

pub struct Edge<E> {
    pub endp: usize,
    pub next: Option<usize>,
    pub data: E
}

pub struct Graph<V, E> {
    pub verts: Vec<Vertex<V>>,
    pub edges: Vec<Edge<E>>,
}

impl<V, E> Graph<V, E> where V: Clone {
    pub fn new(vmax: usize, emax: usize, vdata: V) -> Graph<V, E> {
        Graph {
            verts: vec![Vertex{ first: None, data: vdata }; vmax],
            edges: Vec::with_capacity(2 * emax)
        }
    }

    pub fn add_edge(&mut self, a: usize, b: usize, data: E, rdata: E) {
        self.edges.push(Edge{
            endp: a,
            next: self.verts[a].first,
            data: data
        });
        self.verts[a].first = Some(self.edges.len() - 1);
        self.edges.push(Edge{
            endp: b,
            next: self.verts[b].first,
            data: rdata
        });
        self.verts[b].first = Some(self.edges.len() - 1);
    }

    pub fn adj_list<'a>(&'a self, u: usize) -> GraphIterator<'a, V, E> {
        GraphIterator { graph: self, next_e: self.verts[u].first }
    }
}

pub struct GraphIterator<'a, V: 'a, E: 'a> {
    graph: &'a Graph<V, E>,
    next_e: Option<usize>
}

impl<'a, V, E> ::std::iter::Iterator for GraphIterator<'a, V, E> {
    // produces an outgoing edge and vertex
    type Item = (usize, usize);

    fn next(&mut self) -> Option<Self::Item> {
        if let Some(e) = self.next_e {
            let v = self.graph.edges[e ^ 1].endp;
            self.next_e = self.graph.edges[e].next;
            Some((e, v))
        }
        else {
            None
        }
    }
}

#[derive(Clone)]
struct VFlowData {
    lev: Option<usize>,
    cur: Option<usize>
}

pub struct EFlowData {
    pub flow: i64,
    pub cap: i64,
    pub cost: i64
}

pub struct FlowGraph {
    graph: Graph<VFlowData, EFlowData>
}

impl FlowGraph {
    pub fn new(vmax: usize, emax: usize) -> FlowGraph {
        let data = VFlowData { lev: None, cur: None };
        let graph = Graph::new(vmax, emax, data);
        FlowGraph { graph: graph }
    }

    pub fn add_edge(&mut self, a: usize, b: usize, cap: i64, cost: i64) {
        let data = EFlowData { flow: 0, cap: cap, cost: cost };
        let rdata = EFlowData { cost: -cost, ..data };
        self.graph.add_edge(a, b, data, rdata);
    }

    fn bfs(&mut self, s: usize, t: usize) -> bool {
        let g = &mut self.graph;
        for v in &mut g.verts { v.data.lev = None; }
        let mut q = ::std::collections::VecDeque::<usize>::new();
        q.push_back(s);
        g.verts[s].data.lev = Some(0);
        while let Some(u) = q.pop_front() {
            g.verts[u].data.cur = g.verts[u].first;
            for (e, v) in g.adj_list(u).collect::<Vec<_>>() {
                let edge = &g.edges[e];
                if g.verts[v].data.lev == None && edge.data.flow < edge.data.cap {
                    q.push_back(v);
                    g.verts[v].data.lev = Some(g.verts[u].data.lev.unwrap() + 1);
                }
            }
        }
        return g.verts[t].data.lev != None;
    }

    fn dfs(&mut self, u: usize, t: usize, f: i64) -> i64 {
        if u == t { return f; }
        let mut df = 0;

        while let Some(e) = self.graph.verts[u].data.cur {
            let v = self.graph.edges[e ^ 1].endp;
            if let (Some(lu), Some(lv)) = (self.graph.verts[u].data.lev, self.graph.verts[v].data.lev) {
                let rem_cap = self.graph.edges[e].data.cap
                            - self.graph.edges[e].data.flow;
                if rem_cap > 0 && lv == lu + 1 {
                    let cf = self.dfs(v, t, ::std::cmp::min(rem_cap, f - df));
                    self.graph.edges[e].data.flow += cf;
                    self.graph.edges[e ^ 1].data.flow -= cf;
                    df += cf;
                    if df == f { break; }
                }
            }
            self.graph.verts[u].data.cur = self.graph.edges[e].next;
        }
        return df;
    }

    // Dinic's fast maximum flow: V^2E in general,
    // min(V^(2/3),sqrt(E))E on unit caps, sqrt(V)E on bipartite
    pub fn dinic(&mut self, s: usize, t: usize) -> i64 {
        let mut flow = 0;
        while self.bfs(s, t) {
            flow += self.dfs(s, t, 0x3f3f3f3f);
        }
        flow
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_basic_flow()
    {
        let mut graph = FlowGraph::new(3, 2);
        graph.add_edge(0, 1, 4, 1);
        graph.add_edge(1, 2, 3, 1);
        let flow = graph.dinic(0, 2);
        assert_eq!(flow, 3);
    }
}
<|endoftext|>