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

use core::prelude::*;

use ast::*;
use ast;
use ast_util;
use codemap::{span, BytePos, dummy_sp};
use parse::token;
use visit;

use core::cmp;
use core::int;
use core::option;
use core::str;
use core::to_bytes;
use core::vec;

pub pure fn path_name_i(idents: &[ident], intr: @token::ident_interner)
                     -> ~str {
    // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
    str::connect(idents.map(|i| *intr.get(*i)), ~"::")
}


pub pure fn path_to_ident(p: @path) -> ident { vec::last(p.idents) }

pub pure fn local_def(id: node_id) -> def_id {
    ast::def_id { crate: local_crate, node: id }
}

pub pure fn is_local(did: ast::def_id) -> bool { did.crate == local_crate }

pub pure fn stmt_id(s: stmt) -> node_id {
    match s.node {
      stmt_decl(_, id) => id,
      stmt_expr(_, id) => id,
      stmt_semi(_, id) => id,
      stmt_mac(*) => die!(~"attempted to analyze unexpanded stmt")
    }
}

pub fn variant_def_ids(d: def) -> {enm: def_id, var: def_id} {
    match d {
      def_variant(enum_id, var_id) => {
        return {enm: enum_id, var: var_id}
      }
      _ => die!(~"non-variant in variant_def_ids")
    }
}

pub pure fn def_id_of_def(d: def) -> def_id {
    match d {
      def_fn(id, _) | def_static_method(id, _, _) | def_mod(id) |
      def_foreign_mod(id) | def_const(id) |
      def_variant(_, id) | def_ty(id) | def_ty_param(id, _) |
      def_use(id) | def_struct(id) => {
        id
      }
      def_arg(id, _, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id)
      | def_upvar(id, _, _, _) | def_binding(id, _) | def_region(id)
      | def_typaram_binder(id) | def_label(id) => {
        local_def(id)
      }

      def_prim_ty(_) => die!()
    }
}

pub pure fn binop_to_str(op: binop) -> ~str {
    match op {
      add => return ~"+",
      subtract => return ~"-",
      mul => return ~"*",
      div => return ~"/",
      rem => return ~"%",
      and => return ~"&&",
      or => return ~"||",
      bitxor => return ~"^",
      bitand => return ~"&",
      bitor => return ~"|",
      shl => return ~"<<",
      shr => return ~">>",
      eq => return ~"==",
      lt => return ~"<",
      le => return ~"<=",
      ne => return ~"!=",
      ge => return ~">=",
      gt => return ~">"
    }
}

pub pure fn binop_to_method_name(op: binop) -> Option<~str> {
    match op {
      add => return Some(~"add"),
      subtract => return Some(~"sub"),
      mul => return Some(~"mul"),
      div => return Some(~"div"),
      rem => return Some(~"modulo"),
      bitxor => return Some(~"bitxor"),
      bitand => return Some(~"bitand"),
      bitor => return Some(~"bitor"),
      shl => return Some(~"shl"),
      shr => return Some(~"shr"),
      lt => return Some(~"lt"),
      le => return Some(~"le"),
      ge => return Some(~"ge"),
      gt => return Some(~"gt"),
      eq => return Some(~"eq"),
      ne => return Some(~"ne"),
      and | or => return None
    }
}

pub pure fn lazy_binop(b: binop) -> bool {
    match b {
      and => true,
      or => true,
      _ => false
    }
}

pub pure fn is_shift_binop(b: binop) -> bool {
    match b {
      shl => true,
      shr => true,
      _ => false
    }
}

pub pure fn unop_to_str(op: unop) -> ~str {
    match op {
      box(mt) => if mt == m_mutbl { ~"@mut " } else { ~"@" },
      uniq(mt) => if mt == m_mutbl { ~"~mut " } else { ~"~" },
      deref => ~"*",
      not => ~"!",
      neg => ~"-"
    }
}

pub pure fn is_path(e: @expr) -> bool {
    return match e.node { expr_path(_) => true, _ => false };
}

pub pure fn int_ty_to_str(t: int_ty) -> ~str {
    match t {
      ty_char => ~"u8", // ???
      ty_i => ~"",
      ty_i8 => ~"i8",
      ty_i16 => ~"i16",
      ty_i32 => ~"i32",
      ty_i64 => ~"i64"
    }
}

pub pure fn int_ty_max(t: int_ty) -> u64 {
    match t {
      ty_i8 => 0x80u64,
      ty_i16 => 0x8000u64,
      ty_i | ty_char | ty_i32 => 0x80000000u64, // actually ni about ty_i
      ty_i64 => 0x8000000000000000u64
    }
}

pub pure fn uint_ty_to_str(t: uint_ty) -> ~str {
    match t {
      ty_u => ~"u",
      ty_u8 => ~"u8",
      ty_u16 => ~"u16",
      ty_u32 => ~"u32",
      ty_u64 => ~"u64"
    }
}

pub pure fn uint_ty_max(t: uint_ty) -> u64 {
    match t {
      ty_u8 => 0xffu64,
      ty_u16 => 0xffffu64,
      ty_u | ty_u32 => 0xffffffffu64, // actually ni about ty_u
      ty_u64 => 0xffffffffffffffffu64
    }
}

pub pure fn float_ty_to_str(t: float_ty) -> ~str {
    match t { ty_f => ~"f", ty_f32 => ~"f32", ty_f64 => ~"f64" }
}

pub pure fn is_call_expr(e: @expr) -> bool {
    match e.node { expr_call(_, _, _) => true, _ => false }
}

// This makes def_id hashable
pub impl def_id : to_bytes::IterBytes {
    #[inline(always)]
    pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
        to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f);
    }
}

pub fn block_from_expr(e: @expr) -> blk {
    let blk_ = default_block(~[], option::Some::<@expr>(e), e.id);
    return spanned {node: blk_, span: e.span};
}

pub fn default_block(
    +stmts1: ~[@stmt],
    expr1: Option<@expr>,
    id1: node_id
) -> blk_ {
    ast::blk_ {
        view_items: ~[],
        stmts: stmts1,
        expr: expr1,
        id: id1,
        rules: default_blk,
    }
}

pub fn ident_to_path(s: span, +i: ident) -> @path {
    @ast::path { span: s,
                 global: false,
                 idents: ~[i],
                 rp: None,
                 types: ~[] }
}

pub fn ident_to_pat(id: node_id, s: span, +i: ident) -> @pat {
    @ast::pat { id: id,
                node: pat_ident(bind_by_copy, ident_to_path(s, i), None),
                span: s }
}

pub pure fn is_unguarded(a: &arm) -> bool {
    match a.guard {
      None => true,
      _    => false
    }
}

pub pure fn unguarded_pat(a: &arm) -> Option<~[@pat]> {
    if is_unguarded(a) { Some(/* FIXME (#2543) */ copy a.pats) } else { None }
}

pub fn public_methods(ms: ~[@method]) -> ~[@method] {
    do ms.filtered |m| {
        match m.vis {
            public => true,
            _   => false
        }
    }
}

// extract a ty_method from a trait_method. if the trait_method is
// a default, pull out the useful fields to make a ty_method
pub fn trait_method_to_ty_method(method: trait_method) -> ty_method {
    match method {
        required(ref m) => (*m),
        provided(m) => {
            ty_method {
                ident: m.ident,
                attrs: m.attrs,
                purity: m.purity,
                decl: m.decl,
                tps: m.tps,
                self_ty: m.self_ty,
                id: m.id,
                span: m.span,
            }
        }
    }
}

pub fn split_trait_methods(trait_methods: ~[trait_method])
    -> (~[ty_method], ~[@method]) {
    let mut reqd = ~[], provd = ~[];
    for trait_methods.each |trt_method| {
        match *trt_method {
          required(ref tm) => reqd.push((*tm)),
          provided(m) => provd.push(m)
        }
    };
    (reqd, provd)
}

