<commit_before>//! Advertizes the capabilities of the LSP Server.
use std::env;

use crate::semantic_tokens;

use lsp_types::{
    CallHierarchyServerCapability, ClientCapabilities, CodeActionOptions,
    CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
    DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
    ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
    SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
    SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
    TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
    WorkDoneProgressOptions,
};

pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
    let mut code_action_provider = CodeActionProviderCapability::Simple(true);

    match client_caps.text_document.as_ref() {
        Some(it) => {
            match it.code_action.as_ref().and_then(|c| c.code_action_literal_support.as_ref()) {
                Some(_literal_support) => {
                    code_action_provider =
                        CodeActionProviderCapability::Options(CodeActionOptions {
                            // Advertise support for all built-in CodeActionKinds.
                            // Ideally we would base this off of the client capabilities
                            // but the client is supposed to fall back gracefully for unknown values.
                            code_action_kinds: Some(vec![
                                lsp_types::code_action_kind::EMPTY.to_string(),
                                lsp_types::code_action_kind::QUICKFIX.to_string(),
                                lsp_types::code_action_kind::REFACTOR.to_string(),
                                lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
                                lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
                                lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
                                lsp_types::code_action_kind::SOURCE.to_string(),
                                lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
                            ]),
                            work_done_progress_options: Default::default(),
                        });
                }
                None => {}
            }
        }
        None => {}
    };

    ServerCapabilities {
        text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
            open_close: Some(true),
            change: Some(if env::var("RA_NO_INCREMENTAL_SYNC").is_ok() {
                TextDocumentSyncKind::Full
            } else {
                TextDocumentSyncKind::Incremental
            }),
            will_save: None,
            will_save_wait_until: None,
            save: Some(SaveOptions::default()),
        })),
        hover_provider: Some(true),
        completion_provider: Some(CompletionOptions {
            resolve_provider: None,
            trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
            work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
        }),
        signature_help_provider: Some(SignatureHelpOptions {
            trigger_characters: Some(vec!["(".to_string(), ",".to_string()]),
            retrigger_characters: None,
            work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
        }),
        declaration_provider: None,
        definition_provider: Some(true),
        type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
        implementation_provider: Some(ImplementationProviderCapability::Simple(true)),
        references_provider: Some(true),
        document_highlight_provider: Some(true),
        document_symbol_provider: Some(true),
        workspace_symbol_provider: Some(true),
        code_action_provider: Some(code_action_provider),
        code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
        document_formatting_provider: Some(true),
        document_range_formatting_provider: None,
        document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
            first_trigger_character: "=".to_string(),
            more_trigger_character: Some(vec![".".to_string(), ">".to_string()]),
        }),
        selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
        semantic_highlighting: None,
        folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
        rename_provider: Some(RenameProviderCapability::Options(RenameOptions {
            prepare_provider: Some(true),
            work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
        })),
        document_link_provider: None,
        color_provider: None,
        execute_command_provider: None,
        workspace: None,
        call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
        semantic_tokens_provider: Some(
            SemanticTokensOptions {
                legend: SemanticTokensLegend {
                    token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(),
                    token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
                },

                document_provider: Some(SemanticTokensDocumentProvider::Bool(true)),
                range_provider: Some(true),
                work_done_progress_options: Default::default(),
            }
            .into(),
        ),
        experimental: Default::default(),
    }
}
<commit_msg>Fill code action capabilities with a function<commit_after>//! Advertizes the capabilities of the LSP Server.
use std::env;

use crate::semantic_tokens;

use lsp_types::{
    CallHierarchyServerCapability, ClientCapabilities, CodeActionOptions,
    CodeActionProviderCapability, CodeLensOptions, CompletionOptions,
    DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
    ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
    SelectionRangeProviderCapability, SemanticTokensDocumentProvider, SemanticTokensLegend,
    SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability,
    TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability,
    WorkDoneProgressOptions,
};

pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabilities {
    let code_action_provider = code_action_capabilities(client_caps);

    ServerCapabilities {
        text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions {
            open_close: Some(true),
            change: Some(if env::var("RA_NO_INCREMENTAL_SYNC").is_ok() {
                TextDocumentSyncKind::Full
            } else {
                TextDocumentSyncKind::Incremental
            }),
            will_save: None,
            will_save_wait_until: None,
            save: Some(SaveOptions::default()),
        })),
        hover_provider: Some(true),
        completion_provider: Some(CompletionOptions {
            resolve_provider: None,
            trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
            work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
        }),
        signature_help_provider: Some(SignatureHelpOptions {
            trigger_characters: Some(vec!["(".to_string(), ",".to_string()]),
            retrigger_characters: None,
            work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
        }),
        declaration_provider: None,
        definition_provider: Some(true),
        type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)),
        implementation_provider: Some(ImplementationProviderCapability::Simple(true)),
        references_provider: Some(true),
        document_highlight_provider: Some(true),
        document_symbol_provider: Some(true),
        workspace_symbol_provider: Some(true),
        code_action_provider: Some(code_action_provider),
        code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
        document_formatting_provider: Some(true),
        document_range_formatting_provider: None,
        document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
            first_trigger_character: "=".to_string(),
            more_trigger_character: Some(vec![".".to_string(), ">".to_string()]),
        }),
        selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)),
        semantic_highlighting: None,
        folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)),
        rename_provider: Some(RenameProviderCapability::Options(RenameOptions {
            prepare_provider: Some(true),
            work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
        })),
        document_link_provider: None,
        color_provider: None,
        execute_command_provider: None,
        workspace: None,
        call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
        semantic_tokens_provider: Some(
            SemanticTokensOptions {
                legend: SemanticTokensLegend {
                    token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(),
                    token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
                },

                document_provider: Some(SemanticTokensDocumentProvider::Bool(true)),
                range_provider: Some(true),
                work_done_progress_options: Default::default(),
            }
            .into(),
        ),
        experimental: Default::default(),
    }
}

fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability {
    client_caps
        .text_document
        .as_ref()
        .and_then(|it| it.code_action.as_ref())
        .and_then(|it| it.code_action_literal_support.as_ref())
        .map_or(CodeActionProviderCapability::Simple(true), |_| {
            CodeActionProviderCapability::Options(CodeActionOptions {
                // Advertise support for all built-in CodeActionKinds.
                // Ideally we would base this off of the client capabilities
                // but the client is supposed to fall back gracefully for unknown values.
                code_action_kinds: Some(vec![
                    lsp_types::code_action_kind::EMPTY.to_string(),
                    lsp_types::code_action_kind::QUICKFIX.to_string(),
                    lsp_types::code_action_kind::REFACTOR.to_string(),
                    lsp_types::code_action_kind::REFACTOR_EXTRACT.to_string(),
                    lsp_types::code_action_kind::REFACTOR_INLINE.to_string(),
                    lsp_types::code_action_kind::REFACTOR_REWRITE.to_string(),
                    lsp_types::code_action_kind::SOURCE.to_string(),
                    lsp_types::code_action_kind::SOURCE_ORGANIZE_IMPORTS.to_string(),
                ]),
                work_done_progress_options: Default::default(),
            })
        })
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

pub trait EarlyReturnVisitor {
    fn visit(selections: &[Selection]) {
        let mut to_visit = Vec::from(selections);
        while let Some(selection) = to_visit.pop() {
            match selection {
                Selection::FragmentSpread(s) => {}
                Selection::InlineFragment(_) => todo!(),
                Selection::LinkedField(_) => todo!(),
                Selection::ScalarField(_) => todo!(),
                Selection::Condition(_) => todo!(),
            }
        }
    }

    fn visit_fragment(
        &mut self,
        to_visit: &mut Vec<&Selection>,
        fragment: &FragmentDefinition,
    ) -> bool {
        to_visit.push(fragment.selections);
        false
    }

    fn visit_inline_fragment(
        &mut self,
        to_visit: &mut Vec<&Selection>,
        fragment: &InlineFragment,
    ) -> bool {
        to_visit.push(fragment.selections);
    }

    fn visit_linkedField(
        &mut self,
        to_visit: &mut Vec<&Selection>,
        fragment: &InlineFragment,
    ) -> bool {
        to_visit.push(fragment.selections);
    }
}
<commit_msg>remove unused early_return_visitor<commit_after><|endoftext|>


<commit_before>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

// Transformation which injects global invariants into the bytecode.

#[allow(unused_imports)]
use log::{debug, info, log, warn};

use crate::{
    function_data_builder::FunctionDataBuilder,
    function_target::FunctionData,
    function_target_pipeline::{FunctionTargetProcessor, FunctionTargetsHolder, FunctionVariant},
    options::{ProverOptions, PROVER_DEFAULT_OPTIONS},
    stackless_bytecode::{BorrowNode, Bytecode, Operation, PropKind},
    usage_analysis,
};

use crate::spec_translator::SpecTranslator;

use move_model::{
    ast::{ConditionKind, GlobalInvariant},
    model::{FunctionEnv, GlobalId, QualifiedId, StructId},
    pragmas::CONDITION_ISOLATED_PROP,
};
use std::collections::BTreeSet;

const GLOBAL_INVARIANT_FAILS_MESSAGE: &str = "global memory invariant does not hold";

pub struct GlobalInvariantInstrumentationProcessor {}

impl GlobalInvariantInstrumentationProcessor {
    pub fn new() -> Box<Self> {
        Box::new(Self {})
    }
}

impl FunctionTargetProcessor for GlobalInvariantInstrumentationProcessor {
    fn process(
        &self,
        _targets: &mut FunctionTargetsHolder,
        fun_env: &FunctionEnv<'_>,
        data: FunctionData,
    ) -> FunctionData {
        if fun_env.is_native() || fun_env.is_intrinsic() {
            // Nothing to do.
            return data;
        }
        if data.variant != FunctionVariant::Verification && !fun_env.has_friend() {
            // Only need to instrument if this is a verification variant, or if the
            // function has a friend and is verified in the friends context.
            return data;
        }

        let options = fun_env
            .module_env
            .env
            .get_extension::<ProverOptions>()
            .unwrap_or_else(|| &*PROVER_DEFAULT_OPTIONS);

        Instrumenter::run(options, fun_env, data)
    }

    fn name(&self) -> String {
        "global_invariant_instrumenter".to_string()
    }
}

struct Instrumenter<'a> {
    _options: &'a ProverOptions,
    builder: FunctionDataBuilder<'a>,
}

