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

use rustc::ty::TypeFoldable;
use rustc::ty::subst::Substs;
use rustc::ty::{Ty, TyCtxt, ClosureSubsts};
use rustc::mir::{Mir, Location, Rvalue, BasicBlock, Statement, StatementKind};
use rustc::mir::visit::MutVisitor;
use rustc::mir::transform::{MirPass, MirSource};
use rustc::infer::{self, InferCtxt};
use syntax_pos::Span;

#[allow(dead_code)]
struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
    infcx: InferCtxt<'a, 'gcx, 'tcx>,
    source: Mir<'tcx>
}

impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> {
    pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, source: Mir<'tcx>) -> Self {
        NLLVisitor {
            infcx: infcx,
            source: source,
        }
    }

    fn renumber_regions<T>(&self, value: &T, span: Span) -> T where T: TypeFoldable<'tcx> {
        self.infcx.tcx.fold_regions(value, &mut false, |_region, _depth| {
            self.infcx.next_region_var(infer::MiscVariable(span))
        })
    }
}

fn span_from_location<'tcx>(source: Mir<'tcx>, location: Location) -> Span {
    source[location.block].statements[location.statement_index].source_info.span
}

impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
    fn visit_ty(&mut self, ty: &mut Ty<'tcx>) {
        let old_ty = *ty;
        // FIXME: Nashenas88 - span should be narrowed down
        *ty = self.renumber_regions(&old_ty, self.source.span);
    }

    fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>) {
        // FIXME: Nashenas88 - span should be narrowed down
        *substs = self.renumber_regions(&{*substs}, self.source.span);
    }

    fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
        match *rvalue {
            Rvalue::Ref(ref mut r, _, _) => {
                let span = span_from_location(location);
                let old_r = *r;
                *r = self.renumber_regions(&old_r, span);
            }
            Rvalue::Use(..) |
            Rvalue::Repeat(..) |
            Rvalue::Len(..) |
            Rvalue::Cast(..) |
            Rvalue::BinaryOp(..) |
            Rvalue::CheckedBinaryOp(..) |
            Rvalue::UnaryOp(..) |
            Rvalue::Discriminant(..) |
            Rvalue::NullaryOp(..) |
            Rvalue::Aggregate(..) => {
                // These variants don't contain regions.
            }
        }
        self.super_rvalue(rvalue, location);
    }

    fn visit_closure_substs(&mut self,
                            substs: &mut ClosureSubsts<'tcx>) {
        // FIXME: Nashenas88 - span should be narrowed down
        *substs = self.renumber_regions(substs, self.source.span);
    }

    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::EndRegion(_) = statement.kind {
            statement.kind = StatementKind::Nop;
        }
        self.super_statement(block, statement, location);
    }
}

// MIR Pass for non-lexical lifetimes
pub struct NLL;

impl MirPass for NLL {
    fn run_pass<'a, 'tcx>(&self,
                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _: MirSource,
                          mir: &mut Mir<'tcx>) {
        if !tcx.sess.opts.debugging_opts.nll {
            return;
        }

        tcx.infer_ctxt().enter(|infcx| {
            let mut visitor = NLLVisitor::new(infcx, mir.clone());
            // Clone mir so we can mutate it without disturbing the rest
            // of the compiler
            let mut mir = mir.clone();
            visitor.visit_mir(&mut mir);
        })
    }
}<commit_msg>Consume MirVisitor changes and use more accurate spans for region renumbering<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.

use rustc::ty::TypeFoldable;
use rustc::ty::subst::Substs;
use rustc::ty::{Ty, TyCtxt, ClosureSubsts};
use rustc::mir::{Mir, Location, Rvalue, BasicBlock, Statement, StatementKind};
use rustc::mir::visit::{MutVisitor, Lookup};
use rustc::mir::transform::{MirPass, MirSource};
use rustc::infer::{self, InferCtxt};
use syntax_pos::Span;

#[allow(dead_code)]
struct NLLVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
    infcx: InferCtxt<'a, 'gcx, 'tcx>,
    source: &'a Mir<'tcx>
}

impl<'a, 'gcx, 'tcx> NLLVisitor<'a, 'gcx, 'tcx> {
    pub fn new(infcx: InferCtxt<'a, 'gcx, 'tcx>, source: &'a Mir<'tcx>) -> Self {
        NLLVisitor {
            infcx: infcx,
            source: source,
        }
    }

    fn renumber_regions<T>(&self, value: &T, span: Span) -> T where T: TypeFoldable<'tcx> {
        self.infcx.tcx.fold_regions(value, &mut false, |_region, _depth| {
            self.infcx.next_region_var(infer::MiscVariable(span))
        })
    }
}

fn span_from_location<'tcx>(source: &Mir<'tcx>, location: Location) -> Span {
    source[location.block].statements[location.statement_index].source_info.span
}

impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
    fn visit_ty(&mut self, ty: &mut Ty<'tcx>, lookup: Lookup) {
        let old_ty = *ty;
        let span = match lookup {
            Lookup::Loc(location) => span_from_location(self.source, location),
            Lookup::Src(source_info) => source_info.span,
        };
        *ty = self.renumber_regions(&old_ty, span);
    }

    fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>, location: Location) {
        *substs = self.renumber_regions(&{*substs}, span_from_location(self.source, location));
    }

    fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
        match *rvalue {
            Rvalue::Ref(ref mut r, _, _) => {
                let old_r = *r;
                *r = self.renumber_regions(&old_r, span_from_location(self.source, location));
            }
            Rvalue::Use(..) |
            Rvalue::Repeat(..) |
            Rvalue::Len(..) |
            Rvalue::Cast(..) |
            Rvalue::BinaryOp(..) |
            Rvalue::CheckedBinaryOp(..) |
            Rvalue::UnaryOp(..) |
            Rvalue::Discriminant(..) |
            Rvalue::NullaryOp(..) |
            Rvalue::Aggregate(..) => {
                // These variants don't contain regions.
            }
        }
        self.super_rvalue(rvalue, location);
    }

    fn visit_closure_substs(&mut self,
                            substs: &mut ClosureSubsts<'tcx>,
                            location: Location) {
        *substs = self.renumber_regions(substs, span_from_location(self.source, location));
    }

    fn visit_statement(&mut self,
                       block: BasicBlock,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        if let StatementKind::EndRegion(_) = statement.kind {
            statement.kind = StatementKind::Nop;
        }
        self.super_statement(block, statement, location);
    }
}

// MIR Pass for non-lexical lifetimes
pub struct NLL;

impl MirPass for NLL {
    fn run_pass<'a, 'tcx>(&self,
                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
                          _: MirSource,
                          mir: &mut Mir<'tcx>) {
        if !tcx.sess.opts.debugging_opts.nll {
            return;
        }

        tcx.infer_ctxt().enter(|infcx| {
            // Clone mir so we can mutate it without disturbing the rest
            // of the compiler
            let mut renumbered_mir = mir.clone();

            // Note that we're using the passed-in mir for the visitor. This is
            // so we can lookup locations during traversal without worrying about
            // maintaing both a mutable and immutable reference to the same object
            let mut visitor = NLLVisitor::new(infcx, &mir);
            visitor.visit_mir(&mut renumbered_mir);
        })
    }
}<|endoftext|>


<commit_before>use hir::{self, HasCrate, HasSource, HirDisplay};
use syntax::ast::{self, make, AstNode, HasGenericParams, HasName, HasVisibility};

use crate::{
    utils::{convert_param_list_to_arg_list, find_struct_impl, render_snippet, Cursor},
    AssistContext, AssistId, AssistKind, Assists, GroupLabel,
};
use syntax::ast::edit::AstNodeEdit;

// Assist: generate_delegate_methods
//
// Generate delegate methods.
//
// ```
// struct Age(u8);
// impl Age {
//     fn age(&self) -> u8 {
//         self.0
//     }
// }
//
// struct Person {
//     ag$0e: Age,
// }
// ```
// ->
// ```
// struct Age(u8);
// impl Age {
//     fn age(&self) -> u8 {
//         self.0
//     }
// }
//
// struct Person {
//     age: Age,
// }
//
// impl Person {
//     $0fn age(&self) -> u8 {
//         self.age.age()
//     }
// }
// ```
pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let strukt = ctx.find_node_at_offset::<ast::Struct>()?;
    let strukt_name = strukt.name()?;

    let (field_name, field_ty) = match ctx.find_node_at_offset::<ast::RecordField>() {
        Some(field) => {
            let field_name = field.name()?;
            let field_ty = field.ty()?;
            (format!("{}", field_name), field_ty)
        }
        None => {
            let field = ctx.find_node_at_offset::<ast::TupleField>()?;
            let field_list = ctx.find_node_at_offset::<ast::TupleFieldList>()?;
            let field_list_index = field_list.fields().position(|it| it == field)?;
            let field_ty = field.ty()?;
            (format!("{}", field_list_index), field_ty)
        }
    };

    let sema_field_ty = ctx.sema.resolve_type(&field_ty)?;
    let krate = sema_field_ty.krate(ctx.db());
    let mut methods = vec![];
    sema_field_ty.iterate_assoc_items(ctx.db(), krate, |item| {
        if let hir::AssocItem::Function(f) = item {
            if f.self_param(ctx.db()).is_some() {
                methods.push(f)
            }
        }
        Option::<()>::None
    });

    let target = field_ty.syntax().text_range();
    for method in methods {
        let adt = ast::Adt::Struct(strukt.clone());
        let name = method.name(ctx.db()).to_string();
        let impl_def = find_struct_impl(ctx, &adt, &name).flatten();
        acc.add_group(
            &GroupLabel("Generate delegate methods…".to_owned()),
            AssistId("generate_delegate_methods", AssistKind::Generate),
            format!("Generate delegate for `{}.{}()`", field_name, method.name(ctx.db())),
            target,
            |builder| {
                // Create the function
                let method_source = match method.source(ctx.db()) {
                    Some(source) => source.value,
                    None => return,
                };
                let method_name = method.name(ctx.db());
                let vis = method_source.visibility();
                let name = make::name(&method.name(ctx.db()).to_string());
                let params =
                    method_source.param_list().unwrap_or_else(|| make::param_list(None, []));
                let type_params = method_source.generic_param_list();
                let arg_list = match method_source.param_list() {
                    Some(list) => convert_param_list_to_arg_list(list),
                    None => make::arg_list([]),
                };
                let tail_expr = make::expr_method_call(
                    make::ext::field_from_idents(["self", &field_name]).unwrap(), // This unwrap is ok because we have at least 1 arg in the list
                    make::name_ref(&method_name.to_string()),
                    arg_list,
                );
                let body = make::block_expr([], Some(tail_expr));
                let ret_type = method.ret_type(ctx.db());
                let ret_type = if ret_type.is_unknown() {
                    // FIXME: we currently can't resolve certain generics, and
                    // are returning placeholders instead. We should fix our
                    // type resolution here, so we return fewer placeholders.
                    Some(make::ret_type(make::ty_placeholder()))
                } else {
                    let ret_type = &ret_type.display(ctx.db()).to_string();
                    Some(make::ret_type(make::ty(ret_type)))
                };
                let is_async = method_source.async_token().is_some();
                let f = make::fn_(vis, name, type_params, params, body, ret_type, is_async)
                    .indent(ast::edit::IndentLevel(1))
                    .clone_for_update();

                let cursor = Cursor::Before(f.syntax());

                // Create or update an impl block, attach the function to it,
                // then insert into our code.
                match impl_def {
                    Some(impl_def) => {
                        // Remember where in our source our `impl` block lives.
                        let impl_def = impl_def.clone_for_update();
                        let old_range = impl_def.syntax().text_range();

                        // Attach the function to the impl block
                        let assoc_items = impl_def.get_or_create_assoc_item_list();
                        assoc_items.add_item(f.clone().into());

                        // Update the impl block.
                        match ctx.config.snippet_cap {
                            Some(cap) => {
                                let snippet = render_snippet(cap, impl_def.syntax(), cursor);
                                builder.replace_snippet(cap, old_range, snippet);
                            }
                            None => {
                                builder.replace(old_range, impl_def.syntax().to_string());
                            }
                        }
                    }
                    None => {
                        // Attach the function to the impl block
                        let name = &strukt_name.to_string();
                        let params = strukt.generic_param_list();
                        let ty_params = params.clone();
                        let impl_def = make::impl_(make::ext::ident_path(name), params, ty_params)
                            .clone_for_update();
                        let assoc_items = impl_def.get_or_create_assoc_item_list();
                        assoc_items.add_item(f.clone().into());

                        // Insert the impl block.
                        match ctx.config.snippet_cap {
                            Some(cap) => {
                                let offset = strukt.syntax().text_range().end();
                                let snippet = render_snippet(cap, impl_def.syntax(), cursor);
                                let snippet = format!("\n\n{}", snippet);
                                builder.insert_snippet(cap, offset, snippet);
                            }
                            None => {
                                let offset = strukt.syntax().text_range().end();
                                let snippet = format!("\n\n{}", impl_def.syntax().to_string());
                                builder.insert(offset, snippet);
                            }
                        }
                    }
                }
            },
        )?;
    }
    Some(())
}

#[cfg(test)]
mod tests {
    use crate::tests::check_assist;

    use super::*;

    #[test]
    fn test_generate_delegate_create_impl_block() {
        check_assist(
            generate_delegate_methods,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person {
    ag$0e: Age,
}"#,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person {
    age: Age,
}

impl Person {
    $0fn age(&self) -> u8 {
        self.age.age()
    }
}"#,
        );
    }

    #[test]
    fn test_generate_delegate_update_impl_block() {
        check_assist(
            generate_delegate_methods,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person {
    ag$0e: Age,
}

impl Person {}"#,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person {
    age: Age,
}

impl Person {
    $0fn age(&self) -> u8 {
        self.age.age()
    }
}"#,
        );
    }

    #[test]
    fn test_generate_delegate_tuple_struct() {
        check_assist(
            generate_delegate_methods,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person(A$0ge);"#,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person(Age);

impl Person {
    $0fn age(&self) -> u8 {
        self.0.age()
    }
}"#,
        );
    }

    #[test]
    fn test_generate_delegate_enable_all_attributes() {
        check_assist(
            generate_delegate_methods,
            r#"
struct Age<T>(T);
impl<T> Age<T> {
    pub(crate) async fn age<J, 'a>(&'a mut self, ty: T, arg: J) -> T {
        self.0
    }
}

struct Person<T> {
    ag$0e: Age<T>,
}"#,
            r#"
struct Age<T>(T);
impl<T> Age<T> {
    pub(crate) async fn age<J, 'a>(&'a mut self, ty: T, arg: J) -> T {
        self.0
    }
}

struct Person<T> {
    age: Age<T>,
}

impl<T> Person<T> {
    $0pub(crate) async fn age<J, 'a>(&'a mut self, ty: T, arg: J) -> _ {
        self.age.age(ty, arg)
    }
}"#,
        );
    }
}
<commit_msg>fix ret type in generic<commit_after>use hir::{self, HasCrate, HasSource};
use syntax::ast::{self, make, AstNode, HasGenericParams, HasName, HasVisibility};

use crate::{
    utils::{convert_param_list_to_arg_list, find_struct_impl, render_snippet, Cursor},
    AssistContext, AssistId, AssistKind, Assists, GroupLabel,
};
use syntax::ast::edit::AstNodeEdit;

// Assist: generate_delegate_methods
//
// Generate delegate methods.
//
// ```
// struct Age(u8);
// impl Age {
//     fn age(&self) -> u8 {
//         self.0
//     }
// }
//
// struct Person {
//     ag$0e: Age,
// }
// ```
// ->
// ```
// struct Age(u8);
// impl Age {
//     fn age(&self) -> u8 {
//         self.0
//     }
// }
//
// struct Person {
//     age: Age,
// }
//
// impl Person {
//     $0fn age(&self) -> u8 {
//         self.age.age()
//     }
// }
// ```
pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let strukt = ctx.find_node_at_offset::<ast::Struct>()?;
    let strukt_name = strukt.name()?;

    let (field_name, field_ty) = match ctx.find_node_at_offset::<ast::RecordField>() {
        Some(field) => {
            let field_name = field.name()?;
            let field_ty = field.ty()?;
            (format!("{}", field_name), field_ty)
        }
        None => {
            let field = ctx.find_node_at_offset::<ast::TupleField>()?;
            let field_list = ctx.find_node_at_offset::<ast::TupleFieldList>()?;
            let field_list_index = field_list.fields().position(|it| it == field)?;
            let field_ty = field.ty()?;
            (format!("{}", field_list_index), field_ty)
        }
    };

    let sema_field_ty = ctx.sema.resolve_type(&field_ty)?;
    let krate = sema_field_ty.krate(ctx.db());
    let mut methods = vec![];
    sema_field_ty.iterate_assoc_items(ctx.db(), krate, |item| {
        if let hir::AssocItem::Function(f) = item {
            if f.self_param(ctx.db()).is_some() {
                methods.push(f)
            }
        }
        Option::<()>::None
    });

    let target = field_ty.syntax().text_range();
    for method in methods {
        let adt = ast::Adt::Struct(strukt.clone());
        let name = method.name(ctx.db()).to_string();
        let impl_def = find_struct_impl(ctx, &adt, &name).flatten();
        acc.add_group(
            &GroupLabel("Generate delegate methods…".to_owned()),
            AssistId("generate_delegate_methods", AssistKind::Generate),
            format!("Generate delegate for `{}.{}()`", field_name, method.name(ctx.db())),
            target,
            |builder| {
                // Create the function
                let method_source = match method.source(ctx.db()) {
                    Some(source) => source.value,
                    None => return,
                };
                let method_name = method.name(ctx.db());
                let vis = method_source.visibility();
                let name = make::name(&method.name(ctx.db()).to_string());
                let params =
                    method_source.param_list().unwrap_or_else(|| make::param_list(None, []));
                let type_params = method_source.generic_param_list();
                let arg_list = match method_source.param_list() {
                    Some(list) => convert_param_list_to_arg_list(list),
                    None => make::arg_list([]),
                };
                let tail_expr = make::expr_method_call(
                    make::ext::field_from_idents(["self", &field_name]).unwrap(), // This unwrap is ok because we have at least 1 arg in the list
                    make::name_ref(&method_name.to_string()),
                    arg_list,
                );
                let body = make::block_expr([], Some(tail_expr));
                let ret_type = method_source.ret_type();
                let is_async = method_source.async_token().is_some();
                let f = make::fn_(vis, name, type_params, params, body, ret_type, is_async)
                    .indent(ast::edit::IndentLevel(1))
                    .clone_for_update();

                let cursor = Cursor::Before(f.syntax());

                // Create or update an impl block, attach the function to it,
                // then insert into our code.
                match impl_def {
                    Some(impl_def) => {
                        // Remember where in our source our `impl` block lives.
                        let impl_def = impl_def.clone_for_update();
                        let old_range = impl_def.syntax().text_range();

                        // Attach the function to the impl block
                        let assoc_items = impl_def.get_or_create_assoc_item_list();
                        assoc_items.add_item(f.clone().into());

                        // Update the impl block.
                        match ctx.config.snippet_cap {
                            Some(cap) => {
                                let snippet = render_snippet(cap, impl_def.syntax(), cursor);
                                builder.replace_snippet(cap, old_range, snippet);
                            }
                            None => {
                                builder.replace(old_range, impl_def.syntax().to_string());
                            }
                        }
                    }
                    None => {
                        // Attach the function to the impl block
                        let name = &strukt_name.to_string();
                        let params = strukt.generic_param_list();
                        let ty_params = params.clone();
                        let impl_def = make::impl_(make::ext::ident_path(name), params, ty_params)
                            .clone_for_update();
                        let assoc_items = impl_def.get_or_create_assoc_item_list();
                        assoc_items.add_item(f.clone().into());

                        // Insert the impl block.
                        match ctx.config.snippet_cap {
                            Some(cap) => {
                                let offset = strukt.syntax().text_range().end();
                                let snippet = render_snippet(cap, impl_def.syntax(), cursor);
                                let snippet = format!("\n\n{}", snippet);
                                builder.insert_snippet(cap, offset, snippet);
                            }
                            None => {
                                let offset = strukt.syntax().text_range().end();
                                let snippet = format!("\n\n{}", impl_def.syntax().to_string());
                                builder.insert(offset, snippet);
                            }
                        }
                    }
                }
            },
        )?;
    }
    Some(())
}

#[cfg(test)]
mod tests {
    use crate::tests::check_assist;

    use super::*;

    #[test]
    fn test_generate_delegate_create_impl_block() {
        check_assist(
            generate_delegate_methods,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person {
    ag$0e: Age,
}"#,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person {
    age: Age,
}

impl Person {
    $0fn age(&self) -> u8 {
        self.age.age()
    }
}"#,
        );
    }

    #[test]
    fn test_generate_delegate_update_impl_block() {
        check_assist(
            generate_delegate_methods,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person {
    ag$0e: Age,
}

impl Person {}"#,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person {
    age: Age,
}

impl Person {
    $0fn age(&self) -> u8 {
        self.age.age()
    }
}"#,
        );
    }

    #[test]
    fn test_generate_delegate_tuple_struct() {
        check_assist(
            generate_delegate_methods,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person(A$0ge);"#,
            r#"
struct Age(u8);
impl Age {
    fn age(&self) -> u8 {
        self.0
    }
}

struct Person(Age);

impl Person {
    $0fn age(&self) -> u8 {
        self.0.age()
    }
}"#,
        );
    }

    #[test]
    fn test_generate_delegate_enable_all_attributes() {
        check_assist(
            generate_delegate_methods,
            r#"
struct Age<T>(T);
impl<T> Age<T> {
    pub(crate) async fn age<J, 'a>(&'a mut self, ty: T, arg: J) -> T {
        self.0
    }
}

struct Person<T> {
    ag$0e: Age<T>,
}"#,
            r#"
struct Age<T>(T);
impl<T> Age<T> {
    pub(crate) async fn age<J, 'a>(&'a mut self, ty: T, arg: J) -> T {
        self.0
    }
}

struct Person<T> {
    age: Age<T>,
}

impl<T> Person<T> {
    $0pub(crate) async fn age<J, 'a>(&'a mut self, ty: T, arg: J) -> T {
        self.age.age(ty, arg)
    }
}"#,
        );
    }
}
<|endoftext|>


<commit_before>#![feature(proc_macro)]

extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;
use syn::{ExprLit, Lit};