pub pure fn struct_field_visibility(field: ast::struct_field) -> visibility {
    match field.node.kind {
        ast::named_field(_, _, visibility) => visibility,
        ast::unnamed_field => ast::public
    }
}

pub trait inlined_item_utils {
    fn ident() -> ident;
    fn id() -> ast::node_id;
    fn accept<E>(e: E, v: visit::vt<E>);
}

pub impl inlined_item: inlined_item_utils {
    fn ident() -> ident {
        match self {
          ii_item(i) => /* FIXME (#2543) */ copy i.ident,
          ii_foreign(i) => /* FIXME (#2543) */ copy i.ident,
          ii_method(_, m) => /* FIXME (#2543) */ copy m.ident,
          ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm
        }
    }

    fn id() -> ast::node_id {
        match self {
          ii_item(i) => i.id,
          ii_foreign(i) => i.id,
          ii_method(_, m) => m.id,
          ii_dtor(ref dtor, _, _, _) => (*dtor).node.id
        }
    }

    fn accept<E>(e: E, v: visit::vt<E>) {
        match self {
          ii_item(i) => (v.visit_item)(i, e, v),
          ii_foreign(i) => (v.visit_foreign_item)(i, e, v),
          ii_method(_, m) => visit::visit_method_helper(m, e, v),
          ii_dtor(ref dtor, _, tps, parent_id) => {
              visit::visit_struct_dtor_helper((*dtor), tps, parent_id, e, v);
          }
        }
    }<commit_msg>libsyntax: Add explicit self to ast_util. rs=explicit-selfing<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::prelude::*;

use ast::*;
use ast;
use ast_util;
use codemap::{span, BytePos, dummy_sp};
use parse::token;
use visit;

use core::cmp;
use core::int;
use core::option;
use core::str;
use core::to_bytes;
use core::vec;

pub pure fn path_name_i(idents: &[ident], intr: @token::ident_interner)
                     -> ~str {
    // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
    str::connect(idents.map(|i| *intr.get(*i)), ~"::")
}


pub pure fn path_to_ident(p: @path) -> ident { vec::last(p.idents) }

pub pure fn local_def(id: node_id) -> def_id {
    ast::def_id { crate: local_crate, node: id }
}

pub pure fn is_local(did: ast::def_id) -> bool { did.crate == local_crate }

pub pure fn stmt_id(s: stmt) -> node_id {
    match s.node {
      stmt_decl(_, id) => id,
      stmt_expr(_, id) => id,
      stmt_semi(_, id) => id,
      stmt_mac(*) => die!(~"attempted to analyze unexpanded stmt")
    }
}

pub fn variant_def_ids(d: def) -> {enm: def_id, var: def_id} {
    match d {
      def_variant(enum_id, var_id) => {
        return {enm: enum_id, var: var_id}
      }
      _ => die!(~"non-variant in variant_def_ids")
    }
}

pub pure fn def_id_of_def(d: def) -> def_id {
    match d {
      def_fn(id, _) | def_static_method(id, _, _) | def_mod(id) |
      def_foreign_mod(id) | def_const(id) |
      def_variant(_, id) | def_ty(id) | def_ty_param(id, _) |
      def_use(id) | def_struct(id) => {
        id
      }
      def_arg(id, _, _) | def_local(id, _) | def_self(id, _) | def_self_ty(id)
      | def_upvar(id, _, _, _) | def_binding(id, _) | def_region(id)
      | def_typaram_binder(id) | def_label(id) => {
        local_def(id)
      }

      def_prim_ty(_) => die!()
    }
}

pub pure fn binop_to_str(op: binop) -> ~str {
    match op {
      add => return ~"+",
      subtract => return ~"-",
      mul => return ~"*",
      div => return ~"/",
      rem => return ~"%",
      and => return ~"&&",
      or => return ~"||",
      bitxor => return ~"^",
      bitand => return ~"&",
      bitor => return ~"|",
      shl => return ~"<<",
      shr => return ~">>",
      eq => return ~"==",
      lt => return ~"<",
      le => return ~"<=",
      ne => return ~"!=",
      ge => return ~">=",
      gt => return ~">"
    }
}

pub pure fn binop_to_method_name(op: binop) -> Option<~str> {
    match op {
      add => return Some(~"add"),
      subtract => return Some(~"sub"),
      mul => return Some(~"mul"),
      div => return Some(~"div"),
      rem => return Some(~"modulo"),
      bitxor => return Some(~"bitxor"),
      bitand => return Some(~"bitand"),
      bitor => return Some(~"bitor"),
      shl => return Some(~"shl"),
      shr => return Some(~"shr"),
      lt => return Some(~"lt"),
      le => return Some(~"le"),
      ge => return Some(~"ge"),
      gt => return Some(~"gt"),
      eq => return Some(~"eq"),
      ne => return Some(~"ne"),
      and | or => return None
    }
}

pub pure fn lazy_binop(b: binop) -> bool {
    match b {
      and => true,
      or => true,
      _ => false
    }
}

pub pure fn is_shift_binop(b: binop) -> bool {
    match b {
      shl => true,
      shr => true,
      _ => false
    }
}

pub pure fn unop_to_str(op: unop) -> ~str {
    match op {
      box(mt) => if mt == m_mutbl { ~"@mut " } else { ~"@" },
      uniq(mt) => if mt == m_mutbl { ~"~mut " } else { ~"~" },
      deref => ~"*",
      not => ~"!",
      neg => ~"-"
    }
}

pub pure fn is_path(e: @expr) -> bool {
    return match e.node { expr_path(_) => true, _ => false };
}

pub pure fn int_ty_to_str(t: int_ty) -> ~str {
    match t {
      ty_char => ~"u8", // ???
      ty_i => ~"",
      ty_i8 => ~"i8",
      ty_i16 => ~"i16",
      ty_i32 => ~"i32",
      ty_i64 => ~"i64"
    }
}

pub pure fn int_ty_max(t: int_ty) -> u64 {
    match t {
      ty_i8 => 0x80u64,
      ty_i16 => 0x8000u64,
      ty_i | ty_char | ty_i32 => 0x80000000u64, // actually ni about ty_i
      ty_i64 => 0x8000000000000000u64
    }
}

pub pure fn uint_ty_to_str(t: uint_ty) -> ~str {
    match t {
      ty_u => ~"u",
      ty_u8 => ~"u8",
      ty_u16 => ~"u16",
      ty_u32 => ~"u32",
      ty_u64 => ~"u64"
    }
}

pub pure fn uint_ty_max(t: uint_ty) -> u64 {
    match t {
      ty_u8 => 0xffu64,
      ty_u16 => 0xffffu64,
      ty_u | ty_u32 => 0xffffffffu64, // actually ni about ty_u
      ty_u64 => 0xffffffffffffffffu64
    }
}

pub pure fn float_ty_to_str(t: float_ty) -> ~str {
    match t { ty_f => ~"f", ty_f32 => ~"f32", ty_f64 => ~"f64" }
}

pub pure fn is_call_expr(e: @expr) -> bool {
    match e.node { expr_call(_, _, _) => true, _ => false }
}

// This makes def_id hashable
pub impl def_id : to_bytes::IterBytes {
    #[inline(always)]
    pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
        to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f);
    }
}