impl<'a> Instrumenter<'a> {
    fn run(
        options: &'a ProverOptions,
        fun_env: &FunctionEnv<'a>,
        data: FunctionData,
    ) -> FunctionData {
        let builder = FunctionDataBuilder::new(fun_env, data);
        let mut instrumenter = Instrumenter {
            _options: options,
            builder,
        };
        instrumenter.instrument();
        instrumenter.builder.data
    }

    fn instrument(&mut self) {
        // Extract and clear current code
        let old_code = std::mem::take(&mut self.builder.data.code);

        // Emit entrypoint assumptions if this is a verification entry.
        let assumed_at_update = if self.builder.data.variant == FunctionVariant::Verification {
            self.instrument_entrypoint()
        } else {
            BTreeSet::new()
        };

        // Generate new instrumented code.
        for bc in old_code {
            self.instrument_bytecode(bc, &assumed_at_update);
        }
    }

    fn instrument_entrypoint(&mut self) -> BTreeSet<GlobalId> {
        // Emit an assume of all invariants over memory touched by this function, and which
        // stem from modules in the dependency graph.
        //
        // Also returns the set of invariant ids which are to be assumed before an update
        // happens instead here at the entrypoint. It is more efficient to emit those assumes
        // not until they are actually needed. Those invariants include (a) those which are
        // marked by the user explicitly as `[isolated]` (b) those which are not declared
        // in dependent modules and from which the code should therefore not depend on, apart
        // of for the update itself.
        let env = self.builder.global_env();
        let mut invariants = BTreeSet::new();
        let mut invariants_for_modified_memory = BTreeSet::new();
        for mem in usage_analysis::get_used_memory(&self.builder.get_target()) {
            invariants.extend(env.get_global_invariants_for_memory(*mem));
        }
        for mem in usage_analysis::get_modified_memory(&self.builder.get_target()) {
            invariants_for_modified_memory.extend(env.get_global_invariants_for_memory(*mem));
        }

        let mut assumed_at_update = BTreeSet::new();
        let module_env = &self.builder.fun_env.module_env;
        let mut translated = SpecTranslator::translate_invariants(
            &mut self.builder,
            invariants.iter().filter_map(|id| {
                env.get_global_invariant(*id).filter(|inv| {
                    if inv.kind == ConditionKind::Invariant {
                        if module_env.is_transitive_dependency(inv.declaring_module)
                            && !module_env
                                .env
                                .is_property_true(&inv.properties, CONDITION_ISOLATED_PROP)
                                .unwrap_or(false)
                        {
                            true
                        } else {
                            assumed_at_update.insert(*id);
                            false
                        }
                    } else {
                        false
                    }
                })
            }),
        );
        for (loc, _, cond) in std::mem::take(&mut translated.invariants) {
            self.builder.set_next_debug_comment(format!(
                "global invariant {}",
                loc.display(self.builder.global_env())
            ));
            self.builder
                .emit_with(|id| Bytecode::Prop(id, PropKind::Assume, cond));
        }
        assumed_at_update
    }

    fn instrument_bytecode(&mut self, bc: Bytecode, assumed_at_update: &BTreeSet<GlobalId>) {
        use BorrowNode::*;
        use Bytecode::*;
        use Operation::*;
        match &bc {
            Call(_, _, WriteBack(GlobalRoot(mem)), ..) => {
                self.emit_invariants_for_update(*mem, assumed_at_update, move |builder| {
                    builder.emit(bc);
                })
            }
            Call(_, _, MoveTo(mid, sid, _), ..) | Call(_, _, MoveFrom(mid, sid, _), ..) => self
                .emit_invariants_for_update(
                    mid.qualified(*sid),
                    assumed_at_update,
                    move |builder| {
                        builder.emit(bc);
                    },
                ),
            _ => self.builder.emit(bc),
        }
    }

    fn emit_invariants_for_update<F>(
        &mut self,
        mem: QualifiedId<StructId>,
        assumed_at_update: &BTreeSet<GlobalId>,
        emit_update: F,
    ) where
        F: FnOnce(&mut FunctionDataBuilder<'_>),
    {
        // Translate the invariants, computing any state to be saved as well. State saves are
        // necessary for update invariants which contain the `old(..)` expressions.
        let invariants = self.get_verified_invariants_for_mem(mem);
        let mut translated =
            SpecTranslator::translate_invariants(&mut self.builder, invariants.iter().cloned());

        // Emit all necessary state saves for 'update' invariants.
        self.builder
            .set_next_debug_comment("state save for global update invariants".to_string());
        for (mem, label) in std::mem::take(&mut translated.saved_memory) {
            self.builder
                .emit_with(|id| Bytecode::SaveMem(id, label, mem));
        }
        for (var, label) in std::mem::take(&mut translated.saved_spec_vars) {
            self.builder
                .emit_with(|id| Bytecode::SaveSpecVar(id, label, var));
        }
        self.builder.clear_next_debug_comment();

        // For all invariants which are assumed at update, emit an assume before the memory update.
        for (_, _, cond) in translated
            .invariants
            .iter()
            .filter(|(_, id, _)| assumed_at_update.contains(id))
        {
            self.builder
                .emit_with(|id| Bytecode::Prop(id, PropKind::Assume, cond.clone()));
        }

        // Emit the code which performs the update on `mem`.
        emit_update(&mut self.builder);

        // Emit assertions of translated invariants.
        for (loc, _, cond) in std::mem::take(&mut translated.invariants) {
            self.builder.set_next_debug_comment(format!(
                "global invariant {}",
                loc.display(self.builder.global_env())
            ));
            self.builder
                .set_loc_and_vc_info(loc, GLOBAL_INVARIANT_FAILS_MESSAGE);
            self.builder
                .emit_with(|id| Bytecode::Prop(id, PropKind::Assert, cond));
        }
    }

    /// Returns the invariants which need to be verified if the given memory is updated.
    /// This filters out those invariants which stem from modules which are not verification
    /// target.
    fn get_verified_invariants_for_mem(
        &self,
        mem: QualifiedId<StructId>,
    ) -> Vec<&'a GlobalInvariant> {
        let env = self.builder.global_env();
        env.get_global_invariants_for_memory(mem)
            .iter()
            .filter_map(|id| {
                env.get_global_invariant(*id)
                    .filter(|inv| env.get_module(inv.declaring_module).is_target())
            })
            .collect()
    }
}
<commit_msg>[move-prover] Add illustration of computing global information for a pipeline step.<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

// Transformation which injects global invariants into the bytecode.

#[allow(unused_imports)]
use log::{debug, info, log, warn};

use crate::{
    function_data_builder::FunctionDataBuilder,
    function_target::FunctionData,
    function_target_pipeline::{FunctionTargetProcessor, FunctionTargetsHolder, FunctionVariant},
    options::{ProverOptions, PROVER_DEFAULT_OPTIONS},
    stackless_bytecode::{BorrowNode, Bytecode, Operation, PropKind},
    usage_analysis,
};

use crate::spec_translator::SpecTranslator;

use move_model::{
    ast::{ConditionKind, GlobalInvariant},
    model::{FunctionEnv, GlobalEnv, GlobalId, QualifiedId, StructId},
    pragmas::CONDITION_ISOLATED_PROP,
};
use std::collections::BTreeSet;

const GLOBAL_INVARIANT_FAILS_MESSAGE: &str = "global memory invariant does not hold";

pub struct GlobalInvariantInstrumentationProcessor {}

impl GlobalInvariantInstrumentationProcessor {
    pub fn new() -> Box<Self> {
        Box::new(Self {})
    }
}

impl FunctionTargetProcessor for GlobalInvariantInstrumentationProcessor {
    fn process(
        &self,
        _targets: &mut FunctionTargetsHolder,
        fun_env: &FunctionEnv<'_>,
        data: FunctionData,
    ) -> FunctionData {
        if fun_env.is_native() || fun_env.is_intrinsic() {
            // Nothing to do.
            return data;
        }
        if data.variant != FunctionVariant::Verification && !fun_env.has_friend() {
            // Only need to instrument if this is a verification variant, or if the
            // function has a friend and is verified in the friends context.
            return data;
        }

        let options = fun_env
            .module_env
            .env
            .get_extension::<ProverOptions>()
            .unwrap_or_else(|| &*PROVER_DEFAULT_OPTIONS);

        Instrumenter::run(options, fun_env, data)
    }

    fn name(&self) -> String {
        "global_invariant_instrumenter".to_string()
    }

    fn initialize(&self, _env: &GlobalEnv, _targets: &mut FunctionTargetsHolder) {
        // This function can be used to compute any needed information ahead
        // of the time `process` is called for each individual function.
        //
        // In order to iterate over all functions in targets, one can use code as below:
        //
        //   let mut analysis_info = AnalysisInfo::new();
        //   for (qfun_id, variant) in targets.get_funs_and_variants() {
        //       let fun_env = env.get_module(qfun_id.module_id).into_function(qfun_id.id);
        //       let fun_target = targets.get_target(&fun_env, variant);
        //       << Do something with fun_env/fun_target >>
        //   }
        //   // Store the computed info into an extension in the environment
        //   env.set_extension(analysis_info);
        //
        // One can then use in `process` the following to retrieve the analysis result.
        //
        //   let analysis_info = env.get_extension::<AnalysisInfo>();
        //   ...
    }
}

struct Instrumenter<'a> {
    _options: &'a ProverOptions,
    builder: FunctionDataBuilder<'a>,
}

impl<'a> Instrumenter<'a> {
    fn run(
        options: &'a ProverOptions,
        fun_env: &FunctionEnv<'a>,
        data: FunctionData,
    ) -> FunctionData {
        let builder = FunctionDataBuilder::new(fun_env, data);
        let mut instrumenter = Instrumenter {
            _options: options,
            builder,
        };
        instrumenter.instrument();
        instrumenter.builder.data
    }

