<commit_before>//! Contains utility functions to generate suggestions.
#![deny(missing_docs_in_private_items)]
// currently ignores lifetimes and generics
#![allow(use_self)]

use matches::matches;
use rustc::hir;
use rustc::lint::{EarlyContext, LateContext, LintContext};
use rustc_errors;
use std::borrow::Cow;
use std::fmt::Display;
use std;
use syntax::source_map::{CharPos, Span};
use syntax::parse::token;
use syntax::print::pprust::token_to_string;
use syntax::util::parser::AssocOp;
use syntax::ast;
use crate::utils::{higher, snippet, snippet_opt};
use syntax_pos::{BytePos, Pos};

/// A helper type to build suggestion correctly handling parenthesis.
pub enum Sugg<'a> {
    /// An expression that never needs parenthesis such as `1337` or `[0; 42]`.
    NonParen(Cow<'a, str>),
    /// An expression that does not fit in other variants.
    MaybeParen(Cow<'a, str>),
    /// A binary operator expression, including `as`-casts and explicit type
    /// coercion.
    BinOp(AssocOp, Cow<'a, str>),
}

/// Literal constant `1`, for convenience.
pub const ONE: Sugg<'static> = Sugg::NonParen(Cow::Borrowed("1"));

impl Display for Sugg<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        match *self {
            Sugg::NonParen(ref s) | Sugg::MaybeParen(ref s) | Sugg::BinOp(_, ref s) => s.fmt(f),
        }
    }
}

#[allow(wrong_self_convention)] // ok, because of the function `as_ty` method
impl<'a> Sugg<'a> {
    /// Prepare a suggestion from an expression.
    pub fn hir_opt(cx: &LateContext<'_, '_>, expr: &hir::Expr) -> Option<Self> {
        snippet_opt(cx, expr.span).map(|snippet| {
            let snippet = Cow::Owned(snippet);
            match expr.node {
                hir::ExprKind::AddrOf(..) |
                hir::ExprKind::Box(..) |
                hir::ExprKind::Closure(.., _) |
                hir::ExprKind::If(..) |
                hir::ExprKind::Unary(..) |
                hir::ExprKind::Match(..) => Sugg::MaybeParen(snippet),
                hir::ExprKind::Continue(..) |
                hir::ExprKind::Yield(..) |
                hir::ExprKind::Array(..) |
                hir::ExprKind::Block(..) |
                hir::ExprKind::Break(..) |
                hir::ExprKind::Call(..) |
                hir::ExprKind::Field(..) |
                hir::ExprKind::Index(..) |
                hir::ExprKind::InlineAsm(..) |
                hir::ExprKind::Lit(..) |
                hir::ExprKind::Loop(..) |
                hir::ExprKind::MethodCall(..) |
                hir::ExprKind::Path(..) |
                hir::ExprKind::Repeat(..) |
                hir::ExprKind::Ret(..) |
                hir::ExprKind::Struct(..) |
                hir::ExprKind::Tup(..) |
                hir::ExprKind::While(..) => Sugg::NonParen(snippet),
                hir::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet),
                hir::ExprKind::AssignOp(op, ..) => Sugg::BinOp(hirbinop2assignop(op), snippet),
                hir::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(higher::binop(op.node)), snippet),
                hir::ExprKind::Cast(..) => Sugg::BinOp(AssocOp::As, snippet),
                hir::ExprKind::Type(..) => Sugg::BinOp(AssocOp::Colon, snippet),
            }
        })
    }

    /// Convenience function around `hir_opt` for suggestions with a default
    /// text.
    pub fn hir(cx: &LateContext<'_, '_>, expr: &hir::Expr, default: &'a str) -> Self {
        Self::hir_opt(cx, expr).unwrap_or_else(|| Sugg::NonParen(Cow::Borrowed(default)))
    }

    /// Prepare a suggestion from an expression.
    pub fn ast(cx: &EarlyContext<'_>, expr: &ast::Expr, default: &'a str) -> Self {
        use syntax::ast::RangeLimits;

        let snippet = snippet(cx, expr.span, default);

        match expr.node {
            ast::ExprKind::AddrOf(..) |
            ast::ExprKind::Box(..) |
            ast::ExprKind::Closure(..) |
            ast::ExprKind::If(..) |
            ast::ExprKind::IfLet(..) |
            ast::ExprKind::ObsoleteInPlace(..) |
            ast::ExprKind::Unary(..) |
            ast::ExprKind::Match(..) => Sugg::MaybeParen(snippet),
            ast::ExprKind::Async(..) |
            ast::ExprKind::Block(..) |
            ast::ExprKind::Break(..) |
            ast::ExprKind::Call(..) |
            ast::ExprKind::Catch(..) |
            ast::ExprKind::Continue(..) |
            ast::ExprKind::Yield(..) |
            ast::ExprKind::Field(..) |
            ast::ExprKind::ForLoop(..) |
            ast::ExprKind::Index(..) |
            ast::ExprKind::InlineAsm(..) |
            ast::ExprKind::Lit(..) |
            ast::ExprKind::Loop(..) |
            ast::ExprKind::Mac(..) |
            ast::ExprKind::MethodCall(..) |
            ast::ExprKind::Paren(..) |
            ast::ExprKind::Path(..) |
            ast::ExprKind::Repeat(..) |
            ast::ExprKind::Ret(..) |
            ast::ExprKind::Struct(..) |
            ast::ExprKind::Try(..) |
            ast::ExprKind::Tup(..) |
            ast::ExprKind::Array(..) |
            ast::ExprKind::While(..) |
            ast::ExprKind::WhileLet(..) => Sugg::NonParen(snippet),
            ast::ExprKind::Range(.., RangeLimits::HalfOpen) => Sugg::BinOp(AssocOp::DotDot, snippet),
            ast::ExprKind::Range(.., RangeLimits::Closed) => Sugg::BinOp(AssocOp::DotDotEq, snippet),
            ast::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet),
            ast::ExprKind::AssignOp(op, ..) => Sugg::BinOp(astbinop2assignop(op), snippet),
            ast::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(op.node), snippet),
            ast::ExprKind::Cast(..) => Sugg::BinOp(AssocOp::As, snippet),
            ast::ExprKind::Type(..) => Sugg::BinOp(AssocOp::Colon, snippet),
        }
    }

    /// Convenience method to create the `<lhs> && <rhs>` suggestion.
    pub fn and(self, rhs: &Self) -> Sugg<'static> {
        make_binop(ast::BinOpKind::And, &self, rhs)<commit_msg>fix clippy breakage due to https://github.com/rust-lang/rust/pull/52602<commit_after>//! Contains utility functions to generate suggestions.