pub fn block_from_expr(e: @expr) -> blk {
    let blk_ = default_block(~[], option::Some::<@expr>(e), e.id);
    return spanned {node: blk_, span: e.span};
}

pub fn default_block(
    +stmts1: ~[@stmt],
    expr1: Option<@expr>,
    id1: node_id
) -> blk_ {
    ast::blk_ {
        view_items: ~[],
        stmts: stmts1,
        expr: expr1,
        id: id1,
        rules: default_blk,
    }
}

pub fn ident_to_path(s: span, +i: ident) -> @path {
    @ast::path { span: s,
                 global: false,
                 idents: ~[i],
                 rp: None,
                 types: ~[] }
}

pub fn ident_to_pat(id: node_id, s: span, +i: ident) -> @pat {
    @ast::pat { id: id,
                node: pat_ident(bind_by_copy, ident_to_path(s, i), None),
                span: s }
}

pub pure fn is_unguarded(a: &arm) -> bool {
    match a.guard {
      None => true,
      _    => false
    }
}

pub pure fn unguarded_pat(a: &arm) -> Option<~[@pat]> {
    if is_unguarded(a) { Some(/* FIXME (#2543) */ copy a.pats) } else { None }
}

pub fn public_methods(ms: ~[@method]) -> ~[@method] {
    do ms.filtered |m| {
        match m.vis {
            public => true,
            _   => false
        }
    }
}

// extract a ty_method from a trait_method. if the trait_method is
// a default, pull out the useful fields to make a ty_method
pub fn trait_method_to_ty_method(method: trait_method) -> ty_method {
    match method {
        required(ref m) => (*m),
        provided(m) => {
            ty_method {
                ident: m.ident,
                attrs: m.attrs,
                purity: m.purity,
                decl: m.decl,
                tps: m.tps,
                self_ty: m.self_ty,
                id: m.id,
                span: m.span,
            }
        }
    }
}

pub fn split_trait_methods(trait_methods: ~[trait_method])
    -> (~[ty_method], ~[@method]) {
    let mut reqd = ~[], provd = ~[];
    for trait_methods.each |trt_method| {
        match *trt_method {
          required(ref tm) => reqd.push((*tm)),
          provided(m) => provd.push(m)
        }
    };
    (reqd, provd)
}

pub pure fn struct_field_visibility(field: ast::struct_field) -> visibility {
    match field.node.kind {
        ast::named_field(_, _, visibility) => visibility,
        ast::unnamed_field => ast::public
    }
}

pub trait inlined_item_utils {
    fn ident(&self) -> ident;
    fn id(&self) -> ast::node_id;
    fn accept<E>(&self, e: E, v: visit::vt<E>);
}

pub impl inlined_item: inlined_item_utils {
    fn ident(&self) -> ident {
        match *self {
            ii_item(i) => /* FIXME (#2543) */ copy i.ident,
            ii_foreign(i) => /* FIXME (#2543) */ copy i.ident,
            ii_method(_, m) => /* FIXME (#2543) */ copy m.ident,
            ii_dtor(_, nm, _, _) => /* FIXME (#2543) */ copy nm
        }
    }

    fn id(&self) -> ast::node_id {
        match *self {
            ii_item(i) => i.id,
            ii_foreign(i) => i.id,
            ii_method(_, m) => m.id,
            ii_dtor(ref dtor, _, _, _) => (*dtor).node.id
        }
    }

    fn accept<E>(&self, e: E, v: visit::vt<E>) {
        match *self {
            ii_item(i) => (v.visit_item)(i, e, v),
            ii_foreign(i) => (v.visit_foreign_item)(i, e, v),
            ii_method(_, m) => visit::visit_method_helper(m, e, v),
            ii_dtor(ref dtor, _, tps, parent_id) => {
              visit::visit_struct_dtor_helper((*dtor), tps, parent_id, e, v);
            }
        }
    }
{'fraction_non_alphanumeric': 0.17382204875841395, 'fraction_numerical': 0.016969285593076533, 'mean_word_length': 2.1498307500445395, 'pattern_counts': {'":': 2, '<': 31, '<?xml version=': 0, '>': 303, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 8, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4480268', 'n_tokens_mistral': 6900, 'n_tokens_neox': 6665, 'n_words': 1566}