wip
This commit is contained in:
parent
a3f0087b11
commit
680a9e0531
2 changed files with 104 additions and 38 deletions
|
|
@ -9,10 +9,8 @@ fn test_tags_javascript() {
|
|||
r#"
|
||||
((function_definition
|
||||
name: (identifier) @name
|
||||
body: (block
|
||||
. (string) @doc)) @function
|
||||
body: (block . (string) @doc)) @function
|
||||
(set! replace @doc "(^['\s]*)|(['\s]*$)"))
|
||||
|
||||
(function_definition
|
||||
name: (identifier) @name) @function
|
||||
(class_definition
|
||||
|
|
|
|||
138
tags/src/lib.rs
138
tags/src/lib.rs
|
|
@ -1,12 +1,19 @@
|
|||
use serde::{Serialize, Serializer};
|
||||
use tree_sitter::{Language, Parser, Query, QueryCursor, QueryError};
|
||||
use std::{ops, str};
|
||||
use tree_sitter::{Language, Node, Parser, Point, Query, QueryCursor, QueryError};
|
||||
|
||||
/// Contains the data neeeded to compute tags for code written in a
|
||||
/// particular language.
|
||||
pub struct TagsConfiguration {
|
||||
pub language: Language,
|
||||
pub query: Query,
|
||||
call_capture_index: Option<u32>,
|
||||
class_capture_index: Option<u32>,
|
||||
doc_capture_index: Option<u32>,
|
||||
function_capture_index: Option<u32>,
|
||||
locals_pattern_index: usize,
|
||||
module_capture_index: Option<u32>,
|
||||
name_capture_index: Option<u32>,
|
||||
}
|
||||
|
||||
pub struct TagsContext {
|
||||
|
|
@ -14,22 +21,10 @@ pub struct TagsContext {
|
|||
cursor: QueryCursor,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Range {
|
||||
pub start: i64,
|
||||
pub end: i64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Loc {
|
||||
pub byte_range: Range,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Span {
|
||||
pub start: Pos,
|
||||
pub end: Pos,
|
||||
pub byte_range: ops::Range<usize>,
|
||||
pub span: ops::Range<Pos>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
|
@ -56,22 +51,6 @@ pub struct Tag<'a> {
|
|||
pub docs: Option<&'a str>,
|
||||
}
|
||||
|
||||
impl Serialize for TagKind {
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
TagKind::Call => "Call",
|
||||
TagKind::Module => "Module",
|
||||
TagKind::Class => "Class",
|
||||
TagKind::Method => "Method",
|
||||
TagKind::Function => "Function",
|
||||
}
|
||||
.serialize(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl TagsConfiguration {
|
||||
pub fn new(
|
||||
language: Language,
|
||||
|
|
@ -89,10 +68,35 @@ impl TagsConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
let mut call_capture_index = None;
|
||||
let mut class_capture_index = None;
|
||||
let mut doc_capture_index = None;
|
||||
let mut function_capture_index = None;
|
||||
let mut module_capture_index = None;
|
||||
let mut name_capture_index = None;
|
||||
for (i, name) in query.capture_names().iter().enumerate() {
|
||||
let index = match name.as_str() {
|
||||
"call" => &mut call_capture_index,
|
||||
"class" => &mut class_capture_index,
|
||||
"doc" => &mut doc_capture_index,
|
||||
"function" => &mut function_capture_index,
|
||||
"module" => &mut module_capture_index,
|
||||
"name" => &mut name_capture_index,
|
||||
_ => continue,
|
||||
};
|
||||
*index = Some(i as u32);
|
||||
}
|
||||
|
||||
Ok(TagsConfiguration {
|
||||
language,
|
||||
query,
|
||||
locals_pattern_index,
|
||||
function_capture_index,
|
||||
class_capture_index,
|
||||
module_capture_index,
|
||||
doc_capture_index,
|
||||
call_capture_index,
|
||||
name_capture_index,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -105,7 +109,11 @@ impl TagsContext {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn generate_tags(&mut self, config: &TagsConfiguration, source: &[u8]) -> Vec<Tag> {
|
||||
pub fn generate_tags<'a>(
|
||||
&mut self,
|
||||
config: &TagsConfiguration,
|
||||
source: &'a [u8],
|
||||
) -> Vec<Tag<'a>> {
|
||||
self.parser
|
||||
.set_language(config.language)
|
||||
.expect("Incompatible language");
|
||||
|
|
@ -119,10 +127,70 @@ impl TagsContext {
|
|||
&source[node.byte_range()]
|
||||
});
|
||||
matches
|
||||
.map(|mat| {
|
||||
for capture in mat.captures {}
|
||||
unimplemented!();
|
||||
.filter_map(|mat| {
|
||||
let mut call_node = None;
|
||||
let mut doc_node = None;
|
||||
let mut class_node = None;
|
||||
let mut function_node = None;
|
||||
let mut module_node = None;
|
||||
let mut name_node = None;
|
||||
|
||||
for capture in mat.captures {
|
||||
let index = Some(capture.index);
|
||||
let node = Some(capture.node);
|
||||
if index == config.call_capture_index {
|
||||
call_node = node;
|
||||
} else if index == config.class_capture_index {
|
||||
class_node = node;
|
||||
} else if index == config.doc_capture_index {
|
||||
doc_node = node;
|
||||
} else if index == config.function_capture_index {
|
||||
function_node = node;
|
||||
} else if index == config.module_capture_index {
|
||||
module_node = node;
|
||||
} else if index == config.name_capture_index {
|
||||
name_node = node;
|
||||
}
|
||||
}
|
||||
|
||||
if let (Some(function), Some(name)) = (function_node, name_node) {
|
||||
if let Ok(name) = str::from_utf8(&source[name.byte_range()]) {
|
||||
return Some(Tag {
|
||||
name,
|
||||
line: "",
|
||||
loc: loc_for_node(function),
|
||||
kind: TagKind::Function,
|
||||
docs: doc_node
|
||||
.and_then(|n| str::from_utf8(&source[n.byte_range()]).ok()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for TagKind {
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
TagKind::Call => "Call",
|
||||
TagKind::Module => "Module",
|
||||
TagKind::Class => "Class",
|
||||
TagKind::Method => "Method",
|
||||
TagKind::Function => "Function",
|
||||
}
|
||||
.serialize(s)
|
||||
}
|
||||
}
|
||||
|
||||
fn loc_for_node(node: Node) -> Loc {
|
||||
Loc {
|
||||
byte_range: node.byte_range(),
|
||||
span: node.start_position()..node.start_position(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue