Repository: ruby/prism
Pull request #2800 (2024-05-10 14:26:56)

Rename `operator` -> `binary_operator`
We need to add C++ support for Sorbet, and having a keyword as struct fields is causing issues. In this PR we're renaming `operator` to `binary_operator`.

In the Ruby layer, we alias the old method and provide a deprecation warning. In the other layers it will require updates. Sorry!


Patch:
diff --git a/config.yml b/config.yml
index 8b4ffad0..eb22d573 100644
--- a/config.yml
+++ b/config.yml
@@ -1212,9 +1212,9 @@ nodes:
         type: constant
       - name: write_name
         type: constant
-      - name: operator
+      - name: binary_operator
         type: constant
-      - name: operator_loc
+      - name: binary_operator_loc
         type: location
       - name: value
         type: node
@@ -1370,11 +1370,11 @@ nodes:
         type: constant
       - name: name_loc
         type: location
-      - name: operator_loc
+      - name: binary_operator_loc
         type: location
       - name: value
         type: node
-      - name: operator
+      - name: binary_operator
         type: constant
     comment: |
       Represents assigning to a class variable using an operator that isn't `=`.
@@ -1480,11 +1480,11 @@ nodes:
         type: constant
       - name: name_loc
         type: location
-      - name: operator_loc
+      - name: binary_operator_loc
         type: location
       - name: value
         type: node
-      - name: operator
+      - name: binary_operator
         type: constant
     comment: |
       Represents assigning to a constant using an operator that isn't `=`.
@@ -1568,11 +1568,11 @@ nodes:
       - name: target
         type: node
         kind: ConstantPathNode
-      - name: operator_loc
+      - name: binary_operator_loc
         type: location
       - name: value
         type: node
-      - name: operator
+      - name: binary_operator
         type: constant
     comment: |
       Represents assigning to a constant path using an operator that isn't `=`.
@@ -1939,11 +1939,11 @@ nodes:
         type: constant
       - name: name_loc
         type: location
-      - name: operator_loc
+      - name: binary_operator_loc
         type: location
       - name: value
         type: node
-      - name: operator
+      - name: binary_operator
         type: constant
     comment: |
       Represents assigning to a global variable using an operator that isn't `=`.
@@ -2275,9 +2275,9 @@ nodes:
         type: location
       - name: block
         type: node?
-      - name: operator
+      - name: binary_operator
         type: constant
-      - name: operator_loc
+      - name: binary_operator_loc
         type: location
       - name: value
         type: node
@@ -2363,11 +2363,11 @@ nodes:
         type: constant
       - name: name_loc
         type: location
-      - name: operator_loc
+      - name: binary_operator_loc
         type: location
       - name: value
         type: node
-      - name: operator
+      - name: binary_operator
         type: constant
     comment: |
       Represents assigning to an instance variable using an operator that isn't `=`.
@@ -2643,13 +2643,13 @@ nodes:
     fields:
       - name: name_loc
         type: location
-      - name: operator_loc
+      - name: binary_operator_loc
         type: location
       - name: value
         type: node
       - name: name
         type: constant
-      - name: operator
+      - name: binary_operator
         type: constant
       - name: depth
         type: uint32
diff --git a/lib/prism/desugar_compiler.rb b/lib/prism/desugar_compiler.rb
index 9b62c00d..de024451 100644
--- a/lib/prism/desugar_compiler.rb
+++ b/lib/prism/desugar_compiler.rb
@@ -73,7 +73,7 @@ module Prism
 
     # Desugar `x += y` to `x = x + y`
     def compile
-      operator_loc = node.operator_loc.chop
+      binary_operator_loc = node.binary_operator_loc.chop
 
       write_class.new(
         source,
@@ -84,15 +84,15 @@ module Prism
           0,
           read_class.new(source, *arguments, node.name_loc),
           nil,
-          operator_loc.slice.to_sym,
-          operator_loc,
+          binary_operator_loc.slice.to_sym,
+          binary_operator_loc,
           nil,
           ArgumentsNode.new(source, 0, [node.value], node.value.location),
           nil,
           nil,
           node.location
         ),
-        node.operator_loc.copy(start_offset: node.operator_loc.end_offset - 1, length: 1),
+        node.binary_operator_loc.copy(start_offset: node.binary_operator_loc.end_offset - 1, length: 1),
         node.location
       )
     end
diff --git a/lib/prism/node_ext.rb b/lib/prism/node_ext.rb
index 13830dad..ceec76b8 100644
--- a/lib/prism/node_ext.rb
+++ b/lib/prism/node_ext.rb
@@ -3,6 +3,17 @@
 # Here we are reopening the prism module to provide methods on nodes that aren't
 # templated and are meant as convenience methods.
 module Prism
+  class Node
+    def deprecated(*replacements) # :nodoc:
+      suggest = replacements.map { |replacement| "#{self.class}##{replacement}" }
+      warn(<<~MSG, category: :deprecated)
+        [deprecation]: #{self.class}##{caller_locations(1, 1)[0].label} is deprecated \
+        and will be removed in the next major version. Use #{suggest.join("/")} instead.
+        #{(caller(1, 3) || []).join("\n")}
+      MSG
+    end
+  end
+
   module RegularExpressionOptions # :nodoc:
     # Returns a numeric value that represents the flags that were used to create
     # the regular expression.
@@ -168,13 +179,7 @@ module Prism
     # constant read or a missing node. To not cause a breaking change, we
     # continue to supply that API.
     def child
-      warn(<<~MSG, category: :deprecated)
-        DEPRECATED: ConstantPathNode#child is deprecated and will be removed \
-        in the next major version. Use \
-        ConstantPathNode#name/ConstantPathNode#name_loc instead. Called from \
-        #{caller(1, 1)&.first}.
-      MSG
-
+      deprecated("name", "name_loc")
       name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location)
     end
   end
@@ -210,13 +215,7 @@ module Prism
     # constant read or a missing node. To not cause a breaking change, we
     # continue to supply that API.
     def child
-      warn(<<~MSG, category: :deprecated)
-        DEPRECATED: ConstantPathTargetNode#child is deprecated and will be \
-        removed in the next major version. Use \
-        ConstantPathTargetNode#name/ConstantPathTargetNode#name_loc instead. \
-        Called from #{caller(1, 1)&.first}.
-      MSG
-
+      deprecated("name", "name_loc")
       name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location)
     end
   end
@@ -301,4 +300,132 @@ module Prism
       attribute_write? ? message_loc&.adjoin("=") : message_loc
     end
   end
+
+  class CallOperatorWriteNode < Node
+    # Returns the binary operator used to modify the receiver. This method is
+    # deprecated in favor of #binary_operator.
+    def operator
+      deprecated("binary_operator")
+      binary_operator
+    end
+
+    # Returns the location of the binary operator used to modify the receiver.
+    # This method is deprecated in favor of #binary_operator_loc.
+    def operator_loc
+      deprecated("binary_operator_loc")
+      binary_operator_loc
+    end
+  end
+
+  class ClassVariableOperatorWriteNode < Node
+    # Returns the binary operator used to modify the receiver. This method is
+    # deprecated in favor of #binary_operator.
+    def operator
+      deprecated("binary_operator")
+      binary_operator
+    end
+
+    # Returns the location of the binary operator used to modify the receiver.
+    # This method is deprecated in favor of #binary_operator_loc.
+    def operator_loc
+      deprecated("binary_operator_loc")
+      binary_operator_loc
+    end
+  end
+
+  class ConstantOperatorWriteNode < Node
+    # Returns the binary operator used to modify the receiver. This method is
+    # deprecated in favor of #binary_operator.
+    def operator
+      deprecated("binary_operator")
+      binary_operator
+    end
+
+    # Returns the location of the binary operator used to modify the receiver.
+    # This method is deprecated in favor of #binary_operator_loc.
+    def operator_loc
+      deprecated("binary_operator_loc")
+      binary_operator_loc
+    end
+  end
+
+  class ConstantPathOperatorWriteNode < Node
+    # Returns the binary operator used to modify the receiver. This method is
+    # deprecated in favor of #binary_operator.
+    def operator
+      deprecated("binary_operator")
+      binary_operator
+    end
+
+    # Returns the location of the binary operator used to modify the receiver.
+    # This method is deprecated in favor of #binary_operator_loc.
+    def operator_loc
+      deprecated("binary_operator_loc")
+      binary_operator_loc
+    end
+  end
+
+  class GlobalVariableOperatorWriteNode < Node
+    # Returns the binary operator used to modify the receiver. This method is
+    # deprecated in favor of #binary_operator.
+    def operator
+      deprecated("binary_operator")
+      binary_operator
+    end
+
+    # Returns the location of the binary operator used to modify the receiver.
+    # This method is deprecated in favor of #binary_operator_loc.
+    def operator_loc
+      deprecated("binary_operator_loc")
+      binary_operator_loc
+    end
+  end
+
+  class IndexOperatorWriteNode < Node
+    # Returns the binary operator used to modify the receiver. This method is
+    # deprecated in favor of #binary_operator.
+    def operator
+      deprecated("binary_operator")
+      binary_operator
+    end
+
+    # Returns the location of the binary operator used to modify the receiver.
+    # This method is deprecated in favor of #binary_operator_loc.
+    def operator_loc
+      deprecated("binary_operator_loc")
+      binary_operator_loc
+    end
+  end
+
+  class InstanceVariableOperatorWriteNode < Node
+    # Returns the binary operator used to modify the receiver. This method is
+    # deprecated in favor of #binary_operator.
+    def operator
+      deprecated("binary_operator")
+      binary_operator
+    end
+
+    # Returns the location of the binary operator used to modify the receiver.
+    # This method is deprecated in favor of #binary_operator_loc.
+    def operator_loc
+      deprecated("binary_operator_loc")
+      binary_operator_loc
+    end
+  end
+
+  class LocalVariableOperatorWriteNode < Node
+    # Returns the binary operator used to modify the receiver. This method is
+    # deprecated in favor of #binary_operator.
+    def operator
+      deprecated("binary_operator")
+      binary_operator
+    end
+
+    # Returns the location of the binary operator used to modify the receiver.
+    # This method is deprecated in favor of #binary_operator_loc.
+    def operator_loc
+      deprecated("binary_operator_loc")
+      binary_operator_loc
+    end
+  end
 end
diff --git a/lib/prism/translation/parser/compiler.rb b/lib/prism/translation/parser/compiler.rb
index c3116133..a6c3118e 100644
--- a/lib/prism/translation/parser/compiler.rb
+++ b/lib/prism/translation/parser/compiler.rb
@@ -328,18 +328,48 @@ module Prism
               [],
               nil
             ),
-            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)],
             visit(node.value)
           )
         end
 
         # foo.bar &&= baz
         # ^^^^^^^^^^^^^^^
-        alias visit_call_and_write_node visit_call_operator_write_node
+        def visit_call_and_write_node(node)
+          call_operator_loc = node.call_operator_loc
+
+          builder.op_assign(
+            builder.call_method(
+              visit(node.receiver),
+              call_operator_loc.nil? ? nil : [{ "." => :dot, "&." => :anddot, "::" => "::" }.fetch(call_operator_loc.slice), srange(call_operator_loc)],
+              node.message_loc ? [node.read_name, srange(node.message_loc)] : nil,
+              nil,
+              [],
+              nil
+            ),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # foo.bar ||= baz
         # ^^^^^^^^^^^^^^^
-        alias visit_call_or_write_node visit_call_operator_write_node
+        def visit_call_or_write_node(node)
+          call_operator_loc = node.call_operator_loc
+
+          builder.op_assign(
+            builder.call_method(
+              visit(node.receiver),
+              call_operator_loc.nil? ? nil : [{ "." => :dot, "&." => :anddot, "::" => "::" }.fetch(call_operator_loc.slice), srange(call_operator_loc)],
+              node.message_loc ? [node.read_name, srange(node.message_loc)] : nil,
+              nil,
+              [],
+              nil
+            ),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # foo.bar, = 1
         # ^^^^^^^
@@ -419,18 +449,30 @@ module Prism
         def visit_class_variable_operator_write_node(node)
           builder.op_assign(
             builder.assignable(builder.cvar(token(node.name_loc))),
-            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)],
             visit(node.value)
           )
         end
 
         # @@foo &&= bar
         # ^^^^^^^^^^^^^
-        alias visit_class_variable_and_write_node visit_class_variable_operator_write_node
+        def visit_class_variable_and_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.cvar(token(node.name_loc))),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # @@foo ||= bar
         # ^^^^^^^^^^^^^
-        alias visit_class_variable_or_write_node visit_class_variable_operator_write_node
+        def visit_class_variable_or_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.cvar(token(node.name_loc))),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # @@foo, = bar
         # ^^^^^
@@ -458,18 +500,30 @@ module Prism
         def visit_constant_operator_write_node(node)
           builder.op_assign(
             builder.assignable(builder.const([node.name, srange(node.name_loc)])),
-            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)],
             visit(node.value)
           )
         end
 
         # Foo &&= bar
         # ^^^^^^^^^^^^
-        alias visit_constant_and_write_node visit_constant_operator_write_node
+        def visit_constant_and_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.const([node.name, srange(node.name_loc)])),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # Foo ||= bar
         # ^^^^^^^^^^^^
-        alias visit_constant_or_write_node visit_constant_operator_write_node
+        def visit_constant_or_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.const([node.name, srange(node.name_loc)])),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # Foo, = bar
         # ^^^
@@ -512,18 +566,30 @@ module Prism
         def visit_constant_path_operator_write_node(node)
           builder.op_assign(
             builder.assignable(visit(node.target)),
-            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)],
             visit(node.value)
           )
         end
 
         # Foo::Bar &&= baz
         # ^^^^^^^^^^^^^^^^
-        alias visit_constant_path_and_write_node visit_constant_path_operator_write_node
+        def visit_constant_path_and_write_node(node)
+          builder.op_assign(
+            builder.assignable(visit(node.target)),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # Foo::Bar ||= baz
         # ^^^^^^^^^^^^^^^^
-        alias visit_constant_path_or_write_node visit_constant_path_operator_write_node
+        def visit_constant_path_or_write_node(node)
+          builder.op_assign(
+            builder.assignable(visit(node.target)),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # Foo::Bar, = baz
         # ^^^^^^^^
@@ -711,18 +777,30 @@ module Prism
         def visit_global_variable_operator_write_node(node)
           builder.op_assign(
             builder.assignable(builder.gvar(token(node.name_loc))),
-            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)],
             visit(node.value)
           )
         end
 
         # $foo &&= bar
         # ^^^^^^^^^^^^
-        alias visit_global_variable_and_write_node visit_global_variable_operator_write_node
+        def visit_global_variable_and_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.gvar(token(node.name_loc))),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # $foo ||= bar
         # ^^^^^^^^^^^^
-        alias visit_global_variable_or_write_node visit_global_variable_operator_write_node
+        def visit_global_variable_or_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.gvar(token(node.name_loc))),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # $foo, = bar
         # ^^^^
@@ -857,18 +935,46 @@ module Prism
               visit_all(arguments),
               token(node.closing_loc)
             ),
-            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)],
             visit(node.value)
           )
         end
 
         # foo[bar] &&= baz
         # ^^^^^^^^^^^^^^^^
-        alias visit_index_and_write_node visit_index_operator_write_node
+        def visit_index_and_write_node(node)
+          arguments = node.arguments&.arguments || []
+          arguments << node.block if node.block
+
+          builder.op_assign(
+            builder.index(
+              visit(node.receiver),
+              token(node.opening_loc),
+              visit_all(arguments),
+              token(node.closing_loc)
+            ),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # foo[bar] ||= baz
         # ^^^^^^^^^^^^^^^^
-        alias visit_index_or_write_node visit_index_operator_write_node
+        def visit_index_or_write_node(node)
+          arguments = node.arguments&.arguments || []
+          arguments << node.block if node.block
+
+          builder.op_assign(
+            builder.index(
+              visit(node.receiver),
+              token(node.opening_loc),
+              visit_all(arguments),
+              token(node.closing_loc)
+            ),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # foo[bar], = 1
         # ^^^^^^^^
@@ -902,18 +1008,30 @@ module Prism
         def visit_instance_variable_operator_write_node(node)
           builder.op_assign(
             builder.assignable(builder.ivar(token(node.name_loc))),
-            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)],
             visit(node.value)
           )
         end
 
         # @foo &&= bar
         # ^^^^^^^^^^^^
-        alias visit_instance_variable_and_write_node visit_instance_variable_operator_write_node
+        def visit_instance_variable_and_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.ivar(token(node.name_loc))),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # @foo ||= bar
         # ^^^^^^^^^^^^
-        alias visit_instance_variable_or_write_node visit_instance_variable_operator_write_node
+        def visit_instance_variable_or_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.ivar(token(node.name_loc))),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # @foo, = bar
         # ^^^^
@@ -1108,18 +1226,30 @@ module Prism
         def visit_local_variable_operator_write_node(node)
           builder.op_assign(
             builder.assignable(builder.ident(token(node.name_loc))),
-            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)],
             visit(node.value)
           )
         end
 
         # foo &&= bar
         # ^^^^^^^^^^^
-        alias visit_local_variable_and_write_node visit_local_variable_operator_write_node
+        def visit_local_variable_and_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.ident(token(node.name_loc))),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # foo ||= bar
         # ^^^^^^^^^^^
-        alias visit_local_variable_or_write_node visit_local_variable_operator_write_node
+        def visit_local_variable_or_write_node(node)
+          builder.op_assign(
+            builder.assignable(builder.ident(token(node.name_loc))),
+            [node.operator_loc.slice.chomp("="), srange(node.operator_loc)],
+            visit(node.value)
+          )
+        end
 
         # foo, = bar
         # ^^^
diff --git a/lib/prism/translation/ripper.rb b/lib/prism/translation/ripper.rb
index d226bb58..68f65856 100644
--- a/lib/prism/translation/ripper.rb
+++ b/lib/prism/translation/ripper.rb
@@ -1181,8 +1181,8 @@ module Prism
         bounds(node.location)
         target = on_field(receiver, call_operator, message)
 
-        bounds(node.operator_loc)
-        operator = on_op("#{node.operator}=")
+        bounds(node.binary_operator_loc)
+        operator = on_op("#{node.binary_operator}=")
         value = visit_write_value(node.value)
 
         bounds(node.location)
@@ -1339,8 +1339,8 @@ module Prism
         bounds(node.name_loc)
         target = on_var_field(on_cvar(node.name.to_s))
 
-        bounds(node.operator_loc)
-        operator = on_op("#{node.operator}=")
+        bounds(node.binary_operator_loc)
+        operator = on_op("#{node.binary_operator}=")
         value = visit_write_value(node.value)
 
         bounds(node.location)
@@ -1409,8 +1409,8 @@ module Prism
         bounds(node.name_loc)
         target = on_var_field(on_const(node.name.to_s))
 
-        bounds(node.operator_loc)
-        operator = on_op("#{node.operator}=")
+        bounds(node.binary_operator_loc)
+        operator = on_op("#{node.binary_operator}=")
         value = visit_write_value(node.value)
 
         bounds(node.location)
@@ -1510,8 +1510,8 @@ module Prism
         target = visit_constant_path_write_node_target(node.target)
         value = visit(node.value)
 
-        bounds(node.operator_loc)
-        operator = on_op("#{node.operator}=")
+        bounds(node.binary_operator_loc)
+        operator = on_op("#{node.binary_operator}=")
         value = visit_write_value(node.value)
 
         bounds(node.location)
@@ -1802,8 +1802,8 @@ module Prism
         bounds(node.name_loc)
         target = on_var_field(on_gvar(node.name.to_s))
 
-        bounds(node.operator_loc)
-        operator = on_op("#{node.operator}=")
+        bounds(node.binary_operator_loc)
+        operator = on_op("#{node.binary_operator}=")
         value = visit_write_value(node.value)
 
         bounds(node.location)
@@ -1983,8 +1983,8 @@ module Prism
         bounds(node.location)
         target = on_aref_field(receiver, arguments)
 
-        bounds(node.operator_loc)
-        operator = on_op("#{node.operator}=")
+        bounds(node.binary_operator_loc)
+        operator = on_op("#{node.binary_operator}=")
         value = visit_write_value(node.value)
 
         bounds(node.location)
@@ -2059,8 +2059,8 @@ module Prism
         bounds(node.name_loc)
         target = on_var_field(on_ivar(node.name.to_s))
 
-        bounds(node.operator_loc)
-        operator = on_op("#{node.operator}=")
+        bounds(node.binary_operator_loc)
+        operator = on_op("#{node.binary_operator}=")
         value = visit_write_value(node.value)
 
         bounds(node.location)
@@ -2337,8 +2337,8 @@ module Prism
         bounds(node.name_loc)
         target = on_var_field(on_ident(node.name_loc.slice))
 
-        bounds(node.operator_loc)
-        operator = on_op("#{node.operator}=")
+        bounds(node.binary_operator_loc)
+        operator = on_op("#{node.binary_operator}=")
         value = visit_write_value(node.value)
 
         bounds(node.location)
diff --git a/lib/prism/translation/ruby_parser.rb b/lib/prism/translation/ruby_parser.rb
index c6f741c8..d01a762a 100644
--- a/lib/prism/translation/ruby_parser.rb
+++ b/lib/prism/translation/ruby_parser.rb
@@ -271,9 +271,9 @@ module Prism
         # ^^^^^^^^^^^^^^^
         def visit_call_operator_write_node(node)
           if op_asgn?(node)
-            s(node, op_asgn_type(node, :op_asgn), visit(node.receiver), visit_write_value(node.value), node.read_name, node.operator)
+            s(node, op_asgn_type(node, :op_asgn), visit(node.receiver), visit_write_value(node.value), node.read_name, node.binary_operator)
           else
-            s(node, op_asgn_type(node, :op_asgn2), visit(node.receiver), node.write_name, node.operator, visit_write_value(node.value))
+            s(node, op_asgn_type(node, :op_asgn2), visit(node.receiver), node.write_name, node.binary_operator, visit_write_value(node.value))
           end
         end
 
@@ -372,7 +372,7 @@ module Prism
         # @@foo += bar
         # ^^^^^^^^^^^^
         def visit_class_variable_operator_write_node(node)
-          s(node, class_variable_write_type, node.name, s(node, :call, s(node, :cvar, node.name), node.operator, visit_write_value(node.value)))
+          s(node, class_variable_write_type, node.name, s(node, :call, s(node, :cvar, node.name), node.binary_operator, visit_write_value(node.value)))
         end
 
         # @@foo &&= bar
@@ -417,7 +417,7 @@ module Prism
         # Foo += bar
         # ^^^^^^^^^^^
         def visit_constant_operator_write_node(node)
-          s(node, :cdecl, node.name, s(node, :call, s(node, :const, node.name), node.operator, visit_write_value(node.value)))
+          s(node, :cdecl, node.name, s(node, :call, s(node, :const, node.name), node.binary_operator, visit_write_value(node.value)))
         end
 
         # Foo &&= bar
@@ -460,7 +460,7 @@ module Prism
         # Foo::Bar += baz
         # ^^^^^^^^^^^^^^^
         def visit_constant_path_operator_write_node(node)
-          s(node, :op_asgn, visit(node.target), node.operator, visit_write_value(node.value))
+          s(node, :op_asgn, visit(node.target), node.binary_operator, visit_write_value(node.value))
         end
 
         # Foo::Bar &&= baz
@@ -627,7 +627,7 @@ module Prism
         # $foo += bar
         # ^^^^^^^^^^^
         def visit_global_variable_operator_write_node(node)
-          s(node, :gasgn, node.name, s(node, :call, s(node, :gvar, node.name), node.operator, visit(node.value)))
+          s(node, :gasgn, node.name, s(node, :call, s(node, :gvar, node.name), node.binary_operator, visit(node.value)))
         end
 
         # $foo &&= bar
@@ -719,7 +719,7 @@ module Prism
             arglist << visit(node.block) if !node.block.nil?
           end
 
-          s(node, :op_asgn1, visit(node.receiver), arglist, node.operator, visit_write_value(node.value))
+          s(node, :op_asgn1, visit(node.receiver), arglist, node.binary_operator, visit_write_value(node.value))
         end
 
         # foo[bar] &&= baz
@@ -775,7 +775,7 @@ module Prism
         # @foo += bar
         # ^^^^^^^^^^^
         def visit_instance_variable_operator_write_node(node)
-          s(node, :iasgn, node.name, s(node, :call, s(node, :ivar, node.name), node.operator, visit_write_value(node.value)))
+          s(node, :iasgn, node.name, s(node, :call, s(node, :ivar, node.name), node.binary_operator, visit_write_value(node.value)))
         end
 
         # @foo &&= bar
@@ -960,7 +960,7 @@ module Prism
         # foo += bar
         # ^^^^^^^^^^
         def visit_local_variable_operator_write_node(node)
-          s(node, :lasgn, node.name, s(node, :call, s(node, :lvar, node.name), node.operator, visit_write_value(node.value)))
+          s(node, :lasgn, node.name, s(node, :call, s(node, :lvar, node.name), node.binary_operator, visit_write_value(node.value)))
         end
 
         # foo &&= bar
diff --git a/rakelib/lint.rake b/rakelib/lint.rake
index 58b39f5a..89d5a01b 100644
--- a/rakelib/lint.rake
+++ b/rakelib/lint.rake
@@ -28,6 +28,12 @@ task :lint do
     exit(1)
   end
 
+  if (operators = nodes.select { |node| node.fetch("fields", []).any? { |field| field["name"] == "operator" } }).any?
+    names = operators.map { |node| node.fetch("name") }
+    warn("Nodes cannot have fields named 'operator' because it is a C++ reserved keyword, found in #{names.join(", ")}")
+    exit(1)
+  end
+
   if (uncommented = nodes.select { |node| !node.key?("comment") }).any?
     names = uncommented.map { |node| node.fetch("name") }
     warn("Expected all nodes to be commented, missing comments for #{names.join(", ")}")
diff --git a/src/prism.c b/src/prism.c
index b217b469..b517aa95 100644
--- a/src/prism.c
+++ b/src/prism.c
@@ -3080,8 +3080,8 @@ pm_call_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target,
         .message_loc = target->message_loc,
         .read_name = 0,
         .write_name = target->name,
-        .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
-        .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
+        .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
+        .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
         .value = value
     };
 
@@ -3119,8 +3119,8 @@ pm_index_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target,
         .arguments = target->arguments,
         .closing_loc = target->closing_loc,
         .block = target->block,
-        .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
-        .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
+        .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
+        .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
         .value = value
     };
 
@@ -3464,9 +3464,9 @@ pm_class_variable_operator_write_node_create(pm_parser_t *parser, pm_class_varia
         },
         .name = target->name,
         .name_loc = target->base.location,
-        .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
+        .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
         .value = value,
-        .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
+        .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
     };
 
     return node;
@@ -3580,9 +3580,9 @@ pm_constant_path_operator_write_node_create(pm_parser_t *parser, pm_constant_pat
             }
         },
         .target = target,
-        .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
+        .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
         .value = value,
-        .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
+        .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
     };
 
     return node;
@@ -3707,9 +3707,9 @@ pm_constant_operator_write_node_create(pm_parser_t *parser, pm_constant_read_nod
         },
         .name = target->name,
         .name_loc = target->base.location,
-        .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
+        .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
         .value = value,
-        .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
+        .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
     };
 
     return node;
@@ -4560,9 +4560,9 @@ pm_global_variable_operator_write_node_create(pm_parser_t *parser, pm_node_t *ta
         },
         .name = pm_global_variable_write_name(parser, target),
         .name_loc = target->location,
-        .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
+        .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
         .value = value,
-        .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
+        .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
     };
 
     return node;
@@ -5068,9 +5068,9 @@ pm_instance_variable_operator_write_node_create(pm_parser_t *parser, pm_instance
         },
         .name = target->name,
         .name_loc = target->base.location,
-        .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
+        .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
         .value = value,
-        .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
+        .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1)
     };
 
     return node;
@@ -5664,10 +5664,10 @@ pm_local_variable_operator_write_node_create(pm_parser_t *parser, pm_node_t *tar
             }
         },
         .name_loc = target->location,
-        .operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
+        .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator),
         .value = value,
         .name = name,
-        .operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
+        .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1),
         .depth = depth
     };
 


Test patch:
diff --git a/test/prism/snapshots/arrays.txt b/test/prism/snapshots/arrays.txt
index e8e53aac..90a4d8f3 100644
--- a/test/prism/snapshots/arrays.txt
+++ b/test/prism/snapshots/arrays.txt
@@ -960,8 +960,8 @@
         │   ├── arguments: ∅
         │   ├── closing_loc: (84,4)-(84,5) = "]"
         │   ├── block: ∅
-        │   ├── operator: :+
-        │   ├── operator_loc: (84,6)-(84,8) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (84,6)-(84,8) = "+="
         │   └── value:
         │       @ IntegerNode (location: (84,9)-(84,10))
         │       ├── flags: decimal
@@ -1040,8 +1040,8 @@
         │   ├── arguments: ∅
         │   ├── closing_loc: (90,8)-(90,9) = "]"
         │   ├── block: ∅
-        │   ├── operator: :+
-        │   ├── operator_loc: (90,10)-(90,12) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (90,10)-(90,12) = "+="
         │   └── value:
         │       @ IntegerNode (location: (90,13)-(90,14))
         │       ├── flags: decimal
@@ -1143,8 +1143,8 @@
         │   │           └── block: ∅
         │   ├── closing_loc: (96,7)-(96,8) = "]"
         │   ├── block: ∅
-        │   ├── operator: :+
-        │   ├── operator_loc: (96,9)-(96,11) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (96,9)-(96,11) = "+="
         │   └── value:
         │       @ IntegerNode (location: (96,12)-(96,13))
         │       ├── flags: decimal
@@ -1262,8 +1262,8 @@
         │   │           └── block: ∅
         │   ├── closing_loc: (102,11)-(102,12) = "]"
         │   ├── block: ∅
-        │   ├── operator: :+
-        │   ├── operator_loc: (102,13)-(102,15) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (102,13)-(102,15) = "+="
         │   └── value:
         │       @ IntegerNode (location: (102,16)-(102,17))
         │       ├── flags: decimal
@@ -1633,8 +1633,8 @@
         │   │           │           └── expression: ∅
         │   │           ├── closing_loc: (116,13)-(116,14) = "]"
         │   │           ├── block: ∅
-        │   │           ├── operator: :+
-        │   │           ├── operator_loc: (116,15)-(116,17) = "+="
+        │   │           ├── binary_operator: :+
+        │   │           ├── binary_operator_loc: (116,15)-(116,17) = "+="
         │   │           └── value:
         │   │               @ IntegerNode (location: (116,18)-(116,19))
         │   │               ├── flags: decimal
diff --git a/test/prism/snapshots/blocks.txt b/test/prism/snapshots/blocks.txt
index 0b1ec52e..1c996ebd 100644
--- a/test/prism/snapshots/blocks.txt
+++ b/test/prism/snapshots/blocks.txt
@@ -158,13 +158,13 @@
         │       │   └── body: (length: 1)
         │       │       └── @ LocalVariableOperatorWriteNode (location: (7,24)-(7,33))
         │       │           ├── name_loc: (7,24)-(7,28) = "memo"
-        │       │           ├── operator_loc: (7,29)-(7,31) = "+="
+        │       │           ├── binary_operator_loc: (7,29)-(7,31) = "+="
         │       │           ├── value:
         │       │           │   @ LocalVariableReadNode (location: (7,32)-(7,33))
         │       │           │   ├── name: :x
         │       │           │   └── depth: 0
         │       │           ├── name: :memo
-        │       │           ├── operator: :+
+        │       │           ├── binary_operator: :+
         │       │           └── depth: 0
         │       ├── opening_loc: (7,12)-(7,13) = "{"
         │       └── closing_loc: (7,34)-(7,35) = "}"
diff --git a/test/prism/snapshots/boolean_operators.txt b/test/prism/snapshots/boolean_operators.txt
index ace8047e..3bf33430 100644
--- a/test/prism/snapshots/boolean_operators.txt
+++ b/test/prism/snapshots/boolean_operators.txt
@@ -21,7 +21,7 @@
         │   └── depth: 0
         ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,6))
         │   ├── name_loc: (3,0)-(3,1) = "a"
-        │   ├── operator_loc: (3,2)-(3,4) = "+="
+        │   ├── binary_operator_loc: (3,2)-(3,4) = "+="
         │   ├── value:
         │   │   @ CallNode (location: (3,5)-(3,6))
         │   │   ├── flags: variable_call, ignore_visibility
@@ -34,7 +34,7 @@
         │   │   ├── closing_loc: ∅
         │   │   └── block: ∅
         │   ├── name: :a
-        │   ├── operator: :+
+        │   ├── binary_operator: :+
         │   └── depth: 0
         └── @ LocalVariableOrWriteNode (location: (5,0)-(5,7))
             ├── name_loc: (5,0)-(5,1) = "a"
diff --git a/test/prism/snapshots/defined.txt b/test/prism/snapshots/defined.txt
index 53a50818..c60173ff 100644
--- a/test/prism/snapshots/defined.txt
+++ b/test/prism/snapshots/defined.txt
@@ -28,13 +28,13 @@
         │   ├── value:
         │   │   @ LocalVariableOperatorWriteNode (location: (3,9)-(3,15))
         │   │   ├── name_loc: (3,9)-(3,10) = "x"
-        │   │   ├── operator_loc: (3,11)-(3,13) = "%="
+        │   │   ├── binary_operator_loc: (3,11)-(3,13) = "%="
         │   │   ├── value:
         │   │   │   @ IntegerNode (location: (3,14)-(3,15))
         │   │   │   ├── flags: decimal
         │   │   │   └── value: 2
         │   │   ├── name: :x
-        │   │   ├── operator: :%
+        │   │   ├── binary_operator: :%
         │   │   └── depth: 0
         │   ├── rparen_loc: (3,15)-(3,16) = ")"
         │   └── keyword_loc: (3,0)-(3,8) = "defined?"
diff --git a/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
index b5acfa1d..f9792aeb 100644
--- a/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
+++ b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt
@@ -10,9 +10,9 @@
             │   ├── name: :X
             │   ├── delimiter_loc: (1,0)-(1,2) = "::"
             │   └── name_loc: (1,2)-(1,3) = "X"
-            ├── operator_loc: (1,4)-(1,6) = "&="
+            ├── binary_operator_loc: (1,4)-(1,6) = "&="
             ├── value:
             │   @ IntegerNode (location: (1,7)-(1,8))
             │   ├── flags: decimal
             │   └── value: 1
-            └── operator: :&
+            └── binary_operator: :&
diff --git a/test/prism/snapshots/seattlerb/index_0_opasgn.txt b/test/prism/snapshots/seattlerb/index_0_opasgn.txt
index 239a5492..322eae99 100644
--- a/test/prism/snapshots/seattlerb/index_0_opasgn.txt
+++ b/test/prism/snapshots/seattlerb/index_0_opasgn.txt
@@ -21,8 +21,8 @@
             ├── arguments: ∅
             ├── closing_loc: (1,2)-(1,3) = "]"
             ├── block: ∅
