tags: Start work on handling local variables for ruby support
This commit is contained in:
parent
651fa38c93
commit
aedab72afa
2 changed files with 197 additions and 36 deletions
|
|
@ -1,7 +1,7 @@
|
|||
use super::helpers::allocations;
|
||||
use super::helpers::fixtures::get_language;
|
||||
use super::helpers::fixtures::{get_language, get_language_queries_path};
|
||||
use std::ffi::CString;
|
||||
use std::{ptr, slice, str};
|
||||
use std::{fs, ptr, slice, str};
|
||||
use tree_sitter_tags::c_lib as c;
|
||||
use tree_sitter_tags::{TagKind, TagsConfiguration, TagsContext};
|
||||
|
||||
|
|
@ -47,10 +47,22 @@ const JS_TAG_QUERY: &'static str = r#"
|
|||
(call_expression function: (identifier) @name) @call
|
||||
"#;
|
||||
|
||||
const RUBY_TAG_QUERY: &'static str = r#"
|
||||
(method
|
||||
name: (identifier) @name) @method
|
||||
|
||||
(method_call
|
||||
method: (identifier) @name) @call
|
||||
|
||||
((identifier) @name @call
|
||||
(is-not? local))
|
||||
"#;
|
||||
|
||||
#[test]
|
||||
fn test_tags_python() {
|
||||
let language = get_language("python");
|
||||
let tags_config = TagsConfiguration::new(language, PYTHON_TAG_QUERY, "").unwrap();
|
||||
let mut tag_context = TagsContext::new();
|
||||
|
||||
let source = br#"
|
||||
class Customer:
|
||||
|
|
@ -66,7 +78,6 @@ fn test_tags_python() {
|
|||
}
|
||||
"#;
|
||||
|
||||
let mut tag_context = TagsContext::new();
|
||||
let tags = tag_context
|
||||
.generate_tags(&tags_config, source)
|
||||
.collect::<Vec<_>>();
|
||||
|
|
@ -95,8 +106,6 @@ fn test_tags_python() {
|
|||
fn test_tags_javascript() {
|
||||
let language = get_language("javascript");
|
||||
let tags_config = TagsConfiguration::new(language, JS_TAG_QUERY, "").unwrap();
|
||||
|
||||
let mut tag_context = TagsContext::new();
|
||||
let source = br#"
|
||||
// hi
|
||||
|
||||
|
|
@ -116,6 +125,8 @@ fn test_tags_javascript() {
|
|||
|
||||
}
|
||||
"#;
|
||||
|
||||
let mut tag_context = TagsContext::new();
|
||||
let tags = tag_context
|
||||
.generate_tags(&tags_config, source)
|
||||
.collect::<Vec<_>>();
|
||||
|
|
@ -138,6 +149,58 @@ fn test_tags_javascript() {
|
|||
assert_eq!(tags[2].docs, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tags_ruby() {
|
||||
let language = get_language("ruby");
|
||||
let locals_query =
|
||||
fs::read_to_string(get_language_queries_path("ruby").join("locals.scm")).unwrap();
|
||||
let tags_config = TagsConfiguration::new(language, RUBY_TAG_QUERY, &locals_query).unwrap();
|
||||
let source = strip_whitespace(
|
||||
8,
|
||||
"
|
||||
b = 1
|
||||
|
||||
def foo()
|
||||
c = 1
|
||||
|
||||
# a is a method because it is not in scope
|
||||
# b is a method because `b` doesn't capture variables from its containing scope
|
||||
bar a, b, c
|
||||
|
||||
[1, 2, 3].each do |a|
|
||||
# a is a parameter
|
||||
# b is a method
|
||||
# c is a variable, because the block captures variables from its containing scope.
|
||||
baz a, b, c
|
||||
end
|
||||
end",
|
||||
);
|
||||
|
||||
let mut tag_context = TagsContext::new();
|
||||
let tags = tag_context
|
||||
.generate_tags(&tags_config, source.as_bytes())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(
|
||||
tags.iter()
|
||||
.map(|t| (
|
||||
substr(source.as_bytes(), &t.name_range),
|
||||
t.kind,
|
||||
(t.span.start.row, t.span.start.column),
|
||||
))
|
||||
.collect::<Vec<_>>(),
|
||||
&[
|
||||
("foo", TagKind::Method, (2, 0)),
|
||||
("bar", TagKind::Call, (7, 4)),
|
||||
("a", TagKind::Call, (7, 8)),
|
||||
("b", TagKind::Call, (7, 11)),
|
||||
("each", TagKind::Call, (9, 14)),
|
||||
("baz", TagKind::Call, (13, 8)),
|
||||
("b", TagKind::Call, (13, 15),),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tags_via_c_api() {
|
||||
allocations::record(|| {
|
||||
|
|
@ -146,7 +209,9 @@ fn test_tags_via_c_api() {
|
|||
let scope_name = "source.js";
|
||||
let language = get_language("javascript");
|
||||
|
||||
let source_code = "
|
||||
let source_code = strip_whitespace(
|
||||
12,
|
||||
"
|
||||
var a = 1;
|
||||
|
||||
// one
|
||||
|
|
@ -161,13 +226,8 @@ fn test_tags_via_c_api() {
|
|||
|
||||
}
|
||||
|
||||
b(a);"
|
||||
.lines()
|
||||
.skip(1)
|
||||
// remove extra indentation
|
||||
.map(|line| &line[line.len().min(12)..])
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
b(a);",
|
||||
);
|
||||
|
||||
let c_scope_name = CString::new(scope_name).unwrap();
|
||||
let result = c::ts_tagger_add_language(
|
||||
|
|
@ -238,3 +298,11 @@ fn test_tags_via_c_api() {
|
|||
fn substr<'a>(source: &'a [u8], range: &std::ops::Range<usize>) -> &'a str {
|
||||
std::str::from_utf8(&source[range.clone()]).unwrap()
|
||||
}
|
||||
|
||||
fn strip_whitespace(indent: usize, s: &str) -> String {
|
||||
s.lines()
|
||||
.skip(1)
|
||||
.map(|line| &line[line.len().min(indent)..])
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue