Find all occurrences of `needle` in `content` within the byte range `[scope_start, scope_end)` that are textually identical to the selected expression, excluding the original selection `[sel_start, sel_end)`. Returns `(start, end)` byte offset pairs. Word boundaries are checked so that substrings of longer identifiers are not matched.
(
content: &str,
needle: &str,
sel_start: usize,
sel_end: usize,
scope_start: usize,
scope_end: usize,
)
| 1944 | /// Returns `(start, end)` byte offset pairs. Word boundaries are checked |
| 1945 | /// so that substrings of longer identifiers are not matched. |
| 1946 | pub(crate) fn find_identical_occurrences( |
| 1947 | content: &str, |
| 1948 | needle: &str, |
| 1949 | sel_start: usize, |
| 1950 | sel_end: usize, |
| 1951 | scope_start: usize, |
| 1952 | scope_end: usize, |
| 1953 | ) -> Vec<(usize, usize)> { |
| 1954 | if needle.is_empty() || scope_start >= scope_end || scope_end > content.len() { |
| 1955 | return Vec::new(); |
| 1956 | } |
| 1957 | let haystack = &content[scope_start..scope_end]; |
| 1958 | let mut results = Vec::new(); |
| 1959 | let mut search_from = 0; |
| 1960 | while let Some(pos) = haystack[search_from..].find(needle) { |
| 1961 | let abs_start = scope_start + search_from + pos; |
| 1962 | let abs_end = abs_start + needle.len(); |
| 1963 | // Skip the original selection. |
| 1964 | if abs_start != sel_start || abs_end != sel_end { |
| 1965 | // Check word boundaries to avoid matching substrings. |
| 1966 | let before_ok = abs_start == 0 |
| 1967 | || !content.as_bytes()[abs_start - 1].is_ascii_alphanumeric() |
| 1968 | && content.as_bytes()[abs_start - 1] != b'_' |
| 1969 | && content.as_bytes()[abs_start - 1] != b'$'; |
| 1970 | let after_ok = abs_end >= content.len() |
| 1971 | || !content.as_bytes()[abs_end].is_ascii_alphanumeric() |
| 1972 | && content.as_bytes()[abs_end] != b'_'; |
| 1973 | if before_ok && after_ok { |
| 1974 | results.push((abs_start, abs_end)); |
| 1975 | } |
| 1976 | } |
| 1977 | search_from = search_from + pos + 1; |
| 1978 | } |
| 1979 | results |
| 1980 | } |
| 1981 | |
| 1982 | /// Infer a [`PhpType`] from a literal expression string. |
| 1983 | /// |