    fn instrument(&mut self) {
        // Extract and clear current code
        let old_code = std::mem::take(&mut self.builder.data.code);

        // Emit entrypoint assumptions if this is a verification entry.
        let assumed_at_update = if self.builder.data.variant == FunctionVariant::Verification {
            self.instrument_entrypoint()
        } else {
            BTreeSet::new()
        };

        // Generate new instrumented code.
        for bc in old_code {
            self.instrument_bytecode(bc, &assumed_at_update);
        }
    }

    fn instrument_entrypoint(&mut self) -> BTreeSet<GlobalId> {
        // Emit an assume of all invariants over memory touched by this function, and which
        // stem from modules in the dependency graph.
        //
        // Also returns the set of invariant ids which are to be assumed before an update
        // happens instead here at the entrypoint. It is more efficient to emit those assumes
        // not until they are actually needed. Those invariants include (a) those which are
        // marked by the user explicitly as `[isolated]` (b) those which are not declared
        // in dependent modules and from which the code should therefore not depend on, apart
        // of for the update itself.
        let env = self.builder.global_env();
        let mut invariants = BTreeSet::new();
        let mut invariants_for_modified_memory = BTreeSet::new();
        for mem in usage_analysis::get_used_memory(&self.builder.get_target()) {
            invariants.extend(env.get_global_invariants_for_memory(*mem));
        }
        for mem in usage_analysis::get_modified_memory(&self.builder.get_target()) {
            invariants_for_modified_memory.extend(env.get_global_invariants_for_memory(*mem));
        }

        let mut assumed_at_update = BTreeSet::new();
        let module_env = &self.builder.fun_env.module_env;
        let mut translated = SpecTranslator::translate_invariants(
            &mut self.builder,
            invariants.iter().filter_map(|id| {
                env.get_global_invariant(*id).filter(|inv| {
                    if inv.kind == ConditionKind::Invariant {
                        if module_env.is_transitive_dependency(inv.declaring_module)
                            && !module_env
                                .env
                                .is_property_true(&inv.properties, CONDITION_ISOLATED_PROP)
                                .unwrap_or(false)
                        {
                            true
                        } else {
                            assumed_at_update.insert(*id);
                            false
                        }
                    } else {
                        false
                    }
                })
            }),
        );
        for (loc, _, cond) in std::mem::take(&mut translated.invariants) {
            self.builder.set_next_debug_comment(format!(
                "global invariant {}",
                loc.display(self.builder.global_env())
            ));
            self.builder
                .emit_with(|id| Bytecode::Prop(id, PropKind::Assume, cond));
        }
        assumed_at_update
    }

    fn instrument_bytecode(&mut self, bc: Bytecode, assumed_at_update: &BTreeSet<GlobalId>) {
        use BorrowNode::*;
        use Bytecode::*;
        use Operation::*;
        match &bc {
            Call(_, _, WriteBack(GlobalRoot(mem)), ..) => {
                self.emit_invariants_for_update(*mem, assumed_at_update, move |builder| {
                    builder.emit(bc);
                })
            }
            Call(_, _, MoveTo(mid, sid, _), ..) | Call(_, _, MoveFrom(mid, sid, _), ..) => self
                .emit_invariants_for_update(
                    mid.qualified(*sid),
                    assumed_at_update,
                    move |builder| {
                        builder.emit(bc);
                    },
                ),
            _ => self.builder.emit(bc),
        }
    }

    fn emit_invariants_for_update<F>(
        &mut self,
        mem: QualifiedId<StructId>,
        assumed_at_update: &BTreeSet<GlobalId>,
        emit_update: F,
    ) where
        F: FnOnce(&mut FunctionDataBuilder<'_>),
    {
        // Translate the invariants, computing any state to be saved as well. State saves are
        // necessary for update invariants which contain the `old(..)` expressions.
        let invariants = self.get_verified_invariants_for_mem(mem);
        let mut translated =
            SpecTranslator::translate_invariants(&mut self.builder, invariants.iter().cloned());

        // Emit all necessary state saves for 'update' invariants.
        self.builder
            .set_next_debug_comment("state save for global update invariants".to_string());
        for (mem, label) in std::mem::take(&mut translated.saved_memory) {
            self.builder
                .emit_with(|id| Bytecode::SaveMem(id, label, mem));
        }
        for (var, label) in std::mem::take(&mut translated.saved_spec_vars) {
            self.builder
                .emit_with(|id| Bytecode::SaveSpecVar(id, label, var));
        }
        self.builder.clear_next_debug_comment();

        // For all invariants which are assumed at update, emit an assume before the memory update.
        for (_, _, cond) in translated
            .invariants
            .iter()
            .filter(|(_, id, _)| assumed_at_update.contains(id))
        {
            self.builder
                .emit_with(|id| Bytecode::Prop(id, PropKind::Assume, cond.clone()));
        }

        // Emit the code which performs the update on `mem`.
        emit_update(&mut self.builder);

        // Emit assertions of translated invariants.
        for (loc, _, cond) in std::mem::take(&mut translated.invariants) {
            self.builder.set_next_debug_comment(format!(
                "global invariant {}",
                loc.display(self.builder.global_env())
            ));
            self.builder
                .set_loc_and_vc_info(loc, GLOBAL_INVARIANT_FAILS_MESSAGE);
            self.builder
                .emit_with(|id| Bytecode::Prop(id, PropKind::Assert, cond));
        }
    }

    /// Returns the invariants which need to be verified if the given memory is updated.
    /// This filters out those invariants which stem from modules which are not verification
    /// target.
    fn get_verified_invariants_for_mem(
        &self,
        mem: QualifiedId<StructId>,
    ) -> Vec<&'a GlobalInvariant> {
        let env = self.builder.global_env();
        env.get_global_invariants_for_memory(mem)
            .iter()
            .filter_map(|id| {
                env.get_global_invariant(*id)
                    .filter(|inv| env.get_module(inv.declaring_module).is_target())
            })
            .collect()
    }
}
<|endoftext|>


<commit_before>use std::cast;
use std::libc;
use std::ptr;
use std::str;

// CU16String is a cursed version of `std::c_str::CString`
// which treats null-terminated utf-16 strings.

/// The representation of a C UTF-16 string.
pub struct CU16String {
    priv buf: *u16,
    priv owns_buffer_: bool,
}

// TODO: iter
impl CU16String {
    /// Create a CU16String from a pointer.
    pub unsafe fn new(buf: *u16, owns_buffer: bool) -> CU16String {
        CU16String { buf: buf, owns_buffer_: owns_buffer }
    }

    /// Unwraps the wrapped `*u16` from the `CU16String` wrapper.
    /// Any ownership of the buffer by the `CU16String` wrapper is forgotten.
    pub unsafe fn unwrap(self) -> *u16 {
        let mut c_u16_str = self;
        c_u16_str.owns_buffer_ = false;
        c_u16_str.buf
    }

    /// Calls a closure with a reference to the underlying `*u16`.
    ///
    /// # Failure
    ///
    /// Fails if the CU16String is null.
    pub fn with_ref<T>(&self, f: &fn(*u16) -> T) -> T {
        if self.buf.is_null() { fail!("CU16String is null!"); }
        f(self.buf)
    }

    /// Calls a closure with a mutable reference to the underlying `*u16`.
    ///
    /// # Failure
    ///
    /// Fails if the CU16String is null.
    pub fn with_mut_ref<T>(&mut self, f: &fn(*mut u16) -> T) -> T {
        if self.buf.is_null() { fail!("CU16String is null!"); }
        f(unsafe { cast::transmute_mut_unsafe(self.buf) })
    }

    /// Returns true if the CU16String is a null.
    pub fn is_null(&self) -> bool {
        self.buf.is_null()
    }

    /// Returns true if the CU16String is not null.
    pub fn is_not_null(&self) -> bool {
        self.buf.is_not_null()
    }

    /// Returns whether or not the `CU16String` owns the buffer.
    pub fn owns_buffer(&self) -> bool {
        self.owns_buffer_
    }

    /// Converts the CU16String into a `&[u8]` without copying.
    ///
    /// # Failure
    ///
    /// Fails if the CU16String is null.
    #[inline]
    pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
        if self.buf.is_null() { fail!("CU16String is null!"); }
        unsafe {
            cast::transmute((self.buf, self.len() + 1))
        }
    }
}

impl CU16String {
    pub fn as_u16_vec<'a>(&'a self) -> &'a [u16] {
        if self.buf.is_null() { fail!("CU16String is null!"); }
        unsafe {
            cast::transmute((self.buf, self.len() + 1))
        }
    }
}

impl ToStr for CU16String {
    #[inline]
    fn to_str(&self) -> ~str {
        if self.buf.is_null() {
        }
        str::from_utf16(self.as_u16_vec())
    }
}

impl Drop for CU16String {
    fn drop(&mut self) {
        if self.owns_buffer_ {
            unsafe {
                libc::free(self.buf as *libc::c_void)
            }
        }
    }
}

impl Container for CU16String {
    #[inline]
    fn len(&self) -> uint {
        unsafe {
            ptr::position(self.buf, |c| *c == 0)
        }
    }
}

/// Parses a C utf-16 "multistring".
/// See `std::c_str::from_c_multistring` for detailed explanation.
pub unsafe fn from_c_u16_multistring(buf: *u16, count: Option<uint>, f: |&CU16String|) -> uint {

    let mut curr_ptr: uint = buf as uint;
    let mut ctr = 0;
    let (limited_count, limit) = match count {
        Some(limit) => (true, limit),
        None => (false, 0)
    };
    while ((limited_count && ctr < limit) || !limited_count)
          && *(curr_ptr as *u16) != 0 as u16 {
        let cstr = CU16String::new(curr_ptr as *u16, false);
        f(&cstr);
        curr_ptr += (cstr.len() * 1 + 1) * 2;
        ctr += 1;
    }
    return ctr;
}

/// A generic trait for converting a value to a `CU16String`, like `ToCStr`.
pub trait ToCU16Str {
    fn with_c_u16_str<T>(&self, f: &fn(*u16) -> T) -> T;
}

