fn search_scope_headers(point: usize, scopestart: usize, msrc: &str, searchstr: &str,
                        filepath: &Path, search_type: SearchType,
                        local: bool) -> vec::IntoIter<Match> {
    debug!("search_scope_headers for |{}| pt: {}", searchstr, scopestart);
    if let Some(stmtstart) = scopes::find_stmt_start(msrc, scopestart) {
        let preblock = &msrc[stmtstart..scopestart];
        debug!("PHIL search_scope_headers preblock is |{}|", preblock);

        if preblock.starts_with("fn") || preblock.starts_with("pub fn") {
            return search_fn_args(stmtstart, scopestart, msrc, searchstr, filepath, search_type, local);

        // 'if let' can be an expression, so might not be at the start of the stmt
        } else if let Some(n) = preblock.find("if let") {
            let ifletstart = stmtstart + n;
            let s = (&msrc[ifletstart..scopestart+1]).to_string() + "}";
            if txt_matches(search_type, searchstr, &*s) {
                let mut out = matchers::match_if_let(&*s, 0, s.len(), searchstr,
                                                     filepath, search_type, local);
                for m in out.iter_mut() {
                    m.point += ifletstart;
                }
                return out.into_iter();
            }
        } else if let Some(n) = util::find_last_str("match ", preblock) {
            // TODO: this code is crufty. refactor me!
            let matchstart = stmtstart + n;
            let matchstmt = typeinf::get_first_stmt(&msrc[matchstart..]);
            // The definition could be in the match LHS arms. Try to find this
            debug!("PHIL found a match statement, examining match arms (len {}) |{}|",
                   matchstmt.len(), matchstmt);

            let masked_matchstmt = mask_matchstmt(matchstmt, scopestart+1 - matchstart);
            debug!("PHIL masked match stmt is len {} |{}|", masked_matchstmt.len(), masked_matchstmt);

            // Locate the match arm LHS by finding the => just before point and then backtracking
            let mut rhs = &*masked_matchstmt;
            let mut arm = 0;
            while let Some(n) = rhs.find("=>") {
                debug!("PHIL match arm n is {}, {}, {}, {}", arm, n, matchstart, point);
                if arm + n + matchstart > point {
                    break;
                } else {
                    arm += n + 2;
                    rhs = &rhs[n+2..];
                }
            }
            debug!("PHIL matched arm rhs is |{}|", &masked_matchstmt[arm-2..]);

            let lhs_start = scopes::get_start_of_pattern(msrc, matchstart + arm -2);
            let lhs = &msrc[lhs_start..matchstart + arm - 2];

            // Now create a pretend match expression with just the one match arm in it
            let mut fauxmatchstmt = (&msrc[matchstart..scopestart]).to_string();
            fauxmatchstmt = fauxmatchstmt + "{";
            let faux_prefix_size = fauxmatchstmt.len();
            fauxmatchstmt = fauxmatchstmt + lhs + " => () };";

            debug!("PHIL arm lhs is |{}|", lhs);
            debug!("PHIL arm fauxmatchstmt is |{}|, {}", fauxmatchstmt, faux_prefix_size);
            let mut out = Vec::new();
            for &(start,end) in ast::parse_pat_idents(fauxmatchstmt).iter() {
                let (start,end) = (lhs_start + start - faux_prefix_size,
                                   lhs_start + end - faux_prefix_size);
                let s = &msrc[start..end];

                if symbol_matches(search_type, searchstr, s) {
                    out.push(Match {
                                    matchstr: s.to_string(),
                                    filepath: filepath.to_path_buf(),
                                    point: start,
                                    local: local,
                                    mtype: MatchArm,
                                    contextstr: lhs.trim().to_string(),
                                    generic_args: Vec::new(),
                                    generic_types: Vec::new()
                    });
                    if let SearchType::ExactMatch = search_type {
                        break;
                    }
                }
            }
            return out.into_iter();
        }
    }

    Vec::new().into_iter()
}
// scope headers include fn decls, if let, while let etc..
scope headers include fn decls, if let, while let etc
scope headers include fn decls if let while let etc
fn search_scope_headers(point: usize, scopestart: usize, msrc: &str, searchstr: &str,
                        filepath: &Path, search_type: SearchType,
                        local: bool) -> vec::IntoIter<Match> {
    debug!("search_scope_headers for |{}| pt: {}", searchstr, scopestart);
    if let Some(stmtstart) = scopes::find_stmt_start(msrc, scopestart) {
        let preblock = &msrc[stmtstart..scopestart];
        debug!("PHIL search_scope_headers preblock is |{}|", preblock);
        if preblock.starts_with("fn") || preblock.starts_with("pub fn") {
            return search_fn_args(stmtstart, scopestart, msrc, searchstr, filepath, search_type, local);
        // 'if let' can be an expression, so might not be at the start of the stmt
        } else if let Some(n) = preblock.find("if let") {
            let ifletstart = stmtstart + n;
            let s = (&msrc[ifletstart..scopestart+1]).to_string() + "}";
            if txt_matches(search_type, searchstr, &*s) {
                let mut out = matchers::match_if_let(&*s, 0, s.len(), searchstr,
                                                     filepath, search_type, local);
                for m in out.iter_mut() {
                    m.point += ifletstart;
                }
                return out.into_iter();
            }
        } else if let Some(n) = util::find_last_str("match ", preblock) {
            // TODO: this code is crufty. refactor me!
            let matchstart = stmtstart + n;
            let matchstmt = typeinf::get_first_stmt(&msrc[matchstart..]);
            // The definition could be in the match LHS arms. Try to find this
            debug!("PHIL found a match statement, examining match arms (len {}) |{}|",
                   matchstmt.len(), matchstmt);
            let masked_matchstmt = mask_matchstmt(matchstmt, scopestart+1 - matchstart);
            debug!("PHIL masked match stmt is len {} |{}|", masked_matchstmt.len(), masked_matchstmt);
            // Locate the match arm LHS by finding the => just before point and then backtracking
            let mut rhs = &*masked_matchstmt;
            let mut arm = 0;
            while let Some(n) = rhs.find("=>") {
                debug!("PHIL match arm n is {}, {}, {}, {}", arm, n, matchstart, point);
                if arm + n + matchstart > point {
                    break;
                } else {
                    arm += n + 2;
                    rhs = &rhs[n+2..];
                }
            }
            debug!("PHIL matched arm rhs is |{}|", &masked_matchstmt[arm-2..]);
            let lhs_start = scopes::get_start_of_pattern(msrc, matchstart + arm -2);
            let lhs = &msrc[lhs_start..matchstart + arm - 2];
            // Now create a pretend match expression with just the one match arm in it
            let mut fauxmatchstmt = (&msrc[matchstart..scopestart]).to_string();
            fauxmatchstmt = fauxmatchstmt + "{";
            let faux_prefix_size = fauxmatchstmt.len();
            fauxmatchstmt = fauxmatchstmt + lhs + " => () };";
            debug!("PHIL arm lhs is |{}|", lhs);
            debug!("PHIL arm fauxmatchstmt is |{}|, {}", fauxmatchstmt, faux_prefix_size);
            let mut out = Vec::new();
            for &(start,end) in ast::parse_pat_idents(fauxmatchstmt).iter() {
                let (start,end) = (lhs_start + start - faux_prefix_size,
                                   lhs_start + end - faux_prefix_size);
                let s = &msrc[start..end];
                if symbol_matches(search_type, searchstr, s) {
                    out.push(Match {
                                    matchstr: s.to_string(),
                                    filepath: filepath.to_path_buf(),
                                    point: start,
                                    local: local,
                                    mtype: MatchArm,
                                    contextstr: lhs.trim().to_string(),
                                    generic_args: Vec::new(),
                                    generic_types: Vec::new()
                    });
                    if let SearchType::ExactMatch = search_type {
                        break;
                    }
                }
            }
            return out.into_iter();
        }
    }
    Vec::new().into_iter()
}
fn search_scope_headers ( point : usize , scopestart : usize , msrc : & str , searchstr : & str , filepath : & Path , search_type : SearchType , local : bool ) -> vec :: IntoIter < Match > { debug ! ( " " searchstr scopestart ) ; if let Some ( stmtstart ) = scopes :: find_stmt_start ( msrc , scopestart ) { let preblock = & msrc [ stmtstart .. scopestart ] ; debug ! ( " " preblock ) ; if preblock . starts_with ( " " ) || preblock . starts_with ( " " ) { return search_fn_args ( stmtstart , scopestart , msrc , searchstr , filepath , search_type , local ) ; // 'if let' can be an expression, so might not be at the start of the stmt } else if let Some ( n ) = preblock . find ( " " ) { let ifletstart = stmtstart + n ; let s = ( & msrc [ ifletstart .. scopestart + 1 ] ) . to_string ( ) + " " ; if txt_matches ( search_type , searchstr , & * s ) { let mut out = matchers :: match_if_let ( & * s , 0 , s . len ( ) , searchstr , filepath , search_type , local ) ; for m in out . iter_mut ( ) { m . point += ifletstart ; } return out . into_iter ( ) ; } } else if let Some ( n ) = util :: find_last_str ( " " , preblock ) { // TODO: this code is crufty. refactor me! let matchstart = stmtstart + n ; let matchstmt = typeinf :: get_first_stmt ( & msrc [ matchstart .. ] ) ; // The definition could be in the match LHS arms. Try to find this debug ! ( " " matchstmt len ( ) matchstmt ) ; let masked_matchstmt = mask_matchstmt ( matchstmt , scopestart + 1 - matchstart ) ; debug ! ( " " masked_matchstmt len ( ) masked_matchstmt ) ; // Locate the match arm LHS by finding the => just before point and then backtracking let mut rhs = & * masked_matchstmt ; let mut arm = 0 ; while let Some ( n ) = rhs . find ( " " ) { debug ! ( " " arm n matchstart point ) ; if arm + n + matchstart > point { break ; } else { arm += n + 2 ; rhs = & rhs [ n + 2 .. ] ; } } debug ! ( " " masked_matchstmt [ arm 2 ] ) ; let lhs_start = scopes :: get_start_of_pattern ( msrc , matchstart + arm - 2 ) ; let lhs = & msrc [ lhs_start .. matchstart + arm - 2 ] ; // Now create a pretend match expression with just the one match arm in it let mut fauxmatchstmt = ( & msrc [ matchstart .. scopestart ] ) . to_string ( ) ; fauxmatchstmt = fauxmatchstmt + " " ; let faux_prefix_size = fauxmatchstmt . len ( ) ; fauxmatchstmt = fauxmatchstmt + lhs + " " ; debug ! ( " " lhs ) ; debug ! ( " " fauxmatchstmt faux_prefix_size ) ; let mut out = Vec :: new ( ) ; for & ( start , end ) in ast :: parse_pat_idents ( fauxmatchstmt ) . iter ( ) { let ( start , end ) = ( lhs_start + start - faux_prefix_size , lhs_start + end - faux_prefix_size ) ; let s = & msrc [ start .. end ] ; if symbol_matches ( search_type , searchstr , s ) { out . push ( Match { matchstr : s . to_string ( ) , filepath : filepath . to_path_buf ( ) , point : start , local : local , mtype : MatchArm , contextstr : lhs . trim ( ) . to_string ( ) , generic_args : Vec :: new ( ) , generic_types : Vec :: new ( ) } ) ; if let SearchType :: ExactMatch = search_type { break ; } } } return out . into_iter ( ) ; } } Vec :: new ( ) . into_iter ( ) }
scope headers include fn decls, if let, while let etc..
scope headers include fn decls if let while let etc ..
point
usize
scopestart
usize
msrc
&str
searchstr
&str
filepath
&Path
search_type
SearchType
local
bool