-            ├── operator: :+
-            ├── operator_loc: (1,4)-(1,6) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (1,4)-(1,6) = "+="
             └── value:
                 @ CallNode (location: (1,7)-(1,8))
                 ├── flags: variable_call, ignore_visibility
diff --git a/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt b/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt
index 92373aee..edef2304 100644
--- a/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt
+++ b/test/prism/snapshots/seattlerb/messy_op_asgn_lineno.txt
@@ -27,7 +27,7 @@
             │           │           │   ├── name: :C
             │           │           │   ├── delimiter_loc: (1,4)-(1,6) = "::"
             │           │           │   └── name_loc: (1,6)-(1,7) = "C"
-            │           │           ├── operator_loc: (1,8)-(1,10) = "*="
+            │           │           ├── binary_operator_loc: (1,8)-(1,10) = "*="
             │           │           ├── value:
             │           │           │   @ CallNode (location: (1,11)-(1,14))
             │           │           │   ├── flags: ignore_visibility
@@ -52,7 +52,7 @@
             │           │           │   │           └── block: ∅
             │           │           │   ├── closing_loc: ∅
             │           │           │   └── block: ∅
-            │           │           └── operator: :*
+            │           │           └── binary_operator: :*
             │           ├── opening_loc: (1,2)-(1,3) = "("
             │           └── closing_loc: (1,14)-(1,15) = ")"
             ├── closing_loc: ∅
diff --git a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt
index e0e8c5b3..523ccde4 100644
--- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt
+++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt
@@ -12,7 +12,7 @@
             │   ├── name: :B
             │   ├── delimiter_loc: (1,1)-(1,3) = "::"
             │   └── name_loc: (1,3)-(1,4) = "B"
-            ├── operator_loc: (1,5)-(1,7) = "*="
+            ├── binary_operator_loc: (1,5)-(1,7) = "*="
             ├── value:
             │   @ CallNode (location: (1,8)-(1,11))
             │   ├── flags: ignore_visibility
@@ -37,4 +37,4 @@
             │   │           └── block: ∅
             │   ├── closing_loc: ∅
             │   └── block: ∅
-            └── operator: :*
+            └── binary_operator: :*
diff --git a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt
index 0daadcf6..b9d00edc 100644
--- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt
+++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt
@@ -12,8 +12,8 @@
             ├── message_loc: (1,3)-(1,4) = "b"
             ├── read_name: :b
             ├── write_name: :b=
-            ├── operator: :+
-            ├── operator_loc: (1,5)-(1,7) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (1,5)-(1,7) = "+="
             └── value:
                 @ IntegerNode (location: (1,8)-(1,9))
                 ├── flags: decimal
diff --git a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
index ea860316..c12ea398 100644
--- a/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
+++ b/test/prism/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt
@@ -12,8 +12,8 @@
             ├── message_loc: (1,3)-(1,4) = "b"
             ├── read_name: :b
             ├── write_name: :b=
-            ├── operator: :*
-            ├── operator_loc: (1,5)-(1,7) = "*="
+            ├── binary_operator: :*
+            ├── binary_operator_loc: (1,5)-(1,7) = "*="
             └── value:
                 @ CallNode (location: (1,8)-(1,11))
                 ├── flags: ignore_visibility
diff --git a/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt b/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt
index 8199eb24..84eef70b 100644
--- a/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt
+++ b/test/prism/snapshots/seattlerb/parse_line_defn_complex.txt
@@ -40,13 +40,13 @@
             │       │   └── block: ∅
             │       ├── @ LocalVariableOperatorWriteNode (location: (3,2)-(3,8))
             │       │   ├── name_loc: (3,2)-(3,3) = "y"
-            │       │   ├── operator_loc: (3,4)-(3,6) = "*="
+            │       │   ├── binary_operator_loc: (3,4)-(3,6) = "*="
             │       │   ├── value:
             │       │   │   @ IntegerNode (location: (3,7)-(3,8))
             │       │   │   ├── flags: decimal
             │       │   │   └── value: 2
             │       │   ├── name: :y
-            │       │   ├── operator: :*
+            │       │   ├── binary_operator: :*
             │       │   └── depth: 0
             │       └── @ ReturnNode (location: (4,2)-(4,10))
             │           ├── flags: redundant
diff --git a/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt b/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt
index 5c2eb2da..d113f2af 100644
--- a/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt
+++ b/test/prism/snapshots/seattlerb/parse_line_op_asgn.txt
@@ -5,7 +5,7 @@
     └── body: (length: 2)
         ├── @ LocalVariableOperatorWriteNode (location: (1,6)-(2,11))
         │   ├── name_loc: (1,6)-(1,9) = "foo"
-        │   ├── operator_loc: (1,10)-(1,12) = "+="
+        │   ├── binary_operator_loc: (1,10)-(1,12) = "+="
         │   ├── value:
         │   │   @ CallNode (location: (2,8)-(2,11))
         │   │   ├── flags: variable_call, ignore_visibility
@@ -18,7 +18,7 @@
         │   │   ├── closing_loc: ∅
         │   │   └── block: ∅
         │   ├── name: :foo
-        │   ├── operator: :+
+        │   ├── binary_operator: :+
         │   └── depth: 0
         └── @ CallNode (location: (3,6)-(3,9))
             ├── flags: variable_call, ignore_visibility
diff --git a/test/prism/snapshots/seattlerb/safe_op_asgn.txt b/test/prism/snapshots/seattlerb/safe_op_asgn.txt
index 7a9fd2b7..ebcedd6b 100644
--- a/test/prism/snapshots/seattlerb/safe_op_asgn.txt
+++ b/test/prism/snapshots/seattlerb/safe_op_asgn.txt
@@ -20,8 +20,8 @@
             ├── message_loc: (1,3)-(1,4) = "b"
             ├── read_name: :b
             ├── write_name: :b=
-            ├── operator: :+
-            ├── operator_loc: (1,5)-(1,7) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (1,5)-(1,7) = "+="
             └── value:
                 @ CallNode (location: (1,8)-(1,11))
                 ├── flags: ignore_visibility
diff --git a/test/prism/snapshots/unparser/corpus/literal/opasgn.txt b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt
index 8dc08496..0761b473 100644
--- a/test/prism/snapshots/unparser/corpus/literal/opasgn.txt
+++ b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt
@@ -5,53 +5,53 @@
     └── body: (length: 24)
         ├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,6))
         │   ├── name_loc: (1,0)-(1,1) = "a"
-        │   ├── operator_loc: (1,2)-(1,4) = "+="
+        │   ├── binary_operator_loc: (1,2)-(1,4) = "+="
         │   ├── value:
         │   │   @ IntegerNode (location: (1,5)-(1,6))
         │   │   ├── flags: decimal
         │   │   └── value: 2
         │   ├── name: :a
-        │   ├── operator: :+
+        │   ├── binary_operator: :+
         │   └── depth: 0
         ├── @ LocalVariableOperatorWriteNode (location: (2,0)-(2,6))
         │   ├── name_loc: (2,0)-(2,1) = "a"
-        │   ├── operator_loc: (2,2)-(2,4) = "-="
+        │   ├── binary_operator_loc: (2,2)-(2,4) = "-="
         │   ├── value:
         │   │   @ IntegerNode (location: (2,5)-(2,6))
         │   │   ├── flags: decimal
         │   │   └── value: 2
         │   ├── name: :a
-        │   ├── operator: :-
+        │   ├── binary_operator: :-
         │   └── depth: 0
         ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,7))
         │   ├── name_loc: (3,0)-(3,1) = "a"
-        │   ├── operator_loc: (3,2)-(3,5) = "**="
+        │   ├── binary_operator_loc: (3,2)-(3,5) = "**="
         │   ├── value:
         │   │   @ IntegerNode (location: (3,6)-(3,7))
         │   │   ├── flags: decimal
         │   │   └── value: 2
         │   ├── name: :a
-        │   ├── operator: :**
+        │   ├── binary_operator: :**
         │   └── depth: 0
         ├── @ LocalVariableOperatorWriteNode (location: (4,0)-(4,6))
         │   ├── name_loc: (4,0)-(4,1) = "a"
-        │   ├── operator_loc: (4,2)-(4,4) = "*="
+        │   ├── binary_operator_loc: (4,2)-(4,4) = "*="
         │   ├── value:
         │   │   @ IntegerNode (location: (4,5)-(4,6))
         │   │   ├── flags: decimal
         │   │   └── value: 2
         │   ├── name: :a
-        │   ├── operator: :*
+        │   ├── binary_operator: :*
         │   └── depth: 0
         ├── @ LocalVariableOperatorWriteNode (location: (5,0)-(5,6))
         │   ├── name_loc: (5,0)-(5,1) = "a"
-        │   ├── operator_loc: (5,2)-(5,4) = "/="
+        │   ├── binary_operator_loc: (5,2)-(5,4) = "/="
         │   ├── value:
         │   │   @ IntegerNode (location: (5,5)-(5,6))
         │   │   ├── flags: decimal
         │   │   └── value: 2
         │   ├── name: :a
-        │   ├── operator: :/
+        │   ├── binary_operator: :/
         │   └── depth: 0
         ├── @ LocalVariableAndWriteNode (location: (6,0)-(6,7))
         │   ├── name_loc: (6,0)-(6,1) = "a"
@@ -162,8 +162,8 @@
         │   ├── message_loc: (10,2)-(10,3) = "b"
         │   ├── read_name: :b
         │   ├── write_name: :b=
-        │   ├── operator: :+
-        │   ├── operator_loc: (10,4)-(10,6) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (10,4)-(10,6) = "+="
         │   └── value:
         │       @ IntegerNode (location: (10,7)-(10,8))
         │       ├── flags: decimal
@@ -178,8 +178,8 @@
         │   ├── message_loc: (11,2)-(11,3) = "b"
         │   ├── read_name: :b
         │   ├── write_name: :b=
-        │   ├── operator: :-
-        │   ├── operator_loc: (11,4)-(11,6) = "-="
+        │   ├── binary_operator: :-
+        │   ├── binary_operator_loc: (11,4)-(11,6) = "-="
         │   └── value:
         │       @ IntegerNode (location: (11,7)-(11,8))
         │       ├── flags: decimal
@@ -194,8 +194,8 @@
         │   ├── message_loc: (12,2)-(12,3) = "b"
         │   ├── read_name: :b
         │   ├── write_name: :b=
-        │   ├── operator: :**
-        │   ├── operator_loc: (12,4)-(12,7) = "**="
+        │   ├── binary_operator: :**
+        │   ├── binary_operator_loc: (12,4)-(12,7) = "**="
         │   └── value:
         │       @ IntegerNode (location: (12,8)-(12,9))
         │       ├── flags: decimal
@@ -210,8 +210,8 @@
         │   ├── message_loc: (13,2)-(13,3) = "b"
         │   ├── read_name: :b
         │   ├── write_name: :b=
-        │   ├── operator: :*
-        │   ├── operator_loc: (13,4)-(13,6) = "*="
+        │   ├── binary_operator: :*
+        │   ├── binary_operator_loc: (13,4)-(13,6) = "*="
         │   └── value:
         │       @ IntegerNode (location: (13,7)-(13,8))
         │       ├── flags: decimal
@@ -226,8 +226,8 @@
         │   ├── message_loc: (14,2)-(14,3) = "b"
         │   ├── read_name: :b
         │   ├── write_name: :b=
-        │   ├── operator: :/
-        │   ├── operator_loc: (14,4)-(14,6) = "/="
+        │   ├── binary_operator: :/
+        │   ├── binary_operator_loc: (14,4)-(14,6) = "/="
         │   └── value:
         │       @ IntegerNode (location: (14,7)-(14,8))
         │       ├── flags: decimal
@@ -293,8 +293,8 @@
         │   │           └── block: ∅
         │   ├── closing_loc: (17,3)-(17,4) = "]"
         │   ├── block: ∅
-        │   ├── operator: :+
-        │   ├── operator_loc: (17,5)-(17,7) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (17,5)-(17,7) = "+="
         │   └── value:
         │       @ IntegerNode (location: (17,8)-(17,9))
         │       ├── flags: decimal
@@ -323,8 +323,8 @@
         │   │           └── block: ∅
         │   ├── closing_loc: (18,3)-(18,4) = "]"
         │   ├── block: ∅
-        │   ├── operator: :-
-        │   ├── operator_loc: (18,5)-(18,7) = "-="
+        │   ├── binary_operator: :-
+        │   ├── binary_operator_loc: (18,5)-(18,7) = "-="
         │   └── value:
         │       @ IntegerNode (location: (18,8)-(18,9))
         │       ├── flags: decimal
@@ -353,8 +353,8 @@
         │   │           └── block: ∅
         │   ├── closing_loc: (19,3)-(19,4) = "]"
         │   ├── block: ∅
-        │   ├── operator: :**
-        │   ├── operator_loc: (19,5)-(19,8) = "**="
+        │   ├── binary_operator: :**
+        │   ├── binary_operator_loc: (19,5)-(19,8) = "**="
         │   └── value:
         │       @ IntegerNode (location: (19,9)-(19,10))
         │       ├── flags: decimal
@@ -383,8 +383,8 @@
         │   │           └── block: ∅
         │   ├── closing_loc: (20,3)-(20,4) = "]"
         │   ├── block: ∅
-        │   ├── operator: :*
-        │   ├── operator_loc: (20,5)-(20,7) = "*="
+        │   ├── binary_operator: :*
+        │   ├── binary_operator_loc: (20,5)-(20,7) = "*="
         │   └── value:
         │       @ IntegerNode (location: (20,8)-(20,9))
         │       ├── flags: decimal
@@ -413,8 +413,8 @@
         │   │           └── block: ∅
         │   ├── closing_loc: (21,3)-(21,4) = "]"
         │   ├── block: ∅
-        │   ├── operator: :/
-        │   ├── operator_loc: (21,5)-(21,7) = "/="
+        │   ├── binary_operator: :/
+        │   ├── binary_operator_loc: (21,5)-(21,7) = "/="
         │   └── value:
         │       @ IntegerNode (location: (21,8)-(21,9))
         │       ├── flags: decimal
@@ -501,8 +501,8 @@
             ├── message_loc: (24,4)-(24,5) = "A"
             ├── read_name: :A
             ├── write_name: :A=
-            ├── operator: :+
-            ├── operator_loc: (24,6)-(24,8) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (24,6)-(24,8) = "+="
             └── value:
                 @ IntegerNode (location: (24,9)-(24,10))
                 ├── flags: decimal
diff --git a/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt b/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt
index e100dd8e..7dd26a38 100644
--- a/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt
+++ b/test/prism/snapshots/unparser/corpus/semantic/opasgn.txt
@@ -44,8 +44,8 @@
             │           └── closing_loc: (1,10)-(1,11) = "\""
             ├── closing_loc: (1,11)-(1,12) = "]"
             ├── block: ∅
-            ├── operator: :+
-            ├── operator_loc: (1,13)-(1,15) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (1,13)-(1,15) = "+="
             └── value:
                 @ InterpolatedStringNode (location: (1,16)-(1,25))
                 ├── flags: ∅
diff --git a/test/prism/snapshots/whitequark/const_op_asgn.txt b/test/prism/snapshots/whitequark/const_op_asgn.txt
index 505ce6ef..71df6208 100644
--- a/test/prism/snapshots/whitequark/const_op_asgn.txt
+++ b/test/prism/snapshots/whitequark/const_op_asgn.txt
@@ -10,21 +10,21 @@
         │   │   ├── name: :A
         │   │   ├── delimiter_loc: (1,0)-(1,2) = "::"
         │   │   └── name_loc: (1,2)-(1,3) = "A"
-        │   ├── operator_loc: (1,4)-(1,6) = "+="
+        │   ├── binary_operator_loc: (1,4)-(1,6) = "+="
         │   ├── value:
         │   │   @ IntegerNode (location: (1,7)-(1,8))
         │   │   ├── flags: decimal
         │   │   └── value: 1
-        │   └── operator: :+
+        │   └── binary_operator: :+
         ├── @ ConstantOperatorWriteNode (location: (3,0)-(3,6))
         │   ├── name: :A
         │   ├── name_loc: (3,0)-(3,1) = "A"
-        │   ├── operator_loc: (3,2)-(3,4) = "+="
+        │   ├── binary_operator_loc: (3,2)-(3,4) = "+="
         │   ├── value:
         │   │   @ IntegerNode (location: (3,5)-(3,6))
         │   │   ├── flags: decimal
         │   │   └── value: 1
-        │   └── operator: :+
+        │   └── binary_operator: :+
         ├── @ ConstantPathOperatorWriteNode (location: (5,0)-(5,9))
         │   ├── target:
         │   │   @ ConstantPathNode (location: (5,0)-(5,4))
@@ -34,12 +34,12 @@
         │   │   ├── name: :A
         │   │   ├── delimiter_loc: (5,1)-(5,3) = "::"
         │   │   └── name_loc: (5,3)-(5,4) = "A"
-        │   ├── operator_loc: (5,5)-(5,7) = "+="
+        │   ├── binary_operator_loc: (5,5)-(5,7) = "+="
         │   ├── value:
         │   │   @ IntegerNode (location: (5,8)-(5,9))
         │   │   ├── flags: decimal
         │   │   └── value: 1
-        │   └── operator: :+
+        │   └── binary_operator: :+
         ├── @ DefNode (location: (7,0)-(7,21))
         │   ├── name: :x
         │   ├── name_loc: (7,4)-(7,5) = "x"
diff --git a/test/prism/snapshots/whitequark/op_asgn.txt b/test/prism/snapshots/whitequark/op_asgn.txt
index 8f24a35a..f7266179 100644
--- a/test/prism/snapshots/whitequark/op_asgn.txt
+++ b/test/prism/snapshots/whitequark/op_asgn.txt
@@ -20,8 +20,8 @@
         │   ├── message_loc: (1,4)-(1,5) = "A"
         │   ├── read_name: :A
         │   ├── write_name: :A=
