prism 0.14.0 → 0.15.1
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 +4 -4
- data/CHANGELOG.md +25 -1
- data/README.md +1 -1
- data/config.yml +86 -21
- data/ext/prism/api_node.c +213 -67
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +133 -83
- data/include/prism/diagnostic.h +1 -0
- data/include/prism/node.h +7 -0
- data/include/prism/util/pm_constant_pool.h +20 -6
- data/include/prism/version.h +3 -3
- data/include/prism.h +1 -1
- data/lib/prism/compiler.rb +9 -0
- data/lib/prism/debug.rb +30 -26
- data/lib/prism/dispatcher.rb +42 -0
- data/lib/prism/dsl.rb +23 -8
- data/lib/prism/ffi.rb +2 -2
- data/lib/prism/lex_compat.rb +9 -9
- data/lib/prism/mutation_compiler.rb +18 -3
- data/lib/prism/node.rb +580 -120
- data/lib/prism/serialize.rb +84 -78
- data/lib/prism/visitor.rb +9 -0
- data/prism.gemspec +1 -1
- data/src/diagnostic.c +1 -0
- data/src/node.c +99 -18
- data/src/prettyprint.c +102 -45
- data/src/prism.c +288 -88
- data/src/serialize.c +95 -57
- data/src/util/pm_constant_pool.c +25 -11
- metadata +2 -2
data/lib/prism/node.rb
CHANGED
@@ -1018,8 +1018,12 @@ module Prism
|
|
1018
1018
|
# $'
|
1019
1019
|
# ^^
|
1020
1020
|
class BackReferenceReadNode < Node
|
1021
|
-
#
|
1022
|
-
|
1021
|
+
# attr_reader name: Symbol
|
1022
|
+
attr_reader :name
|
1023
|
+
|
1024
|
+
# def initialize: (name: Symbol, location: Location) -> void
|
1025
|
+
def initialize(name, location)
|
1026
|
+
@name = name
|
1023
1027
|
@location = location
|
1024
1028
|
end
|
1025
1029
|
|
@@ -1046,6 +1050,7 @@ module Prism
|
|
1046
1050
|
# def copy: (**params) -> BackReferenceReadNode
|
1047
1051
|
def copy(**params)
|
1048
1052
|
BackReferenceReadNode.new(
|
1053
|
+
params.fetch(:name) { name },
|
1049
1054
|
params.fetch(:location) { location },
|
1050
1055
|
)
|
1051
1056
|
end
|
@@ -1055,11 +1060,12 @@ module Prism
|
|
1055
1060
|
|
1056
1061
|
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
|
1057
1062
|
def deconstruct_keys(keys)
|
1058
|
-
{ location: location }
|
1063
|
+
{ name: name, location: location }
|
1059
1064
|
end
|
1060
1065
|
|
1061
1066
|
def inspect(inspector = NodeInspector.new)
|
1062
1067
|
inspector << inspector.header(self)
|
1068
|
+
inspector << "└── name: #{name.inspect}\n"
|
1063
1069
|
inspector.to_str
|
1064
1070
|
end
|
1065
1071
|
|
@@ -1913,15 +1919,6 @@ module Prism
|
|
1913
1919
|
# attr_reader message_loc: Location?
|
1914
1920
|
attr_reader :message_loc
|
1915
1921
|
|
1916
|
-
# attr_reader opening_loc: Location?
|
1917
|
-
attr_reader :opening_loc
|
1918
|
-
|
1919
|
-
# attr_reader arguments: ArgumentsNode?
|
1920
|
-
attr_reader :arguments
|
1921
|
-
|
1922
|
-
# attr_reader closing_loc: Location?
|
1923
|
-
attr_reader :closing_loc
|
1924
|
-
|
1925
1922
|
# attr_reader flags: Integer
|
1926
1923
|
private attr_reader :flags
|
1927
1924
|
|
@@ -1937,14 +1934,11 @@ module Prism
|
|
1937
1934
|
# attr_reader value: Node
|
1938
1935
|
attr_reader :value
|
1939
1936
|
|
1940
|
-
# def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?,
|
1941
|
-
def initialize(receiver, call_operator_loc, message_loc,
|
1937
|
+
# def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Node, location: Location) -> void
|
1938
|
+
def initialize(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
|
1942
1939
|
@receiver = receiver
|
1943
1940
|
@call_operator_loc = call_operator_loc
|
1944
1941
|
@message_loc = message_loc
|
1945
|
-
@opening_loc = opening_loc
|
1946
|
-
@arguments = arguments
|
1947
|
-
@closing_loc = closing_loc
|
1948
1942
|
@flags = flags
|
1949
1943
|
@read_name = read_name
|
1950
1944
|
@write_name = write_name
|
@@ -1960,21 +1954,20 @@ module Prism
|
|
1960
1954
|
|
1961
1955
|
# def child_nodes: () -> Array[nil | Node]
|
1962
1956
|
def child_nodes
|
1963
|
-
[receiver,
|
1957
|
+
[receiver, value]
|
1964
1958
|
end
|
1965
1959
|
|
1966
1960
|
# def compact_child_nodes: () -> Array[Node]
|
1967
1961
|
def compact_child_nodes
|
1968
1962
|
compact = []
|
1969
1963
|
compact << receiver if receiver
|
1970
|
-
compact << arguments if arguments
|
1971
1964
|
compact << value
|
1972
1965
|
compact
|
1973
1966
|
end
|
1974
1967
|
|
1975
1968
|
# def comment_targets: () -> Array[Node | Location]
|
1976
1969
|
def comment_targets
|
1977
|
-
[*receiver, *call_operator_loc, *message_loc,
|
1970
|
+
[*receiver, *call_operator_loc, *message_loc, operator_loc, value]
|
1978
1971
|
end
|
1979
1972
|
|
1980
1973
|
# def copy: (**params) -> CallAndWriteNode
|
@@ -1983,9 +1976,6 @@ module Prism
|
|
1983
1976
|
params.fetch(:receiver) { receiver },
|
1984
1977
|
params.fetch(:call_operator_loc) { call_operator_loc },
|
1985
1978
|
params.fetch(:message_loc) { message_loc },
|
1986
|
-
params.fetch(:opening_loc) { opening_loc },
|
1987
|
-
params.fetch(:arguments) { arguments },
|
1988
|
-
params.fetch(:closing_loc) { closing_loc },
|
1989
1979
|
params.fetch(:flags) { flags },
|
1990
1980
|
params.fetch(:read_name) { read_name },
|
1991
1981
|
params.fetch(:write_name) { write_name },
|
@@ -2000,7 +1990,7 @@ module Prism
|
|
2000
1990
|
|
2001
1991
|
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
|
2002
1992
|
def deconstruct_keys(keys)
|
2003
|
-
{ receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc,
|
1993
|
+
{ receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, flags: flags, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value, location: location }
|
2004
1994
|
end
|
2005
1995
|
|
2006
1996
|
# def call_operator: () -> String?
|
@@ -2013,16 +2003,6 @@ module Prism
|
|
2013
2003
|
message_loc&.slice
|
2014
2004
|
end
|
2015
2005
|
|
2016
|
-
# def opening: () -> String?
|
2017
|
-
def opening
|
2018
|
-
opening_loc&.slice
|
2019
|
-
end
|
2020
|
-
|
2021
|
-
# def closing: () -> String?
|
2022
|
-
def closing
|
2023
|
-
closing_loc&.slice
|
2024
|
-
end
|
2025
|
-
|
2026
2006
|
# def safe_navigation?: () -> bool
|
2027
2007
|
def safe_navigation?
|
2028
2008
|
flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
|
@@ -2048,14 +2028,6 @@ module Prism
|
|
2048
2028
|
end
|
2049
2029
|
inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
|
2050
2030
|
inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
|
2051
|
-
inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
|
2052
|
-
if (arguments = self.arguments).nil?
|
2053
|
-
inspector << "├── arguments: ∅\n"
|
2054
|
-
else
|
2055
|
-
inspector << "├── arguments:\n"
|
2056
|
-
inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
2057
|
-
end
|
2058
|
-
inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
|
2059
2031
|
flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
|
2060
2032
|
inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
|
2061
2033
|
inspector << "├── read_name: #{read_name.inspect}\n"
|
@@ -2307,15 +2279,6 @@ module Prism
|
|
2307
2279
|
# attr_reader message_loc: Location?
|
2308
2280
|
attr_reader :message_loc
|
2309
2281
|
|
2310
|
-
# attr_reader opening_loc: Location?
|
2311
|
-
attr_reader :opening_loc
|
2312
|
-
|
2313
|
-
# attr_reader arguments: ArgumentsNode?
|
2314
|
-
attr_reader :arguments
|
2315
|
-
|
2316
|
-
# attr_reader closing_loc: Location?
|
2317
|
-
attr_reader :closing_loc
|
2318
|
-
|
2319
2282
|
# attr_reader flags: Integer
|
2320
2283
|
private attr_reader :flags
|
2321
2284
|
|
@@ -2334,14 +2297,11 @@ module Prism
|
|
2334
2297
|
# attr_reader value: Node
|
2335
2298
|
attr_reader :value
|
2336
2299
|
|
2337
|
-
# def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?,
|
2338
|
-
def initialize(receiver, call_operator_loc, message_loc,
|
2300
|
+
# def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator: Symbol, operator_loc: Location, value: Node, location: Location) -> void
|
2301
|
+
def initialize(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator, operator_loc, value, location)
|
2339
2302
|
@receiver = receiver
|
2340
2303
|
@call_operator_loc = call_operator_loc
|
2341
2304
|
@message_loc = message_loc
|
2342
|
-
@opening_loc = opening_loc
|
2343
|
-
@arguments = arguments
|
2344
|
-
@closing_loc = closing_loc
|
2345
2305
|
@flags = flags
|
2346
2306
|
@read_name = read_name
|
2347
2307
|
@write_name = write_name
|
@@ -2358,21 +2318,20 @@ module Prism
|
|
2358
2318
|
|
2359
2319
|
# def child_nodes: () -> Array[nil | Node]
|
2360
2320
|
def child_nodes
|
2361
|
-
[receiver,
|
2321
|
+
[receiver, value]
|
2362
2322
|
end
|
2363
2323
|
|
2364
2324
|
# def compact_child_nodes: () -> Array[Node]
|
2365
2325
|
def compact_child_nodes
|
2366
2326
|
compact = []
|
2367
2327
|
compact << receiver if receiver
|
2368
|
-
compact << arguments if arguments
|
2369
2328
|
compact << value
|
2370
2329
|
compact
|
2371
2330
|
end
|
2372
2331
|
|
2373
2332
|
# def comment_targets: () -> Array[Node | Location]
|
2374
2333
|
def comment_targets
|
2375
|
-
[*receiver, *call_operator_loc, *message_loc,
|
2334
|
+
[*receiver, *call_operator_loc, *message_loc, operator_loc, value]
|
2376
2335
|
end
|
2377
2336
|
|
2378
2337
|
# def copy: (**params) -> CallOperatorWriteNode
|
@@ -2381,9 +2340,6 @@ module Prism
|
|
2381
2340
|
params.fetch(:receiver) { receiver },
|
2382
2341
|
params.fetch(:call_operator_loc) { call_operator_loc },
|
2383
2342
|
params.fetch(:message_loc) { message_loc },
|
2384
|
-
params.fetch(:opening_loc) { opening_loc },
|
2385
|
-
params.fetch(:arguments) { arguments },
|
2386
|
-
params.fetch(:closing_loc) { closing_loc },
|
2387
2343
|
params.fetch(:flags) { flags },
|
2388
2344
|
params.fetch(:read_name) { read_name },
|
2389
2345
|
params.fetch(:write_name) { write_name },
|
@@ -2399,7 +2355,7 @@ module Prism
|
|
2399
2355
|
|
2400
2356
|
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
|
2401
2357
|
def deconstruct_keys(keys)
|
2402
|
-
{ receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc,
|
2358
|
+
{ receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, flags: flags, read_name: read_name, write_name: write_name, operator: operator, operator_loc: operator_loc, value: value, location: location }
|
2403
2359
|
end
|
2404
2360
|
|
2405
2361
|
# def call_operator: () -> String?
|
@@ -2412,16 +2368,6 @@ module Prism
|
|
2412
2368
|
message_loc&.slice
|
2413
2369
|
end
|
2414
2370
|
|
2415
|
-
# def opening: () -> String?
|
2416
|
-
def opening
|
2417
|
-
opening_loc&.slice
|
2418
|
-
end
|
2419
|
-
|
2420
|
-
# def closing: () -> String?
|
2421
|
-
def closing
|
2422
|
-
closing_loc&.slice
|
2423
|
-
end
|
2424
|
-
|
2425
2371
|
# def safe_navigation?: () -> bool
|
2426
2372
|
def safe_navigation?
|
2427
2373
|
flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
|
@@ -2442,14 +2388,6 @@ module Prism
|
|
2442
2388
|
end
|
2443
2389
|
inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
|
2444
2390
|
inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
|
2445
|
-
inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
|
2446
|
-
if (arguments = self.arguments).nil?
|
2447
|
-
inspector << "├── arguments: ∅\n"
|
2448
|
-
else
|
2449
|
-
inspector << "├── arguments:\n"
|
2450
|
-
inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
2451
|
-
end
|
2452
|
-
inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
|
2453
2391
|
flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
|
2454
2392
|
inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
|
2455
2393
|
inspector << "├── read_name: #{read_name.inspect}\n"
|
@@ -2504,15 +2442,6 @@ module Prism
|
|
2504
2442
|
# attr_reader message_loc: Location?
|
2505
2443
|
attr_reader :message_loc
|
2506
2444
|
|
2507
|
-
# attr_reader opening_loc: Location?
|
2508
|
-
attr_reader :opening_loc
|
2509
|
-
|
2510
|
-
# attr_reader arguments: ArgumentsNode?
|
2511
|
-
attr_reader :arguments
|
2512
|
-
|
2513
|
-
# attr_reader closing_loc: Location?
|
2514
|
-
attr_reader :closing_loc
|
2515
|
-
|
2516
2445
|
# attr_reader flags: Integer
|
2517
2446
|
private attr_reader :flags
|
2518
2447
|
|
@@ -2528,14 +2457,11 @@ module Prism
|
|
2528
2457
|
# attr_reader value: Node
|
2529
2458
|
attr_reader :value
|
2530
2459
|
|
2531
|
-
# def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?,
|
2532
|
-
def initialize(receiver, call_operator_loc, message_loc,
|
2460
|
+
# def initialize: (receiver: Node?, call_operator_loc: Location?, message_loc: Location?, flags: Integer, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Node, location: Location) -> void
|
2461
|
+
def initialize(receiver, call_operator_loc, message_loc, flags, read_name, write_name, operator_loc, value, location)
|
2533
2462
|
@receiver = receiver
|
2534
2463
|
@call_operator_loc = call_operator_loc
|
2535
2464
|
@message_loc = message_loc
|
2536
|
-
@opening_loc = opening_loc
|
2537
|
-
@arguments = arguments
|
2538
|
-
@closing_loc = closing_loc
|
2539
2465
|
@flags = flags
|
2540
2466
|
@read_name = read_name
|
2541
2467
|
@write_name = write_name
|
@@ -2551,21 +2477,20 @@ module Prism
|
|
2551
2477
|
|
2552
2478
|
# def child_nodes: () -> Array[nil | Node]
|
2553
2479
|
def child_nodes
|
2554
|
-
[receiver,
|
2480
|
+
[receiver, value]
|
2555
2481
|
end
|
2556
2482
|
|
2557
2483
|
# def compact_child_nodes: () -> Array[Node]
|
2558
2484
|
def compact_child_nodes
|
2559
2485
|
compact = []
|
2560
2486
|
compact << receiver if receiver
|
2561
|
-
compact << arguments if arguments
|
2562
2487
|
compact << value
|
2563
2488
|
compact
|
2564
2489
|
end
|
2565
2490
|
|
2566
2491
|
# def comment_targets: () -> Array[Node | Location]
|
2567
2492
|
def comment_targets
|
2568
|
-
[*receiver, *call_operator_loc, *message_loc,
|
2493
|
+
[*receiver, *call_operator_loc, *message_loc, operator_loc, value]
|
2569
2494
|
end
|
2570
2495
|
|
2571
2496
|
# def copy: (**params) -> CallOrWriteNode
|
@@ -2574,9 +2499,6 @@ module Prism
|
|
2574
2499
|
params.fetch(:receiver) { receiver },
|
2575
2500
|
params.fetch(:call_operator_loc) { call_operator_loc },
|
2576
2501
|
params.fetch(:message_loc) { message_loc },
|
2577
|
-
params.fetch(:opening_loc) { opening_loc },
|
2578
|
-
params.fetch(:arguments) { arguments },
|
2579
|
-
params.fetch(:closing_loc) { closing_loc },
|
2580
2502
|
params.fetch(:flags) { flags },
|
2581
2503
|
params.fetch(:read_name) { read_name },
|
2582
2504
|
params.fetch(:write_name) { write_name },
|
@@ -2591,7 +2513,7 @@ module Prism
|
|
2591
2513
|
|
2592
2514
|
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
|
2593
2515
|
def deconstruct_keys(keys)
|
2594
|
-
{ receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc,
|
2516
|
+
{ receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, flags: flags, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value, location: location }
|
2595
2517
|
end
|
2596
2518
|
|
2597
2519
|
# def call_operator: () -> String?
|
@@ -2604,16 +2526,6 @@ module Prism
|
|
2604
2526
|
message_loc&.slice
|
2605
2527
|
end
|
2606
2528
|
|
2607
|
-
# def opening: () -> String?
|
2608
|
-
def opening
|
2609
|
-
opening_loc&.slice
|
2610
|
-
end
|
2611
|
-
|
2612
|
-
# def closing: () -> String?
|
2613
|
-
def closing
|
2614
|
-
closing_loc&.slice
|
2615
|
-
end
|
2616
|
-
|
2617
2529
|
# def safe_navigation?: () -> bool
|
2618
2530
|
def safe_navigation?
|
2619
2531
|
flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
|
@@ -2639,14 +2551,6 @@ module Prism
|
|
2639
2551
|
end
|
2640
2552
|
inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
|
2641
2553
|
inspector << "├── message_loc: #{inspector.location(message_loc)}\n"
|
2642
|
-
inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
|
2643
|
-
if (arguments = self.arguments).nil?
|
2644
|
-
inspector << "├── arguments: ∅\n"
|
2645
|
-
else
|
2646
|
-
inspector << "├── arguments:\n"
|
2647
|
-
inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
2648
|
-
end
|
2649
|
-
inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
|
2650
2554
|
flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
|
2651
2555
|
inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
|
2652
2556
|
inspector << "├── read_name: #{read_name.inspect}\n"
|
@@ -7826,6 +7730,562 @@ module Prism
|
|
7826
7730
|
end
|
7827
7731
|
end
|
7828
7732
|
|
7733
|
+
# Represents the use of the `&&=` operator on a call to the `[]` method.
|
7734
|
+
#
|
7735
|
+
# foo.bar[baz] &&= value
|
7736
|
+
# ^^^^^^^^^^^^^^^^^^^^^^
|
7737
|
+
class IndexAndWriteNode < Node
|
7738
|
+
# attr_reader receiver: Node?
|
7739
|
+
attr_reader :receiver
|
7740
|
+
|
7741
|
+
# attr_reader call_operator_loc: Location?
|
7742
|
+
attr_reader :call_operator_loc
|
7743
|
+
|
7744
|
+
# attr_reader opening_loc: Location
|
7745
|
+
attr_reader :opening_loc
|
7746
|
+
|
7747
|
+
# attr_reader arguments: ArgumentsNode?
|
7748
|
+
attr_reader :arguments
|
7749
|
+
|
7750
|
+
# attr_reader closing_loc: Location
|
7751
|
+
attr_reader :closing_loc
|
7752
|
+
|
7753
|
+
# attr_reader block: Node?
|
7754
|
+
attr_reader :block
|
7755
|
+
|
7756
|
+
# attr_reader flags: Integer
|
7757
|
+
private attr_reader :flags
|
7758
|
+
|
7759
|
+
# attr_reader operator_loc: Location
|
7760
|
+
attr_reader :operator_loc
|
7761
|
+
|
7762
|
+
# attr_reader value: Node
|
7763
|
+
attr_reader :value
|
7764
|
+
|
7765
|
+
# def initialize: (receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, flags: Integer, operator_loc: Location, value: Node, location: Location) -> void
|
7766
|
+
def initialize(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
|
7767
|
+
@receiver = receiver
|
7768
|
+
@call_operator_loc = call_operator_loc
|
7769
|
+
@opening_loc = opening_loc
|
7770
|
+
@arguments = arguments
|
7771
|
+
@closing_loc = closing_loc
|
7772
|
+
@block = block
|
7773
|
+
@flags = flags
|
7774
|
+
@operator_loc = operator_loc
|
7775
|
+
@value = value
|
7776
|
+
@location = location
|
7777
|
+
end
|
7778
|
+
|
7779
|
+
# def accept: (visitor: Visitor) -> void
|
7780
|
+
def accept(visitor)
|
7781
|
+
visitor.visit_index_and_write_node(self)
|
7782
|
+
end
|
7783
|
+
|
7784
|
+
# def child_nodes: () -> Array[nil | Node]
|
7785
|
+
def child_nodes
|
7786
|
+
[receiver, arguments, block, value]
|
7787
|
+
end
|
7788
|
+
|
7789
|
+
# def compact_child_nodes: () -> Array[Node]
|
7790
|
+
def compact_child_nodes
|
7791
|
+
compact = []
|
7792
|
+
compact << receiver if receiver
|
7793
|
+
compact << arguments if arguments
|
7794
|
+
compact << block if block
|
7795
|
+
compact << value
|
7796
|
+
compact
|
7797
|
+
end
|
7798
|
+
|
7799
|
+
# def comment_targets: () -> Array[Node | Location]
|
7800
|
+
def comment_targets
|
7801
|
+
[*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value]
|
7802
|
+
end
|
7803
|
+
|
7804
|
+
# def copy: (**params) -> IndexAndWriteNode
|
7805
|
+
def copy(**params)
|
7806
|
+
IndexAndWriteNode.new(
|
7807
|
+
params.fetch(:receiver) { receiver },
|
7808
|
+
params.fetch(:call_operator_loc) { call_operator_loc },
|
7809
|
+
params.fetch(:opening_loc) { opening_loc },
|
7810
|
+
params.fetch(:arguments) { arguments },
|
7811
|
+
params.fetch(:closing_loc) { closing_loc },
|
7812
|
+
params.fetch(:block) { block },
|
7813
|
+
params.fetch(:flags) { flags },
|
7814
|
+
params.fetch(:operator_loc) { operator_loc },
|
7815
|
+
params.fetch(:value) { value },
|
7816
|
+
params.fetch(:location) { location },
|
7817
|
+
)
|
7818
|
+
end
|
7819
|
+
|
7820
|
+
# def deconstruct: () -> Array[nil | Node]
|
7821
|
+
alias deconstruct child_nodes
|
7822
|
+
|
7823
|
+
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
|
7824
|
+
def deconstruct_keys(keys)
|
7825
|
+
{ receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, flags: flags, operator_loc: operator_loc, value: value, location: location }
|
7826
|
+
end
|
7827
|
+
|
7828
|
+
# def call_operator: () -> String?
|
7829
|
+
def call_operator
|
7830
|
+
call_operator_loc&.slice
|
7831
|
+
end
|
7832
|
+
|
7833
|
+
# def opening: () -> String
|
7834
|
+
def opening
|
7835
|
+
opening_loc.slice
|
7836
|
+
end
|
7837
|
+
|
7838
|
+
# def closing: () -> String
|
7839
|
+
def closing
|
7840
|
+
closing_loc.slice
|
7841
|
+
end
|
7842
|
+
|
7843
|
+
# def safe_navigation?: () -> bool
|
7844
|
+
def safe_navigation?
|
7845
|
+
flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
|
7846
|
+
end
|
7847
|
+
|
7848
|
+
# def variable_call?: () -> bool
|
7849
|
+
def variable_call?
|
7850
|
+
flags.anybits?(CallNodeFlags::VARIABLE_CALL)
|
7851
|
+
end
|
7852
|
+
|
7853
|
+
# def operator: () -> String
|
7854
|
+
def operator
|
7855
|
+
operator_loc.slice
|
7856
|
+
end
|
7857
|
+
|
7858
|
+
def inspect(inspector = NodeInspector.new)
|
7859
|
+
inspector << inspector.header(self)
|
7860
|
+
if (receiver = self.receiver).nil?
|
7861
|
+
inspector << "├── receiver: ∅\n"
|
7862
|
+
else
|
7863
|
+
inspector << "├── receiver:\n"
|
7864
|
+
inspector << receiver.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
7865
|
+
end
|
7866
|
+
inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
|
7867
|
+
inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
|
7868
|
+
if (arguments = self.arguments).nil?
|
7869
|
+
inspector << "├── arguments: ∅\n"
|
7870
|
+
else
|
7871
|
+
inspector << "├── arguments:\n"
|
7872
|
+
inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
7873
|
+
end
|
7874
|
+
inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
|
7875
|
+
if (block = self.block).nil?
|
7876
|
+
inspector << "├── block: ∅\n"
|
7877
|
+
else
|
7878
|
+
inspector << "├── block:\n"
|
7879
|
+
inspector << block.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
7880
|
+
end
|
7881
|
+
flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
|
7882
|
+
inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
|
7883
|
+
inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
|
7884
|
+
inspector << "└── value:\n"
|
7885
|
+
inspector << inspector.child_node(value, " ")
|
7886
|
+
inspector.to_str
|
7887
|
+
end
|
7888
|
+
|
7889
|
+
# Sometimes you want to check an instance of a node against a list of
|
7890
|
+
# classes to see what kind of behavior to perform. Usually this is done by
|
7891
|
+
# calling `[cls1, cls2].include?(node.class)` or putting the node into a
|
7892
|
+
# case statement and doing `case node; when cls1; when cls2; end`. Both of
|
7893
|
+
# these approaches are relatively slow because of the constant lookups,
|
7894
|
+
# method calls, and/or array allocations.
|
7895
|
+
#
|
7896
|
+
# Instead, you can call #type, which will return to you a symbol that you
|
7897
|
+
# can use for comparison. This is faster than the other approaches because
|
7898
|
+
# it uses a single integer comparison, but also because if you're on CRuby
|
7899
|
+
# you can take advantage of the fact that case statements with all symbol
|
7900
|
+
# keys will use a jump table.
|
7901
|
+
#
|
7902
|
+
# def type: () -> Symbol
|
7903
|
+
def type
|
7904
|
+
:index_and_write_node
|
7905
|
+
end
|
7906
|
+
|
7907
|
+
# Similar to #type, this method returns a symbol that you can use for
|
7908
|
+
# splitting on the type of the node without having to do a long === chain.
|
7909
|
+
# Note that like #type, it will still be slower than using == for a single
|
7910
|
+
# class, but should be faster in a case statement or an array comparison.
|
7911
|
+
#
|
7912
|
+
# def self.type: () -> Symbol
|
7913
|
+
def self.type
|
7914
|
+
:index_and_write_node
|
7915
|
+
end
|
7916
|
+
end
|
7917
|
+
|
7918
|
+
# Represents the use of an assignment operator on a call to `[]`.
|
7919
|
+
#
|
7920
|
+
# foo.bar[baz] += value
|
7921
|
+
# ^^^^^^^^^^^^^^^^^^^^^
|
7922
|
+
class IndexOperatorWriteNode < Node
|
7923
|
+
# attr_reader receiver: Node?
|
7924
|
+
attr_reader :receiver
|
7925
|
+
|
7926
|
+
# attr_reader call_operator_loc: Location?
|
7927
|
+
attr_reader :call_operator_loc
|
7928
|
+
|
7929
|
+
# attr_reader opening_loc: Location
|
7930
|
+
attr_reader :opening_loc
|
7931
|
+
|
7932
|
+
# attr_reader arguments: ArgumentsNode?
|
7933
|
+
attr_reader :arguments
|
7934
|
+
|
7935
|
+
# attr_reader closing_loc: Location
|
7936
|
+
attr_reader :closing_loc
|
7937
|
+
|
7938
|
+
# attr_reader block: Node?
|
7939
|
+
attr_reader :block
|
7940
|
+
|
7941
|
+
# attr_reader flags: Integer
|
7942
|
+
private attr_reader :flags
|
7943
|
+
|
7944
|
+
# attr_reader operator: Symbol
|
7945
|
+
attr_reader :operator
|
7946
|
+
|
7947
|
+
# attr_reader operator_loc: Location
|
7948
|
+
attr_reader :operator_loc
|
7949
|
+
|
7950
|
+
# attr_reader value: Node
|
7951
|
+
attr_reader :value
|
7952
|
+
|
7953
|
+
# def initialize: (receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, flags: Integer, operator: Symbol, operator_loc: Location, value: Node, location: Location) -> void
|
7954
|
+
def initialize(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator, operator_loc, value, location)
|
7955
|
+
@receiver = receiver
|
7956
|
+
@call_operator_loc = call_operator_loc
|
7957
|
+
@opening_loc = opening_loc
|
7958
|
+
@arguments = arguments
|
7959
|
+
@closing_loc = closing_loc
|
7960
|
+
@block = block
|
7961
|
+
@flags = flags
|
7962
|
+
@operator = operator
|
7963
|
+
@operator_loc = operator_loc
|
7964
|
+
@value = value
|
7965
|
+
@location = location
|
7966
|
+
end
|
7967
|
+
|
7968
|
+
# def accept: (visitor: Visitor) -> void
|
7969
|
+
def accept(visitor)
|
7970
|
+
visitor.visit_index_operator_write_node(self)
|
7971
|
+
end
|
7972
|
+
|
7973
|
+
# def child_nodes: () -> Array[nil | Node]
|
7974
|
+
def child_nodes
|
7975
|
+
[receiver, arguments, block, value]
|
7976
|
+
end
|
7977
|
+
|
7978
|
+
# def compact_child_nodes: () -> Array[Node]
|
7979
|
+
def compact_child_nodes
|
7980
|
+
compact = []
|
7981
|
+
compact << receiver if receiver
|
7982
|
+
compact << arguments if arguments
|
7983
|
+
compact << block if block
|
7984
|
+
compact << value
|
7985
|
+
compact
|
7986
|
+
end
|
7987
|
+
|
7988
|
+
# def comment_targets: () -> Array[Node | Location]
|
7989
|
+
def comment_targets
|
7990
|
+
[*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value]
|
7991
|
+
end
|
7992
|
+
|
7993
|
+
# def copy: (**params) -> IndexOperatorWriteNode
|
7994
|
+
def copy(**params)
|
7995
|
+
IndexOperatorWriteNode.new(
|
7996
|
+
params.fetch(:receiver) { receiver },
|
7997
|
+
params.fetch(:call_operator_loc) { call_operator_loc },
|
7998
|
+
params.fetch(:opening_loc) { opening_loc },
|
7999
|
+
params.fetch(:arguments) { arguments },
|
8000
|
+
params.fetch(:closing_loc) { closing_loc },
|
8001
|
+
params.fetch(:block) { block },
|
8002
|
+
params.fetch(:flags) { flags },
|
8003
|
+
params.fetch(:operator) { operator },
|
8004
|
+
params.fetch(:operator_loc) { operator_loc },
|
8005
|
+
params.fetch(:value) { value },
|
8006
|
+
params.fetch(:location) { location },
|
8007
|
+
)
|
8008
|
+
end
|
8009
|
+
|
8010
|
+
# def deconstruct: () -> Array[nil | Node]
|
8011
|
+
alias deconstruct child_nodes
|
8012
|
+
|
8013
|
+
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
|
8014
|
+
def deconstruct_keys(keys)
|
8015
|
+
{ receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, flags: flags, operator: operator, operator_loc: operator_loc, value: value, location: location }
|
8016
|
+
end
|
8017
|
+
|
8018
|
+
# def call_operator: () -> String?
|
8019
|
+
def call_operator
|
8020
|
+
call_operator_loc&.slice
|
8021
|
+
end
|
8022
|
+
|
8023
|
+
# def opening: () -> String
|
8024
|
+
def opening
|
8025
|
+
opening_loc.slice
|
8026
|
+
end
|
8027
|
+
|
8028
|
+
# def closing: () -> String
|
8029
|
+
def closing
|
8030
|
+
closing_loc.slice
|
8031
|
+
end
|
8032
|
+
|
8033
|
+
# def safe_navigation?: () -> bool
|
8034
|
+
def safe_navigation?
|
8035
|
+
flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
|
8036
|
+
end
|
8037
|
+
|
8038
|
+
# def variable_call?: () -> bool
|
8039
|
+
def variable_call?
|
8040
|
+
flags.anybits?(CallNodeFlags::VARIABLE_CALL)
|
8041
|
+
end
|
8042
|
+
|
8043
|
+
def inspect(inspector = NodeInspector.new)
|
8044
|
+
inspector << inspector.header(self)
|
8045
|
+
if (receiver = self.receiver).nil?
|
8046
|
+
inspector << "├── receiver: ∅\n"
|
8047
|
+
else
|
8048
|
+
inspector << "├── receiver:\n"
|
8049
|
+
inspector << receiver.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
8050
|
+
end
|
8051
|
+
inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
|
8052
|
+
inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
|
8053
|
+
if (arguments = self.arguments).nil?
|
8054
|
+
inspector << "├── arguments: ∅\n"
|
8055
|
+
else
|
8056
|
+
inspector << "├── arguments:\n"
|
8057
|
+
inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
8058
|
+
end
|
8059
|
+
inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
|
8060
|
+
if (block = self.block).nil?
|
8061
|
+
inspector << "├── block: ∅\n"
|
8062
|
+
else
|
8063
|
+
inspector << "├── block:\n"
|
8064
|
+
inspector << block.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
8065
|
+
end
|
8066
|
+
flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
|
8067
|
+
inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
|
8068
|
+
inspector << "├── operator: #{operator.inspect}\n"
|
8069
|
+
inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
|
8070
|
+
inspector << "└── value:\n"
|
8071
|
+
inspector << inspector.child_node(value, " ")
|
8072
|
+
inspector.to_str
|
8073
|
+
end
|
8074
|
+
|
8075
|
+
# Sometimes you want to check an instance of a node against a list of
|
8076
|
+
# classes to see what kind of behavior to perform. Usually this is done by
|
8077
|
+
# calling `[cls1, cls2].include?(node.class)` or putting the node into a
|
8078
|
+
# case statement and doing `case node; when cls1; when cls2; end`. Both of
|
8079
|
+
# these approaches are relatively slow because of the constant lookups,
|
8080
|
+
# method calls, and/or array allocations.
|
8081
|
+
#
|
8082
|
+
# Instead, you can call #type, which will return to you a symbol that you
|
8083
|
+
# can use for comparison. This is faster than the other approaches because
|
8084
|
+
# it uses a single integer comparison, but also because if you're on CRuby
|
8085
|
+
# you can take advantage of the fact that case statements with all symbol
|
8086
|
+
# keys will use a jump table.
|
8087
|
+
#
|
8088
|
+
# def type: () -> Symbol
|
8089
|
+
def type
|
8090
|
+
:index_operator_write_node
|
8091
|
+
end
|
8092
|
+
|
8093
|
+
# Similar to #type, this method returns a symbol that you can use for
|
8094
|
+
# splitting on the type of the node without having to do a long === chain.
|
8095
|
+
# Note that like #type, it will still be slower than using == for a single
|
8096
|
+
# class, but should be faster in a case statement or an array comparison.
|
8097
|
+
#
|
8098
|
+
# def self.type: () -> Symbol
|
8099
|
+
def self.type
|
8100
|
+
:index_operator_write_node
|
8101
|
+
end
|
8102
|
+
end
|
8103
|
+
|
8104
|
+
# Represents the use of the `||=` operator on a call to `[]`.
|
8105
|
+
#
|
8106
|
+
# foo.bar[baz] ||= value
|
8107
|
+
# ^^^^^^^^^^^^^^^^^^^^^^
|
8108
|
+
class IndexOrWriteNode < Node
|
8109
|
+
# attr_reader receiver: Node?
|
8110
|
+
attr_reader :receiver
|
8111
|
+
|
8112
|
+
# attr_reader call_operator_loc: Location?
|
8113
|
+
attr_reader :call_operator_loc
|
8114
|
+
|
8115
|
+
# attr_reader opening_loc: Location
|
8116
|
+
attr_reader :opening_loc
|
8117
|
+
|
8118
|
+
# attr_reader arguments: ArgumentsNode?
|
8119
|
+
attr_reader :arguments
|
8120
|
+
|
8121
|
+
# attr_reader closing_loc: Location
|
8122
|
+
attr_reader :closing_loc
|
8123
|
+
|
8124
|
+
# attr_reader block: Node?
|
8125
|
+
attr_reader :block
|
8126
|
+
|
8127
|
+
# attr_reader flags: Integer
|
8128
|
+
private attr_reader :flags
|
8129
|
+
|
8130
|
+
# attr_reader operator_loc: Location
|
8131
|
+
attr_reader :operator_loc
|
8132
|
+
|
8133
|
+
# attr_reader value: Node
|
8134
|
+
attr_reader :value
|
8135
|
+
|
8136
|
+
# def initialize: (receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, flags: Integer, operator_loc: Location, value: Node, location: Location) -> void
|
8137
|
+
def initialize(receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, flags, operator_loc, value, location)
|
8138
|
+
@receiver = receiver
|
8139
|
+
@call_operator_loc = call_operator_loc
|
8140
|
+
@opening_loc = opening_loc
|
8141
|
+
@arguments = arguments
|
8142
|
+
@closing_loc = closing_loc
|
8143
|
+
@block = block
|
8144
|
+
@flags = flags
|
8145
|
+
@operator_loc = operator_loc
|
8146
|
+
@value = value
|
8147
|
+
@location = location
|
8148
|
+
end
|
8149
|
+
|
8150
|
+
# def accept: (visitor: Visitor) -> void
|
8151
|
+
def accept(visitor)
|
8152
|
+
visitor.visit_index_or_write_node(self)
|
8153
|
+
end
|
8154
|
+
|
8155
|
+
# def child_nodes: () -> Array[nil | Node]
|
8156
|
+
def child_nodes
|
8157
|
+
[receiver, arguments, block, value]
|
8158
|
+
end
|
8159
|
+
|
8160
|
+
# def compact_child_nodes: () -> Array[Node]
|
8161
|
+
def compact_child_nodes
|
8162
|
+
compact = []
|
8163
|
+
compact << receiver if receiver
|
8164
|
+
compact << arguments if arguments
|
8165
|
+
compact << block if block
|
8166
|
+
compact << value
|
8167
|
+
compact
|
8168
|
+
end
|
8169
|
+
|
8170
|
+
# def comment_targets: () -> Array[Node | Location]
|
8171
|
+
def comment_targets
|
8172
|
+
[*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value]
|
8173
|
+
end
|
8174
|
+
|
8175
|
+
# def copy: (**params) -> IndexOrWriteNode
|
8176
|
+
def copy(**params)
|
8177
|
+
IndexOrWriteNode.new(
|
8178
|
+
params.fetch(:receiver) { receiver },
|
8179
|
+
params.fetch(:call_operator_loc) { call_operator_loc },
|
8180
|
+
params.fetch(:opening_loc) { opening_loc },
|
8181
|
+
params.fetch(:arguments) { arguments },
|
8182
|
+
params.fetch(:closing_loc) { closing_loc },
|
8183
|
+
params.fetch(:block) { block },
|
8184
|
+
params.fetch(:flags) { flags },
|
8185
|
+
params.fetch(:operator_loc) { operator_loc },
|
8186
|
+
params.fetch(:value) { value },
|
8187
|
+
params.fetch(:location) { location },
|
8188
|
+
)
|
8189
|
+
end
|
8190
|
+
|
8191
|
+
# def deconstruct: () -> Array[nil | Node]
|
8192
|
+
alias deconstruct child_nodes
|
8193
|
+
|
8194
|
+
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
|
8195
|
+
def deconstruct_keys(keys)
|
8196
|
+
{ receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, flags: flags, operator_loc: operator_loc, value: value, location: location }
|
8197
|
+
end
|
8198
|
+
|
8199
|
+
# def call_operator: () -> String?
|
8200
|
+
def call_operator
|
8201
|
+
call_operator_loc&.slice
|
8202
|
+
end
|
8203
|
+
|
8204
|
+
# def opening: () -> String
|
8205
|
+
def opening
|
8206
|
+
opening_loc.slice
|
8207
|
+
end
|
8208
|
+
|
8209
|
+
# def closing: () -> String
|
8210
|
+
def closing
|
8211
|
+
closing_loc.slice
|
8212
|
+
end
|
8213
|
+
|
8214
|
+
# def safe_navigation?: () -> bool
|
8215
|
+
def safe_navigation?
|
8216
|
+
flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
|
8217
|
+
end
|
8218
|
+
|
8219
|
+
# def variable_call?: () -> bool
|
8220
|
+
def variable_call?
|
8221
|
+
flags.anybits?(CallNodeFlags::VARIABLE_CALL)
|
8222
|
+
end
|
8223
|
+
|
8224
|
+
# def operator: () -> String
|
8225
|
+
def operator
|
8226
|
+
operator_loc.slice
|
8227
|
+
end
|
8228
|
+
|
8229
|
+
def inspect(inspector = NodeInspector.new)
|
8230
|
+
inspector << inspector.header(self)
|
8231
|
+
if (receiver = self.receiver).nil?
|
8232
|
+
inspector << "├── receiver: ∅\n"
|
8233
|
+
else
|
8234
|
+
inspector << "├── receiver:\n"
|
8235
|
+
inspector << receiver.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
8236
|
+
end
|
8237
|
+
inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
|
8238
|
+
inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
|
8239
|
+
if (arguments = self.arguments).nil?
|
8240
|
+
inspector << "├── arguments: ∅\n"
|
8241
|
+
else
|
8242
|
+
inspector << "├── arguments:\n"
|
8243
|
+
inspector << arguments.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
8244
|
+
end
|
8245
|
+
inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
|
8246
|
+
if (block = self.block).nil?
|
8247
|
+
inspector << "├── block: ∅\n"
|
8248
|
+
else
|
8249
|
+
inspector << "├── block:\n"
|
8250
|
+
inspector << block.inspect(inspector.child_inspector("│ ")).delete_prefix(inspector.prefix)
|
8251
|
+
end
|
8252
|
+
flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?)].compact
|
8253
|
+
inspector << "├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n"
|
8254
|
+
inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
|
8255
|
+
inspector << "└── value:\n"
|
8256
|
+
inspector << inspector.child_node(value, " ")
|
8257
|
+
inspector.to_str
|
8258
|
+
end
|
8259
|
+
|
8260
|
+
# Sometimes you want to check an instance of a node against a list of
|
8261
|
+
# classes to see what kind of behavior to perform. Usually this is done by
|
8262
|
+
# calling `[cls1, cls2].include?(node.class)` or putting the node into a
|
8263
|
+
# case statement and doing `case node; when cls1; when cls2; end`. Both of
|
8264
|
+
# these approaches are relatively slow because of the constant lookups,
|
8265
|
+
# method calls, and/or array allocations.
|
8266
|
+
#
|
8267
|
+
# Instead, you can call #type, which will return to you a symbol that you
|
8268
|
+
# can use for comparison. This is faster than the other approaches because
|
8269
|
+
# it uses a single integer comparison, but also because if you're on CRuby
|
8270
|
+
# you can take advantage of the fact that case statements with all symbol
|
8271
|
+
# keys will use a jump table.
|
8272
|
+
#
|
8273
|
+
# def type: () -> Symbol
|
8274
|
+
def type
|
8275
|
+
:index_or_write_node
|
8276
|
+
end
|
8277
|
+
|
8278
|
+
# Similar to #type, this method returns a symbol that you can use for
|
8279
|
+
# splitting on the type of the node without having to do a long === chain.
|
8280
|
+
# Note that like #type, it will still be slower than using == for a single
|
8281
|
+
# class, but should be faster in a case statement or an array comparison.
|
8282
|
+
#
|
8283
|
+
# def self.type: () -> Symbol
|
8284
|
+
def self.type
|
8285
|
+
:index_or_write_node
|
8286
|
+
end
|
8287
|
+
end
|
8288
|
+
|
7829
8289
|
# Represents the use of the `&&=` operator for assignment to an instance variable.
|
7830
8290
|
#
|
7831
8291
|
# @target &&= value
|