impl<'self> ToCU16Str for &'self str {
    fn with_c_u16_str<T>(&self, f: &fn(*u16) -> T) -> T {
        let mut t = self.to_utf16();
        // Null terminate before passing on.
        t.push(0u16);
        t.as_imm_buf(|buf, _len| f(buf))
    }
}

impl<S: Str> ToCU16Str for Option<S> {
    fn with_c_u16_str<T>(&self, f: &fn(*u16) -> T) -> T {
        match self {
            &None => f(ptr::null()),
            &Some(ref s) => {
                s.as_slice().with_c_u16_str(f)
            },
        }
    }
}

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

    #[test]
    fn test_from_c_u16_multistring() {
        let test: &[u16] = [
            0xac00, 0x00,
            0xac00, 0xac00, 0x00,
            0xac00, 0xac00, 0xac00, 0x00,
            0xac00, 0xac00, 0xac00, 0xac02, 0x00,
            0x00,
        ];
        let compare = [
            "가",
            "가가",
            "가가가",
            "가가가갂",
        ];
        let mut i = 0;
        do test.as_imm_buf |buf, _len| {
            unsafe {
                do from_c_u16_multistring(buf, None) |cu| {
                    let b = cu.to_str();
                    assert_eq!(b.char_len(), i + 1);
                    assert_eq!(b, compare[i].to_owned());
                    i += 1;
                }
            }
        };
        assert_eq!(i, 4);
    }
}
<commit_msg>wchar: Remove broken as_bytes, add as_u16_vec test<commit_after>use std::cast;
use std::libc;
use std::ptr;
use std::str;

// CU16String is a cursed version of `std::c_str::CString`
// which treats null-terminated utf-16 strings.

/// The representation of a C UTF-16 string.
pub struct CU16String {
    priv buf: *u16,
    priv owns_buffer_: bool,
}

// TODO: iter
impl CU16String {
    /// Create a CU16String from a pointer.
    pub unsafe fn new(buf: *u16, owns_buffer: bool) -> CU16String {
        CU16String { buf: buf, owns_buffer_: owns_buffer }
    }

    /// Unwraps the wrapped `*u16` from the `CU16String` wrapper.
    /// Any ownership of the buffer by the `CU16String` wrapper is forgotten.
    pub unsafe fn unwrap(self) -> *u16 {
        let mut c_u16_str = self;
        c_u16_str.owns_buffer_ = false;
        c_u16_str.buf
    }

    /// Calls a closure with a reference to the underlying `*u16`.
    ///
    /// # Failure
    ///
    /// Fails if the CU16String is null.
    pub fn with_ref<T>(&self, f: &fn(*u16) -> T) -> T {
        if self.buf.is_null() { fail!("CU16String is null!"); }
        f(self.buf)
    }

    /// Calls a closure with a mutable reference to the underlying `*u16`.
    ///
    /// # Failure
    ///
    /// Fails if the CU16String is null.
    pub fn with_mut_ref<T>(&mut self, f: &fn(*mut u16) -> T) -> T {
        if self.buf.is_null() { fail!("CU16String is null!"); }
        f(unsafe { cast::transmute_mut_unsafe(self.buf) })
    }

    /// Returns true if the CU16String is a null.
    pub fn is_null(&self) -> bool {
        self.buf.is_null()
    }

    /// Returns true if the CU16String is not null.
    pub fn is_not_null(&self) -> bool {
        self.buf.is_not_null()
    }

    /// Returns whether or not the `CU16String` owns the buffer.
    pub fn owns_buffer(&self) -> bool {
        self.owns_buffer_
    }
}

impl CU16String {
    /// Converts the CU16String into a `&[u8]` without copying.
    ///
    /// # Failure
    ///
    /// Fails if the CU16String is null.
    #[inline]
    pub fn as_u16_vec<'a>(&'a self) -> &'a [u16] {
        if self.buf.is_null() { fail!("CU16String is null!"); }
        unsafe {
            cast::transmute((self.buf, self.len() + 1))
        }
    }
}

impl ToStr for CU16String {
    #[inline]
    fn to_str(&self) -> ~str {
        if self.buf.is_null() {
        }
        str::from_utf16(self.as_u16_vec())
    }
}

impl Drop for CU16String {
    fn drop(&mut self) {
        if self.owns_buffer_ {
            unsafe {
                libc::free(self.buf as *libc::c_void)
            }
        }
    }
}

impl Container for CU16String {
    #[inline]
    fn len(&self) -> uint {
        unsafe {
            ptr::position(self.buf, |c| *c == 0)
        }
    }
}

/// Parses a C utf-16 "multistring".
/// See `std::c_str::from_c_multistring` for detailed explanation.
pub unsafe fn from_c_u16_multistring(buf: *u16, count: Option<uint>, f: |&CU16String|) -> uint {

    let mut curr_ptr: uint = buf as uint;
    let mut ctr = 0;
    let (limited_count, limit) = match count {
        Some(limit) => (true, limit),
        None => (false, 0)
    };
    while ((limited_count && ctr < limit) || !limited_count)
          && *(curr_ptr as *u16) != 0 as u16 {
        let cstr = CU16String::new(curr_ptr as *u16, false);
        f(&cstr);
        curr_ptr += (cstr.len() * 1 + 1) * 2;
        ctr += 1;
    }
    return ctr;
}

/// A generic trait for converting a value to a `CU16String`, like `ToCStr`.
pub trait ToCU16Str {
    fn with_c_u16_str<T>(&self, f: &fn(*u16) -> T) -> T;
}

impl<'self> ToCU16Str for &'self str {
    fn with_c_u16_str<T>(&self, f: &fn(*u16) -> T) -> T {
        let mut t = self.to_utf16();
        // Null terminate before passing on.
        t.push(0u16);
        t.as_imm_buf(|buf, _len| f(buf))
    }
}

impl<S: Str> ToCU16Str for Option<S> {
    fn with_c_u16_str<T>(&self, f: &fn(*u16) -> T) -> T {
        match self {
            &None => f(ptr::null()),
            &Some(ref s) => {
                s.as_slice().with_c_u16_str(f)
            },
        }
    }
}

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

    #[test]
    fn test_as_u16_vec() {
        let u16s: &[u16] = [
            0xac00, 0x20, 0xac00, 0x00,
        ];

        do u16s.as_imm_buf |buf, _len| {
            let cu = unsafe { CU16String::new(buf, false) };
            let v = cu.as_u16_vec();
            debug!("v: {:?}", v);
            assert_eq!(v, u16s);
        }
    }

    #[test]
    fn test_from_c_u16_multistring() {
        let test: &[u16] = [
            0xac00, 0x00,
            0xac00, 0xac00, 0x00,
            0xac00, 0xac00, 0xac00, 0x00,
            0xac00, 0xac00, 0xac00, 0xac02, 0x00,
            0x00,
        ];
        let compare = [
            "가",
            "가가",
            "가가가",
            "가가가갂",
        ];
        let mut i = 0;
        do test.as_imm_buf |buf, _len| {
            unsafe {
                do from_c_u16_multistring(buf, None) |cu| {
                    let b = cu.to_str();
                    assert_eq!(b.char_len(), i + 1);
                    assert_eq!(b, compare[i].to_owned());
                    i += 1;
                }
            }
        };
        assert_eq!(i, 4);
    }
}
<|endoftext|>


<commit_before>use crate::NewlineStyle;

/// Apply this newline style to the formatted text. When the style is set
/// to `Auto`, the `raw_input_text` is used to detect the existing line
/// endings.
///
/// If the style is set to `Auto` and `raw_input_text` contains no
/// newlines, the `Native` style will be used.
pub(crate) fn apply_newline_style(
    newline_style: NewlineStyle,
    formatted_text: &mut String,
    raw_input_text: &str,
) {
    match effective_newline_style(newline_style, raw_input_text) {
        EffectiveNewlineStyle::Windows => {
            *formatted_text = convert_to_windows_newlines(formatted_text);
        }
        EffectiveNewlineStyle::Unix => {}
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum EffectiveNewlineStyle {
    Windows,
    Unix,
}

fn effective_newline_style(
    newline_style: NewlineStyle,
    raw_input_text: &str,
) -> EffectiveNewlineStyle {
    match newline_style {
        NewlineStyle::Auto => auto_detect_newline_style(raw_input_text),
        NewlineStyle::Native => native_newline_style(),
        NewlineStyle::Windows => EffectiveNewlineStyle::Windows,
        NewlineStyle::Unix => EffectiveNewlineStyle::Unix,
    }
}

const LINE_FEED: char = '\n';
const CARRIAGE_RETURN: char = '\r';

fn auto_detect_newline_style(raw_input_text: &str) -> EffectiveNewlineStyle {
    let first_line_feed_pos = raw_input_text.chars().position(|ch| ch == LINE_FEED);
    match first_line_feed_pos {
        Some(first_line_feed_pos) => {
            let char_before_line_feed_pos = first_line_feed_pos.saturating_sub(1);
            let char_before_line_feed = raw_input_text.chars().nth(char_before_line_feed_pos);
            match char_before_line_feed {
                Some(CARRIAGE_RETURN) => EffectiveNewlineStyle::Windows,
                _ => EffectiveNewlineStyle::Unix,
            }
        }
        None => native_newline_style(),
    }
}

fn native_newline_style() -> EffectiveNewlineStyle {
    if cfg!(windows) {
        EffectiveNewlineStyle::Windows
    } else {
        EffectiveNewlineStyle::Unix
    }
}

fn convert_to_windows_newlines(formatted_text: &String) -> String {
    let mut transformed = String::with_capacity(2 * formatted_text.capacity());
    for c in formatted_text.chars() {
        const WINDOWS_NEWLINE: &str = "\r\n";
        match c {
            LINE_FEED => transformed.push_str(WINDOWS_NEWLINE),
            c => transformed.push(c),
        }
    }
    transformed
}

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

    #[test]
    fn auto_detects_unix_newlines() {
        assert_eq!(
            EffectiveNewlineStyle::Unix,
            auto_detect_newline_style("One\nTwo\nThree")
        );
    }

    #[test]
    fn auto_detects_windows_newlines() {
        assert_eq!(
            EffectiveNewlineStyle::Windows,
            auto_detect_newline_style("One\r\nTwo\r\nThree")
        );
    }

    #[test]
    fn auto_detects_windows_newlines_with_multibyte_char_on_first_line() {
        assert_eq!(
            EffectiveNewlineStyle::Windows,
            auto_detect_newline_style("A 🎢 of a first line\r\nTwo\r\nThree")
        );
    }

    #[test]
    fn falls_back_to_native_newlines_if_no_newlines_are_found() {
        let expected_newline_style = if cfg!(windows) {
            EffectiveNewlineStyle::Windows
        } else {
            EffectiveNewlineStyle::Unix
        };
        assert_eq!(
            expected_newline_style,
            auto_detect_newline_style("One Two Three")
        );
    }

    #[test]
    fn auto_detects_and_applies_unix_newlines() {
        let formatted_text = "One\nTwo\nThree";
        let raw_input_text = "One\nTwo\nThree";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Auto, &mut out, raw_input_text);
        assert_eq!("One\nTwo\nThree", &out, "auto should detect 'lf'");
    }

    #[test]
    fn auto_detects_and_applies_windows_newlines() {
        let formatted_text = "One\nTwo\nThree";
        let raw_input_text = "One\r\nTwo\r\nThree";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Auto, &mut out, raw_input_text);
        assert_eq!("One\r\nTwo\r\nThree", &out, "auto should detect 'crlf'");
    }

    #[test]
    fn auto_detects_and_applies_native_newlines() {
        let formatted_text = "One\nTwo\nThree";
        let raw_input_text = "One Two Three";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Auto, &mut out, raw_input_text);

        if cfg!(windows) {
            assert_eq!(
                "One\r\nTwo\r\nThree", &out,
                "auto-native-windows should detect 'crlf'"
            );
        } else {
            assert_eq!(
                "One\nTwo\nThree", &out,
                "auto-native-unix should detect 'lf'"
            );
        }
    }

    #[test]
    fn preserves_standalone_carriage_returns_when_applying_windows_newlines() {
        let formatted_text = "One\nTwo\nThree\rDrei";
        let raw_input_text = "One\nTwo\nThree\rDrei";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Windows, &mut out, raw_input_text);

        assert_eq!("One\r\nTwo\r\nThree\rDrei", &out);
    }

    #[test]
    fn preserves_standalone_carriage_returns_when_applying_unix_newlines() {
        let formatted_text = "One\nTwo\nThree\rDrei";
        let raw_input_text = "One\nTwo\nThree\rDrei";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Unix, &mut out, raw_input_text);

        assert_eq!("One\nTwo\nThree\rDrei", &out);
    }
}
<commit_msg>Implement conversion to unix newlines<commit_after>use crate::NewlineStyle;

/// Apply this newline style to the formatted text. When the style is set
/// to `Auto`, the `raw_input_text` is used to detect the existing line
/// endings.
///
/// If the style is set to `Auto` and `raw_input_text` contains no
/// newlines, the `Native` style will be used.
pub(crate) fn apply_newline_style(
    newline_style: NewlineStyle,
    formatted_text: &mut String,
    raw_input_text: &str,
) {
    *formatted_text = match effective_newline_style(newline_style, raw_input_text) {
        EffectiveNewlineStyle::Windows => convert_to_windows_newlines(formatted_text),
        EffectiveNewlineStyle::Unix => convert_to_unix_newlines(formatted_text),
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum EffectiveNewlineStyle {
    Windows,
    Unix,
}

fn effective_newline_style(
    newline_style: NewlineStyle,
    raw_input_text: &str,
) -> EffectiveNewlineStyle {
    match newline_style {
        NewlineStyle::Auto => auto_detect_newline_style(raw_input_text),
        NewlineStyle::Native => native_newline_style(),
        NewlineStyle::Windows => EffectiveNewlineStyle::Windows,
        NewlineStyle::Unix => EffectiveNewlineStyle::Unix,
    }
}

const LINE_FEED: char = '\n';
const CARRIAGE_RETURN: char = '\r';
const WINDOWS_NEWLINE: &str = "\r\n";
const UNIX_NEWLINE: &str = "\n";

fn auto_detect_newline_style(raw_input_text: &str) -> EffectiveNewlineStyle {
    let first_line_feed_pos = raw_input_text.chars().position(|ch| ch == LINE_FEED);
    match first_line_feed_pos {
        Some(first_line_feed_pos) => {
            let char_before_line_feed_pos = first_line_feed_pos.saturating_sub(1);
            let char_before_line_feed = raw_input_text.chars().nth(char_before_line_feed_pos);
            match char_before_line_feed {
                Some(CARRIAGE_RETURN) => EffectiveNewlineStyle::Windows,
                _ => EffectiveNewlineStyle::Unix,
            }
        }
        None => native_newline_style(),
    }
}

fn native_newline_style() -> EffectiveNewlineStyle {
    if cfg!(windows) {
        EffectiveNewlineStyle::Windows
    } else {
        EffectiveNewlineStyle::Unix
    }
}

fn convert_to_windows_newlines(formatted_text: &String) -> String {
    let mut transformed = String::with_capacity(2 * formatted_text.capacity());
    for c in formatted_text.chars() {
        match c {
            LINE_FEED => transformed.push_str(WINDOWS_NEWLINE),
            c => transformed.push(c),
        }
    }
    transformed
}

fn convert_to_unix_newlines(formatted_text: &String) -> String {
    formatted_text.replace(WINDOWS_NEWLINE, UNIX_NEWLINE)
}

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

    #[test]
    fn auto_detects_unix_newlines() {
        assert_eq!(
            EffectiveNewlineStyle::Unix,
            auto_detect_newline_style("One\nTwo\nThree")
        );
    }

    #[test]
    fn auto_detects_windows_newlines() {
        assert_eq!(
            EffectiveNewlineStyle::Windows,
            auto_detect_newline_style("One\r\nTwo\r\nThree")
        );
    }

    #[test]
    fn auto_detects_windows_newlines_with_multibyte_char_on_first_line() {
        assert_eq!(
            EffectiveNewlineStyle::Windows,
            auto_detect_newline_style("A 🎢 of a first line\r\nTwo\r\nThree")
        );
    }

    #[test]
    fn falls_back_to_native_newlines_if_no_newlines_are_found() {
        let expected_newline_style = if cfg!(windows) {
            EffectiveNewlineStyle::Windows
        } else {
            EffectiveNewlineStyle::Unix
        };
        assert_eq!(
            expected_newline_style,
            auto_detect_newline_style("One Two Three")
        );
    }

    #[test]
    fn auto_detects_and_applies_unix_newlines() {
        let formatted_text = "One\nTwo\nThree";
        let raw_input_text = "One\nTwo\nThree";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Auto, &mut out, raw_input_text);
        assert_eq!("One\nTwo\nThree", &out, "auto should detect 'lf'");
    }

    #[test]
    fn auto_detects_and_applies_windows_newlines() {
        let formatted_text = "One\nTwo\nThree";
        let raw_input_text = "One\r\nTwo\r\nThree";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Auto, &mut out, raw_input_text);
        assert_eq!("One\r\nTwo\r\nThree", &out, "auto should detect 'crlf'");
    }

    #[test]
    fn auto_detects_and_applies_native_newlines() {
        let formatted_text = "One\nTwo\nThree";
        let raw_input_text = "One Two Three";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Auto, &mut out, raw_input_text);

        if cfg!(windows) {
            assert_eq!(
                "One\r\nTwo\r\nThree", &out,
                "auto-native-windows should detect 'crlf'"
            );
        } else {
            assert_eq!(
                "One\nTwo\nThree", &out,
                "auto-native-unix should detect 'lf'"
            );
        }
    }

    #[test]
    fn applies_unix_newlines() {
        let formatted_text = "One\r\nTwo\nThree";
        let raw_input_text = formatted_text;

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Unix, &mut out, raw_input_text);

        assert_eq!("One\nTwo\nThree", &out);
    }

    #[test]
    fn preserves_standalone_carriage_returns_when_applying_windows_newlines() {
        let formatted_text = "One\nTwo\nThree\rDrei";
        let raw_input_text = "One\nTwo\nThree\rDrei";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Windows, &mut out, raw_input_text);

        assert_eq!("One\r\nTwo\r\nThree\rDrei", &out);
    }

    #[test]
    fn preserves_standalone_carriage_returns_when_applying_unix_newlines() {
        let formatted_text = "One\nTwo\nThree\rDrei";
        let raw_input_text = "One\nTwo\nThree\rDrei";

        let mut out = String::from(formatted_text);
        apply_newline_style(NewlineStyle::Unix, &mut out, raw_input_text);

        assert_eq!("One\nTwo\nThree\rDrei", &out);
    }
}
<|endoftext|>


<commit_before>//! `CommandBuffer` methods for graphics operations.
use std::borrow::Borrow;
use std::ops::Range;

use Backend;
use {image, pso};
use buffer::IndexBufferView;
use query::{Query, QueryControl, QueryId};
use queue::capability::{Graphics, GraphicsOrCompute, Supports};
use super::{
    CommandBuffer, RawCommandBuffer,
    RenderPassInlineEncoder, RenderPassSecondaryEncoder,
    Shot, Level, Primary,
    ClearColorRaw, ClearDepthStencilRaw, ClearValueRaw,
};

/// A universal clear color supporting integer formats
/// as well as the standard floating-point.
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ClearColor {
    /// Standard floating-point `vec4` color
    Float(pso::ColorValue),
    /// Integer vector to clear `ivec4` targets.
    Int([i32; 4]),
    /// Unsigned int vector to clear `uvec4` targets.
    Uint([u32; 4]),
}

macro_rules! impl_clear {
    { $( $ty:ty = $sub:ident[$a:expr, $b:expr, $c:expr, $d:expr], )* } => {
        $(
            impl From<$ty> for ClearColor {
                fn from(v: $ty) -> Self {
                    ClearColor::$sub([v[$a], v[$b], v[$c], v[$d]])
                }
            }
        )*
    }
}