#[proc_macro]
pub fn factorial(input: TokenStream) -> TokenStream {
    match syn::parse(input) {
        Ok(ExprLit {
            lit: Lit::Int(lit), ..
        }) => {
            let result: u64 = (1..=lit.value()).product();
            result.to_string().parse().unwrap()
        }
        _ => quote!(compile_error!("argument must be an integer literal")).into(),
    }
}
<commit_msg>remove redundant proc_macro feature gate<commit_after>extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use proc_macro::TokenStream;
use syn::{ExprLit, Lit};

#[proc_macro]
pub fn factorial(input: TokenStream) -> TokenStream {
    match syn::parse(input) {
        Ok(ExprLit {
            lit: Lit::Int(lit), ..
        }) => {
            let result: u64 = (1..=lit.value()).product();
            result.to_string().parse().unwrap()
        }
        _ => quote!(compile_error!("argument must be an integer literal")).into(),
    }
}
<|endoftext|>


<commit_before>use syn::*;

pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<&Vec<NestedMetaItem>> {
    for attr in attrs {
        match attr.value {
            MetaItem::List(ref attr_name, ref items) => {
                if attr_name == "graphql" {
                    return Some(items);
                }
            },
            _ => {},
        }
    }
    None
}

pub fn keyed_item_value(item: &NestedMetaItem, name: &str, must_be_string: bool)
    -> Option<String>
{
    let item = match item {
        &NestedMetaItem::MetaItem(ref item) => item,
        _ => { return None; }
    };
    let lit = match item {
        &MetaItem::NameValue(ref ident, ref lit) => {
            if ident == name {
                lit
            } else {
                return None;
            }
        },
        _ => { return None; },
    };
    match lit {
        &Lit::Str(ref val, _) => {
            Some(val.clone())
        },
        _ => {
            if must_be_string {
                panic!(format!(
                    "Invalid format for attribute \"{:?}\": expected a string",
                    item));
            } else {
                None
            }
        },
    }
}
<commit_msg>Duplicating to_camel_case in codegen<commit_after>use syn::*;

pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<&Vec<NestedMetaItem>> {
    for attr in attrs {
        match attr.value {
            MetaItem::List(ref attr_name, ref items) => {
                if attr_name == "graphql" {
                    return Some(items);
                }
            },
            _ => {},
        }
    }
    None
}

pub fn keyed_item_value(item: &NestedMetaItem, name: &str, must_be_string: bool)
    -> Option<String>
{
    let item = match item {
        &NestedMetaItem::MetaItem(ref item) => item,
        _ => { return None; }
    };
    let lit = match item {
        &MetaItem::NameValue(ref ident, ref lit) => {
            if ident == name {
                lit
            } else {
                return None;
            }
        },
        _ => { return None; },
    };
    match lit {
        &Lit::Str(ref val, _) => {
            Some(val.clone())
        },
        _ => {
            if must_be_string {
                panic!(format!(
                    "Invalid format for attribute \"{:?}\": expected a string",
                    item));
            } else {
                None
            }
        },
    }
}

// Note: duplicated from juniper crate!
#[doc(hidden)]
pub fn to_camel_case(s: &str) -> String {
    let mut dest = String::new();

    for (i, part) in s.split('_').enumerate() {
        if i > 0 && part.len() == 1 {
            dest.push_str(&part.to_uppercase());
        }
        else if i > 0 && part.len() > 1 {
            let first = part.chars().next().unwrap().to_uppercase().collect::<String>();
            let second = &part[1..];

            dest.push_str(&first);
            dest.push_str(second);
        }
        else if i == 0 {
            dest.push_str(part);
        }
    }

    dest
}

#[test]
fn test_to_camel_case() {
    assert_eq!(&to_camel_case("test")[..], "test");
    assert_eq!(&to_camel_case("_test")[..], "Test");
    assert_eq!(&to_camel_case("first_second")[..], "firstSecond");
    assert_eq!(&to_camel_case("first_")[..], "first");
    assert_eq!(&to_camel_case("a_b_c")[..], "aBC");
    assert_eq!(&to_camel_case("a_bc")[..], "aBc");
    assert_eq!(&to_camel_case("a_b")[..], "aB");
    assert_eq!(&to_camel_case("a")[..], "a");
    assert_eq!(&to_camel_case("")[..], "");
}
<|endoftext|>


<commit_before>// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::errors::{CompilationError, Error};
use crate::{EvalContext, EvalContextOutputs, EvalOutputs};

/// A higher level interface to EvalContext. A bit closer to a Repl. Provides commands (start with
/// ':') that alter context state or print information.
pub struct CommandContext {
    print_timings: bool,
    eval_context: EvalContext,
    last_errors: Vec<CompilationError>,
}

impl CommandContext {
    pub fn new() -> Result<(CommandContext, EvalContextOutputs), Error> {
        let (eval_context, eval_context_outputs) = EvalContext::new()?;
        let command_context = CommandContext::with_eval_context(eval_context);
        Ok((command_context, eval_context_outputs))
    }

    pub fn with_eval_context(eval_context: EvalContext) -> CommandContext {
        CommandContext {
            print_timings: false,
            eval_context,
            last_errors: Vec::new(),
        }
    }

    pub fn execute(&mut self, to_run: &str) -> Result<EvalOutputs, Error> {
        use regex::Regex;
        use std::time::Instant;
        lazy_static! {
            static ref COMMAND_RE: Regex = Regex::new("^ *(:[^ ]+)( +(.*))?$").unwrap();
        }
        let mut eval_outputs = EvalOutputs::new();
        let start = Instant::now();
        let mut to_eval = Vec::new();
        for line in to_run.lines() {
            // We only accept commands up until the first non-command.
            if to_eval.is_empty() {
                if let Some(captures) = COMMAND_RE.captures(line) {
                    eval_outputs.merge(
                        self.process_command(&captures[1], captures.get(3).map(|m| m.as_str()))?,
                    );
                    continue;
                }
            }
            to_eval.push(line)
        }
        let result = if to_run.is_empty() {
            Ok(EvalOutputs::new())
        } else {
            self.eval_context.eval(&to_eval.join("\n"))
        };
        let duration = start.elapsed();
        match result {
            Ok(m) => {
                eval_outputs.merge(m);
                if self.print_timings {
                    eval_outputs.timing = Some(duration);
                }
                Ok(eval_outputs)
            }
            Err(Error::CompilationErrors(errors)) => {
                self.last_errors = errors.clone();
                Err(Error::CompilationErrors(errors))
            }
            x => x,
        }
    }

    fn load_config(&mut self) -> Result<EvalOutputs, Error> {
        let mut outputs = EvalOutputs::new();
        if let Some(config_dir) = dirs::config_dir() {
            let config_file = config_dir.join("evcxr").join("init.evcxr");
            if config_file.exists() {
                println!("Loading startup commands from {:?}", config_file);
                let contents = std::fs::read_to_string(config_file)?;
                for line in contents.lines() {
                    outputs.merge(self.execute(line)?);
                }
            }
        }
        Ok(outputs)
    }

    fn process_command(&mut self, command: &str, args: Option<&str>) -> Result<EvalOutputs, Error> {
        match command {
            ":internal_debug" => {
                let debug_mode = !self.eval_context.debug_mode();
                self.eval_context.set_debug_mode(debug_mode);
                text_output(format!("Internals debugging: {}", debug_mode))
            }
            ":load_config" => self.load_config(),
            ":version" => text_output(env!("CARGO_PKG_VERSION")),
            ":vars" => {
                let mut outputs = EvalOutputs::new();
                outputs
                    .content_by_mime_type
                    .insert("text/plain".to_owned(), self.vars_as_text());
                outputs
                    .content_by_mime_type
                    .insert("text/html".to_owned(), self.vars_as_html());
                Ok(outputs)
            }
            ":preserve_vars_on_panic" => {
                self.eval_context.preserve_vars_on_panic = args == Some("1");
                text_output(format!(
                    "Preserve vars on panic: {}",
                    self.eval_context.preserve_vars_on_panic
                ))
            }
            ":clear" => self.eval_context.clear().map(|_| EvalOutputs::new()),
            ":dep" => {
                use regex::Regex;
                let args = if let Some(v) = args {
                    v
                } else {
                    bail!(":dep requires arguments")
                };
                lazy_static! {
                    static ref DEP_RE: Regex = Regex::new("^([^= ]+) *= *(.+)$").unwrap();
                }
                if let Some(captures) = DEP_RE.captures(args) {
                    self.eval_context.add_dep(&captures[1], &captures[2])?;
                    Ok(EvalOutputs::new())
                } else {
                    bail!("Invalid :dep command. Expected: name = ...");
                }
            }
            ":last_compile_dir" => {
                text_output(format!("{:?}", self.eval_context.last_compile_dir()))
            }
            ":opt" => {
                let new_level = if let Some(n) = args {
                    &n
                } else if self.eval_context.opt_level() == "2" {
                    "0"
                } else {
                    "2"
                };
                self.eval_context.set_opt_level(new_level)?;
                text_output(format!("Optimization: {}", self.eval_context.opt_level()))
            }
            ":timing" => {
                self.print_timings = !self.print_timings;
                text_output(format!("Timing: {}", self.print_timings))
            }
            ":time_passes" => {
                self.eval_context
                    .set_time_passes(!self.eval_context.time_passes());
                text_output(format!("Time passes: {}", self.eval_context.time_passes()))
            }
            ":sccache" => {
                self.eval_context.set_sccache(args != Some("0"))?;
                text_output(format!("sccache: {}", self.eval_context.sccache()))
            }
            ":explain" => {
                if self.last_errors.is_empty() {
                    bail!("No last error to explain");
                } else {
                    let mut all_explanations = String::new();
                    for error in &self.last_errors {
                        if let Some(explanation) = error.explanation() {
                            all_explanations.push_str(explanation);
                        } else {
                            bail!("Sorry, last error has no explanation");
                        }
                    }
                    text_output(all_explanations)
                }
            }
            ":last_error_json" => {
                let mut errors_out = String::new();
                for error in &self.last_errors {
                    use std::fmt::Write;
                    write!(&mut errors_out, "{}", error.json)?;
                    errors_out.push('\n');
                }
                bail!(errors_out);
            }
            ":help" => text_output(
                ":vars             List bound variables and their types\n\
                 :opt [level]      Toggle/set optimization level\n\
                 :explain          Print explanation of last error\n\
                 :clear            Clear all state, keeping compilation cache\n\
                 :dep              Add dependency. e.g. :dep regex = \"1.0\"\n\
                 :sccache [0|1]    Set whether to use sccache.\n\
                 :version          Print Evcxr version\n\
                 :preserve_vars_on_panic [0|1]  Try to keep vars on panic\n\n\
                 Mostly for development / debugging purposes:\n\
                 :last_compile_dir Print the directory in which we last compiled\n\
                 :timing           Toggle printing of how long evaluations take\n\
                 :last_error_json  Print the last compilation error as JSON (for debugging)\n\
                 :time_passes      Toggle printing of rustc pass times (requires nightly)\n\
                 :internal_debug   Toggle various internal debugging code",
            ),
            _ => bail!("Unrecognised command {}", command),
        }
    }

    fn vars_as_text(&self) -> String {
        let mut out = String::new();
        for (var, ty) in self.eval_context.variables_and_types() {
            out.push_str(var);
            out.push_str(": ");
            out.push_str(ty);
            out.push_str("\n");
        }
        out
    }