-        │   ├── operator: :+
-        │   ├── operator_loc: (1,6)-(1,8) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (1,6)-(1,8) = "+="
         │   └── value:
         │       @ IntegerNode (location: (1,9)-(1,10))
         │       ├── flags: decimal
@@ -43,8 +43,8 @@
         │   ├── message_loc: (3,4)-(3,5) = "a"
         │   ├── read_name: :a
         │   ├── write_name: :a=
-        │   ├── operator: :+
-        │   ├── operator_loc: (3,6)-(3,8) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (3,6)-(3,8) = "+="
         │   └── value:
         │       @ IntegerNode (location: (3,9)-(3,10))
         │       ├── flags: decimal
@@ -66,8 +66,8 @@
             ├── message_loc: (5,5)-(5,6) = "a"
             ├── read_name: :a
             ├── write_name: :a=
-            ├── operator: :+
-            ├── operator_loc: (5,7)-(5,9) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (5,7)-(5,9) = "+="
             └── value:
                 @ IntegerNode (location: (5,10)-(5,11))
                 ├── flags: decimal
diff --git a/test/prism/snapshots/whitequark/op_asgn_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_cmd.txt
index 7d5ad21d..d2d86b1b 100644
--- a/test/prism/snapshots/whitequark/op_asgn_cmd.txt
+++ b/test/prism/snapshots/whitequark/op_asgn_cmd.txt
@@ -20,8 +20,8 @@
         │   ├── message_loc: (1,4)-(1,5) = "A"
         │   ├── read_name: :A
         │   ├── write_name: :A=
-        │   ├── operator: :+
-        │   ├── operator_loc: (1,6)-(1,8) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (1,6)-(1,8) = "+="
         │   └── value:
         │       @ CallNode (location: (1,9)-(1,14))
         │       ├── flags: ignore_visibility
@@ -63,8 +63,8 @@
         │   ├── message_loc: (3,4)-(3,5) = "a"
         │   ├── read_name: :a
         │   ├── write_name: :a=
-        │   ├── operator: :+
-        │   ├── operator_loc: (3,6)-(3,8) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (3,6)-(3,8) = "+="
         │   └── value:
         │       @ CallNode (location: (3,9)-(3,14))
         │       ├── flags: ignore_visibility
@@ -106,7 +106,7 @@
         │   │   ├── name: :A
         │   │   ├── delimiter_loc: (5,3)-(5,5) = "::"
         │   │   └── name_loc: (5,5)-(5,6) = "A"
-        │   ├── operator_loc: (5,7)-(5,9) = "+="
+        │   ├── binary_operator_loc: (5,7)-(5,9) = "+="
         │   ├── value:
         │   │   @ CallNode (location: (5,10)-(5,15))
         │   │   ├── flags: ignore_visibility
@@ -131,7 +131,7 @@
         │   │   │           └── block: ∅
         │   │   ├── closing_loc: ∅
         │   │   └── block: ∅
-        │   └── operator: :+
+        │   └── binary_operator: :+
         └── @ CallOperatorWriteNode (location: (7,0)-(7,15))
             ├── flags: ∅
             ├── receiver:
@@ -149,8 +149,8 @@
             ├── message_loc: (7,5)-(7,6) = "a"
             ├── read_name: :a
             ├── write_name: :a=
-            ├── operator: :+
-            ├── operator_loc: (7,7)-(7,9) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (7,7)-(7,9) = "+="
             └── value:
                 @ CallNode (location: (7,10)-(7,15))
                 ├── flags: ignore_visibility
diff --git a/test/prism/snapshots/whitequark/op_asgn_index.txt b/test/prism/snapshots/whitequark/op_asgn_index.txt
index fe077fae..b302abda 100644
--- a/test/prism/snapshots/whitequark/op_asgn_index.txt
+++ b/test/prism/snapshots/whitequark/op_asgn_index.txt
@@ -30,8 +30,8 @@
             │           └── value: 1
             ├── closing_loc: (1,8)-(1,9) = "]"
             ├── block: ∅
-            ├── operator: :+
-            ├── operator_loc: (1,10)-(1,12) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (1,10)-(1,12) = "+="
             └── value:
                 @ IntegerNode (location: (1,13)-(1,14))
                 ├── flags: decimal
diff --git a/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
index 87082aad..319ed1a5 100644
--- a/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
+++ b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt
@@ -30,8 +30,8 @@
             │           └── value: 1
             ├── closing_loc: (1,8)-(1,9) = "]"
             ├── block: ∅
-            ├── operator: :+
-            ├── operator_loc: (1,10)-(1,12) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (1,10)-(1,12) = "+="
             └── value:
                 @ CallNode (location: (1,13)-(1,18))
                 ├── flags: ignore_visibility
diff --git a/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt b/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt
index b269104f..840e5a4f 100644
--- a/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt
+++ b/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt
@@ -5,7 +5,7 @@
     └── body: (length: 1)
         └── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,22))
             ├── name_loc: (1,0)-(1,3) = "foo"
-            ├── operator_loc: (1,4)-(1,6) = "+="
+            ├── binary_operator_loc: (1,4)-(1,6) = "+="
             ├── value:
             │   @ RescueModifierNode (location: (1,7)-(1,22))
             │   ├── expression:
@@ -32,5 +32,5 @@
             │       ├── closing_loc: ∅
             │       └── block: ∅
             ├── name: :foo
-            ├── operator: :+
+            ├── binary_operator: :+
             └── depth: 0
diff --git a/test/prism/snapshots/whitequark/ruby_bug_12402.txt b/test/prism/snapshots/whitequark/ruby_bug_12402.txt
index 20bcfeaf..4935007f 100644
--- a/test/prism/snapshots/whitequark/ruby_bug_12402.txt
+++ b/test/prism/snapshots/whitequark/ruby_bug_12402.txt
@@ -5,7 +5,7 @@
     └── body: (length: 14)
         ├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,27))
         │   ├── name_loc: (1,0)-(1,3) = "foo"
-        │   ├── operator_loc: (1,4)-(1,6) = "+="
+        │   ├── binary_operator_loc: (1,4)-(1,6) = "+="
         │   ├── value:
         │   │   @ RescueModifierNode (location: (1,7)-(1,27))
         │   │   ├── expression:
@@ -36,11 +36,11 @@
         │   │   └── rescue_expression:
         │   │       @ NilNode (location: (1,24)-(1,27))
         │   ├── name: :foo
-        │   ├── operator: :+
+        │   ├── binary_operator: :+
         │   └── depth: 0
         ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,28))
         │   ├── name_loc: (3,0)-(3,3) = "foo"
-        │   ├── operator_loc: (3,4)-(3,6) = "+="
+        │   ├── binary_operator_loc: (3,4)-(3,6) = "+="
         │   ├── value:
         │   │   @ RescueModifierNode (location: (3,7)-(3,28))
         │   │   ├── expression:
@@ -71,7 +71,7 @@
         │   │   └── rescue_expression:
         │   │       @ NilNode (location: (3,25)-(3,28))
         │   ├── name: :foo
-        │   ├── operator: :+
+        │   ├── binary_operator: :+
         │   └── depth: 0
         ├── @ LocalVariableWriteNode (location: (5,0)-(5,26))
         │   ├── name: :foo
@@ -151,8 +151,8 @@
         │   ├── message_loc: (9,4)-(9,5) = "C"
         │   ├── read_name: :C
         │   ├── write_name: :C=
-        │   ├── operator: :+
-        │   ├── operator_loc: (9,6)-(9,8) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (9,6)-(9,8) = "+="
         │   └── value:
         │       @ RescueModifierNode (location: (9,9)-(9,29))
         │       ├── expression:
@@ -192,8 +192,8 @@
         │   ├── message_loc: (11,4)-(11,5) = "C"
         │   ├── read_name: :C
         │   ├── write_name: :C=
-        │   ├── operator: :+
-        │   ├── operator_loc: (11,6)-(11,8) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (11,6)-(11,8) = "+="
         │   └── value:
         │       @ RescueModifierNode (location: (11,9)-(11,30))
         │       ├── expression:
@@ -233,8 +233,8 @@
         │   ├── message_loc: (13,4)-(13,5) = "m"
         │   ├── read_name: :m
         │   ├── write_name: :m=
-        │   ├── operator: :+
-        │   ├── operator_loc: (13,6)-(13,8) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (13,6)-(13,8) = "+="
         │   └── value:
         │       @ RescueModifierNode (location: (13,9)-(13,29))
         │       ├── expression:
@@ -274,8 +274,8 @@
         │   ├── message_loc: (15,4)-(15,5) = "m"
         │   ├── read_name: :m
         │   ├── write_name: :m=
