rubydex 0.2.1-aarch64-linux → 0.2.3-aarch64-linux

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.
@@ -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,146 @@ impl<'a> RubyIndexer<'a> {
1276
1274
  }
1277
1275
  }
1278
1276
 
1277
+ #[allow(clippy::too_many_lines)]
1278
+ fn handle_singleton_method_visibility(
1279
+ &mut self,
1280
+ node: &ruby_prism::CallNode,
1281
+ visibility: Visibility,
1282
+ call_name: &str,
1283
+ ) {
1284
+ match node.receiver() {
1285
+ Some(ruby_prism::Node::SelfNode { .. }) | None => match self.nesting_stack.last() {
1286
+ Some(Nesting::Method(_)) => {
1287
+ self.visit_call_node_parts(node);
1288
+ return;
1289
+ }
1290
+ None => {
1291
+ self.local_graph.add_diagnostic(
1292
+ Rule::InvalidMethodVisibility,
1293
+ Offset::from_prism_location(&node.location()),
1294
+ format!("`{call_name}` called at top level"),
1295
+ );
1296
+ self.visit_call_node_parts(node);
1297
+ return;
1298
+ }
1299
+ _ => {}
1300
+ },
1301
+ _ => {
1302
+ self.visit_call_node_parts(node);
1303
+ return;
1304
+ }
1305
+ }
1306
+
1307
+ let Some(arguments) = node.arguments() else {
1308
+ return;
1309
+ };
1310
+
1311
+ let args = arguments.arguments();
1312
+ let arg_count = args.len();
1313
+
1314
+ for argument in &args {
1315
+ match argument {
1316
+ ruby_prism::Node::SymbolNode { .. } | ruby_prism::Node::StringNode { .. } => {
1317
+ self.create_method_visibility_definition(
1318
+ &argument,
1319
+ visibility,
1320
+ DefinitionFlags::SINGLETON_METHOD_VISIBILITY,
1321
+ );
1322
+ }
1323
+ ruby_prism::Node::ArrayNode { .. } if arg_count == 1 => {
1324
+ let array = argument.as_array_node().unwrap();
1325
+ for element in &array.elements() {
1326
+ match element {
1327
+ ruby_prism::Node::SymbolNode { .. } | ruby_prism::Node::StringNode { .. } => {
1328
+ self.create_method_visibility_definition(
1329
+ &element,
1330
+ visibility,
1331
+ DefinitionFlags::SINGLETON_METHOD_VISIBILITY,
1332
+ );
1333
+ }
1334
+ ruby_prism::Node::DefNode { .. } => {
1335
+ let def_node = element.as_def_node().unwrap();
1336
+ if def_node.receiver().is_none() {
1337
+ self.local_graph.add_diagnostic(
1338
+ Rule::InvalidMethodVisibility,
1339
+ Offset::from_prism_location(&element.location()),
1340
+ format!("`{call_name}` requires a singleton method definition"),
1341
+ );
1342
+ self.visit(&element);
1343
+ continue;
1344
+ }
1345
+ let name_loc = def_node.name_loc();
1346
+ let name = Self::location_to_string(&name_loc);
1347
+ self.create_method_visibility_definition_from_name(
1348
+ &name,
1349
+ &name_loc,
1350
+ visibility,
1351
+ DefinitionFlags::SINGLETON_METHOD_VISIBILITY,
1352
+ );
1353
+ self.visit(&element);
1354
+ }
1355
+ _ => {
1356
+ self.local_graph.add_diagnostic(
1357
+ Rule::InvalidMethodVisibility,
1358
+ Offset::from_prism_location(&element.location()),
1359
+ format!(
1360
+ "`{call_name}` array element must be a Symbol, String, or method definition"
1361
+ ),
1362
+ );
1363
+ self.visit(&element);
1364
+ }
1365
+ }
1366
+ }
1367
+ }
1368
+ ruby_prism::Node::DefNode { .. } => {
1369
+ let def_node = argument.as_def_node().unwrap();
1370
+ if def_node.receiver().is_none() {
1371
+ self.local_graph.add_diagnostic(
1372
+ Rule::InvalidMethodVisibility,
1373
+ Offset::from_prism_location(&argument.location()),
1374
+ format!("`{call_name}` requires a singleton method definition"),
1375
+ );
1376
+ self.visit(&argument);
1377
+ continue;
1378
+ }
1379
+ let name_loc = def_node.name_loc();
1380
+ let name = Self::location_to_string(&name_loc);
1381
+ self.create_method_visibility_definition_from_name(
1382
+ &name,
1383
+ &name_loc,
1384
+ visibility,
1385
+ DefinitionFlags::SINGLETON_METHOD_VISIBILITY,
1386
+ );
1387
+ self.visit(&argument);
1388
+ }
1389
+ arg if Self::is_attr_call(&arg) => {
1390
+ self.local_graph.add_diagnostic(
1391
+ Rule::InvalidMethodVisibility,
1392
+ Offset::from_prism_location(&arg.location()),
1393
+ format!("`{call_name}` does not accept `attr_*` arguments"),
1394
+ );
1395
+ self.visit(&arg);
1396
+ }
1397
+ ruby_prism::Node::ArrayNode { .. } => {
1398
+ self.local_graph.add_diagnostic(
1399
+ Rule::InvalidMethodVisibility,
1400
+ Offset::from_prism_location(&argument.location()),
1401
+ format!("`{call_name}` array argument must be the only argument"),
1402
+ );
1403
+ self.visit(&argument);
1404
+ }
1405
+ _ => {
1406
+ self.local_graph.add_diagnostic(
1407
+ Rule::InvalidMethodVisibility,
1408
+ Offset::from_prism_location(&argument.location()),
1409
+ format!("`{call_name}` called with a non-literal argument"),
1410
+ );
1411
+ self.visit(&argument);
1412
+ }
1413
+ }
1414
+ }
1415
+ }
1416
+
1279
1417
  fn is_attr_call(arg: &ruby_prism::Node) -> bool {
1280
1418
  arg.as_call_node().is_some_and(|call| {
1281
1419
  let receiver = call.receiver();
@@ -1313,7 +1451,7 @@ impl<'a> RubyIndexer<'a> {
1313
1451
  arg,
1314
1452
  ruby_prism::Node::SymbolNode { .. } | ruby_prism::Node::StringNode { .. }
1315
1453
  ) {
1316
- self.create_method_visibility_definition(&arg, visibility);
1454
+ self.create_method_visibility_definition(&arg, visibility, DefinitionFlags::empty());
1317
1455
  } else {
1318
1456
  // Unsupported arg — diagnostic + visit for side effects.
1319
1457
  let arg_offset = Offset::from_prism_location(&arg.location());
@@ -1329,15 +1467,17 @@ impl<'a> RubyIndexer<'a> {
1329
1467
  }
1330
1468
  }
1331
1469
 
1332
- fn create_method_visibility_definition(&mut self, arg: &ruby_prism::Node, visibility: Visibility) {
1470
+ fn create_method_visibility_definition(
1471
+ &mut self,
1472
+ arg: &ruby_prism::Node,
1473
+ visibility: Visibility,
1474
+ flags: DefinitionFlags,
1475
+ ) {
1333
1476
  let (name, location) = match arg {
1334
1477
  ruby_prism::Node::SymbolNode { .. } => {
1335
1478
  let symbol = arg.as_symbol_node().unwrap();
1336
- if let Some(value_loc) = symbol.value_loc() {
1337
- (Self::location_to_string(&value_loc), value_loc)
1338
- } else {
1339
- return;
1340
- }
1479
+ let Some(value_loc) = symbol.value_loc() else { return };
1480
+ (Self::location_to_string(&value_loc), value_loc)
1341
1481
  }
1342
1482
  ruby_prism::Node::StringNode { .. } => {
1343
1483
  let string = arg.as_string_node().unwrap();
@@ -1347,15 +1487,25 @@ impl<'a> RubyIndexer<'a> {
1347
1487
  _ => return,
1348
1488
  };
1349
1489
 
1490
+ self.create_method_visibility_definition_from_name(&name, &location, visibility, flags);
1491
+ }
1492
+
1493
+ fn create_method_visibility_definition_from_name(
1494
+ &mut self,
1495
+ name: &str,
1496
+ location: &ruby_prism::Location,
1497
+ visibility: Visibility,
1498
+ flags: DefinitionFlags,
1499
+ ) {
1350
1500
  let str_id = self.local_graph.intern_string(format!("{name}()"));
1351
- let arg_offset = Offset::from_prism_location(&location);
1501
+ let arg_offset = Offset::from_prism_location(location);
1352
1502
  let definition = Definition::MethodVisibility(Box::new(MethodVisibilityDefinition::new(
1353
1503
  str_id,
1354
1504
  visibility,
1355
1505
  self.uri_id,
1356
1506
  arg_offset,
1357
1507
  Box::default(),
1358
- DefinitionFlags::empty(),
1508
+ flags,
1359
1509
  self.current_nesting_definition_id(),
1360
1510
  )));
1361
1511
 
@@ -2049,6 +2199,12 @@ impl Visit<'_> for RubyIndexer<'_> {
2049
2199
  "public_constant" => {
2050
2200
  self.handle_constant_visibility(node, Visibility::Public);
2051
2201
  }
2202
+ "private_class_method" => {
2203
+ self.handle_singleton_method_visibility(node, Visibility::Private, "private_class_method");
2204
+ }
2205
+ "public_class_method" => {
2206
+ self.handle_singleton_method_visibility(node, Visibility::Public, "public_class_method");
2207
+ }
2052
2208
  _ => {
2053
2209
  // For method calls that we don't explicitly handle each part, we continue visiting their parts as we
2054
2210
  // may discover something inside