    fn vars_as_html(&self) -> String {
        let mut out = String::new();
        out.push_str("

Variable	Type
");
        for (var, ty) in self.eval_context.variables_and_types() {
            out.push_str("
");
            html_escape(var, &mut out);
            out.push_str("	");
            html_escape(ty, &mut out);
            out.push_str("
");
        }
        out.push_str("
");
        out
    }
}

fn html_escape(input: &str, out: &mut String) {
    for ch in input.chars() {
        match ch {
            '<' => out.push_str("<"),
            '>' => out.push_str(">"),
            x => out.push(x),
        }
    }
}

fn text_output<T: Into<String>>(text: T) -> Result<EvalOutputs, Error> {
    let mut outputs = EvalOutputs::new();
    let mut content = text.into();
    content.push('\n');
    outputs
        .content_by_mime_type
        .insert("text/plain".to_owned(), content);
    Ok(outputs)
}
<commit_msg>Run prelude.rs after init.evcxr if one exists. Fixes #79<commit_after>// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::errors::{CompilationError, Error};
use crate::{EvalContext, EvalContextOutputs, EvalOutputs};

/// A higher level interface to EvalContext. A bit closer to a Repl. Provides commands (start with
/// ':') that alter context state or print information.
pub struct CommandContext {
    print_timings: bool,
    eval_context: EvalContext,
    last_errors: Vec<CompilationError>,
}

impl CommandContext {
    pub fn new() -> Result<(CommandContext, EvalContextOutputs), Error> {
        let (eval_context, eval_context_outputs) = EvalContext::new()?;
        let command_context = CommandContext::with_eval_context(eval_context);
        Ok((command_context, eval_context_outputs))
    }

    pub fn with_eval_context(eval_context: EvalContext) -> CommandContext {
        CommandContext {
            print_timings: false,
            eval_context,
            last_errors: Vec::new(),
        }
    }

    pub fn execute(&mut self, to_run: &str) -> Result<EvalOutputs, Error> {
        use regex::Regex;
        use std::time::Instant;
        lazy_static! {
            static ref COMMAND_RE: Regex = Regex::new("^ *(:[^ ]+)( +(.*))?$").unwrap();
        }
        let mut eval_outputs = EvalOutputs::new();
        let start = Instant::now();
        let mut to_eval = Vec::new();
        for line in to_run.lines() {
            // We only accept commands up until the first non-command.
            if to_eval.is_empty() {
                if let Some(captures) = COMMAND_RE.captures(line) {
                    eval_outputs.merge(
                        self.process_command(&captures[1], captures.get(3).map(|m| m.as_str()))?,
                    );
                    continue;
                }
            }
            to_eval.push(line)
        }
        let result = if to_run.is_empty() {
            Ok(EvalOutputs::new())
        } else {
            self.eval_context.eval(&to_eval.join("\n"))
        };
        let duration = start.elapsed();
        match result {
            Ok(m) => {
                eval_outputs.merge(m);
                if self.print_timings {
                    eval_outputs.timing = Some(duration);
                }
                Ok(eval_outputs)
            }
            Err(Error::CompilationErrors(errors)) => {
                self.last_errors = errors.clone();
                Err(Error::CompilationErrors(errors))
            }
            x => x,
        }
    }

    fn load_config(&mut self) -> Result<EvalOutputs, Error> {
        let mut outputs = EvalOutputs::new();
        if let Some(config_dir) = dirs::config_dir() {
            let config_dir = config_dir.join("evcxr");
            let config_file = config_dir.join("init.evcxr");
            if config_file.exists() {
                println!("Loading startup commands from {:?}", config_file);
                let contents = std::fs::read_to_string(config_file)?;
                for line in contents.lines() {
                    outputs.merge(self.execute(line)?);
                }
            }
            // Note: Loaded *after* init.evcxr so that it can access `:dep`s (or
            // any other state changed by :commands) specified in the init file.
            let prelude_file = config_dir.join("prelude.rs");
            if prelude_file.exists() {
                println!("Executing prelude from {:?}", prelude_file);
                let prelude = std::fs::read_to_string(prelude_file)?;
                outputs.merge(self.execute(&prelude)?);
            }
        }
        Ok(outputs)
    }

    fn process_command(&mut self, command: &str, args: Option<&str>) -> Result<EvalOutputs, Error> {
        match command {
            ":internal_debug" => {
                let debug_mode = !self.eval_context.debug_mode();
                self.eval_context.set_debug_mode(debug_mode);
                text_output(format!("Internals debugging: {}", debug_mode))
            }
            ":load_config" => self.load_config(),
            ":version" => text_output(env!("CARGO_PKG_VERSION")),
            ":vars" => {
                let mut outputs = EvalOutputs::new();
                outputs
                    .content_by_mime_type
                    .insert("text/plain".to_owned(), self.vars_as_text());
                outputs
                    .content_by_mime_type
                    .insert("text/html".to_owned(), self.vars_as_html());
                Ok(outputs)
            }
            ":preserve_vars_on_panic" => {
                self.eval_context.preserve_vars_on_panic = args == Some("1");
                text_output(format!(
                    "Preserve vars on panic: {}",
                    self.eval_context.preserve_vars_on_panic
                ))
            }
            ":clear" => self.eval_context.clear().map(|_| EvalOutputs::new()),
            ":dep" => {
                use regex::Regex;
                let args = if let Some(v) = args {
                    v
                } else {
                    bail!(":dep requires arguments")
                };
                lazy_static! {
                    static ref DEP_RE: Regex = Regex::new("^([^= ]+) *= *(.+)$").unwrap();
                }
                if let Some(captures) = DEP_RE.captures(args) {
                    self.eval_context.add_dep(&captures[1], &captures[2])?;
                    Ok(EvalOutputs::new())
                } else {
                    bail!("Invalid :dep command. Expected: name = ...");
                }
            }
            ":last_compile_dir" => {
                text_output(format!("{:?}", self.eval_context.last_compile_dir()))
            }
            ":opt" => {
                let new_level = if let Some(n) = args {
                    &n
                } else if self.eval_context.opt_level() == "2" {
                    "0"
                } else {
                    "2"
                };
                self.eval_context.set_opt_level(new_level)?;
                text_output(format!("Optimization: {}", self.eval_context.opt_level()))
            }
            ":timing" => {
                self.print_timings = !self.print_timings;
                text_output(format!("Timing: {}", self.print_timings))
            }
            ":time_passes" => {
                self.eval_context
                    .set_time_passes(!self.eval_context.time_passes());
                text_output(format!("Time passes: {}", self.eval_context.time_passes()))
            }
            ":sccache" => {
                self.eval_context.set_sccache(args != Some("0"))?;
                text_output(format!("sccache: {}", self.eval_context.sccache()))
            }
            ":explain" => {
                if self.last_errors.is_empty() {
                    bail!("No last error to explain");
                } else {
                    let mut all_explanations = String::new();
                    for error in &self.last_errors {
                        if let Some(explanation) = error.explanation() {
                            all_explanations.push_str(explanation);
                        } else {
                            bail!("Sorry, last error has no explanation");
                        }
                    }
                    text_output(all_explanations)
                }
            }
            ":last_error_json" => {
                let mut errors_out = String::new();
                for error in &self.last_errors {
                    use std::fmt::Write;
                    write!(&mut errors_out, "{}", error.json)?;
                    errors_out.push('\n');
                }
                bail!(errors_out);
            }
            ":help" => text_output(
                ":vars             List bound variables and their types\n\
                 :opt [level]      Toggle/set optimization level\n\
                 :explain          Print explanation of last error\n\
                 :clear            Clear all state, keeping compilation cache\n\
                 :dep              Add dependency. e.g. :dep regex = \"1.0\"\n\
                 :sccache [0|1]    Set whether to use sccache.\n\
                 :version          Print Evcxr version\n\
                 :preserve_vars_on_panic [0|1]  Try to keep vars on panic\n\n\
                 Mostly for development / debugging purposes:\n\
                 :last_compile_dir Print the directory in which we last compiled\n\
                 :timing           Toggle printing of how long evaluations take\n\
                 :last_error_json  Print the last compilation error as JSON (for debugging)\n\
                 :time_passes      Toggle printing of rustc pass times (requires nightly)\n\
                 :internal_debug   Toggle various internal debugging code",
            ),
            _ => bail!("Unrecognised command {}", command),
        }
    }

    fn vars_as_text(&self) -> String {
        let mut out = String::new();
        for (var, ty) in self.eval_context.variables_and_types() {
            out.push_str(var);
            out.push_str(": ");
            out.push_str(ty);
            out.push_str("\n");
        }
        out
    }

    fn vars_as_html(&self) -> String {
        let mut out = String::new();
        out.push_str("

Variable	Type
");
        for (var, ty) in self.eval_context.variables_and_types() {
            out.push_str("
");
            html_escape(var, &mut out);
            out.push_str("	");
            html_escape(ty, &mut out);
            out.push_str("
");
        }
        out.push_str("
");
        out
    }
}

fn html_escape(input: &str, out: &mut String) {
    for ch in input.chars() {
        match ch {
            '<' => out.push_str("<"),
            '>' => out.push_str(">"),
            x => out.push(x),
        }
    }
}

fn text_output<T: Into<String>>(text: T) -> Result<EvalOutputs, Error> {
    let mut outputs = EvalOutputs::new();
    let mut content = text.into();
    content.push('\n');
    outputs
        .content_by_mime_type
        .insert("text/plain".to_owned(), content);
    Ok(outputs)
}
<|endoftext|>


<commit_before>use super::gui::EdBuffer;
use super::schedule::Program;

pub trait Action {
    fn apply(&self, buffer: &mut super::gui::EdBuffer) -> Result<(), String>;
    fn reverse(&self, buffer: &mut super::gui::EdBuffer) -> Result<(), String>;
}

pub struct ChangeName {
    old: String,
    new: String
}

impl Action for ChangeName {
    fn apply(&self, buffer: &mut super::gui::EdBuffer) -> Result<(), String> {
        buffer.set_name(&self.new);
        Ok(())
    }

    fn reverse(&self, buffer: &mut super::gui::EdBuffer) -> Result<(), String> {
        buffer.set_name(&self.old);
        Ok(())
    }
}

impl ChangeName {
    pub fn new(orig: &str, novo: &str) -> Box<Action> {
        let changename = ChangeName {
            old: orig.to_string(),
            new: novo.to_string()
        };
        Box::new(changename)
    }
}

pub struct AddProgram {
    program: Program,
}

impl AddProgram {
    pub fn new(prog: &Program) -> Box<Action> {
        Box::new(AddProgram { program: prog.clone() })
    }
}

impl Action for AddProgram {
    fn apply(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        buffer.add_program(&self.program);
        Ok(())
    }

    fn reverse(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        if let Some(x) =  buffer.pop_program() {
            if x != self.program {
                panic!("Modification made after undo without clearing redo buffer!")
            }
        }
        Ok(())
    }
}

pub struct PopProgram {
    program: Program
}

impl PopProgram {
    pub fn new(buffer: &EdBuffer) -> Result<Box<Action>, String> {
        match buffer.last_program() {
            Some(p) => Ok(Box::new(PopProgram { program: p.clone() })),
            None =>  Err("Can not pop an empty program".to_string())
        }
    }
}

impl Action for PopProgram {
    fn apply(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        if let Some(x) = buffer.pop_program() {
            if x != self.program {
                panic!("Modification made after undo without clearing redo buffer!")
            }
        }
        Ok(())
    }

    fn reverse(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        buffer.add_program(&self.program);
        Ok(())
    }
}

pub struct InsertProgram {
    program: Program,
    index: usize
}

impl InsertProgram {
    pub fn new(prog: &Program, idx: usize) -> Box<Action> {
        Box::new(InsertProgram {
            program: prog.clone(),
            index: idx
        })
    }
}

impl Action for InsertProgram {
    fn apply(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        buffer.insert_program(self.index, &self.program)
    }

    fn reverse(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        if let Err(f) = buffer.delete_program(self.index) {
            panic!(format!("Modifications made after undo. Error: {}", f))
        }
        Ok(())
    }
}

pub struct DeleteProgram {
    program: Program,
    index: usize
}

impl DeleteProgram {
    pub fn new(buffer: &EdBuffer, idx: usize) -> Result<Box<Action>, String> {
        match buffer.get_program(idx) {
            Some(p) => Ok(Box::new(DeleteProgram { program: p.clone(), index: idx })),
            None => Err(format!("Can not delete program at {} because it does not exist", idx))
        }
    }
}

impl Action for DeleteProgram {
    fn apply(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        buffer.delete_program(self.index)
    }

    fn reverse(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        if let Err(f) = buffer.insert_program(self.index, &self.program) {
            panic!(format!("Modifications made after undo. Error: {}", f))
        }
        Ok(())
    }
}
<commit_msg>working on making stuff callable from C<commit_after>use super::gui::EdBuffer;
use super::schedule::Program;

pub trait Action {
    #[no_mangle]
    fn apply(&self, buffer: &mut super::gui::EdBuffer) -> Result<(), String>;
    #[no_mangle]
    fn reverse(&self, buffer: &mut super::gui::EdBuffer) -> Result<(), String>;
}

pub struct ChangeName {
    old: String,
    new: String
}

impl Action for ChangeName {
    fn apply(&self, buffer: &mut super::gui::EdBuffer) -> Result<(), String> {
        buffer.set_name(&self.new);
        Ok(())
    }

    fn reverse(&self, buffer: &mut super::gui::EdBuffer) -> Result<(), String> {
        buffer.set_name(&self.old);
        Ok(())
    }
}

impl ChangeName {
    pub fn new(orig: &str, novo: &str) -> Box<Action> {
        let changename = ChangeName {
            old: orig.to_string(),
            new: novo.to_string()
        };
        Box::new(changename)
    }
}

pub struct AddProgram {
    program: Program,
}

impl AddProgram {
    pub fn new(prog: &Program) -> Box<Action> {
        Box::new(AddProgram { program: prog.clone() })
    }
}

impl Action for AddProgram {
    fn apply(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        buffer.add_program(&self.program);
        Ok(())
    }

    fn reverse(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        if let Some(x) =  buffer.pop_program() {
            if x != self.program {
                panic!("Modification made after undo without clearing redo buffer!")
            }
        }
        Ok(())
    }
}

pub struct PopProgram {
    program: Program
}

impl PopProgram {
    pub fn new(buffer: &EdBuffer) -> Result<Box<Action>, String> {
        match buffer.last_program() {
            Some(p) => Ok(Box::new(PopProgram { program: p.clone() })),
            None =>  Err("Can not pop an empty program".to_string())
        }
    }
}

impl Action for PopProgram {
    fn apply(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        if let Some(x) = buffer.pop_program() {
            if x != self.program {
                panic!("Modification made after undo without clearing redo buffer!")
            }
        }
        Ok(())
    }

    fn reverse(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        buffer.add_program(&self.program);
        Ok(())
    }
}

pub struct InsertProgram {
    program: Program,
    index: usize
}

impl InsertProgram {
    pub fn new(prog: &Program, idx: usize) -> Box<Action> {
        Box::new(InsertProgram {
            program: prog.clone(),
            index: idx
        })
    }
}

impl Action for InsertProgram {
    fn apply(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        buffer.insert_program(self.index, &self.program)
    }

    fn reverse(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        if let Err(f) = buffer.delete_program(self.index) {
            panic!(format!("Modifications made after undo. Error: {}", f))
        }
        Ok(())
    }
}

pub struct DeleteProgram {
    program: Program,
    index: usize
}

impl DeleteProgram {
    pub fn new(buffer: &EdBuffer, idx: usize) -> Result<Box<Action>, String> {
        match buffer.get_program(idx) {
            Some(p) => Ok(Box::new(DeleteProgram { program: p.clone(), index: idx })),
            None => Err(format!("Can not delete program at {} because it does not exist", idx))
        }
    }
}

impl Action for DeleteProgram {
    fn apply(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        buffer.delete_program(self.index)
    }

    fn reverse(&self, buffer: &mut EdBuffer) -> Result<(), String> {
        if let Err(f) = buffer.insert_program(self.index, &self.program) {
            panic!(format!("Modifications made after undo. Error: {}", f))
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>use crate::spec::{Target, TargetOptions};

pub fn target() -> Target {
    Target {
        llvm_target: "aarch64-unknown-freebsd".to_string(),
        pointer_width: 64,
        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
        arch: "aarch64".to_string(),
        options: TargetOptions { max_atomic_width: Some(128), ..super::freebsd_base::opts() },
    }
}
<commit_msg>Auto merge of #88023 - devnexen:fbsd_arm64, r=nagisa<commit_after>use crate::spec::{SanitizerSet, Target, TargetOptions};

pub fn target() -> Target {
    Target {
        llvm_target: "aarch64-unknown-freebsd".to_string(),
        pointer_width: 64,
        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
        arch: "aarch64".to_string(),
        options: TargetOptions {
            max_atomic_width: Some(128),
            supported_sanitizers: SanitizerSet::ADDRESS
                | SanitizerSet::MEMORY
                | SanitizerSet::THREAD,
            ..super::freebsd_base::opts()
        },
    }
}
<|endoftext|>


<commit_before>use std::marker;
use std::sync::Arc;
use std::sync::Mutex;

use futures::future::Future;

use error;
use misc::any_to_string;
use std::panic::AssertUnwindSafe;

pub trait DiedType: Default + Clone {
    fn what() -> &'static str;
}

#[derive(Copy, Clone, Default)]
pub struct ClientDiedType;
#[derive(Copy, Clone, Default)]
pub struct ConnDiedType;

impl DiedType for ClientDiedType {
    fn what() -> &'static str {
        "client"
    }
}

impl DiedType for ConnDiedType {
    fn what() -> &'static str {
        "connection"
    }
}

#[derive(Default, Clone)]
pub(crate) struct SomethingDiedErrorHolder<D: DiedType> {
    error: Arc<Mutex<Option<Arc<error::Error>>>>,
    _marker: marker::PhantomData<D>,
}

impl<D: DiedType> SomethingDiedErrorHolder<D> {
    pub fn new() -> Self {
        Default::default()
    }

    pub fn client_died_error(&self) -> Option<Arc<error::Error>> {
        let lock = self.error.lock().unwrap();
        (*lock).clone()
    }

    pub fn error(&self) -> error::Error {
        error::Error::ClientDied(self.client_died_error())
    }

    fn set_once(&self, error: error::Error) {
        let mut lock = self.error.lock().unwrap();
        if (*lock).is_none() {
            *lock = Some(Arc::new(error));
        }
    }

    pub fn wrap_future(
        &self,
        future: impl Future<Item = (), Error = error::Error>,
    ) -> impl Future<Item = (), Error = ()> {
        let holder = self.clone();
        let future = future.then(move |r| {
            match r {
                Ok(()) => {
                    info!("{} completed without errors", D::what());
                    holder.set_once(error::Error::ClientCompletedWithoutError);
                }
                Err(e) => {
                    warn!("{} completed with error: {:?}", D::what(), e);
                    holder.set_once(e);
                }
            }
            Ok::<(), ()>(())
        });

        let holder = self.clone();
        let future = AssertUnwindSafe(future).catch_unwind().then(move |r| {
            if let Err(e) = r {
                let message = any_to_string(e);
                warn!("{} panicked: {}", D::what(), message);
                holder.set_once(error::Error::ClientPanicked(message));
            }
            Ok(())
        });

        future
    }
}
<commit_msg>Visibility<commit_after>use std::marker;
use std::sync::Arc;
use std::sync::Mutex;

use futures::future::Future;

use error;
use misc::any_to_string;
use std::panic::AssertUnwindSafe;

pub(crate) trait DiedType: Default + Clone {
    fn what() -> &'static str;
}

#[derive(Copy, Clone, Default)]
pub(crate) struct ClientDiedType;
#[derive(Copy, Clone, Default)]
pub(crate) struct ConnDiedType;

impl DiedType for ClientDiedType {
    fn what() -> &'static str {
        "client"
    }
}

impl DiedType for ConnDiedType {
    fn what() -> &'static str {
        "connection"
    }
}

#[derive(Default, Clone)]
pub(crate) struct SomethingDiedErrorHolder<D: DiedType> {
    error: Arc<Mutex<Option<Arc<error::Error>>>>,
    _marker: marker::PhantomData<D>,
}

impl<D: DiedType> SomethingDiedErrorHolder<D> {
    pub fn new() -> Self {
        Default::default()
    }

    pub fn client_died_error(&self) -> Option<Arc<error::Error>> {
        let lock = self.error.lock().unwrap();
        (*lock).clone()
    }

    pub fn error(&self) -> error::Error {
        error::Error::ClientDied(self.client_died_error())
    }

    fn set_once(&self, error: error::Error) {
        let mut lock = self.error.lock().unwrap();
        if (*lock).is_none() {
            *lock = Some(Arc::new(error));
        }
    }

    pub fn wrap_future(
        &self,
        future: impl Future<Item = (), Error = error::Error>,
    ) -> impl Future<Item = (), Error = ()> {
        let holder = self.clone();
        let future = future.then(move |r| {
            match r {
                Ok(()) => {
                    info!("{} completed without errors", D::what());
                    holder.set_once(error::Error::ClientCompletedWithoutError);
                }
                Err(e) => {
                    warn!("{} completed with error: {:?}", D::what(), e);
                    holder.set_once(e);
                }
            }
            Ok::<(), ()>(())
        });

        let holder = self.clone();
        let future = AssertUnwindSafe(future).catch_unwind().then(move |r| {
            if let Err(e) = r {
                let message = any_to_string(e);
                warn!("{} panicked: {}", D::what(), message);
                holder.set_once(error::Error::ClientPanicked(message));
            }
            Ok(())
        });

        future
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The Rouille developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

#[macro_use]
extern crate rouille;

use std::io;
use std::env;
use std::process::Command;
use rouille::cgi::CgiRun;

fn main() {
    rouille::start_server("localhost:8080", move |request| {
        rouille::log(&request, io::stdout(), || {
            let mut cmd = Command::new("git");
            cmd.arg("http-backend");
            cmd.env("GIT_PROJECT_ROOT", env::current_dir().unwrap().to_str().unwrap());
            cmd.env("GIT_HTTP_EXPORT_ALL", "");
            cmd.start_cgi(&request).unwrap()
        })
    });
}
<commit_msg>Add comments to the git example<commit_after>// Copyright (c) 2016 The Rouille developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

#[macro_use]
extern crate rouille;

use std::io;
use std::env;
use std::process::Command;
use rouille::cgi::CgiRun;

fn main() {
    // This example demonstrates how to serve a git repository with rouille.
    // After starting this example, you should be able to run `git clone http://localhost:8000/`
    // in order to clone the repository of the current working directory.

    println!("Now listening on localhost:8000");

    rouille::start_server("localhost:8000", move |request| {
        rouille::log(&request, io::stdout(), || {
            // When a request is received, we invoke the `git http-backend` command through CGI.
            let mut cmd = Command::new("git");
            cmd.arg("http-backend");

            // We need to set some git-specific environment variables.
            cmd.env("GIT_PROJECT_ROOT", env::current_dir().unwrap().to_str().unwrap());
            cmd.env("GIT_HTTP_EXPORT_ALL", "");   // This one is required to avoid security errors.

            // Our `cmd` is now ready. We can run it with the `start_cgi` method of the `CgiRun`
            // trait.
            // The `start_cgi` will add other CGI-specific environment variables, then feed stdin
            // and analyze stdout to build a rouille response.
            //
            // Note that an error is returned only if `git http-backend` fails to execute, and not
            // if the client sends bad data for example. In other words, an error can only occur
            // if the server was misconfigured. Therefore it's okay-ish to call `unwrap()` here.
            cmd.start_cgi(&request).unwrap()
        })
    });
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(interpolate_idents)]

extern crate libc;

#[macro_use]
extern crate apache2;

#[macro_use]
extern crate lazy_static;

use libc::{c_void, c_char};
use apache2::{Request, Status, CmdParms, ffi};

struct ExampleConfig {
   pub first_cmd: Option<String>,
   pub second_cmd: Option<String>
}

lazy_static! {
   static ref EXAMPLE_CONFIG: ExampleConfig = ExampleConfig {
      first_cmd: None,
      second_cmd: None
   };
}

fn cmd_process(parms: &mut CmdParms) {
}

#[allow(unused_variables)]
pub extern "C" fn first_cmd(parms: *mut ffi::cmd_parms, mconfig: *mut c_void, w: *const c_char) -> *const c_char {
   std::ptr::null()
}

#[allow(unused_variables)]
pub extern "C" fn second_cmd(parms: *mut ffi::cmd_parms, mconfig: *mut c_void, w: *const c_char) -> *const c_char {
   std::ptr::null()
}

apache2_module!(conf, b"mod_conf\0", commands {
   AP_INIT_TAKE1!(b"FirstCmd\0", first_cmd, apache2::ffi::RSRC_CONF, b"First cmd error message\0");
   AP_INIT_TAKE1!(b"SecondCmd\0", second_cmd, apache2::ffi::RSRC_CONF, b"Second cmd error message\0")
});

fn conf_handler(r: &mut Request) -> Result<Status, ()> {
   if try!(r.handler()) != "conf" {
      return Ok(Status::DECLINED)
   }

   r.set_content_type("text/plain; charset=utf-8");

   try!(r.write("CONF: *****"));

   Ok(Status::OK)
}
<commit_msg>mod_conf example_config C-struct.<commit_after>#![feature(plugin)]
#![plugin(interpolate_idents)]

extern crate libc;

#[macro_use]
extern crate apache2;

#[macro_use]
extern crate lazy_static;

use libc::{c_char};
use apache2::{Request, Status, ffi};
use apache2::wrapper::from_char_ptr;

#[repr(C)]
pub struct example_config {
   pub first_cmd: *const c_char,
   pub second_cmd: *const c_char
}

#[allow(unused_variables)]
pub extern "C" fn first_cmd(parms: *mut ffi::cmd_parms, config: *mut example_config, w: *const c_char) -> *const c_char {
   let val = from_char_ptr(w).unwrap();
   std::ptr::null()
}

#[allow(unused_variables)]
pub extern "C" fn second_cmd(parms: *mut ffi::cmd_parms, config: *mut example_config, w: *const c_char) -> *const c_char {
   let val = from_char_ptr(w).unwrap();
   std::ptr::null()
}

apache2_module!(conf, b"mod_conf\0", commands {
   None, None, None, None,
   AP_INIT_TAKE1!(b"FirstCmd\0", first_cmd, apache2::ffi::RSRC_CONF, b"First cmd description\0");
   AP_INIT_TAKE1!(b"SecondCmd\0", second_cmd, apache2::ffi::RSRC_CONF, b"Second cmd description\0")
});

fn conf_handler(r: &mut Request) -> Result<Status, ()> {
   if try!(r.handler()) != "conf" {
      return Ok(Status::DECLINED)
   }

   r.set_content_type("text/plain; charset=utf-8");

   try!(r.write("CONF: *****"));

   Ok(Status::OK)
}
<|endoftext|>


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

// Checks if the correct registers are being used to pass arguments
// when the sysv64 ABI is specified.

// compile-flags: -Zedition=2018

pub trait Foo {}

// should compile without the dyn trait feature flag
fn foo(x: &dyn Foo) {}

pub fn main() {}
<commit_msg>Fix test<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.

// Checks if the correct registers are being used to pass arguments
// when the sysv64 ABI is specified.

#![feature(rust_2018_preview)]

pub trait Foo {}

// should compile without the dyn trait feature flag
fn foo(x: &dyn Foo) {}

pub fn main() {}
<|endoftext|>


<commit_before>/// This list represents the default file types that ripgrep ships with. In
/// general, any file format is fair game, although it should generally be
/// limited to reasonably popular open formats. For other cases, you can add
/// types to each invocation of ripgrep with the '--type-add' flag.
///
/// If you would like to add or improve this list, please file a PR:
/// <https://github.com/BurntSushi/ripgrep>.
///
/// Please try to keep this list sorted lexicographically and wrapped to 79
/// columns (inclusive).
#[rustfmt::skip]
pub const DEFAULT_TYPES: &[(&str, &[&str])] = &[
    ("agda", &["*.agda", "*.lagda"]),
    ("aidl", &["*.aidl"]),
    ("amake", &["*.mk", "*.bp"]),
    ("asciidoc", &["*.adoc", "*.asc", "*.asciidoc"]),
    ("asm", &["*.asm", "*.s", "*.S"]),
    ("asp", &[
        "*.aspx", "*.aspx.cs", "*.aspx.vb", "*.ascx", "*.ascx.cs",
        "*.ascx.vb", "*.asp"
    ]),
    ("ats", &["*.ats", "*.dats", "*.sats", "*.hats"]),
    ("avro", &["*.avdl", "*.avpr", "*.avsc"]),
    ("awk", &["*.awk"]),
    ("bazel", &[
        "*.bazel", "*.bzl", "*.BUILD", "*.bazelrc", "BUILD", "MODULE.bazel",
        "WORKSPACE", "WORKSPACE.bazel",
    ]),
    ("bitbake", &["*.bb", "*.bbappend", "*.bbclass", "*.conf", "*.inc"]),
    ("brotli", &["*.br"]),
    ("buildstream", &["*.bst"]),
    ("bzip2", &["*.bz2", "*.tbz2"]),
    ("c", &["*.[chH]", "*.[chH].in", "*.cats"]),
    ("cabal", &["*.cabal"]),
    ("cbor", &["*.cbor"]),
    ("ceylon", &["*.ceylon"]),
    ("clojure", &["*.clj", "*.cljc", "*.cljs", "*.cljx"]),
    ("cmake", &["*.cmake", "CMakeLists.txt"]),
    ("coffeescript", &["*.coffee"]),
    ("config", &["*.cfg", "*.conf", "*.config", "*.ini"]),
    ("coq", &["*.v"]),
    ("cpp", &[
        "*.[ChH]", "*.cc", "*.[ch]pp", "*.[ch]xx", "*.hh",  "*.inl",
        "*.[ChH].in", "*.cc.in", "*.[ch]pp.in", "*.[ch]xx.in", "*.hh.in",
    ]),
    ("creole", &["*.creole"]),
    ("crystal", &["Projectfile", "*.cr", "*.ecr", "shard.yml"]),
    ("cs", &["*.cs"]),
    ("csharp", &["*.cs"]),
    ("cshtml", &["*.cshtml"]),
    ("css", &["*.css", "*.scss"]),
    ("csv", &["*.csv"]),
    ("cuda", &["*.cu", "*.cuh"]),
    ("cython", &["*.pyx", "*.pxi", "*.pxd"]),
    ("d", &["*.d"]),
    ("dart", &["*.dart"]),
    ("dhall", &["*.dhall"]),
    ("diff", &["*.patch", "*.diff"]),
    ("docker", &["*Dockerfile*"]),
    ("dts", &["*.dts", "*.dtsi"]),
    ("dvc", &["Dvcfile", "*.dvc"]),
    ("ebuild", &["*.ebuild"]),
    ("edn", &["*.edn"]),
    ("elisp", &["*.el"]),
    ("elixir", &["*.ex", "*.eex", "*.exs"]),
    ("elm", &["*.elm"]),
    ("erb", &["*.erb"]),
    ("erlang", &["*.erl", "*.hrl"]),
    ("fennel", &["*.fnl"]),
    ("fidl", &["*.fidl"]),
    ("fish", &["*.fish"]),
    ("flatbuffers", &["*.fbs"]),
    ("fortran", &[
        "*.f", "*.F", "*.f77", "*.F77", "*.pfo",
        "*.f90", "*.F90", "*.f95", "*.F95",
    ]),
    ("fsharp", &["*.fs", "*.fsx", "*.fsi"]),
    ("fut", &["*.fut"]),
    ("gap", &["*.g", "*.gap", "*.gi", "*.gd", "*.tst"]),
    ("gn", &["*.gn", "*.gni"]),
    ("go", &["*.go"]),
    ("gradle", &["*.gradle"]),
    ("groovy", &["*.groovy", "*.gradle"]),
    ("gzip", &["*.gz", "*.tgz"]),
    ("h", &["*.h", "*.hh", "*.hpp"]),
    ("haml", &["*.haml"]),
    ("hare", &["*.ha"]),
    ("haskell", &["*.hs", "*.lhs", "*.cpphs", "*.c2hs", "*.hsc"]),
    ("hbs", &["*.hbs"]),
    ("hs", &["*.hs", "*.lhs"]),
    ("html", &["*.htm", "*.html", "*.ejs"]),
    ("hy", &["*.hy"]),
    ("idris", &["*.idr", "*.lidr"]),
    ("janet", &["*.janet"]),
    ("java", &["*.java", "*.jsp", "*.jspx", "*.properties"]),
    ("jinja", &["*.j2", "*.jinja", "*.jinja2"]),
    ("jl", &["*.jl"]),
    ("js", &["*.js", "*.jsx", "*.vue"]),
    ("json", &["*.json", "composer.lock"]),
    ("jsonl", &["*.jsonl"]),
    ("julia", &["*.jl"]),
    ("jupyter", &["*.ipynb", "*.jpynb"]),
    ("k", &["*.k"]),
    ("kotlin", &["*.kt", "*.kts"]),
    ("less", &["*.less"]),
    ("license", &[
        // General
        "COPYING", "COPYING[.-]*",
        "COPYRIGHT", "COPYRIGHT[.-]*",
        "EULA", "EULA[.-]*",
        "licen[cs]e", "licen[cs]e.*",
        "LICEN[CS]E", "LICEN[CS]E[.-]*", "*[.-]LICEN[CS]E*",
        "NOTICE", "NOTICE[.-]*",
        "PATENTS", "PATENTS[.-]*",
        "UNLICEN[CS]E", "UNLICEN[CS]E[.-]*",
        // GPL (gpl.txt, etc.)
        "agpl[.-]*",
        "gpl[.-]*",
        "lgpl[.-]*",
        // Other license-specific (APACHE-2.0.txt, etc.)
        "AGPL-*[0-9]*",
        "APACHE-*[0-9]*",
        "BSD-*[0-9]*",
        "CC-BY-*",
        "GFDL-*[0-9]*",
        "GNU-*[0-9]*",
        "GPL-*[0-9]*",
        "LGPL-*[0-9]*",
        "MIT-*[0-9]*",
        "MPL-*[0-9]*",
        "OFL-*[0-9]*",
    ]),
    ("lilypond", &["*.ly", "*.ily"]),
    ("lisp", &["*.el", "*.jl", "*.lisp", "*.lsp", "*.sc", "*.scm"]),
    ("lock", &["*.lock", "package-lock.json"]),
    ("log", &["*.log"]),
    ("lua", &["*.lua"]),
    ("lz4", &["*.lz4"]),
    ("lzma", &["*.lzma"]),
    ("m4", &["*.ac", "*.m4"]),
    ("make", &[
        "[Gg][Nn][Uu]makefile", "[Mm]akefile",
        "[Gg][Nn][Uu]makefile.am", "[Mm]akefile.am",
        "[Gg][Nn][Uu]makefile.in", "[Mm]akefile.in",
        "*.mk", "*.mak"
    ]),
    ("mako", &["*.mako", "*.mao"]),
    ("man", &["*.[0-9lnpx]", "*.[0-9][cEFMmpSx]"]),
    ("markdown", &["*.markdown", "*.md", "*.mdown", "*.mkd", "*.mkdn"]),
    ("matlab", &["*.m"]),
    ("md", &["*.markdown", "*.md", "*.mdown", "*.mkd", "*.mkdn"]),
    ("meson", &["meson.build", "meson_options.txt"]),
    ("minified", &["*.min.html", "*.min.css", "*.min.js"]),
    ("mint", &["*.mint"]),
    ("mk", &["mkfile"]),
    ("ml", &["*.ml"]),
    ("msbuild", &[
        "*.csproj", "*.fsproj", "*.vcxproj", "*.proj", "*.props", "*.targets",
    ]),
    ("nim", &["*.nim", "*.nimf", "*.nimble", "*.nims"]),
    ("nix", &["*.nix"]),
    ("objc", &["*.h", "*.m"]),
    ("objcpp", &["*.h", "*.mm"]),
    ("ocaml", &["*.ml", "*.mli", "*.mll", "*.mly"]),
    ("org", &["*.org", "*.org_archive"]),
    ("pants", &["BUILD"]),
    ("pascal", &["*.pas", "*.dpr", "*.lpr", "*.pp", "*.inc"]),
    ("pdf", &["*.pdf"]),
    ("perl", &["*.perl", "*.pl", "*.PL", "*.plh", "*.plx", "*.pm", "*.t"]),
    ("php", &[
        // note that PHP 6 doesn't exist
        // See: https://wiki.php.net/rfc/php6
        "*.php", "*.php3", "*.php4", "*.php5", "*.php7", "*.php8",
        "*.pht", "*.phtml"
    ]),
    ("po", &["*.po"]),
    ("pod", &["*.pod"]),
    ("postscript", &["*.eps", "*.ps"]),
    ("protobuf", &["*.proto"]),
    ("ps", &["*.cdxml", "*.ps1", "*.ps1xml", "*.psd1", "*.psm1"]),
    ("puppet", &["*.erb", "*.pp", "*.rb"]),
    ("purs", &["*.purs"]),
    ("py", &["*.py"]),
    ("qmake", &["*.pro", "*.pri", "*.prf"]),
    ("qml", &["*.qml"]),
    ("r", &["*.R", "*.r", "*.Rmd", "*.Rnw"]),
    ("racket", &["*.rkt"]),
    ("rdoc", &["*.rdoc"]),
    ("readme", &["README*", "*README"]),
    ("red", &["*.r", "*.red", "*.reds"]),
    ("robot", &["*.robot"]),
    ("rst", &["*.rst"]),
    ("ruby", &[
        // Idiomatic files
        "config.ru", "Gemfile", ".irbrc", "Rakefile",
        // Extensions
        "*.gemspec", "*.rb", "*.rbw"
    ]),
    ("rust", &["*.rs"]),
    ("sass", &["*.sass", "*.scss"]),
    ("scala", &["*.scala", "*.sbt"]),
    ("sh", &[
        // Portable/misc. init files
        ".login", ".logout", ".profile", "profile",
        // bash-specific init files
        ".bash_login", "bash_login",
        ".bash_logout", "bash_logout",
        ".bash_profile", "bash_profile",
        ".bashrc", "bashrc", "*.bashrc",
        // csh-specific init files
        ".cshrc", "*.cshrc",
        // ksh-specific init files
        ".kshrc", "*.kshrc",
        // tcsh-specific init files
        ".tcshrc",
        // zsh-specific init files
        ".zshenv", "zshenv",
        ".zlogin", "zlogin",
        ".zlogout", "zlogout",
        ".zprofile", "zprofile",
        ".zshrc", "zshrc",
        // Extensions
        "*.bash", "*.csh", "*.ksh", "*.sh", "*.tcsh", "*.zsh",
    ]),
    ("slim", &["*.skim", "*.slim", "*.slime"]),
    ("smarty", &["*.tpl"]),
    ("sml", &["*.sml", "*.sig"]),
    ("solidity", &["*.sol"]),
    ("soy", &["*.soy"]),
    ("spark", &["*.spark"]),
    ("spec", &["*.spec"]),
    ("sql", &["*.sql", "*.psql"]),
    ("stylus", &["*.styl"]),
    ("sv", &["*.v", "*.vg", "*.sv", "*.svh", "*.h"]),
    ("svg", &["*.svg"]),
    ("swift", &["*.swift"]),
    ("swig", &["*.def", "*.i"]),
    ("systemd", &[
        "*.automount", "*.conf", "*.device", "*.link", "*.mount", "*.path",
        "*.scope", "*.service", "*.slice", "*.socket", "*.swap", "*.target",
        "*.timer",
    ]),
    ("taskpaper", &["*.taskpaper"]),
    ("tcl", &["*.tcl"]),
    ("tex", &["*.tex", "*.ltx", "*.cls", "*.sty", "*.bib", "*.dtx", "*.ins"]),
    ("texinfo", &["*.texi"]),
    ("textile", &["*.textile"]),
    ("tf", &["*.tf"]),
    ("thrift", &["*.thrift"]),
    ("toml", &["*.toml", "Cargo.lock"]),
    ("ts", &["*.ts", "*.tsx"]),
    ("twig", &["*.twig"]),
    ("txt", &["*.txt"]),
    ("typoscript", &["*.typoscript", "*.ts"]),
    ("vala", &["*.vala"]),
    ("vb", &["*.vb"]),
    ("vcl", &["*.vcl"]),
    ("verilog", &["*.v", "*.vh", "*.sv", "*.svh"]),
    ("vhdl", &["*.vhd", "*.vhdl"]),
    ("vim", &[
        "*.vim", ".vimrc", ".gvimrc", "vimrc", "gvimrc", "_vimrc", "_gvimrc",
    ]),
    ("vimscript", &[
        "*.vim", ".vimrc", ".gvimrc", "vimrc", "gvimrc", "_vimrc", "_gvimrc",
    ]),
    ("webidl", &["*.idl", "*.webidl", "*.widl"]),
    ("wiki", &["*.mediawiki", "*.wiki"]),
    ("xml", &[
        "*.xml", "*.xml.dist", "*.dtd", "*.xsl", "*.xslt", "*.xsd", "*.xjb",
        "*.rng", "*.sch", "*.xhtml",
    ]),
    ("xz", &["*.xz", "*.txz"]),
    ("yacc", &["*.y"]),
    ("yaml", &["*.yaml", "*.yml"]),
    ("yang", &["*.yang"]),
    ("z", &["*.Z"]),
    ("zig", &["*.zig"]),
    ("zsh", &[
        ".zshenv", "zshenv",
        ".zlogin", "zlogin",
        ".zlogout", "zlogout",
        ".zprofile", "zprofile",
        ".zshrc", "zshrc",
        "*.zsh",
    ]),
    ("zstd", &["*.zst", "*.zstd"]),
];
<commit_msg>ignore/types: add embedded puppet templates<commit_after>/// This list represents the default file types that ripgrep ships with. In
/// general, any file format is fair game, although it should generally be
/// limited to reasonably popular open formats. For other cases, you can add
/// types to each invocation of ripgrep with the '--type-add' flag.
///
/// If you would like to add or improve this list, please file a PR:
/// <https://github.com/BurntSushi/ripgrep>.
///
/// Please try to keep this list sorted lexicographically and wrapped to 79
/// columns (inclusive).
#[rustfmt::skip]
pub const DEFAULT_TYPES: &[(&str, &[&str])] = &[
    ("agda", &["*.agda", "*.lagda"]),
    ("aidl", &["*.aidl"]),
    ("amake", &["*.mk", "*.bp"]),
    ("asciidoc", &["*.adoc", "*.asc", "*.asciidoc"]),
    ("asm", &["*.asm", "*.s", "*.S"]),
    ("asp", &[
        "*.aspx", "*.aspx.cs", "*.aspx.vb", "*.ascx", "*.ascx.cs",
        "*.ascx.vb", "*.asp"
    ]),
    ("ats", &["*.ats", "*.dats", "*.sats", "*.hats"]),
    ("avro", &["*.avdl", "*.avpr", "*.avsc"]),
    ("awk", &["*.awk"]),
    ("bazel", &[
        "*.bazel", "*.bzl", "*.BUILD", "*.bazelrc", "BUILD", "MODULE.bazel",
        "WORKSPACE", "WORKSPACE.bazel",
    ]),
    ("bitbake", &["*.bb", "*.bbappend", "*.bbclass", "*.conf", "*.inc"]),
    ("brotli", &["*.br"]),
    ("buildstream", &["*.bst"]),
    ("bzip2", &["*.bz2", "*.tbz2"]),
    ("c", &["*.[chH]", "*.[chH].in", "*.cats"]),
    ("cabal", &["*.cabal"]),
    ("cbor", &["*.cbor"]),
    ("ceylon", &["*.ceylon"]),
    ("clojure", &["*.clj", "*.cljc", "*.cljs", "*.cljx"]),
    ("cmake", &["*.cmake", "CMakeLists.txt"]),
    ("coffeescript", &["*.coffee"]),
    ("config", &["*.cfg", "*.conf", "*.config", "*.ini"]),
    ("coq", &["*.v"]),
    ("cpp", &[
        "*.[ChH]", "*.cc", "*.[ch]pp", "*.[ch]xx", "*.hh",  "*.inl",
        "*.[ChH].in", "*.cc.in", "*.[ch]pp.in", "*.[ch]xx.in", "*.hh.in",
    ]),
    ("creole", &["*.creole"]),
    ("crystal", &["Projectfile", "*.cr", "*.ecr", "shard.yml"]),
    ("cs", &["*.cs"]),
    ("csharp", &["*.cs"]),
    ("cshtml", &["*.cshtml"]),
    ("css", &["*.css", "*.scss"]),
    ("csv", &["*.csv"]),
    ("cuda", &["*.cu", "*.cuh"]),
    ("cython", &["*.pyx", "*.pxi", "*.pxd"]),
    ("d", &["*.d"]),
    ("dart", &["*.dart"]),
    ("dhall", &["*.dhall"]),
    ("diff", &["*.patch", "*.diff"]),
    ("docker", &["*Dockerfile*"]),
    ("dts", &["*.dts", "*.dtsi"]),
    ("dvc", &["Dvcfile", "*.dvc"]),
    ("ebuild", &["*.ebuild"]),
    ("edn", &["*.edn"]),
    ("elisp", &["*.el"]),
    ("elixir", &["*.ex", "*.eex", "*.exs"]),
    ("elm", &["*.elm"]),
    ("erb", &["*.erb"]),
    ("erlang", &["*.erl", "*.hrl"]),
    ("fennel", &["*.fnl"]),
    ("fidl", &["*.fidl"]),
    ("fish", &["*.fish"]),
    ("flatbuffers", &["*.fbs"]),
    ("fortran", &[
        "*.f", "*.F", "*.f77", "*.F77", "*.pfo",
        "*.f90", "*.F90", "*.f95", "*.F95",
    ]),
    ("fsharp", &["*.fs", "*.fsx", "*.fsi"]),
    ("fut", &["*.fut"]),
    ("gap", &["*.g", "*.gap", "*.gi", "*.gd", "*.tst"]),
    ("gn", &["*.gn", "*.gni"]),
    ("go", &["*.go"]),
    ("gradle", &["*.gradle"]),
    ("groovy", &["*.groovy", "*.gradle"]),
    ("gzip", &["*.gz", "*.tgz"]),
    ("h", &["*.h", "*.hh", "*.hpp"]),
    ("haml", &["*.haml"]),
    ("hare", &["*.ha"]),
    ("haskell", &["*.hs", "*.lhs", "*.cpphs", "*.c2hs", "*.hsc"]),
    ("hbs", &["*.hbs"]),
    ("hs", &["*.hs", "*.lhs"]),
    ("html", &["*.htm", "*.html", "*.ejs"]),
    ("hy", &["*.hy"]),
    ("idris", &["*.idr", "*.lidr"]),
    ("janet", &["*.janet"]),
    ("java", &["*.java", "*.jsp", "*.jspx", "*.properties"]),
    ("jinja", &["*.j2", "*.jinja", "*.jinja2"]),
    ("jl", &["*.jl"]),
    ("js", &["*.js", "*.jsx", "*.vue"]),
    ("json", &["*.json", "composer.lock"]),
    ("jsonl", &["*.jsonl"]),
    ("julia", &["*.jl"]),
    ("jupyter", &["*.ipynb", "*.jpynb"]),
    ("k", &["*.k"]),
    ("kotlin", &["*.kt", "*.kts"]),
    ("less", &["*.less"]),
    ("license", &[
        // General
        "COPYING", "COPYING[.-]*",
        "COPYRIGHT", "COPYRIGHT[.-]*",
        "EULA", "EULA[.-]*",
        "licen[cs]e", "licen[cs]e.*",
        "LICEN[CS]E", "LICEN[CS]E[.-]*", "*[.-]LICEN[CS]E*",
        "NOTICE", "NOTICE[.-]*",
        "PATENTS", "PATENTS[.-]*",
        "UNLICEN[CS]E", "UNLICEN[CS]E[.-]*",
        // GPL (gpl.txt, etc.)
        "agpl[.-]*",
        "gpl[.-]*",
        "lgpl[.-]*",
        // Other license-specific (APACHE-2.0.txt, etc.)
        "AGPL-*[0-9]*",
        "APACHE-*[0-9]*",
        "BSD-*[0-9]*",
        "CC-BY-*",
        "GFDL-*[0-9]*",
        "GNU-*[0-9]*",
        "GPL-*[0-9]*",
        "LGPL-*[0-9]*",
        "MIT-*[0-9]*",
        "MPL-*[0-9]*",
        "OFL-*[0-9]*",
    ]),
    ("lilypond", &["*.ly", "*.ily"]),
    ("lisp", &["*.el", "*.jl", "*.lisp", "*.lsp", "*.sc", "*.scm"]),
    ("lock", &["*.lock", "package-lock.json"]),
    ("log", &["*.log"]),
    ("lua", &["*.lua"]),
    ("lz4", &["*.lz4"]),
    ("lzma", &["*.lzma"]),
    ("m4", &["*.ac", "*.m4"]),
    ("make", &[
        "[Gg][Nn][Uu]makefile", "[Mm]akefile",
        "[Gg][Nn][Uu]makefile.am", "[Mm]akefile.am",
        "[Gg][Nn][Uu]makefile.in", "[Mm]akefile.in",
        "*.mk", "*.mak"
    ]),
    ("mako", &["*.mako", "*.mao"]),
    ("man", &["*.[0-9lnpx]", "*.[0-9][cEFMmpSx]"]),
    ("markdown", &["*.markdown", "*.md", "*.mdown", "*.mkd", "*.mkdn"]),
    ("matlab", &["*.m"]),
    ("md", &["*.markdown", "*.md", "*.mdown", "*.mkd", "*.mkdn"]),
    ("meson", &["meson.build", "meson_options.txt"]),
    ("minified", &["*.min.html", "*.min.css", "*.min.js"]),
    ("mint", &["*.mint"]),
    ("mk", &["mkfile"]),
    ("ml", &["*.ml"]),
    ("msbuild", &[
        "*.csproj", "*.fsproj", "*.vcxproj", "*.proj", "*.props", "*.targets",
    ]),
    ("nim", &["*.nim", "*.nimf", "*.nimble", "*.nims"]),
    ("nix", &["*.nix"]),
    ("objc", &["*.h", "*.m"]),
    ("objcpp", &["*.h", "*.mm"]),
    ("ocaml", &["*.ml", "*.mli", "*.mll", "*.mly"]),
    ("org", &["*.org", "*.org_archive"]),
    ("pants", &["BUILD"]),
    ("pascal", &["*.pas", "*.dpr", "*.lpr", "*.pp", "*.inc"]),
    ("pdf", &["*.pdf"]),
    ("perl", &["*.perl", "*.pl", "*.PL", "*.plh", "*.plx", "*.pm", "*.t"]),
    ("php", &[
        // note that PHP 6 doesn't exist
        // See: https://wiki.php.net/rfc/php6
        "*.php", "*.php3", "*.php4", "*.php5", "*.php7", "*.php8",
        "*.pht", "*.phtml"
    ]),
    ("po", &["*.po"]),
    ("pod", &["*.pod"]),
    ("postscript", &["*.eps", "*.ps"]),
    ("protobuf", &["*.proto"]),
    ("ps", &["*.cdxml", "*.ps1", "*.ps1xml", "*.psd1", "*.psm1"]),
    ("puppet", &["*.epp", "*.erb", "*.pp", "*.rb"]),
    ("purs", &["*.purs"]),
    ("py", &["*.py"]),
    ("qmake", &["*.pro", "*.pri", "*.prf"]),
    ("qml", &["*.qml"]),
    ("r", &["*.R", "*.r", "*.Rmd", "*.Rnw"]),
    ("racket", &["*.rkt"]),
    ("rdoc", &["*.rdoc"]),
    ("readme", &["README*", "*README"]),
    ("red", &["*.r", "*.red", "*.reds"]),
    ("robot", &["*.robot"]),
    ("rst", &["*.rst"]),
    ("ruby", &[
        // Idiomatic files
        "config.ru", "Gemfile", ".irbrc", "Rakefile",
        // Extensions
        "*.gemspec", "*.rb", "*.rbw"
    ]),
    ("rust", &["*.rs"]),
    ("sass", &["*.sass", "*.scss"]),
    ("scala", &["*.scala", "*.sbt"]),
    ("sh", &[
        // Portable/misc. init files
        ".login", ".logout", ".profile", "profile",
        // bash-specific init files
        ".bash_login", "bash_login",
        ".bash_logout", "bash_logout",
        ".bash_profile", "bash_profile",
        ".bashrc", "bashrc", "*.bashrc",
        // csh-specific init files
        ".cshrc", "*.cshrc",
        // ksh-specific init files
        ".kshrc", "*.kshrc",
        // tcsh-specific init files
        ".tcshrc",
        // zsh-specific init files
        ".zshenv", "zshenv",
        ".zlogin", "zlogin",
        ".zlogout", "zlogout",
        ".zprofile", "zprofile",
        ".zshrc", "zshrc",
        // Extensions
        "*.bash", "*.csh", "*.ksh", "*.sh", "*.tcsh", "*.zsh",
    ]),
    ("slim", &["*.skim", "*.slim", "*.slime"]),
    ("smarty", &["*.tpl"]),
    ("sml", &["*.sml", "*.sig"]),
    ("solidity", &["*.sol"]),
    ("soy", &["*.soy"]),
    ("spark", &["*.spark"]),
    ("spec", &["*.spec"]),
    ("sql", &["*.sql", "*.psql"]),
    ("stylus", &["*.styl"]),
    ("sv", &["*.v", "*.vg", "*.sv", "*.svh", "*.h"]),
    ("svg", &["*.svg"]),
    ("swift", &["*.swift"]),
    ("swig", &["*.def", "*.i"]),
    ("systemd", &[
        "*.automount", "*.conf", "*.device", "*.link", "*.mount", "*.path",
        "*.scope", "*.service", "*.slice", "*.socket", "*.swap", "*.target",
        "*.timer",
    ]),
    ("taskpaper", &["*.taskpaper"]),
    ("tcl", &["*.tcl"]),
    ("tex", &["*.tex", "*.ltx", "*.cls", "*.sty", "*.bib", "*.dtx", "*.ins"]),
    ("texinfo", &["*.texi"]),
    ("textile", &["*.textile"]),
    ("tf", &["*.tf"]),
    ("thrift", &["*.thrift"]),
    ("toml", &["*.toml", "Cargo.lock"]),
    ("ts", &["*.ts", "*.tsx"]),
    ("twig", &["*.twig"]),
    ("txt", &["*.txt"]),
    ("typoscript", &["*.typoscript", "*.ts"]),
    ("vala", &["*.vala"]),
    ("vb", &["*.vb"]),
    ("vcl", &["*.vcl"]),
    ("verilog", &["*.v", "*.vh", "*.sv", "*.svh"]),
    ("vhdl", &["*.vhd", "*.vhdl"]),
    ("vim", &[
        "*.vim", ".vimrc", ".gvimrc", "vimrc", "gvimrc", "_vimrc", "_gvimrc",
    ]),
    ("vimscript", &[
        "*.vim", ".vimrc", ".gvimrc", "vimrc", "gvimrc", "_vimrc", "_gvimrc",
    ]),
    ("webidl", &["*.idl", "*.webidl", "*.widl"]),
    ("wiki", &["*.mediawiki", "*.wiki"]),
    ("xml", &[
        "*.xml", "*.xml.dist", "*.dtd", "*.xsl", "*.xslt", "*.xsd", "*.xjb",
        "*.rng", "*.sch", "*.xhtml",
    ]),
    ("xz", &["*.xz", "*.txz"]),
    ("yacc", &["*.y"]),
    ("yaml", &["*.yaml", "*.yml"]),
    ("yang", &["*.yang"]),
    ("z", &["*.Z"]),
    ("zig", &["*.zig"]),
    ("zsh", &[
        ".zshenv", "zshenv",
        ".zlogin", "zlogin",
        ".zlogout", "zlogout",
        ".zprofile", "zprofile",
        ".zshrc", "zshrc",
        "*.zsh",
    ]),
    ("zstd", &["*.zst", "*.zstd"]),
];
<|endoftext|>