-        │   ├── operator: :+
-        │   ├── operator_loc: (15,6)-(15,8) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (15,6)-(15,8) = "+="
         │   └── value:
         │       @ RescueModifierNode (location: (15,9)-(15,30))
         │       ├── expression:
@@ -395,8 +395,8 @@
         │   ├── message_loc: (21,5)-(21,6) = "m"
         │   ├── read_name: :m
         │   ├── write_name: :m=
-        │   ├── operator: :+
-        │   ├── operator_loc: (21,7)-(21,9) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (21,7)-(21,9) = "+="
         │   └── value:
         │       @ RescueModifierNode (location: (21,10)-(21,30))
         │       ├── expression:
@@ -436,8 +436,8 @@
         │   ├── message_loc: (23,5)-(23,6) = "m"
         │   ├── read_name: :m
         │   ├── write_name: :m=
-        │   ├── operator: :+
-        │   ├── operator_loc: (23,7)-(23,9) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (23,7)-(23,9) = "+="
         │   └── value:
         │       @ RescueModifierNode (location: (23,10)-(23,31))
         │       ├── expression:
@@ -484,8 +484,8 @@
         │   │           └── value: 0
         │   ├── closing_loc: (25,5)-(25,6) = "]"
         │   ├── block: ∅
-        │   ├── operator: :+
-        │   ├── operator_loc: (25,7)-(25,9) = "+="
+        │   ├── binary_operator: :+
+        │   ├── binary_operator_loc: (25,7)-(25,9) = "+="
         │   └── value:
         │       @ RescueModifierNode (location: (25,10)-(25,30))
         │       ├── expression:
@@ -532,8 +532,8 @@
             │           └── value: 0
             ├── closing_loc: (27,5)-(27,6) = "]"
             ├── block: ∅
-            ├── operator: :+
-            ├── operator_loc: (27,7)-(27,9) = "+="
+            ├── binary_operator: :+
+            ├── binary_operator_loc: (27,7)-(27,9) = "+="
             └── value:
                 @ RescueModifierNode (location: (27,10)-(27,31))
                 ├── expression:
diff --git a/test/prism/snapshots/whitequark/ruby_bug_12669.txt b/test/prism/snapshots/whitequark/ruby_bug_12669.txt
index 86b02135..6151143b 100644
--- a/test/prism/snapshots/whitequark/ruby_bug_12669.txt
+++ b/test/prism/snapshots/whitequark/ruby_bug_12669.txt
@@ -5,11 +5,11 @@
     └── body: (length: 4)
         ├── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,18))
         │   ├── name_loc: (1,0)-(1,1) = "a"
-        │   ├── operator_loc: (1,2)-(1,4) = "+="
+        │   ├── binary_operator_loc: (1,2)-(1,4) = "+="
         │   ├── value:
         │   │   @ LocalVariableOperatorWriteNode (location: (1,5)-(1,18))
         │   │   ├── name_loc: (1,5)-(1,6) = "b"
-        │   │   ├── operator_loc: (1,7)-(1,9) = "+="
+        │   │   ├── binary_operator_loc: (1,7)-(1,9) = "+="
         │   │   ├── value:
         │   │   │   @ CallNode (location: (1,10)-(1,18))
         │   │   │   ├── flags: ignore_visibility
@@ -31,14 +31,14 @@
         │   │   │   ├── closing_loc: ∅
         │   │   │   └── block: ∅
         │   │   ├── name: :b
-        │   │   ├── operator: :+
+        │   │   ├── binary_operator: :+
         │   │   └── depth: 0
         │   ├── name: :a
-        │   ├── operator: :+
+        │   ├── binary_operator: :+
         │   └── depth: 0
         ├── @ LocalVariableOperatorWriteNode (location: (3,0)-(3,17))
         │   ├── name_loc: (3,0)-(3,1) = "a"
-        │   ├── operator_loc: (3,2)-(3,4) = "+="
+        │   ├── binary_operator_loc: (3,2)-(3,4) = "+="
         │   ├── value:
         │   │   @ LocalVariableWriteNode (location: (3,5)-(3,17))
         │   │   ├── name: :b
@@ -66,7 +66,7 @@
         │   │   │   └── block: ∅
         │   │   └── operator_loc: (3,7)-(3,8) = "="
         │   ├── name: :a
-        │   ├── operator: :+
+        │   ├── binary_operator: :+
         │   └── depth: 0
         ├── @ LocalVariableWriteNode (location: (5,0)-(5,17))
         │   ├── name: :a
@@ -75,7 +75,7 @@
         │   ├── value:
         │   │   @ LocalVariableOperatorWriteNode (location: (5,4)-(5,17))
         │   │   ├── name_loc: (5,4)-(5,5) = "b"
-        │   │   ├── operator_loc: (5,6)-(5,8) = "+="
+        │   │   ├── binary_operator_loc: (5,6)-(5,8) = "+="
         │   │   ├── value:
         │   │   │   @ CallNode (location: (5,9)-(5,17))
         │   │   │   ├── flags: ignore_visibility
@@ -97,7 +97,7 @@
         │   │   │   ├── closing_loc: ∅
         │   │   │   └── block: ∅
         │   │   ├── name: :b
-        │   │   ├── operator: :+
+        │   │   ├── binary_operator: :+
         │   │   └── depth: 0
         │   └── operator_loc: (5,2)-(5,3) = "="
         └── @ LocalVariableWriteNode (location: (7,0)-(7,16))
diff --git a/test/prism/snapshots/whitequark/var_op_asgn.txt b/test/prism/snapshots/whitequark/var_op_asgn.txt
index f423a62d..f20f612f 100644
--- a/test/prism/snapshots/whitequark/var_op_asgn.txt
+++ b/test/prism/snapshots/whitequark/var_op_asgn.txt
@@ -6,30 +6,30 @@
         ├── @ ClassVariableOperatorWriteNode (location: (1,0)-(1,11))
         │   ├── name: :@@var
         │   ├── name_loc: (1,0)-(1,5) = "@@var"
-        │   ├── operator_loc: (1,6)-(1,8) = "|="
+        │   ├── binary_operator_loc: (1,6)-(1,8) = "|="
         │   ├── value:
         │   │   @ IntegerNode (location: (1,9)-(1,11))
         │   │   ├── flags: decimal
         │   │   └── value: 10
-        │   └── operator: :|
+        │   └── binary_operator: :|
         ├── @ InstanceVariableOperatorWriteNode (location: (3,0)-(3,7))
         │   ├── name: :@a
         │   ├── name_loc: (3,0)-(3,2) = "@a"
-        │   ├── operator_loc: (3,3)-(3,5) = "|="
+        │   ├── binary_operator_loc: (3,3)-(3,5) = "|="
         │   ├── value:
         │   │   @ IntegerNode (location: (3,6)-(3,7))
         │   │   ├── flags: decimal
         │   │   └── value: 1
-        │   └── operator: :|
+        │   └── binary_operator: :|
         ├── @ LocalVariableOperatorWriteNode (location: (5,0)-(5,6))
         │   ├── name_loc: (5,0)-(5,1) = "a"
-        │   ├── operator_loc: (5,2)-(5,4) = "+="
+        │   ├── binary_operator_loc: (5,2)-(5,4) = "+="
         │   ├── value:
         │   │   @ IntegerNode (location: (5,5)-(5,6))
         │   │   ├── flags: decimal
         │   │   └── value: 1
         │   ├── name: :a
-        │   ├── operator: :+
+        │   ├── binary_operator: :+
         │   └── depth: 0
         └── @ DefNode (location: (7,0)-(7,23))
             ├── name: :a
@@ -42,12 +42,12 @@
             │       └── @ ClassVariableOperatorWriteNode (location: (7,7)-(7,18))
             │           ├── name: :@@var
             │           ├── name_loc: (7,7)-(7,12) = "@@var"
-            │           ├── operator_loc: (7,13)-(7,15) = "|="
+            │           ├── binary_operator_loc: (7,13)-(7,15) = "|="
             │           ├── value:
             │           │   @ IntegerNode (location: (7,16)-(7,18))
             │           │   ├── flags: decimal
             │           │   └── value: 10
-            │           └── operator: :|
+            │           └── binary_operator: :|
             ├── locals: []
             ├── def_keyword_loc: (7,0)-(7,3) = "def"
             ├── operator_loc: ∅
diff --git a/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt
index d56c099c..0bfa06d5 100644
--- a/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt
+++ b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt
@@ -5,7 +5,7 @@
     └── body: (length: 1)
         └── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,12))
             ├── name_loc: (1,0)-(1,3) = "foo"
-            ├── operator_loc: (1,4)-(1,6) = "+="
+            ├── binary_operator_loc: (1,4)-(1,6) = "+="
             ├── value:
             │   @ CallNode (location: (1,7)-(1,12))
             │   ├── flags: ignore_visibility
@@ -24,5 +24,5 @@
             │   ├── closing_loc: ∅
             │   └── block: ∅
             ├── name: :foo
-            ├── operator: :+
+            ├── binary_operator: :+
             └── depth: 0