From f32fa784befec156de874396659c1602ac68cc07 Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Sun, 4 Feb 2024 02:00:42 -0500 Subject: [PATCH] chore(highlight): apply clippy fixes --- highlight/README.md | 14 +++-- highlight/src/c_lib.rs | 16 +++--- highlight/src/lib.rs | 121 ++++++++++++++++++++++++----------------- highlight/src/util.rs | 10 ---- 4 files changed, 89 insertions(+), 72 deletions(-) delete mode 100644 highlight/src/util.rs diff --git a/highlight/README.md b/highlight/README.md index 459790ef..e0eb298f 100644 --- a/highlight/README.md +++ b/highlight/README.md @@ -5,9 +5,10 @@ [crates.io]: https://crates.io/crates/tree-sitter-highlight [crates.io badge]: https://img.shields.io/crates/v/tree-sitter-highlight.svg?color=%23B48723 -### Usage +## Usage -Add this crate, and the language-specific crates for whichever languages you want to parse, to your `Cargo.toml`: +Add this crate, and the language-specific crates for whichever languages you want +to parse, to your `Cargo.toml`: ```toml [dependencies] @@ -40,7 +41,8 @@ let highlight_names = [ ]; ``` -Create a highlighter. You need one of these for each thread that you're using for syntax highlighting: +Create a highlighter. You need one of these for each thread that you're using for +syntax highlighting: ```rust use tree_sitter_highlight::Highlighter; @@ -57,9 +59,11 @@ let javascript_language = tree_sitter_javascript::language(); let mut javascript_config = HighlightConfiguration::new( javascript_language, + "javascript", tree_sitter_javascript::HIGHLIGHT_QUERY, tree_sitter_javascript::INJECTION_QUERY, tree_sitter_javascript::LOCALS_QUERY, + false, ).unwrap(); ``` @@ -96,4 +100,6 @@ for event in highlights { } ``` -The last parameter to `highlight` is a *language injection* callback. This allows other languages to be retrieved when Tree-sitter detects an embedded document (for example, a piece of JavaScript code inside of a `script` tag within HTML). +The last parameter to `highlight` is a _language injection_ callback. This allows +other languages to be retrieved when Tree-sitter detects an embedded document +(for example, a piece of JavaScript code inside a `script` tag within HTML). diff --git a/highlight/src/c_lib.rs b/highlight/src/c_lib.rs index 1ab4903a..a06674db 100644 --- a/highlight/src/c_lib.rs +++ b/highlight/src/c_lib.rs @@ -105,20 +105,20 @@ pub unsafe extern "C" fn ts_highlighter_add_language( }; let highlight_query = - slice::from_raw_parts(highlight_query as *const u8, highlight_query_len as usize); + slice::from_raw_parts(highlight_query.cast::(), highlight_query_len as usize); let highlight_query = str::from_utf8(highlight_query).or(Err(ErrorCode::InvalidUtf8))?; let injection_query = if injection_query_len > 0 { let query = - slice::from_raw_parts(injection_query as *const u8, injection_query_len as usize); + slice::from_raw_parts(injection_query.cast::(), injection_query_len as usize); str::from_utf8(query).or(Err(ErrorCode::InvalidUtf8))? } else { "" }; let locals_query = if locals_query_len > 0 { - let query = slice::from_raw_parts(locals_query as *const u8, locals_query_len as usize); + let query = slice::from_raw_parts(locals_query.cast::(), locals_query_len as usize); str::from_utf8(query).or(Err(ErrorCode::InvalidUtf8))? } else { "" @@ -167,7 +167,7 @@ pub extern "C" fn ts_highlight_buffer_new() -> *mut TSHighlightBuffer { /// It cannot be used after this function is called. #[no_mangle] pub unsafe extern "C" fn ts_highlighter_delete(this: *mut TSHighlighter) { - drop(Box::from_raw(this)) + drop(Box::from_raw(this)); } /// Deletes a [`TSHighlightBuffer`] instance. @@ -180,7 +180,7 @@ pub unsafe extern "C" fn ts_highlighter_delete(this: *mut TSHighlighter) { /// It cannot be used after this function is called. #[no_mangle] pub unsafe extern "C" fn ts_highlight_buffer_delete(this: *mut TSHighlightBuffer) { - drop(Box::from_raw(this)) + drop(Box::from_raw(this)); } /// Get the HTML content of a [`TSHighlightBuffer`] instance as a raw pointer. @@ -263,7 +263,7 @@ pub unsafe extern "C" fn ts_highlighter_highlight( let this = unwrap_ptr(this); let output = unwrap_mut_ptr(output); let scope_name = unwrap(CStr::from_ptr(scope_name).to_str()); - let source_code = slice::from_raw_parts(source_code as *const u8, source_code_len as usize); + let source_code = slice::from_raw_parts(source_code.cast::(), source_code_len as usize); let cancellation_flag = cancellation_flag.as_ref(); this.highlight(source_code, scope_name, output, cancellation_flag) } @@ -309,7 +309,7 @@ impl TSHighlighter { .renderer .render(highlights, source_code, &|s| self.attribute_strings[s.0]); match result { - Err(Error::Cancelled) | Err(Error::Unknown) => ErrorCode::Timeout, + Err(Error::Cancelled | Error::Unknown) => ErrorCode::Timeout, Err(Error::InvalidLanguage) => ErrorCode::InvalidLanguage, Ok(()) => ErrorCode::Ok, } @@ -335,7 +335,7 @@ unsafe fn unwrap_mut_ptr<'a, T>(result: *mut T) -> &'a mut T { fn unwrap(result: Result) -> T { result.unwrap_or_else(|error| { - eprintln!("tree-sitter highlight error: {}", error); + eprintln!("tree-sitter highlight error: {error}"); abort(); }) } diff --git a/highlight/src/lib.rs b/highlight/src/lib.rs index 7c717fb6..f1c55026 100644 --- a/highlight/src/lib.rs +++ b/highlight/src/lib.rs @@ -1,7 +1,6 @@ #![doc = include_str!("../README.md")] pub mod c_lib; -pub mod util; pub use c_lib as c; use lazy_static::lazy_static; @@ -180,9 +179,16 @@ struct HighlightIterLayer<'a> { depth: usize, } +impl Default for Highlighter { + fn default() -> Self { + Self::new() + } +} + impl Highlighter { + #[must_use] pub fn new() -> Self { - Highlighter { + Self { parser: Parser::new(), cursors: Vec::new(), } @@ -333,7 +339,7 @@ impl HighlightConfiguration { } let highlight_indices = vec![None; query.capture_names().len()]; - Ok(HighlightConfiguration { + Ok(Self { language, language_name: name.into(), query, @@ -353,7 +359,8 @@ impl HighlightConfiguration { } /// Get a slice containing all of the highlight names used in the configuration. - pub fn names(&self) -> &[&str] { + #[must_use] + pub const fn names(&self) -> &[&str] { self.query.capture_names() } @@ -377,7 +384,7 @@ impl HighlightConfiguration { let mut best_index = None; let mut best_match_len = 0; - for (i, recognized_name) in recognized_names.into_iter().enumerate() { + for (i, recognized_name) in recognized_names.iter().enumerate() { let mut len = 0; let mut matches = true; for part in recognized_name.as_ref().split('.') { @@ -399,16 +406,17 @@ impl HighlightConfiguration { // Return the list of this configuration's capture names that are neither present in the // list of predefined 'canonical' names nor start with an underscore (denoting 'private' captures // used as part of capture internals). + #[must_use] pub fn nonconformant_capture_names(&self, capture_names: &HashSet<&str>) -> Vec<&str> { let capture_names = if capture_names.is_empty() { &*STANDARD_CAPTURE_NAMES } else { - &capture_names + capture_names }; self.names() .iter() .filter(|&n| !(n.starts_with('_') || capture_names.contains(n))) - .map(|n| *n) + .copied() .collect() } } @@ -419,6 +427,7 @@ impl<'a> HighlightIterLayer<'a> { /// In the even that the new layer contains "combined injections" (injections where multiple /// disjoint ranges are parsed as one syntax tree), these will be eagerly processed and /// added to the returned vector. + #[allow(clippy::too_many_arguments)] fn new Option<&'a HighlightConfiguration> + 'a>( source: &'a [u8], parent_name: Option<&str>, @@ -444,7 +453,7 @@ impl<'a> HighlightIterLayer<'a> { .parse(source, None) .ok_or(Error::Cancelled)?; unsafe { highlighter.parser.set_cancellation_flag(None) }; - let mut cursor = highlighter.cursors.pop().unwrap_or(QueryCursor::new()); + let mut cursor = highlighter.cursors.pop().unwrap_or_default(); // Process combined injections. if let Some(combined_injections_query) = &config.combined_injections_query { @@ -514,12 +523,12 @@ impl<'a> HighlightIterLayer<'a> { if queue.is_empty() { break; - } else { - let (next_config, next_depth, next_ranges) = queue.remove(0); - config = next_config; - depth = next_depth; - ranges = next_ranges; } + + let (next_config, next_depth, next_ranges) = queue.remove(0); + config = next_config; + depth = next_depth; + ranges = next_ranges; } Ok(result) @@ -545,7 +554,7 @@ impl<'a> HighlightIterLayer<'a> { let mut parent_range = parent_range_iter .next() .expect("Layers should only be constructed with non-empty ranges vectors"); - for node in nodes.iter() { + for node in nodes { let mut preceding_range = Range { start_byte: 0, start_point: Point::new(0, 0), @@ -568,7 +577,7 @@ impl<'a> HighlightIterLayer<'a> { Some(child.range()) } }) - .chain([following_range].iter().cloned()) + .chain(std::iter::once(following_range)) { let mut range = Range { start_byte: preceding_range.end_byte, @@ -628,7 +637,7 @@ impl<'a> HighlightIterLayer<'a> { .captures .peek() .map(|(m, i)| m.captures[*i].node.start_byte()); - let next_end = self.highlight_end_stack.last().cloned(); + let next_end = self.highlight_end_stack.last().copied(); match (next_start, next_end) { (Some(start), Some(end)) => { if start < end { @@ -685,10 +694,9 @@ where self.layers[0..(i + 1)].rotate_left(1); } break; - } else { - let layer = self.layers.remove(0); - self.highlighter.cursors.push(layer.cursor); } + let layer = self.layers.remove(0); + self.highlighter.cursors.push(layer.cursor); } } @@ -760,7 +768,7 @@ where // If any previous highlight ends before this node starts, then before // processing this capture, emit the source code up until the end of the // previous highlight, and an end event for that highlight. - if let Some(end_byte) = layer.highlight_end_stack.last().cloned() { + if let Some(end_byte) = layer.highlight_end_stack.last().copied() { if end_byte <= range.start { layer.highlight_end_stack.pop(); return self.emit_event(end_byte, Some(HighlightEvent::HighlightEnd)); @@ -769,7 +777,7 @@ where } // If there are no more captures, then emit any remaining highlight end events. // And if there are none of those, then just advance to the end of the document. - else if let Some(end_byte) = layer.highlight_end_stack.last().cloned() { + else if let Some(end_byte) = layer.highlight_end_stack.last().copied() { layer.highlight_end_stack.pop(); return self.emit_event(end_byte, Some(HighlightEvent::HighlightEnd)); } else { @@ -848,12 +856,9 @@ where local_defs: Vec::new(), }; for prop in layer.config.query.property_settings(match_.pattern_index) { - match prop.key.as_ref() { - "local.scope-inherits" => { - scope.inherits = - prop.value.as_ref().map_or(true, |r| r.as_ref() == "true"); - } - _ => {} + if prop.key.as_ref() == "local.scope-inherits" { + scope.inherits = + prop.value.as_ref().map_or(true, |r| r.as_ref() == "true"); } } layer.scope_stack.push(scope); @@ -884,26 +889,24 @@ where } // If the node represents a reference, then try to find the corresponding // definition in the scope stack. - else if Some(capture.index) == layer.config.local_ref_capture_index { - if definition_highlight.is_none() { - definition_highlight = None; - if let Ok(name) = str::from_utf8(&self.source[range.clone()]) { - for scope in layer.scope_stack.iter().rev() { - if let Some(highlight) = - scope.local_defs.iter().rev().find_map(|def| { - if def.name == name && range.start >= def.value_range.end { - Some(def.highlight) - } else { - None - } - }) - { - reference_highlight = highlight; - break; - } - if !scope.inherits { - break; + else if Some(capture.index) == layer.config.local_ref_capture_index + && definition_highlight.is_none() + { + definition_highlight = None; + if let Ok(name) = str::from_utf8(&self.source[range.clone()]) { + for scope in layer.scope_stack.iter().rev() { + if let Some(highlight) = scope.local_defs.iter().rev().find_map(|def| { + if def.name == name && range.start >= def.value_range.end { + Some(def.highlight) + } else { + None } + }) { + reference_highlight = highlight; + break; + } + if !scope.inherits { + break; } } } @@ -993,9 +996,16 @@ where } } +impl Default for HtmlRenderer { + fn default() -> Self { + Self::new() + } +} + impl HtmlRenderer { + #[must_use] pub fn new() -> Self { - let mut result = HtmlRenderer { + let mut result = Self { html: Vec::with_capacity(BUFFER_HTML_RESERVE_CAPACITY), line_offsets: Vec::with_capacity(BUFFER_LINES_RESERVE_CAPACITY), carriage_return_highlight: None, @@ -1095,10 +1105,21 @@ impl HtmlRenderer { self.html.extend(b""); } - fn add_text<'a, F>(&mut self, src: &[u8], highlights: &Vec, attribute_callback: &F) + fn add_text<'a, F>(&mut self, src: &[u8], highlights: &[Highlight], attribute_callback: &F) where F: Fn(Highlight) -> &'a [u8], { + pub const fn html_escape(c: u8) -> Option<&'static [u8]> { + match c as char { + '>' => Some(b">"), + '<' => Some(b"<"), + '&' => Some(b"&"), + '\'' => Some(b"'"), + '"' => Some(b"""), + _ => None, + } + } + let mut last_char_was_cr = false; for c in LossyUtf8::new(src).flat_map(|p| p.bytes()) { // Don't render carriage return characters, but allow lone carriage returns (not @@ -1122,7 +1143,7 @@ impl HtmlRenderer { highlights .iter() .for_each(|scope| self.start_highlight(*scope, attribute_callback)); - } else if let Some(escape) = util::html_escape(c) { + } else if let Some(escape) = html_escape(c) { self.html.extend_from_slice(escape); } else { self.html.push(c); @@ -1161,7 +1182,7 @@ fn injection_for_match<'a>( // that sets the injection.language key. "injection.language" => { if language_name.is_none() { - language_name = prop.value.as_ref().map(|s| s.as_ref()); + language_name = prop.value.as_ref().map(std::convert::AsRef::as_ref); } } diff --git a/highlight/src/util.rs b/highlight/src/util.rs deleted file mode 100644 index 29adb13b..00000000 --- a/highlight/src/util.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub fn html_escape(c: u8) -> Option<&'static [u8]> { - match c as char { - '>' => Some(b">"), - '<' => Some(b"<"), - '&' => Some(b"&"), - '\'' => Some(b"'"), - '"' => Some(b"""), - _ => None, - } -}