#![deny(missing_docs_in_private_items)]
// currently ignores lifetimes and generics
#![allow(use_self)]

use matches::matches;
use rustc::hir;
use rustc::lint::{EarlyContext, LateContext, LintContext};
use rustc_errors;
use std::borrow::Cow;
use std::fmt::Display;
use std;
use syntax::source_map::{CharPos, Span};
use syntax::parse::token;
use syntax::print::pprust::token_to_string;
use syntax::util::parser::AssocOp;
use syntax::ast;
use crate::utils::{higher, snippet, snippet_opt};
use syntax_pos::{BytePos, Pos};

/// A helper type to build suggestion correctly handling parenthesis.
pub enum Sugg<'a> {
    /// An expression that never needs parenthesis such as `1337` or `[0; 42]`.
    NonParen(Cow<'a, str>),
    /// An expression that does not fit in other variants.
    MaybeParen(Cow<'a, str>),
    /// A binary operator expression, including `as`-casts and explicit type
    /// coercion.
    BinOp(AssocOp, Cow<'a, str>),
}

/// Literal constant `1`, for convenience.
pub const ONE: Sugg<'static> = Sugg::NonParen(Cow::Borrowed("1"));

impl Display for Sugg<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        match *self {
            Sugg::NonParen(ref s) | Sugg::MaybeParen(ref s) | Sugg::BinOp(_, ref s) => s.fmt(f),
        }
    }
}

