Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions ext/rubydex/graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,19 @@ static VALUE rdxr_graph_index_all(VALUE self, VALUE file_paths) {
return array;
}

// Indexes a single source string in memory, dispatching to the appropriate indexer based on language_id.
// Indexes a single source string in memory, dispatching to the appropriate indexer based on language_id
//
// Graph#index_source: (String uri, String source, ?String language_id) -> void
// Registered with arity -1 so Ruby can call it with either 2 or 3 arguments.
static VALUE rdxr_graph_index_source(int argc, VALUE *argv, VALUE self) {
VALUE uri, source, language_id;
rb_scan_args(argc, argv, "21", &uri, &source, &language_id);

// Graph#index_source: (String uri, String source, String language_id) -> void
static VALUE rdxr_graph_index_source(VALUE self, VALUE uri, VALUE source, VALUE language_id) {
Check_Type(uri, T_STRING);
Check_Type(source, T_STRING);
Check_Type(language_id, T_STRING);

void *graph;
TypedData_Get_Struct(self, void *, &graph_type, graph);

const char *uri_str = StringValueCStr(uri);
const char *language_id_str = NULL;
if (!NIL_P(language_id)) {
Check_Type(language_id, T_STRING);
language_id_str = StringValueCStr(language_id);
}

const char *language_id_str = StringValueCStr(language_id);
const char *source_str = RSTRING_PTR(source);
size_t source_len = RSTRING_LEN(source);

Expand Down Expand Up @@ -768,7 +760,7 @@ void rdxi_initialize_graph(VALUE moduleRubydex) {

rb_define_alloc_func(cGraph, rdxr_graph_alloc);
rb_define_method(cGraph, "index_all", rdxr_graph_index_all, 1);
rb_define_method(cGraph, "index_source", rdxr_graph_index_source, -1);
rb_define_method(cGraph, "index_source", rdxr_graph_index_source, 3);
rb_define_method(cGraph, "document", rdxr_graph_document, 1);
rb_define_method(cGraph, "delete_document", rdxr_graph_delete_document, 1);
rb_define_method(cGraph, "resolve", rdxr_graph_resolve, 0);
Expand Down
4 changes: 2 additions & 2 deletions rbi/rubydex.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ class Rubydex::Graph
sig { params(file_paths: T::Array[String]).returns(T::Array[String]) }
def index_all(file_paths); end

sig { params(uri: String, source: String, language_id: T.nilable(String)).void }
def index_source(uri, source, language_id = nil); end
sig { params(uri: String, source: String, language_id: String).void }
def index_source(uri, source, language_id); end

# Index all files and dependencies of the workspace that exists in `@workspace_path`
sig { returns(T::Array[String]) }
Expand Down
24 changes: 8 additions & 16 deletions rust/rubydex-sys/src/graph_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,15 +562,13 @@ pub enum IndexSourceResult {
UnsupportedLanguageId = 4,
}

/// Indexes source code from memory using the specified language. If `language_id` is null, infers the language from
/// the URI using the same default as file indexing. Returns `IndexSourceResult::Success` on success or a specific error
/// variant if string conversion or language lookup fails.
/// Indexes source code from memory using the specified language. Returns `IndexSourceResult::Success` on success
/// or a specific error variant if string conversion or language lookup fails.
///
/// # Safety
///
/// - `pointer` must be a valid `GraphPointer` previously returned by this crate.
/// - `uri` must be a valid, null-terminated UTF-8 string.
/// - `language_id` must be either null or a valid, null-terminated UTF-8 string.
/// - `uri` and `language_id` must be valid, null-terminated UTF-8 strings.
/// - `source` must point to a valid UTF-8 byte buffer of at least `source_len` bytes.
/// It may contain null bytes.
#[unsafe(no_mangle)]
Expand All @@ -590,18 +588,12 @@ pub unsafe extern "C" fn rdx_index_source(
return IndexSourceResult::InvalidSource;
};

let language = if language_id.is_null() {
LanguageId::from_path(uri_str.as_str())
} else {
let Ok(language_id_str) = (unsafe { utils::convert_char_ptr_to_string(language_id) }) else {
return IndexSourceResult::InvalidLanguageId;
};

let Ok(language) = LanguageId::from_language_id(&language_id_str) else {
return IndexSourceResult::UnsupportedLanguageId;
};
let Ok(language_id_str) = (unsafe { utils::convert_char_ptr_to_string(language_id) }) else {
return IndexSourceResult::InvalidLanguageId;
};

language
let Ok(language) = LanguageId::from_language_id(&language_id_str) else {
return IndexSourceResult::UnsupportedLanguageId;
};

with_mut_graph(pointer, |graph| {
Expand Down
13 changes: 2 additions & 11 deletions rust/rubydex/src/indexing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ use crate::{
operation::ruby_builder::RubyOperationBuilder,
};
use crossbeam_channel::{Sender, unbounded};
use std::{
ffi::OsStr,
fs,
path::{Path, PathBuf},
sync::Arc,
};
use std::{ffi::OsStr, fs, path::PathBuf, sync::Arc};
use url::Url;

pub mod local_graph;
Expand Down Expand Up @@ -40,10 +35,6 @@ impl From<&OsStr> for LanguageId {
}

impl LanguageId {
pub fn from_path(path: impl AsRef<Path>) -> Self {
path.as_ref().extension().map_or(Self::Ruby, Self::from)
}

/// Determines the language from an LSP language ID string.
///
/// # Errors
Expand Down Expand Up @@ -109,7 +100,7 @@ impl Job for IndexingJob {
return;
};

let language = LanguageId::from_path(&self.path);
let language = self.path.extension().map_or(LanguageId::Ruby, LanguageId::from);
let local_graph = build_local_graph(url.to_string(), &source, &language, self.backend);

self.local_graph_tx
Expand Down
72 changes: 5 additions & 67 deletions test/graph_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -529,80 +529,18 @@ def test_delete_uri_with_invalid_argument

def test_index_source_with_ruby
graph = Rubydex::Graph.new
graph.index_source("file:///foo.rb", <<~RUBY, "ruby")
class Foo
def bar; end
end
RUBY
graph.resolve

assert_empty(graph.diagnostics)
assert_equal("Foo#bar()", graph["Foo#bar()"].name)
end

def test_index_source_infers_ruby_language_id_when_omitted
graph = Rubydex::Graph.new
graph.index_source("file:///foo.rake", <<~RUBY)
class Foo
def bar; end
end
RUBY
graph.resolve

assert_empty(graph.diagnostics)
assert_equal("Foo#bar()", graph["Foo#bar()"].name)
end

def test_index_source_infers_ruby_language_id_when_nil
graph = Rubydex::Graph.new
graph.index_source("untitled:Untitled-1", <<~RUBY, nil)
class Foo
def bar; end
end
RUBY
graph.index_source("file:///foo.rb", "class Foo; end", "ruby")
graph.resolve

assert_empty(graph.diagnostics)
assert_equal("Foo#bar()", graph["Foo#bar()"].name)
assert_equal(2, graph.documents.count)
refute_nil(graph["Foo"])
end

def test_index_source_with_rbs
graph = Rubydex::Graph.new
graph.index_source("file:///foo.rbs", <<~RBS, "rbs")
class Foo
def bar: () -> void
end
RBS
graph.resolve

assert_empty(graph.diagnostics)
assert_equal("Foo#bar()", graph["Foo#bar()"].name)
end

def test_index_source_keeps_explicit_rbs_language_id_override
graph = Rubydex::Graph.new
graph.index_source("file:///foo.rb", <<~RBS, "rbs")
class Foo
def bar: () -> void
end
RBS
graph.resolve
graph.index_source("file:///foo.rbs", "class Foo\nend", "rbs")

assert_empty(graph.diagnostics)
assert_equal("Foo#bar()", graph["Foo#bar()"].name)
end

def test_index_source_infers_rbs_language_id_when_omitted
graph = Rubydex::Graph.new
graph.index_source("file:///foo.rbs", <<~RBS)
class Foo
def bar: () -> void
end
RBS
graph.resolve

assert_empty(graph.diagnostics)
assert_equal("Foo#bar()", graph["Foo#bar()"].name)
assert_equal(2, graph.documents.count)
end

def test_index_source_with_unknown_language_id
Expand Down
Loading