impl_clear! {
    [f32; 4] = Float[0, 1, 2, 3],
    [f32; 3] = Float[0, 1, 2, 0],
    [f32; 2] = Float[0, 1, 0, 0],
    [i32; 4] = Int  [0, 1, 2, 3],
    [i32; 3] = Int  [0, 1, 2, 0],
    [i32; 2] = Int  [0, 1, 0, 0],
    [u32; 4] = Uint [0, 1, 2, 3],
    [u32; 3] = Uint [0, 1, 2, 0],
    [u32; 2] = Uint [0, 1, 0, 0],
}

impl From<f32> for ClearColor {
    fn from(v: f32) -> Self {
        ClearColor::Float([v, 0.0, 0.0, 0.0])
    }
}
impl From<i32> for ClearColor {
    fn from(v: i32) -> Self {
        ClearColor::Int([v, 0, 0, 0])
    }
}
impl From<u32> for ClearColor {
    fn from(v: u32) -> Self {
        ClearColor::Uint([v, 0, 0, 0])
    }
}

impl From<ClearColor> for ClearColorRaw {
    fn from(cv: ClearColor) -> Self {
        match cv {
            ClearColor::Float(cv) => ClearColorRaw { float32: cv },
            ClearColor::Int(cv) => ClearColorRaw { int32: cv },
            ClearColor::Uint(cv) => ClearColorRaw { uint32: cv },
        }
    }
}

/// Depth-stencil target clear values.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ClearDepthStencil(pub pso::DepthValue, pub pso::StencilValue);

impl From<ClearDepthStencil> for ClearDepthStencilRaw {
    fn from(value: ClearDepthStencil) -> Self {
        ClearDepthStencilRaw {
            depth: value.0,
            stencil: value.1,
        }
    }
}

/// General clear values for attachments (color or depth-stencil).
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ClearValue {
    ///
    Color(ClearColor),
    ///
    DepthStencil(ClearDepthStencil),
}

impl From<ClearValue> for ClearValueRaw {
    fn from(value: ClearValue) -> Self {
        match value {
            ClearValue::Color(color) => ClearValueRaw { color: color.into() },
            ClearValue::DepthStencil(ds) => ClearValueRaw { depth_stencil: ds.into() },
        }
    }
}

/// Attachment clear description for the current subpass.
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum AttachmentClear {
    /// Clear color attachment.
    ///
    /// First tuple element denotes the index of the color attachment.
    Color(usize, ClearColor),
    /// Clear depth component of the attachment.
    Depth(pso::DepthValue),
    /// Clear stencil component of the attachment.
    Stencil(pso::StencilValue),
    /// Clear depth-stencil component of the attachment.
    DepthStencil(ClearDepthStencil),
}

/// Parameters for an image resolve operation,
/// where a multi-sampled image is copied into a single-sampled
/// image.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ImageResolve {
    /// Source image and layers.
    pub src_subresource: image::SubresourceLayers,
    /// Source image offset.
    pub src_offset: image::Offset,
    /// Destination image and layers.
    pub dst_subresource: image::SubresourceLayers,
    /// Destination image offset.
    pub dst_offset: image::Offset,
    /// Image extent.
    pub extent: image::Extent,
}

/// Parameters for an image blit operation, where a portion of one image
/// is copied into another, possibly with scaling and filtering.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ImageBlit {
    /// Source image and layers.
    pub src_subresource: image::SubresourceLayers,
    /// Source image bounds.
    pub src_bounds: Range<image::Offset>,
    /// Destination image and layers.
    pub dst_subresource: image::SubresourceLayers,
    /// Destination image bounds.
    pub dst_bounds: Range<image::Offset>,
}

impl<'a, B: Backend, C: Supports<Graphics>, S: Shot, L: Level> CommandBuffer<'a, B, C, S, L> {
    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn begin_render_pass_inline<T>(
        &mut self,
        render_pass: &B::RenderPass,
        frame_buffer: &B::Framebuffer,
        render_area: pso::Rect,
        clear_values: T,
    ) -> RenderPassInlineEncoder<B, L>
    where
        T: IntoIterator,
        T::Item: Borrow<ClearValue>,
    {
        RenderPassInlineEncoder::new(self, render_pass, frame_buffer, render_area, clear_values)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn clear_image<T>(
        &mut self,
        image: &B::Image,
        layout: image::Layout,
        color: ClearColor,
        depth_stencil: ClearDepthStencil,
        subresource_ranges: T,
    ) where
        T: IntoIterator,
        T::Item: Borrow<image::SubresourceRange>,
    {
        self.raw.clear_image(image, layout, color.into(), depth_stencil.into(), subresource_ranges)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn bind_index_buffer(&mut self, ibv: IndexBufferView<B>) {
        self.raw.bind_index_buffer(ibv)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn bind_vertex_buffers(&mut self, first_binding: u32, vbs: pso::VertexBufferSet<B>) {
        self.raw.bind_vertex_buffers(first_binding, vbs)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn bind_graphics_pipeline(&mut self, pipeline: &B::GraphicsPipeline) {
        self.raw.bind_graphics_pipeline(pipeline)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn bind_graphics_descriptor_sets<T>(
        &mut self,
        layout: &B::PipelineLayout,
        first_set: usize,
        sets: T,
    ) where
        T: IntoIterator,
        T::Item: Borrow<B::DescriptorSet>,
    {
        self.raw.bind_graphics_descriptor_sets(layout, first_set, sets)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_viewports<T>(&mut self, first_viewport: u32, viewports: T)
    where
        T: IntoIterator,
        T::Item: Borrow<pso::Viewport>,
    {
        self.raw.set_viewports(first_viewport, viewports)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_scissors<T>(&mut self, first_scissor: u32, scissors: T)
    where
        T: IntoIterator,
        T::Item: Borrow<pso::Rect>,
    {
        self.raw.set_scissors(first_scissor, scissors)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_stencil_reference(&mut self, front: pso::StencilValue, back: pso::StencilValue) {
        self.raw.set_stencil_reference(front, back)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_blend_constants(&mut self, cv: pso::ColorValue) {
        self.raw.set_blend_constants(cv)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_depth_bounds(&mut self, bounds: Range<f32>) {
        self.raw.set_depth_bounds(bounds)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn push_graphics_constants(&mut self, layout: &B::PipelineLayout, stages: pso::ShaderStageFlags, offset: u32, constants: &[u32]) {
        self.raw.push_graphics_constants(layout, stages, offset, constants)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn resolve_image<T>(
        &mut self,
        src: &B::Image,
        src_layout: image::Layout,
        dst: &B::Image,
        dst_layout: image::Layout,
        regions: T,
    ) where
        T: IntoIterator,
        T::Item: Borrow<ImageResolve>
    {
        self.raw.resolve_image(src, src_layout, dst, dst_layout, regions)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn blit_image<T>(
        &mut self,
        src: &B::Image,
        src_layout: image::Layout,
        dst: &B::Image,
        dst_layout: image::Layout,
        filter: image::Filter,
        regions: T,
    ) where
        T: IntoIterator,
        T::Item: Borrow<ImageBlit>,
    {
        self.raw.blit_image(src, src_layout, dst, dst_layout, filter, regions)
    }
}

impl<'a, B: Backend, C: Supports<Graphics>, S: Shot> CommandBuffer<'a, B, C, S, Primary> {
    /// Creates a new secondary render pass.
    pub fn begin_render_pass_secondary<T>(
        &mut self,
        render_pass: &B::RenderPass,
        frame_buffer: &B::Framebuffer,
        render_area: pso::Rect,
        clear_values: T,
    ) -> RenderPassSecondaryEncoder<B>
    where
        T: IntoIterator,
        T::Item: Borrow<ClearValue>,
    {
        RenderPassSecondaryEncoder::new(self, render_pass, frame_buffer, render_area, clear_values)
    }
}

impl<'a, B: Backend, C: Supports<GraphicsOrCompute>, S: Shot, L: Level> CommandBuffer<'a, B, C, S, L> {
    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn begin_query(&mut self, query: Query<B>, flags: QueryControl) {
        self.raw.begin_query(query, flags)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn end_query(&mut self, query: Query<B>) {
        self.raw.end_query(query)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn reset_query_pool(&mut self, pool: &B::QueryPool, queries: Range<QueryId>) {
        self.raw.reset_query_pool(pool, queries)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn write_timestamp(&mut self, stage: pso::PipelineStage, query: Query<B>) {
        self.raw.write_timestamp(stage, query)
    }
}
<commit_msg>Restricts render pass begin to only primary buffers<commit_after>//! `CommandBuffer` methods for graphics operations.
use std::borrow::Borrow;
use std::ops::Range;

use Backend;
use {image, pso};
use buffer::IndexBufferView;
use query::{Query, QueryControl, QueryId};
use queue::capability::{Graphics, GraphicsOrCompute, Supports};
use super::{
    CommandBuffer, RawCommandBuffer,
    RenderPassInlineEncoder, RenderPassSecondaryEncoder,
    Shot, Level, Primary,
    ClearColorRaw, ClearDepthStencilRaw, ClearValueRaw,
};

/// A universal clear color supporting integer formats
/// as well as the standard floating-point.
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ClearColor {
    /// Standard floating-point `vec4` color
    Float(pso::ColorValue),
    /// Integer vector to clear `ivec4` targets.
    Int([i32; 4]),
    /// Unsigned int vector to clear `uvec4` targets.
    Uint([u32; 4]),
}

macro_rules! impl_clear {
    { $( $ty:ty = $sub:ident[$a:expr, $b:expr, $c:expr, $d:expr], )* } => {
        $(
            impl From<$ty> for ClearColor {
                fn from(v: $ty) -> Self {
                    ClearColor::$sub([v[$a], v[$b], v[$c], v[$d]])
                }
            }
        )*
    }
}

impl_clear! {
    [f32; 4] = Float[0, 1, 2, 3],
    [f32; 3] = Float[0, 1, 2, 0],
    [f32; 2] = Float[0, 1, 0, 0],
    [i32; 4] = Int  [0, 1, 2, 3],
    [i32; 3] = Int  [0, 1, 2, 0],
    [i32; 2] = Int  [0, 1, 0, 0],
    [u32; 4] = Uint [0, 1, 2, 3],
    [u32; 3] = Uint [0, 1, 2, 0],
    [u32; 2] = Uint [0, 1, 0, 0],
}

impl From<f32> for ClearColor {
    fn from(v: f32) -> Self {
        ClearColor::Float([v, 0.0, 0.0, 0.0])
    }
}
impl From<i32> for ClearColor {
    fn from(v: i32) -> Self {
        ClearColor::Int([v, 0, 0, 0])
    }
}
impl From<u32> for ClearColor {
    fn from(v: u32) -> Self {
        ClearColor::Uint([v, 0, 0, 0])
    }
}

impl From<ClearColor> for ClearColorRaw {
    fn from(cv: ClearColor) -> Self {
        match cv {
            ClearColor::Float(cv) => ClearColorRaw { float32: cv },
            ClearColor::Int(cv) => ClearColorRaw { int32: cv },
            ClearColor::Uint(cv) => ClearColorRaw { uint32: cv },
        }
    }
}

/// Depth-stencil target clear values.
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ClearDepthStencil(pub pso::DepthValue, pub pso::StencilValue);

impl From<ClearDepthStencil> for ClearDepthStencilRaw {
    fn from(value: ClearDepthStencil) -> Self {
        ClearDepthStencilRaw {
            depth: value.0,
            stencil: value.1,
        }
    }
}

/// General clear values for attachments (color or depth-stencil).
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ClearValue {
    ///
    Color(ClearColor),
    ///
    DepthStencil(ClearDepthStencil),
}

impl From<ClearValue> for ClearValueRaw {
    fn from(value: ClearValue) -> Self {
        match value {
            ClearValue::Color(color) => ClearValueRaw { color: color.into() },
            ClearValue::DepthStencil(ds) => ClearValueRaw { depth_stencil: ds.into() },
        }
    }
}

/// Attachment clear description for the current subpass.
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum AttachmentClear {
    /// Clear color attachment.
    ///
    /// First tuple element denotes the index of the color attachment.
    Color(usize, ClearColor),
    /// Clear depth component of the attachment.
    Depth(pso::DepthValue),
    /// Clear stencil component of the attachment.
    Stencil(pso::StencilValue),
    /// Clear depth-stencil component of the attachment.
    DepthStencil(ClearDepthStencil),
}

/// Parameters for an image resolve operation,
/// where a multi-sampled image is copied into a single-sampled
/// image.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ImageResolve {
    /// Source image and layers.
    pub src_subresource: image::SubresourceLayers,
    /// Source image offset.
    pub src_offset: image::Offset,
    /// Destination image and layers.
    pub dst_subresource: image::SubresourceLayers,
    /// Destination image offset.
    pub dst_offset: image::Offset,
    /// Image extent.
    pub extent: image::Extent,
}

/// Parameters for an image blit operation, where a portion of one image
/// is copied into another, possibly with scaling and filtering.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ImageBlit {
    /// Source image and layers.
    pub src_subresource: image::SubresourceLayers,
    /// Source image bounds.
    pub src_bounds: Range<image::Offset>,
    /// Destination image and layers.
    pub dst_subresource: image::SubresourceLayers,
    /// Destination image bounds.
    pub dst_bounds: Range<image::Offset>,
}

impl<'a, B: Backend, C: Supports<Graphics>, S: Shot, L: Level> CommandBuffer<'a, B, C, S, L> {
    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn clear_image<T>(
        &mut self,
        image: &B::Image,
        layout: image::Layout,
        color: ClearColor,
        depth_stencil: ClearDepthStencil,
        subresource_ranges: T,
    ) where
        T: IntoIterator,
        T::Item: Borrow<image::SubresourceRange>,
    {
        self.raw.clear_image(image, layout, color.into(), depth_stencil.into(), subresource_ranges)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn bind_index_buffer(&mut self, ibv: IndexBufferView<B>) {
        self.raw.bind_index_buffer(ibv)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn bind_vertex_buffers(&mut self, first_binding: u32, vbs: pso::VertexBufferSet<B>) {
        self.raw.bind_vertex_buffers(first_binding, vbs)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn bind_graphics_pipeline(&mut self, pipeline: &B::GraphicsPipeline) {
        self.raw.bind_graphics_pipeline(pipeline)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn bind_graphics_descriptor_sets<T>(
        &mut self,
        layout: &B::PipelineLayout,
        first_set: usize,
        sets: T,
    ) where
        T: IntoIterator,
        T::Item: Borrow<B::DescriptorSet>,
    {
        self.raw.bind_graphics_descriptor_sets(layout, first_set, sets)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_viewports<T>(&mut self, first_viewport: u32, viewports: T)
    where
        T: IntoIterator,
        T::Item: Borrow<pso::Viewport>,
    {
        self.raw.set_viewports(first_viewport, viewports)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_scissors<T>(&mut self, first_scissor: u32, scissors: T)
    where
        T: IntoIterator,
        T::Item: Borrow<pso::Rect>,
    {
        self.raw.set_scissors(first_scissor, scissors)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_stencil_reference(&mut self, front: pso::StencilValue, back: pso::StencilValue) {
        self.raw.set_stencil_reference(front, back)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_blend_constants(&mut self, cv: pso::ColorValue) {
        self.raw.set_blend_constants(cv)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn set_depth_bounds(&mut self, bounds: Range<f32>) {
        self.raw.set_depth_bounds(bounds)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn push_graphics_constants(&mut self, layout: &B::PipelineLayout, stages: pso::ShaderStageFlags, offset: u32, constants: &[u32]) {
        self.raw.push_graphics_constants(layout, stages, offset, constants)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn resolve_image<T>(
        &mut self,
        src: &B::Image,
        src_layout: image::Layout,
        dst: &B::Image,
        dst_layout: image::Layout,
        regions: T,
    ) where
        T: IntoIterator,
        T::Item: Borrow<ImageResolve>
    {
        self.raw.resolve_image(src, src_layout, dst, dst_layout, regions)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn blit_image<T>(
        &mut self,
        src: &B::Image,
        src_layout: image::Layout,
        dst: &B::Image,
        dst_layout: image::Layout,
        filter: image::Filter,
        regions: T,
    ) where
        T: IntoIterator,
        T::Item: Borrow<ImageBlit>,
    {
        self.raw.blit_image(src, src_layout, dst, dst_layout, filter, regions)
    }
}

impl<'a, B: Backend, C: Supports<Graphics>, S: Shot> CommandBuffer<'a, B, C, S, Primary> {
    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn begin_render_pass_inline<T>(
        &mut self,
        render_pass: &B::RenderPass,
        frame_buffer: &B::Framebuffer,
        render_area: pso::Rect,
        clear_values: T,
    ) -> RenderPassInlineEncoder<B, Primary>
    where
        T: IntoIterator,
        T::Item: Borrow<ClearValue>,
    {
        RenderPassInlineEncoder::new(self, render_pass, frame_buffer, render_area, clear_values)
    }

    /// Creates a new secondary render pass.
    pub fn begin_render_pass_secondary<T>(
        &mut self,
        render_pass: &B::RenderPass,
        frame_buffer: &B::Framebuffer,
        render_area: pso::Rect,
        clear_values: T,
    ) -> RenderPassSecondaryEncoder<B>
    where
        T: IntoIterator,
        T::Item: Borrow<ClearValue>,
    {
        RenderPassSecondaryEncoder::new(self, render_pass, frame_buffer, render_area, clear_values)
    }
}

impl<'a, B: Backend, C: Supports<GraphicsOrCompute>, S: Shot, L: Level> CommandBuffer<'a, B, C, S, L> {
    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn begin_query(&mut self, query: Query<B>, flags: QueryControl) {
        self.raw.begin_query(query, flags)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn end_query(&mut self, query: Query<B>) {
        self.raw.end_query(query)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn reset_query_pool(&mut self, pool: &B::QueryPool, queries: Range<QueryId>) {
        self.raw.reset_query_pool(pool, queries)
    }

    /// Identical to the `RawCommandBuffer` method of the same name.
    pub fn write_timestamp(&mut self, stage: pso::PipelineStage, query: Query<B>) {
        self.raw.write_timestamp(stage, query)
    }
}
<|endoftext|>


<commit_before>#![ warn( rust_2018_idioms ) ]
#![ warn( missing_debug_implementations ) ]
#![ warn( missing_docs ) ]

// #![ feature( type_name_of_val ) ]
#![ feature( trace_macros ) ]

//!
//! Implementation of automata.
//!

#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/Readme.md" ) ) ]

/// Abstract layer.
pub mod abs;
/// Canonical representation.
pub mod canonical;
/// Matrix representation.
pub mod matrix;
/// Algorithms.
pub mod algo;

/// Namespace with dependencies.
pub mod dependency
{
}

/// Exposed namespace of the module.
pub mod exposed
{
  pub use super::prelude::*;
  pub use super::abs::exposed::*;
  pub use super::prelude::*;
  pub use super::algo::exposed::*;
  pub use super::canonical::exposed::*;
  pub use super::matrix::exposed::*;
}

pub use exposed::*;

/// Prelude to use: `use wtools::prelude::*`.
pub mod prelude
{
  pub use super::abs::prelude::*;
  pub use super::algo::prelude::*;
  pub use super::canonical::prelude::*;
  pub use super::matrix::prelude::*;
}
<commit_msg>switch off unstable features<commit_after>#![ warn( rust_2018_idioms ) ]
#![ warn( missing_debug_implementations ) ]
#![ warn( missing_docs ) ]

// #![ feature( type_name_of_val ) ]
// #![ feature( trace_macros ) ]

//!
//! Implementation of automata.
//!

#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/Readme.md" ) ) ]

/// Abstract layer.
pub mod abs;
/// Canonical representation.
pub mod canonical;
/// Matrix representation.
pub mod matrix;
/// Algorithms.
pub mod algo;

/// Namespace with dependencies.
pub mod dependency
{
}

/// Exposed namespace of the module.
pub mod exposed
{
  pub use super::prelude::*;
  pub use super::abs::exposed::*;
  pub use super::prelude::*;
  pub use super::algo::exposed::*;
  pub use super::canonical::exposed::*;
  pub use super::matrix::exposed::*;
}

pub use exposed::*;

/// Prelude to use: `use wtools::prelude::*`.
pub mod prelude
{
  pub use super::abs::prelude::*;
  pub use super::algo::prelude::*;
  pub use super::canonical::prelude::*;
  pub use super::matrix::prelude::*;
}
<|endoftext|>


<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 syntax_pos::symbol::Symbol;
use back::write::create_target_machine;
use llvm;
use rustc::session::Session;
use rustc::session::config::PrintRequest;
use libc::c_int;
use std::ffi::CString;

use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Once;

static POISONED: AtomicBool = AtomicBool::new(false);
static INIT: Once = Once::new();

pub(crate) fn init(sess: &Session) {
    unsafe {
        // Before we touch LLVM, make sure that multithreading is enabled.
        INIT.call_once(|| {
            if llvm::LLVMStartMultithreaded() != 1 {
                // use an extra bool to make sure that all future usage of LLVM
                // cannot proceed despite the Once not running more than once.
                POISONED.store(true, Ordering::SeqCst);
            }

            configure_llvm(sess);
        });

        if POISONED.load(Ordering::SeqCst) {
            bug!("couldn't enable multi-threaded LLVM");
        }
    }
}

fn require_inited() {
    INIT.call_once(|| bug!("llvm is not initialized"));
    if POISONED.load(Ordering::SeqCst) {
        bug!("couldn't enable multi-threaded LLVM");
    }
}

unsafe fn configure_llvm(sess: &Session) {
    let mut llvm_c_strs = Vec::new();
    let mut llvm_args = Vec::new();

    {
        let mut add = |arg: &str| {
            let s = CString::new(arg).unwrap();
            llvm_args.push(s.as_ptr());
            llvm_c_strs.push(s);
        };
        add("rustc"); // fake program name
        if sess.time_llvm_passes() { add("-time-passes"); }
        if sess.print_llvm_passes() { add("-debug-pass=Structure"); }

        for arg in &sess.opts.cg.llvm_args {
            add(&(*arg));
        }
    }

    llvm::LLVMInitializePasses();

    llvm::initialize_available_targets();

    llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
                                 llvm_args.as_ptr());
}

// WARNING: the features must be known to LLVM or the feature
// detection code will walk past the end of the feature array,
// leading to crashes.

const ARM_WHITELIST: &'static [&'static str] = &["neon", "v7", "vfp2", "vfp3", "vfp4"];

const AARCH64_WHITELIST: &'static [&'static str] = &["neon", "v7"];

const X86_WHITELIST: &'static [&'static str] = &["avx", "avx2", "bmi", "bmi2", "sse",
                                                 "sse2", "sse3", "sse4.1", "sse4.2",
                                                 "ssse3", "tbm", "lzcnt", "popcnt",
                                                 "sse4a", "rdrnd", "rdseed", "fma",
                                                 "xsave", "xsaveopt", "xsavec",
                                                 "xsaves", "aes", "pclmulqdq",
                                                 "avx512bw", "avx512cd",
                                                 "avx512dq", "avx512er",
                                                 "avx512f", "avx512ifma",
                                                 "avx512pf", "avx512vbmi",
                                                 "avx512vl", "avx512vpopcntdq",
                                                 "mmx", "fxsr"];

const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx", "hvx-double"];

const POWERPC_WHITELIST: &'static [&'static str] = &["altivec",
                                                     "power8-altivec", "power9-altivec",
                                                     "power8-vector", "power9-vector",
                                                     "vsx"];

const MIPS_WHITELIST: &'static [&'static str] = &["msa"];

pub fn to_llvm_feature(s: &str) -> &str {
    match s {
        "pclmulqdq" => "pclmul",
        s => s,
    }
}

pub fn target_features(sess: &Session) -> Vec<Symbol> {
    let target_machine = create_target_machine(sess);
    target_feature_whitelist(sess)
        .iter()
        .filter(|feature| {
            let llvm_feature = to_llvm_feature(feature);
            let cstr = CString::new(llvm_feature).unwrap();
            unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) }
        })
        .map(|feature| Symbol::intern(feature)).collect()
}

pub fn target_feature_whitelist(sess: &Session) -> &'static [&'static str] {
    match &*sess.target.target.arch {
        "arm" => ARM_WHITELIST,
        "aarch64" => AARCH64_WHITELIST,
        "x86" | "x86_64" => X86_WHITELIST,
        "hexagon" => HEXAGON_WHITELIST,
        "mips" | "mips64" => MIPS_WHITELIST,
        "powerpc" | "powerpc64" => POWERPC_WHITELIST,
        _ => &[],
    }
}

pub fn print_version() {
    // Can be called without initializing LLVM
    unsafe {
        println!("LLVM version: {}.{}",
                 llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
    }
}

pub fn print_passes() {
    // Can be called without initializing LLVM
    unsafe { llvm::LLVMRustPrintPasses(); }
}

pub(crate) fn print(req: PrintRequest, sess: &Session) {
    require_inited();
    let tm = create_target_machine(sess);
    unsafe {
        match req {
            PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
            PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm),
            _ => bug!("rustc_trans can't handle print request: {:?}", req),
        }
    }
}
<commit_msg>Rollup merge of #48369 - newpavlov:rdrand, r=nagisa<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 syntax_pos::symbol::Symbol;
use back::write::create_target_machine;
use llvm;
use rustc::session::Session;
use rustc::session::config::PrintRequest;
use libc::c_int;
use std::ffi::CString;

use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Once;

static POISONED: AtomicBool = AtomicBool::new(false);
static INIT: Once = Once::new();

pub(crate) fn init(sess: &Session) {
    unsafe {
        // Before we touch LLVM, make sure that multithreading is enabled.
        INIT.call_once(|| {
            if llvm::LLVMStartMultithreaded() != 1 {
                // use an extra bool to make sure that all future usage of LLVM
                // cannot proceed despite the Once not running more than once.
                POISONED.store(true, Ordering::SeqCst);
            }

            configure_llvm(sess);
        });

        if POISONED.load(Ordering::SeqCst) {
            bug!("couldn't enable multi-threaded LLVM");
        }
    }
}

fn require_inited() {
    INIT.call_once(|| bug!("llvm is not initialized"));
    if POISONED.load(Ordering::SeqCst) {
        bug!("couldn't enable multi-threaded LLVM");
    }
}

unsafe fn configure_llvm(sess: &Session) {
    let mut llvm_c_strs = Vec::new();
    let mut llvm_args = Vec::new();

    {
        let mut add = |arg: &str| {
            let s = CString::new(arg).unwrap();
            llvm_args.push(s.as_ptr());
            llvm_c_strs.push(s);
        };
        add("rustc"); // fake program name
        if sess.time_llvm_passes() { add("-time-passes"); }
        if sess.print_llvm_passes() { add("-debug-pass=Structure"); }

        for arg in &sess.opts.cg.llvm_args {
            add(&(*arg));
        }
    }

    llvm::LLVMInitializePasses();

    llvm::initialize_available_targets();

    llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
                                 llvm_args.as_ptr());
}

// WARNING: the features after applying `to_llvm_feature` must be known
// to LLVM or the feature detection code will walk past the end of the feature
// array, leading to crashes.

const ARM_WHITELIST: &'static [&'static str] = &["neon", "v7", "vfp2", "vfp3", "vfp4"];

const AARCH64_WHITELIST: &'static [&'static str] = &["neon", "v7"];

const X86_WHITELIST: &'static [&'static str] = &["aes", "avx", "avx2", "avx512bw",
                                                 "avx512cd", "avx512dq", "avx512er",
                                                 "avx512f", "avx512ifma", "avx512pf",
                                                 "avx512vbmi", "avx512vl", "avx512vpopcntdq",
                                                 "bmi", "bmi2", "fma", "fxsr",
                                                 "lzcnt", "mmx", "pclmulqdq",
                                                 "popcnt", "rdrand", "rdseed",
                                                 "sse", "sse2", "sse3", "sse4.1",
                                                 "sse4.2", "sse4a", "ssse3",
                                                 "tbm", "xsave", "xsavec",
                                                 "xsaveopt", "xsaves"];

const HEXAGON_WHITELIST: &'static [&'static str] = &["hvx", "hvx-double"];

const POWERPC_WHITELIST: &'static [&'static str] = &["altivec",
                                                     "power8-altivec", "power9-altivec",
                                                     "power8-vector", "power9-vector",
                                                     "vsx"];

const MIPS_WHITELIST: &'static [&'static str] = &["msa"];

pub fn to_llvm_feature(s: &str) -> &str {
    match s {
        "pclmulqdq" => "pclmul",
        "rdrand" => "rdrnd",
        s => s,
    }
}

pub fn target_features(sess: &Session) -> Vec<Symbol> {
    let target_machine = create_target_machine(sess);
    target_feature_whitelist(sess)
        .iter()
        .filter(|feature| {
            let llvm_feature = to_llvm_feature(feature);
            let cstr = CString::new(llvm_feature).unwrap();
            unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) }
        })
        .map(|feature| Symbol::intern(feature)).collect()
}

pub fn target_feature_whitelist(sess: &Session) -> &'static [&'static str] {
    match &*sess.target.target.arch {
        "arm" => ARM_WHITELIST,
        "aarch64" => AARCH64_WHITELIST,
        "x86" | "x86_64" => X86_WHITELIST,
        "hexagon" => HEXAGON_WHITELIST,
        "mips" | "mips64" => MIPS_WHITELIST,
        "powerpc" | "powerpc64" => POWERPC_WHITELIST,
        _ => &[],
    }
}

pub fn print_version() {
    // Can be called without initializing LLVM
    unsafe {
        println!("LLVM version: {}.{}",
                 llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
    }
}

pub fn print_passes() {
    // Can be called without initializing LLVM
    unsafe { llvm::LLVMRustPrintPasses(); }
}

pub(crate) fn print(req: PrintRequest, sess: &Session) {
    require_inited();
    let tm = create_target_machine(sess);
    unsafe {
        match req {
            PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
            PrintRequest::TargetFeatures => llvm::LLVMRustPrintTargetFeatures(tm),
            _ => bug!("rustc_trans can't handle print request: {:?}", req),
        }
    }
}
<|endoftext|>