rubydex 0.2.1-x86_64-darwin → 0.2.2-x86_64-darwin

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 70c39786cd54f2885fb56521315531f53c984578a8231f6ba523f5631fccc16f
4
- data.tar.gz: 9596d0bd9dde11b4f2e24dec970eacbebf67d7ac8a67c504bab0d036961257e8
3
+ metadata.gz: 6c8e8d289434efb0521d97f27511fa7419300233bd5a7806ba1059128fced75f
4
+ data.tar.gz: a413082fe52cab8c539a868e50dfaef456e76963692c2ccaea8b14db1df48bd4
5
5
  SHA512:
6
- metadata.gz: cbf594ef8e3135bd41197ecd04c23e2385251c3a759a65c621807a682cb68aa21c01e9a7eb4edb5c457f62c707b20a600fe4e8f2cd2f89bd3e90b9c9985987b0
7
- data.tar.gz: 25b2e5733c19fc421201ac2b22ebaebb5f992cebc12e03677fa594de91e000313f6f4af0f145508212a333072bcea9bc65c201d4f09559e1ce553546989f53a2
6
+ metadata.gz: efaf6dd52d0446056cf794e598d8593a3599a74ecd4fc4bdf5f7e5bf665e707c5dee6e43a4b5da5d3bd861b44d21e965f279b95a70108b1b25d22e991c29d030
7
+ data.tar.gz: bc333b30708c002e385374e6ab85684262667731192e8be2fdef5f24f4875d8f64881b6753cfa18036ef4423ab30c56dba7735cc33d9720ee287c48172e47bb2
@@ -3,6 +3,7 @@
3
3
  #include "handle.h"
4
4
  #include "location.h"
5
5
  #include "reference.h"
6
+ #include "signature.h"
6
7
  #include "ruby/internal/scan_args.h"
7
8
  #include "rustbindings.h"
8
9
 
@@ -239,6 +240,30 @@ static VALUE rdxr_definition_mixins(VALUE self) {
239
240
  return ary;
240
241
  }
241
242
 
243
+ // MethodDefinition#signatures -> [Rubydex::Signature]
244
+ static VALUE rdxr_method_definition_signatures(VALUE self) {
245
+ HandleData *data;
246
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
247
+
248
+ void *graph;
249
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
250
+
251
+ SignatureArray *arr = rdx_definition_signatures(graph, data->id);
252
+ return rdxi_signatures_to_ruby(arr);
253
+ }
254
+
255
+ // MethodAliasDefinition#signatures -> [Rubydex::Signature]
256
+ static VALUE rdxr_method_alias_definition_signatures(VALUE self) {
257
+ HandleData *data;
258
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
259
+
260
+ void *graph;
261
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
262
+
263
+ SignatureArray *arr = rdx_method_alias_definition_signatures(graph, data->id);
264
+ return rdxi_signatures_to_ruby(arr);
265
+ }
266
+
242
267
  void rdxi_initialize_definition(VALUE mod) {
243
268
  mRubydex = mod;
244
269
 
@@ -273,6 +298,7 @@ void rdxi_initialize_definition(VALUE mod) {
273
298
  cConstantVisibilityDefinition = rb_define_class_under(mRubydex, "ConstantVisibilityDefinition", cDefinition);
274
299
  cMethodVisibilityDefinition = rb_define_class_under(mRubydex, "MethodVisibilityDefinition", cDefinition);
275
300
  cMethodDefinition = rb_define_class_under(mRubydex, "MethodDefinition", cDefinition);
301
+ rb_define_method(cMethodDefinition, "signatures", rdxr_method_definition_signatures, 0);
276
302
  cAttrAccessorDefinition = rb_define_class_under(mRubydex, "AttrAccessorDefinition", cDefinition);
277
303
  cAttrReaderDefinition = rb_define_class_under(mRubydex, "AttrReaderDefinition", cDefinition);
278
304
  cAttrWriterDefinition = rb_define_class_under(mRubydex, "AttrWriterDefinition", cDefinition);
@@ -280,5 +306,6 @@ void rdxi_initialize_definition(VALUE mod) {
280
306
  cInstanceVariableDefinition = rb_define_class_under(mRubydex, "InstanceVariableDefinition", cDefinition);
281
307
  cClassVariableDefinition = rb_define_class_under(mRubydex, "ClassVariableDefinition", cDefinition);
282
308
  cMethodAliasDefinition = rb_define_class_under(mRubydex, "MethodAliasDefinition", cDefinition);
309
+ rb_define_method(cMethodAliasDefinition, "signatures", rdxr_method_alias_definition_signatures, 0);
283
310
  cGlobalVariableAliasDefinition = rb_define_class_under(mRubydex, "GlobalVariableAliasDefinition", cDefinition);
284
311
  }
@@ -5,6 +5,7 @@
5
5
  #include "graph.h"
6
6
  #include "location.h"
7
7
  #include "reference.h"
8
+ #include "signature.h"
8
9
 
9
10
  VALUE mRubydex;
10
11
 
@@ -19,4 +20,5 @@ void Init_rubydex(void) {
19
20
  rdxi_initialize_location(mRubydex);
20
21
  rdxi_initialize_diagnostic(mRubydex);
21
22
  rdxi_initialize_reference(mRubydex);
23
+ rdxi_initialize_signature(mRubydex);
22
24
  }
@@ -0,0 +1,83 @@
1
+ #include "signature.h"
2
+ #include "location.h"
3
+
4
+ static VALUE empty_params = Qundef;
5
+
6
+ VALUE cSignature;
7
+ VALUE cParameter;
8
+ VALUE cPositionalParameter;
9
+ VALUE cOptionalPositionalParameter;
10
+ VALUE cRestPositionalParameter;
11
+ VALUE cPostParameter;
12
+ VALUE cKeywordParameter;
13
+ VALUE cOptionalKeywordParameter;
14
+ VALUE cRestKeywordParameter;
15
+ VALUE cForwardParameter;
16
+ VALUE cBlockParameter;
17
+
18
+ static VALUE parameter_class_for_kind(ParameterKind kind) {
19
+ switch (kind) {
20
+ case ParameterKind_RequiredPositional: return cPositionalParameter;
21
+ case ParameterKind_OptionalPositional: return cOptionalPositionalParameter;
22
+ case ParameterKind_RestPositional: return cRestPositionalParameter;
23
+ case ParameterKind_Post: return cPostParameter;
24
+ case ParameterKind_RequiredKeyword: return cKeywordParameter;
25
+ case ParameterKind_OptionalKeyword: return cOptionalKeywordParameter;
26
+ case ParameterKind_RestKeyword: return cRestKeywordParameter;
27
+ case ParameterKind_Forward: return cForwardParameter;
28
+ case ParameterKind_Block: return cBlockParameter;
29
+ default: rb_raise(rb_eRuntimeError, "Unknown ParameterKind: %d", kind);
30
+ }
31
+ }
32
+
33
+ VALUE rdxi_signatures_to_ruby(SignatureArray *arr) {
34
+ VALUE signatures = rb_ary_new_capa((long)arr->len);
35
+
36
+ for (size_t i = 0; i < arr->len; i++) {
37
+ SignatureEntry sig_entry = arr->items[i];
38
+
39
+ VALUE signature;
40
+ if (sig_entry.parameters_len == 0) {
41
+ signature = rb_class_new_instance(1, &empty_params, cSignature);
42
+ } else {
43
+ VALUE parameters = rb_ary_new_capa((long)sig_entry.parameters_len);
44
+ for (size_t j = 0; j < sig_entry.parameters_len; j++) {
45
+ ParameterEntry param_entry = sig_entry.parameters[j];
46
+
47
+ VALUE param_class = parameter_class_for_kind(param_entry.kind);
48
+ VALUE name_sym = rb_str_intern(rb_utf8_str_new_cstr(param_entry.name));
49
+ VALUE location = rdxi_build_location_value(param_entry.location);
50
+ VALUE param_argv[] = {name_sym, location};
51
+ VALUE param = rb_class_new_instance(2, param_argv, param_class);
52
+
53
+ rb_ary_push(parameters, param);
54
+ }
55
+
56
+ signature = rb_class_new_instance(1, &parameters, cSignature);
57
+ }
58
+
59
+ rb_ary_push(signatures, signature);
60
+ }
61
+
62
+ rdx_definition_signatures_free(arr);
63
+ return signatures;
64
+ }
65
+
66
+ void rdxi_initialize_signature(VALUE mRubydex) {
67
+ cSignature = rb_define_class_under(mRubydex, "Signature", rb_cObject);
68
+
69
+ cParameter = rb_define_class_under(cSignature, "Parameter", rb_cObject);
70
+ cPositionalParameter = rb_define_class_under(cSignature, "PositionalParameter", cParameter);
71
+ cOptionalPositionalParameter = rb_define_class_under(cSignature, "OptionalPositionalParameter", cParameter);
72
+ cRestPositionalParameter = rb_define_class_under(cSignature, "RestPositionalParameter", cParameter);
73
+ cPostParameter = rb_define_class_under(cSignature, "PostParameter", cParameter);
74
+ cKeywordParameter = rb_define_class_under(cSignature, "KeywordParameter", cParameter);
75
+ cOptionalKeywordParameter = rb_define_class_under(cSignature, "OptionalKeywordParameter", cParameter);
76
+ cRestKeywordParameter = rb_define_class_under(cSignature, "RestKeywordParameter", cParameter);
77
+ cForwardParameter = rb_define_class_under(cSignature, "ForwardParameter", cParameter);
78
+ cBlockParameter = rb_define_class_under(cSignature, "BlockParameter", cParameter);
79
+
80
+ empty_params = rb_ary_new();
81
+ OBJ_FREEZE(empty_params);
82
+ rb_gc_register_mark_object(empty_params);
83
+ }
@@ -0,0 +1,23 @@
1
+ #ifndef RUBYDEX_SIGNATURE_H
2
+ #define RUBYDEX_SIGNATURE_H
3
+
4
+ #include "ruby.h"
5
+ #include "rustbindings.h"
6
+
7
+ extern VALUE cSignature;
8
+ extern VALUE cParameter;
9
+ extern VALUE cPositionalParameter;
10
+ extern VALUE cOptionalPositionalParameter;
11
+ extern VALUE cRestPositionalParameter;
12
+ extern VALUE cPostParameter;
13
+ extern VALUE cKeywordParameter;
14
+ extern VALUE cOptionalKeywordParameter;
15
+ extern VALUE cRestKeywordParameter;
16
+ extern VALUE cForwardParameter;
17
+ extern VALUE cBlockParameter;
18
+
19
+ void rdxi_initialize_signature(VALUE mRubydex);
20
+
21
+ VALUE rdxi_signatures_to_ruby(SignatureArray *arr);
22
+
23
+ #endif // RUBYDEX_SIGNATURE_H
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ class Signature
5
+ class Parameter
6
+ #: Symbol
7
+ attr_reader :name
8
+
9
+ #: Location
10
+ attr_reader :location
11
+
12
+ #: (Symbol, Location) -> void
13
+ def initialize(name, location)
14
+ @name = name
15
+ @location = location
16
+ end
17
+ end
18
+
19
+ class PositionalParameter < Parameter; end
20
+ class OptionalPositionalParameter < Parameter; end
21
+ class RestPositionalParameter < Parameter; end
22
+ class PostParameter < Parameter; end
23
+ class KeywordParameter < Parameter; end
24
+ class OptionalKeywordParameter < Parameter; end
25
+ class RestKeywordParameter < Parameter; end
26
+ class ForwardParameter < Parameter; end
27
+ class BlockParameter < Parameter; end
28
+
29
+ #: Array[Parameter]
30
+ attr_reader :parameters
31
+
32
+ #: (Array[Parameter]) -> void
33
+ def initialize(parameters)
34
+ @parameters = parameters
35
+ end
36
+
37
+ #: () -> [Array[PositionalParameter], Array[OptionalPositionalParameter], RestPositionalParameter?, Array[PostParameter], Array[KeywordParameter], Array[OptionalKeywordParameter], RestKeywordParameter?, ForwardParameter?, BlockParameter?]
38
+ def deconstruct
39
+ positionals = [] #: Array[PositionalParameter]
40
+ optional_positionals = [] #: Array[OptionalPositionalParameter]
41
+ rest_positional = nil #: RestPositionalParameter?
42
+ posts = [] #: Array[PostParameter]
43
+ keywords = [] #: Array[KeywordParameter]
44
+ optional_keywords = [] #: Array[OptionalKeywordParameter]
45
+ rest_keyword = nil #: RestKeywordParameter?
46
+ forward = nil #: ForwardParameter?
47
+ block = nil #: BlockParameter?
48
+
49
+ parameters.each do |param|
50
+ case param
51
+ when PositionalParameter then positionals << param
52
+ when OptionalPositionalParameter then optional_positionals << param
53
+ when RestPositionalParameter then rest_positional = param
54
+ when PostParameter then posts << param
55
+ when KeywordParameter then keywords << param
56
+ when OptionalKeywordParameter then optional_keywords << param
57
+ when RestKeywordParameter then rest_keyword = param
58
+ when ForwardParameter then forward = param
59
+ when BlockParameter then block = param
60
+ end
61
+ end
62
+
63
+ [positionals, optional_positionals, rest_positional, posts, keywords, optional_keywords, rest_keyword, forward, block]
64
+ end
65
+
66
+ DECONSTRUCT_KEYS = [
67
+ :positional_parameters,
68
+ :optional_positional_parameters,
69
+ :rest_positional_parameter,
70
+ :post_parameters,
71
+ :keyword_parameters,
72
+ :optional_keyword_parameters,
73
+ :rest_keyword_parameter,
74
+ :forward_parameter,
75
+ :block_parameter,
76
+ ].freeze #: Array[Symbol]
77
+ private_constant :DECONSTRUCT_KEYS
78
+
79
+ #: (Array[Symbol]?) -> Hash[Symbol, untyped]
80
+ def deconstruct_keys(keys)
81
+ keys = DECONSTRUCT_KEYS if keys.nil?
82
+
83
+ positionals, optional_positionals, rest_positional, posts,
84
+ keywords, optional_keywords, rest_keyword, forward, block = deconstruct
85
+
86
+ result = {} #: Hash[Symbol, untyped]
87
+ keys.each do |key|
88
+ case key
89
+ when :positional_parameters then result[key] = positionals
90
+ when :optional_positional_parameters then result[key] = optional_positionals
91
+ when :rest_positional_parameter then result[key] = rest_positional
92
+ when :post_parameters then result[key] = posts
93
+ when :keyword_parameters then result[key] = keywords
94
+ when :optional_keyword_parameters then result[key] = optional_keywords
95
+ when :rest_keyword_parameter then result[key] = rest_keyword
96
+ when :forward_parameter then result[key] = forward
97
+ when :block_parameter then result[key] = block
98
+ end
99
+ end
100
+ result
101
+ end
102
+
103
+ #: () -> Array[PositionalParameter]
104
+ def positional_parameters = deconstruct[0]
105
+
106
+ #: () -> Array[OptionalPositionalParameter]
107
+ def optional_positional_parameters = deconstruct[1]
108
+
109
+ #: () -> RestPositionalParameter?
110
+ def rest_positional_parameter = deconstruct[2]
111
+
112
+ #: () -> Array[PostParameter]
113
+ def post_parameters = deconstruct[3]
114
+
115
+ #: () -> Array[KeywordParameter]
116
+ def keyword_parameters = deconstruct[4]
117
+
118
+ #: () -> Array[OptionalKeywordParameter]
119
+ def optional_keyword_parameters = deconstruct[5]
120
+
121
+ #: () -> RestKeywordParameter?
122
+ def rest_keyword_parameter = deconstruct[6]
123
+
124
+ #: () -> ForwardParameter?
125
+ def forward_parameter = deconstruct[7]
126
+
127
+ #: () -> BlockParameter?
128
+ def block_parameter = deconstruct[8]
129
+ end
130
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubydex
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.2"
5
5
  end
data/lib/rubydex.rb CHANGED
@@ -22,3 +22,4 @@ require "rubydex/keyword"
22
22
  require "rubydex/keyword_parameter"
23
23
  require "rubydex/graph"
24
24
  require "rubydex/declaration"
25
+ require "rubydex/signature"
@@ -1200,9 +1200,7 @@ impl<'a> RubyIndexer<'a> {
1200
1200
  }
1201
1201
  Some(ruby_prism::Node::SelfNode { .. }) | None => match self.nesting_stack.last() {
1202
1202
  Some(Nesting::Method(_)) => {
1203
- // Dynamic private constant (called from a method), we ignore it but don't report an error since it's valid Ruby
1204
- // if being called from a singleton method.
1205
-
1203
+ self.visit_call_node_parts(node);
1206
1204
  return;
1207
1205
  }
1208
1206
  None => {
@@ -1211,7 +1209,7 @@ impl<'a> RubyIndexer<'a> {
1211
1209
  Offset::from_prism_location(&node.location()),
1212
1210
  "Private constant called at top level".to_string(),
1213
1211
  );
1214
-
1212
+ self.visit_call_node_parts(node);
1215
1213
  return;
1216
1214
  }
1217
1215
  _ => None,
@@ -1222,7 +1220,7 @@ impl<'a> RubyIndexer<'a> {
1222
1220
  Offset::from_prism_location(&node.location()),
1223
1221
  "Dynamic receiver for private constant".to_string(),
1224
1222
  );
1225
-
1223
+ self.visit_call_node_parts(node);
1226
1224
  return;
1227
1225
  }
1228
1226
  };
@@ -1252,8 +1250,8 @@ impl<'a> RubyIndexer<'a> {
1252
1250
  Offset::from_prism_location(&argument.location()),
1253
1251
  "Private constant called with non-symbol argument".to_string(),
1254
1252
  );
1255
-
1256
- return;
1253
+ self.visit(&argument);
1254
+ continue;
1257
1255
  }
1258
1256
  };
1259
1257
 
@@ -1276,6 +1274,60 @@ impl<'a> RubyIndexer<'a> {
1276
1274
  }
1277
1275
  }
1278
1276
 
1277
+ fn handle_singleton_method_visibility(
1278
+ &mut self,
1279
+ node: &ruby_prism::CallNode,
1280
+ visibility: Visibility,
1281
+ call_name: &str,
1282
+ ) {
1283
+ match node.receiver() {
1284
+ Some(ruby_prism::Node::SelfNode { .. }) | None => match self.nesting_stack.last() {
1285
+ Some(Nesting::Method(_)) => {
1286
+ self.visit_call_node_parts(node);
1287
+ return;
1288
+ }
1289
+ None => {
1290
+ self.local_graph.add_diagnostic(
1291
+ Rule::InvalidMethodVisibility,
1292
+ Offset::from_prism_location(&node.location()),
1293
+ format!("`{call_name}` called at top level"),
1294
+ );
1295
+ self.visit_call_node_parts(node);
1296
+ return;
1297
+ }
1298
+ _ => {}
1299
+ },
1300
+ _ => {
1301
+ self.visit_call_node_parts(node);
1302
+ return;
1303
+ }
1304
+ }
1305
+
1306
+ let Some(arguments) = node.arguments() else {
1307
+ return;
1308
+ };
1309
+
1310
+ for argument in &arguments.arguments() {
1311
+ match argument {
1312
+ ruby_prism::Node::SymbolNode { .. } | ruby_prism::Node::StringNode { .. } => {
1313
+ self.create_method_visibility_definition(
1314
+ &argument,
1315
+ visibility,
1316
+ DefinitionFlags::SINGLETON_METHOD_VISIBILITY,
1317
+ );
1318
+ }
1319
+ _ => {
1320
+ self.local_graph.add_diagnostic(
1321
+ Rule::InvalidMethodVisibility,
1322
+ Offset::from_prism_location(&argument.location()),
1323
+ format!("`{call_name}` called with a non-literal argument"),
1324
+ );
1325
+ self.visit(&argument);
1326
+ }
1327
+ }
1328
+ }
1329
+ }
1330
+
1279
1331
  fn is_attr_call(arg: &ruby_prism::Node) -> bool {
1280
1332
  arg.as_call_node().is_some_and(|call| {
1281
1333
  let receiver = call.receiver();
@@ -1313,7 +1365,7 @@ impl<'a> RubyIndexer<'a> {
1313
1365
  arg,
1314
1366
  ruby_prism::Node::SymbolNode { .. } | ruby_prism::Node::StringNode { .. }
1315
1367
  ) {
1316
- self.create_method_visibility_definition(&arg, visibility);
1368
+ self.create_method_visibility_definition(&arg, visibility, DefinitionFlags::empty());
1317
1369
  } else {
1318
1370
  // Unsupported arg — diagnostic + visit for side effects.
1319
1371
  let arg_offset = Offset::from_prism_location(&arg.location());
@@ -1329,7 +1381,12 @@ impl<'a> RubyIndexer<'a> {
1329
1381
  }
1330
1382
  }
1331
1383
 
1332
- fn create_method_visibility_definition(&mut self, arg: &ruby_prism::Node, visibility: Visibility) {
1384
+ fn create_method_visibility_definition(
1385
+ &mut self,
1386
+ arg: &ruby_prism::Node,
1387
+ visibility: Visibility,
1388
+ flags: DefinitionFlags,
1389
+ ) {
1333
1390
  let (name, location) = match arg {
1334
1391
  ruby_prism::Node::SymbolNode { .. } => {
1335
1392
  let symbol = arg.as_symbol_node().unwrap();
@@ -1355,7 +1412,7 @@ impl<'a> RubyIndexer<'a> {
1355
1412
  self.uri_id,
1356
1413
  arg_offset,
1357
1414
  Box::default(),
1358
- DefinitionFlags::empty(),
1415
+ flags,
1359
1416
  self.current_nesting_definition_id(),
1360
1417
  )));
1361
1418
 
@@ -2049,6 +2106,12 @@ impl Visit<'_> for RubyIndexer<'_> {
2049
2106
  "public_constant" => {
2050
2107
  self.handle_constant_visibility(node, Visibility::Public);
2051
2108
  }
2109
+ "private_class_method" => {
2110
+ self.handle_singleton_method_visibility(node, Visibility::Private, "private_class_method");
2111
+ }
2112
+ "public_class_method" => {
2113
+ self.handle_singleton_method_visibility(node, Visibility::Public, "public_class_method");
2114
+ }
2052
2115
  _ => {
2053
2116
  // For method calls that we don't explicitly handle each part, we continue visiting their parts as we
2054
2117
  // may discover something inside