#[allow(wrong_self_convention)] // ok, because of the function `as_ty` method
impl<'a> Sugg<'a> {
    /// Prepare a suggestion from an expression.
    pub fn hir_opt(cx: &LateContext<'_, '_>, expr: &hir::Expr) -> Option<Self> {
        snippet_opt(cx, expr.span).map(|snippet| {
            let snippet = Cow::Owned(snippet);
            match expr.node {
                hir::ExprKind::AddrOf(..) |
                hir::ExprKind::Box(..) |
                hir::ExprKind::Closure(.., _) |
                hir::ExprKind::If(..) |
                hir::ExprKind::Unary(..) |
                hir::ExprKind::Match(..) => Sugg::MaybeParen(snippet),
                hir::ExprKind::Continue(..) |
                hir::ExprKind::Yield(..) |
                hir::ExprKind::Array(..) |
                hir::ExprKind::Block(..) |
                hir::ExprKind::Break(..) |
                hir::ExprKind::Call(..) |
                hir::ExprKind::Field(..) |
                hir::ExprKind::Index(..) |
                hir::ExprKind::InlineAsm(..) |
                hir::ExprKind::Lit(..) |
                hir::ExprKind::Loop(..) |
                hir::ExprKind::MethodCall(..) |
                hir::ExprKind::Path(..) |
                hir::ExprKind::Repeat(..) |
                hir::ExprKind::Ret(..) |
                hir::ExprKind::Struct(..) |
                hir::ExprKind::Tup(..) |
                hir::ExprKind::While(..) => Sugg::NonParen(snippet),
                hir::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet),
                hir::ExprKind::AssignOp(op, ..) => Sugg::BinOp(hirbinop2assignop(op), snippet),
                hir::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(higher::binop(op.node)), snippet),
                hir::ExprKind::Cast(..) => Sugg::BinOp(AssocOp::As, snippet),
                hir::ExprKind::Type(..) => Sugg::BinOp(AssocOp::Colon, snippet),
            }
        })
    }

    /// Convenience function around `hir_opt` for suggestions with a default
    /// text.
    pub fn hir(cx: &LateContext<'_, '_>, expr: &hir::Expr, default: &'a str) -> Self {
        Self::hir_opt(cx, expr).unwrap_or_else(|| Sugg::NonParen(Cow::Borrowed(default)))
    }

    /// Prepare a suggestion from an expression.
    pub fn ast(cx: &EarlyContext<'_>, expr: &ast::Expr, default: &'a str) -> Self {
        use syntax::ast::RangeLimits;

        let snippet = snippet(cx, expr.span, default);

        match expr.node {
            ast::ExprKind::AddrOf(..) |
            ast::ExprKind::Box(..) |
            ast::ExprKind::Closure(..) |
            ast::ExprKind::If(..) |
            ast::ExprKind::IfLet(..) |
            ast::ExprKind::ObsoleteInPlace(..) |
            ast::ExprKind::Unary(..) |
            ast::ExprKind::Match(..) => Sugg::MaybeParen(snippet),
            ast::ExprKind::Async(..) |
            ast::ExprKind::Block(..) |
            ast::ExprKind::Break(..) |
            ast::ExprKind::Call(..) |
            ast::ExprKind::Continue(..) |
            ast::ExprKind::Yield(..) |
            ast::ExprKind::Field(..) |
            ast::ExprKind::ForLoop(..) |
            ast::ExprKind::Index(..) |
            ast::ExprKind::InlineAsm(..) |
            ast::ExprKind::Lit(..) |
            ast::ExprKind::Loop(..) |
            ast::ExprKind::Mac(..) |
            ast::ExprKind::MethodCall(..) |
            ast::ExprKind::Paren(..) |
            ast::ExprKind::Path(..) |
            ast::ExprKind::Repeat(..) |
            ast::ExprKind::Ret(..) |
            ast::ExprKind::Struct(..) |
            ast::ExprKind::Try(..) |
            ast::ExprKind::TryBlock(..) |
            ast::ExprKind::Tup(..) |
            ast::ExprKind::Array(..) |
            ast::ExprKind::While(..) |
            ast::ExprKind::WhileLet(..) => Sugg::NonParen(snippet),
            ast::ExprKind::Range(.., RangeLimits::HalfOpen) => Sugg::BinOp(AssocOp::DotDot, snippet),
            ast::ExprKind::Range(.., RangeLimits::Closed) => Sugg::BinOp(AssocOp::DotDotEq, snippet),
            ast::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet),
            ast::ExprKind::AssignOp(op, ..) => Sugg::BinOp(astbinop2assignop(op), snippet),
            ast::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(op.node), snippet),
            ast::ExprKind::Cast(..) => Sugg::BinOp(AssocOp::As, snippet),
            ast::ExprKind::Type(..) => Sugg::BinOp(AssocOp::Colon, snippet),
        }
    }

    /// Convenience method to create the `<lhs> && <rhs>` suggestion.
    pub fn and(self, rhs: &Self) -> Sugg<'static> {
        make_binop(ast::BinOpKind::And, &self, rhs)
{'fraction_non_alphanumeric': 0.19613510611941531, 'fraction_numerical': 0.00222974646956809, 'mean_word_length': 2.326923076923077, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 81, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6587943', 'n_tokens_mistral': 4116, 'n_tokens_neox': 3941, 'n_words': 650}