Skip to content
Open
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
6 changes: 5 additions & 1 deletion ext/rubydex/definition.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,12 @@ static VALUE rdxr_definition_mixins(VALUE self) {
CMixin entry;
while (rdx_mixins_iter_next(iter, &entry)) {
VALUE constant_ref = rdxi_build_constant_reference(data->graph_obj, &entry.constant_reference);
VALUE location = rdxi_build_location_value(entry.location);
rdx_location_free(entry.location);

VALUE mixin_class = rdxi_mixin_class_for_kind(entry.kind);
VALUE mixin = rb_class_new_instance(1, &constant_ref, mixin_class);
VALUE argv[] = {constant_ref, location};
VALUE mixin = rb_class_new_instance(2, argv, mixin_class);
rb_ary_push(ary, mixin);
}

Expand Down
8 changes: 6 additions & 2 deletions lib/rubydex/mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ class Mixin
#: ConstantReference
attr_reader :constant_reference

#: (ConstantReference) -> void
def initialize(constant_reference)
#: Location
attr_reader :location

#: (ConstantReference, Location) -> void
def initialize(constant_reference, location)
@constant_reference = constant_reference
@location = location
end
end

Expand Down
7 changes: 5 additions & 2 deletions rbi/rubydex.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,11 @@ class Rubydex::Mixin
sig { returns(Rubydex::ConstantReference) }
attr_reader :constant_reference

sig { params(constant_reference: Rubydex::ConstantReference).void }
def initialize(constant_reference); end
sig { returns(Rubydex::Location) }
attr_reader :location

sig { params(constant_reference: Rubydex::ConstantReference, location: Rubydex::Location).void }
def initialize(constant_reference, location); end
end

class Rubydex::Include < Rubydex::Mixin; end
Expand Down
19 changes: 16 additions & 3 deletions rust/rubydex-sys/src/definition_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ pub enum MixinKind {
pub struct CMixin {
pub kind: MixinKind,
pub constant_reference: CConstantReference,
pub location: *mut Location,
}

#[derive(Debug)]
Expand Down Expand Up @@ -482,9 +483,21 @@ pub unsafe extern "C" fn rdx_definition_mixins(pointer: GraphPointer, definition

let entries: Vec<CMixin> = mixins
.iter()
.map(|mixin| CMixin {
kind: map_mixin_kind(mixin),
constant_reference: CConstantReference::from_id(graph, *mixin.constant_reference_id()),
.map(|mixin| {
let constant_reference = graph
.constant_references()
.get(mixin.constant_reference_id())
.expect("Constant reference not found");
let document = graph
.documents()
.get(&constant_reference.uri_id())
.expect("document should exist");

CMixin {
kind: map_mixin_kind(mixin),
constant_reference: CConstantReference::from_id(graph, *mixin.constant_reference_id()),
location: create_location_for_uri_and_offset(graph, document, mixin.offset()),
}
})
.collect();

Expand Down
18 changes: 9 additions & 9 deletions rust/rubydex/src/indexing/rbs_indexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl<'a> RBSIndexer<'a> {
}
}

fn index_mixin(&mut self, type_name: &TypeNameNode, mixin_fn: fn(ConstantReferenceId) -> Mixin) {
fn index_mixin(&mut self, type_name: &TypeNameNode, mixin_fn: fn(ConstantReferenceId, Offset) -> Mixin) {
let Some(lexical_nesting_id) = self.parent_lexical_scope_id() else {
return;
};
Expand All @@ -136,9 +136,9 @@ impl<'a> RBSIndexer<'a> {

let constant_ref_id =
self.local_graph
.add_constant_reference(ConstantReference::new(name_id, self.uri_id, offset));
.add_constant_reference(ConstantReference::new(name_id, self.uri_id, offset.clone()));

self.add_mixin_to_current_lexical_scope(lexical_nesting_id, mixin_fn(constant_ref_id));
self.add_mixin_to_current_lexical_scope(lexical_nesting_id, mixin_fn(constant_ref_id, offset));
}

fn add_member_to_current_lexical_scope(&mut self, owner_id: DefinitionId, member_id: DefinitionId) {
Expand Down Expand Up @@ -511,20 +511,20 @@ impl Visit for RBSIndexer<'_> {
}

fn visit_include_node(&mut self, include_node: &IncludeNode) {
self.index_mixin(&include_node.name(), |ref_id| {
Mixin::Include(IncludeDefinition::new(ref_id))
self.index_mixin(&include_node.name(), |ref_id, offset| {
Mixin::Include(IncludeDefinition::new(ref_id, offset))
});
}

fn visit_prepend_node(&mut self, prepend_node: &PrependNode) {
self.index_mixin(&prepend_node.name(), |ref_id| {
Mixin::Prepend(PrependDefinition::new(ref_id))
self.index_mixin(&prepend_node.name(), |ref_id, offset| {
Mixin::Prepend(PrependDefinition::new(ref_id, offset))
});
}

fn visit_extend_node(&mut self, extend_node: &ExtendNode) {
self.index_mixin(&extend_node.name(), |ref_id| {
Mixin::Extend(ExtendDefinition::new(ref_id))
self.index_mixin(&extend_node.name(), |ref_id, offset| {
Mixin::Extend(ExtendDefinition::new(ref_id, offset))
});
}

Expand Down
7 changes: 4 additions & 3 deletions rust/rubydex/src/indexing/ruby_indexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,7 @@ impl<'a> RubyIndexer<'a> {
};

let parent_nesting_id = self.current_nesting_definition_id();
let mixin_offset = Offset::from_prism_location(&node.location());

// Collect all arguments as constant references. Ignore anything that isn't a constant
let mixin_arguments = arguments
Expand Down Expand Up @@ -1015,9 +1016,9 @@ impl<'a> RubyIndexer<'a> {
.add_constant_reference(ConstantReference::new(id, self.uri_id, offset));

let mixin = match mixin_type {
MixinType::Include => Mixin::Include(IncludeDefinition::new(constant_ref_id)),
MixinType::Prepend => Mixin::Prepend(PrependDefinition::new(constant_ref_id)),
MixinType::Extend => Mixin::Extend(ExtendDefinition::new(constant_ref_id)),
MixinType::Include => Mixin::Include(IncludeDefinition::new(constant_ref_id, mixin_offset.clone())),
MixinType::Prepend => Mixin::Prepend(PrependDefinition::new(constant_ref_id, mixin_offset.clone())),
MixinType::Extend => Mixin::Extend(ExtendDefinition::new(constant_ref_id, mixin_offset.clone())),
};

match self.local_graph.get_definition_mut(lexical_nesting_id).unwrap() {
Expand Down
18 changes: 17 additions & 1 deletion rust/rubydex/src/model/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,27 +209,43 @@ impl Mixin {
Mixin::Extend(def) => def.constant_reference_id(),
}
}

#[must_use]
pub fn offset(&self) -> &Offset {
match self {
Mixin::Include(def) => def.offset(),
Mixin::Prepend(def) => def.offset(),
Mixin::Extend(def) => def.offset(),
}
}
}

macro_rules! mixin_definition {
($variant:ident, $name:ident) => {
#[derive(Debug, Clone)]
pub struct $name {
constant_reference_id: ConstantReferenceId,
offset: Offset,
}

impl $name {
#[must_use]
pub const fn new(constant_reference_id: ConstantReferenceId) -> Self {
pub const fn new(constant_reference_id: ConstantReferenceId, offset: Offset) -> Self {
Self {
constant_reference_id,
offset,
}
}

#[must_use]
pub fn constant_reference_id(&self) -> &ConstantReferenceId {
&self.constant_reference_id
}

#[must_use]
pub fn offset(&self) -> &Offset {
&self.offset
}
}
};
}
Expand Down
6 changes: 3 additions & 3 deletions rust/rubydex/src/operation/applier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,9 @@ impl OperationApplier {
};

let mixin = match op.kind {
MixinKind::Include => Mixin::Include(IncludeDefinition::new(constant_reference_id)),
MixinKind::Prepend => Mixin::Prepend(PrependDefinition::new(constant_reference_id)),
MixinKind::Extend => Mixin::Extend(ExtendDefinition::new(constant_reference_id)),
MixinKind::Include => Mixin::Include(IncludeDefinition::new(constant_reference_id, op.offset.clone())),
MixinKind::Prepend => Mixin::Prepend(PrependDefinition::new(constant_reference_id, op.offset.clone())),
MixinKind::Extend => Mixin::Extend(ExtendDefinition::new(constant_reference_id, op.offset.clone())),
};

if let Some(owner) = self.local_graph.get_definition_mut(owner_id) {
Expand Down
1 change: 1 addition & 0 deletions rust/rubydex/src/operation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ pub struct SetConstantVisibility {
pub struct Mixin {
pub kind: MixinKind,
pub target: Target,
pub offset: Offset,
}

#[derive(Debug)]
Expand Down
2 changes: 2 additions & 0 deletions rust/rubydex/src/operation/ruby_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,7 @@ impl<'a> RubyOperationBuilder<'a> {
};

let has_owner = self.current_owner_name_id().is_some();
let mixin_offset = Offset::from_prism_location(&node.location());

let mixin_arguments = arguments
.arguments()
Expand Down Expand Up @@ -893,6 +894,7 @@ impl<'a> RubyOperationBuilder<'a> {
self.operations.push(Operation::Mixin(op::Mixin {
kind,
target: Target::Constant(name_id),
offset: mixin_offset.clone(),
}));
}
}
Expand Down
30 changes: 30 additions & 0 deletions test/definition_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,42 @@ class NoMixins; end

assert_instance_of(Rubydex::Include, mixins[0])
assert_instance_of(Rubydex::UnresolvedConstantReference, mixins[0].constant_reference)
assert_equal(
Rubydex::DisplayLocation.new(
uri: context.uri_to("file1.rb"),
start_line: 6,
start_column: 3,
end_line: 6,
end_column: 13,
),
mixins[0].location.to_display,
)

assert_instance_of(Rubydex::Prepend, mixins[1])
assert_instance_of(Rubydex::UnresolvedConstantReference, mixins[1].constant_reference)
assert_equal(
Rubydex::DisplayLocation.new(
uri: context.uri_to("file1.rb"),
start_line: 7,
start_column: 3,
end_line: 7,
end_column: 13,
),
mixins[1].location.to_display,
)

assert_instance_of(Rubydex::Extend, mixins[2])
assert_instance_of(Rubydex::UnresolvedConstantReference, mixins[2].constant_reference)
assert_equal(
Rubydex::DisplayLocation.new(
uri: context.uri_to("file1.rb"),
start_line: 8,
start_column: 3,
end_line: 8,
end_column: 12,
),
mixins[2].location.to_display,
)

# After resolution, mixins have resolved constant references
graph.resolve
Expand Down
Loading