rubocop-sketchup 1.2.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +20 -19
  3. data/assets/output.html.erb +301 -301
  4. data/config/default.yml +379 -379
  5. data/lib/rubocop/sketchup/config.rb +63 -63
  6. data/lib/rubocop/sketchup/cop/bugs/material_name.rb +108 -108
  7. data/lib/rubocop/sketchup/cop/bugs/render_mode.rb +72 -72
  8. data/lib/rubocop/sketchup/cop/bugs/uniform_scaling.rb +36 -36
  9. data/lib/rubocop/sketchup/cop/deprecations/add_separator_to_menu.rb +25 -25
  10. data/lib/rubocop/sketchup/cop/deprecations/operation_next_transparent.rb +30 -30
  11. data/lib/rubocop/sketchup/cop/deprecations/require_all.rb +27 -27
  12. data/lib/rubocop/sketchup/cop/deprecations/set_texture_projection.rb +26 -26
  13. data/lib/rubocop/sketchup/cop/deprecations/show_ruby_panel.rb +25 -25
  14. data/lib/rubocop/sketchup/cop/deprecations/sketchup_set.rb +30 -30
  15. data/lib/rubocop/sketchup/cop/performance/openssl.rb +41 -41
  16. data/lib/rubocop/sketchup/cop/performance/operation_disable_ui.rb +33 -33
  17. data/lib/rubocop/sketchup/cop/performance/selection_bulk.rb +79 -79
  18. data/lib/rubocop/sketchup/cop/performance/type_check.rb +63 -63
  19. data/lib/rubocop/sketchup/cop/performance/typename.rb +24 -24
  20. data/lib/rubocop/sketchup/cop/requirements/api_namespace.rb +30 -30
  21. data/lib/rubocop/sketchup/cop/requirements/exit.rb +33 -33
  22. data/lib/rubocop/sketchup/cop/requirements/extension_namespace.rb +125 -125
  23. data/lib/rubocop/sketchup/cop/requirements/file_structure.rb +97 -97
  24. data/lib/rubocop/sketchup/cop/requirements/gem_install.rb +45 -45
  25. data/lib/rubocop/sketchup/cop/requirements/get_extension_license.rb +95 -95
  26. data/lib/rubocop/sketchup/cop/requirements/global_constants.rb +38 -38
  27. data/lib/rubocop/sketchup/cop/requirements/global_include.rb +42 -42
  28. data/lib/rubocop/sketchup/cop/requirements/global_methods.rb +65 -65
  29. data/lib/rubocop/sketchup/cop/requirements/global_variables.rb +95 -95
  30. data/lib/rubocop/sketchup/cop/requirements/language_handler_globals.rb +46 -46
  31. data/lib/rubocop/sketchup/cop/requirements/load_path.rb +83 -83
  32. data/lib/rubocop/sketchup/cop/requirements/minimal_registration.rb +73 -73
  33. data/lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb +161 -161
  34. data/lib/rubocop/sketchup/cop/requirements/register_extension.rb +45 -45
  35. data/lib/rubocop/sketchup/cop/requirements/ruby_core_namespace.rb +291 -291
  36. data/lib/rubocop/sketchup/cop/requirements/ruby_stdlib_namespace.rb +634 -634
  37. data/lib/rubocop/sketchup/cop/requirements/shipped_extensions_namespace.rb +61 -61
  38. data/lib/rubocop/sketchup/cop/requirements/sketchup_extension.rb +119 -119
  39. data/lib/rubocop/sketchup/cop/requirements/sketchup_require.rb +150 -149
  40. data/lib/rubocop/sketchup/cop/suggestions/add_group.rb +49 -49
  41. data/lib/rubocop/sketchup/cop/suggestions/compatibility.rb +128 -128
  42. data/lib/rubocop/sketchup/cop/suggestions/dc_internals.rb +34 -34
  43. data/lib/rubocop/sketchup/cop/suggestions/file_encoding.rb +78 -78
  44. data/lib/rubocop/sketchup/cop/suggestions/model_entities.rb +58 -58
  45. data/lib/rubocop/sketchup/cop/suggestions/monkey_patched_api.rb +45 -45
  46. data/lib/rubocop/sketchup/cop/suggestions/operation_name.rb +137 -137
  47. data/lib/rubocop/sketchup/cop/suggestions/sketchup_find_support_file.rb +39 -39
  48. data/lib/rubocop/sketchup/cop/suggestions/tool_drawing_bounds.rb +45 -45
  49. data/lib/rubocop/sketchup/cop/suggestions/tool_invalidate.rb +68 -68
  50. data/lib/rubocop/sketchup/cop/suggestions/tool_user_input.rb +41 -41
  51. data/lib/rubocop/sketchup/cop/suggestions/toolbar_timer.rb +65 -65
  52. data/lib/rubocop/sketchup/cop.rb +110 -110
  53. data/lib/rubocop/sketchup/dc_globals.rb +24 -24
  54. data/lib/rubocop/sketchup/dc_methods.rb +130 -130
  55. data/lib/rubocop/sketchup/extension_project.rb +65 -65
  56. data/lib/rubocop/sketchup/features.rb +1477 -1420
  57. data/lib/rubocop/sketchup/formatter/extension_review.rb +269 -269
  58. data/lib/rubocop/sketchup/inject.rb +19 -19
  59. data/lib/rubocop/sketchup/namespace.rb +49 -49
  60. data/lib/rubocop/sketchup/namespace_checker.rb +103 -46
  61. data/lib/rubocop/sketchup/no_comment_disable.rb +17 -17
  62. data/lib/rubocop/sketchup/range_help.rb +52 -52
  63. data/lib/rubocop/sketchup/sketchup_target_range.rb +75 -75
  64. data/lib/rubocop/sketchup/sketchup_version.rb +129 -128
  65. data/lib/rubocop/sketchup/tool_checker.rb +41 -43
  66. data/lib/rubocop/sketchup/version.rb +7 -7
  67. data/lib/rubocop/sketchup.rb +14 -14
  68. data/lib/rubocop-sketchup.rb +53 -53
  69. data/rubocop-sketchup.gemspec +29 -29
  70. metadata +8 -8
@@ -1,49 +1,49 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupSuggestions
6
- # The idiomatic way to create groups via the Ruby API differ from the
7
- # way you'd do it from the UI.
8
- #
9
- # Using the API you should prefer to create the group first, then add
10
- # your geometry into the group. This is more performant and predictable.
11
- #
12
- # Grouping existing geometry via the API have historically been affected
13
- # by bugs and issues.
14
- #
15
- # If you do have to group existing geometry via the API, make sure you
16
- # group geometry from the active context; `model.active_entities`.
17
- # Otherwise you might run into unexpected issues, even crashes.
18
- #
19
- # @example Adding new geometry
20
- # # bad
21
- # face1 = model.active_entities.add_face(points1)
22
- # face2 = model.active_entities.add_face(points2)
23
- # group = model.active_entities.add_group([face1, face2])
24
- #
25
- # # good
26
- # group = model.active_entities.add_group
27
- # face1 = group.entities.add_face(points1)
28
- # face2 = group.entities.add_face(points2)
29
- class AddGroup < Cop
30
-
31
- include RangeHelp
32
-
33
- MSG = 'Avoid creating groups out of existing entities.'
34
-
35
- def_node_matcher :add_group?, <<-PATTERN
36
- (send _ :add_group ...)
37
- PATTERN
38
-
39
- def on_send(node)
40
- return unless add_group?(node)
41
- return if node.arguments.empty?
42
-
43
- add_offense(node, location: arguments_range(node))
44
- end
45
-
46
- end
47
- end
48
- end
49
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupSuggestions
6
+ # The idiomatic way to create groups via the Ruby API differ from the
7
+ # way you'd do it from the UI.
8
+ #
9
+ # Using the API you should prefer to create the group first, then add
10
+ # your geometry into the group. This is more performant and predictable.
11
+ #
12
+ # Grouping existing geometry via the API have historically been affected
13
+ # by bugs and issues.
14
+ #
15
+ # If you do have to group existing geometry via the API, make sure you
16
+ # group geometry from the active context; `model.active_entities`.
17
+ # Otherwise you might run into unexpected issues, even crashes.
18
+ #
19
+ # @example Adding new geometry
20
+ # # bad
21
+ # face1 = model.active_entities.add_face(points1)
22
+ # face2 = model.active_entities.add_face(points2)
23
+ # group = model.active_entities.add_group([face1, face2])
24
+ #
25
+ # # good
26
+ # group = model.active_entities.add_group
27
+ # face1 = group.entities.add_face(points1)
28
+ # face2 = group.entities.add_face(points2)
29
+ class AddGroup < Cop
30
+
31
+ include RangeHelp
32
+
33
+ MSG = 'Avoid creating groups out of existing entities.'
34
+
35
+ def_node_matcher :add_group?, <<-PATTERN
36
+ (send _ :add_group ...)
37
+ PATTERN
38
+
39
+ def on_send(node)
40
+ return unless add_group?(node)
41
+ return if node.arguments.empty?
42
+
43
+ add_offense(node, location: arguments_range(node))
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,128 +1,128 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupSuggestions
6
- # It's easy to lose track of what API feature was added in what version or
7
- # SketchUp. You can configure your target SketchUp version and be notified
8
- # if you use features introduced in newer versions.
9
- #
10
- # @example Add this to your .rubocop.yml
11
- # AllCops:
12
- # SketchUp:
13
- # TargetSketchUpVersion: 2016 M1
14
- class Compatibility < SketchUp::Cop
15
-
16
- include SketchUp::Features
17
- include SketchUp
18
-
19
- MSG = 'Incompatible feature with target SketchUp version'
20
-
21
- def_node_matcher :module_definition?, <<~PATTERN
22
- {class module (casgn _ _ class_constructor?)}
23
- PATTERN
24
-
25
- def on_def(node)
26
- return unless observer_method?(node)
27
-
28
- feature_name = "##{node.method_name}"
29
- check_feature(node, :method, feature_name)
30
- end
31
-
32
- def on_send(node)
33
- feature_name = ''
34
- if module_method?(node)
35
- feature_name = "#{node.receiver.const_name}.#{node.method_name}"
36
- else
37
- # Instance methods are harder. It's difficult to infer the type of
38
- # the receiver. If we only check the method name in isolation we
39
- # will get too many false positives with method names matching
40
- # methods in Ruby itself and other older features.
41
- # We try to match names that are unlikely to cause much noise.
42
- return unless checkable_instance_method?(node)
43
-
44
- feature_name = "##{node.method_name}"
45
- end
46
- check_feature(node, :method, feature_name)
47
- end
48
-
49
- def on_const(node)
50
- if node.parent && module_definition?(node.parent)
51
- # This catches definition of classes and modules.
52
- namespace = Namespace.new(node.parent_module_name)
53
- return unless namespace.top_level?
54
- end
55
-
56
- feature_name = node.const_name
57
- [:class, :module, :constant].each { |type|
58
- check_feature(node, type, feature_name)
59
- }
60
- end
61
-
62
- private
63
-
64
- def check_feature(node, type, feature_name)
65
- return unless sketchup_target_version?
66
-
67
- full_feature_name = feature_name
68
- FEATURES.each { |feature_set|
69
- version = feature_set[:version]
70
- feature_version = SketchUp::SketchUpVersion.new(version)
71
- next unless feature_version > sketchup_target_version
72
-
73
- objects = feature_set[:types][type] || []
74
- if type == :method && instance_method?(feature_name)
75
- # Instance methods are simply matching the method name since it's
76
- # very difficult to determine the type of the receiver.
77
- full_feature_name = objects.find { |object|
78
- object.end_with?(feature_name)
79
- }
80
- next unless full_feature_name
81
- else
82
- next unless objects.include?(feature_name)
83
- end
84
- report(node, full_feature_name, feature_version, type)
85
- }
86
- end
87
-
88
- def report(node, feature_name, feature_version, feature_type)
89
- message = "The #{feature_type} `#{feature_name}` was added in "\
90
- "#{feature_version} which is incompatible with target "\
91
- "#{sketchup_target_version}."
92
- location = find_node_location(node)
93
- add_offense(node, location: location, message: message)
94
- end
95
-
96
- def find_node_location(node)
97
- # Highlight the most pertinent piece of the expression.
98
- if node.const_type?
99
- :expression
100
- elsif node.send_type?
101
- :selector
102
- elsif node.def_type?
103
- :name
104
- else # rubocop:disable Lint/DuplicateBranch
105
- :expression
106
- end
107
- end
108
-
109
- def module_method?(node)
110
- node.receiver&.const_type?
111
- end
112
-
113
- def instance_method?(feature_name)
114
- feature_name.start_with?('#')
115
- end
116
-
117
- def checkable_instance_method?(node)
118
- INSTANCE_METHODS.include?(node.method_name)
119
- end
120
-
121
- def observer_method?(node)
122
- OBSERVER_METHODS.include?(node.method_name)
123
- end
124
-
125
- end
126
- end
127
- end
128
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupSuggestions
6
+ # It's easy to lose track of what API feature was added in what version or
7
+ # SketchUp. You can configure your target SketchUp version and be notified
8
+ # if you use features introduced in newer versions.
9
+ #
10
+ # @example Add this to your .rubocop.yml
11
+ # AllCops:
12
+ # SketchUp:
13
+ # TargetSketchUpVersion: 2016 M1
14
+ class Compatibility < SketchUp::Cop
15
+
16
+ include SketchUp::Features
17
+ include SketchUp
18
+
19
+ MSG = 'Incompatible feature with target SketchUp version'
20
+
21
+ def_node_matcher :module_definition?, <<~PATTERN
22
+ {class module (casgn _ _ class_constructor?)}
23
+ PATTERN
24
+
25
+ def on_def(node)
26
+ return unless observer_method?(node)
27
+
28
+ feature_name = "##{node.method_name}"
29
+ check_feature(node, :method, feature_name)
30
+ end
31
+
32
+ def on_send(node)
33
+ feature_name = ''
34
+ if module_method?(node)
35
+ feature_name = "#{node.receiver.const_name}.#{node.method_name}"
36
+ else
37
+ # Instance methods are harder. It's difficult to infer the type of
38
+ # the receiver. If we only check the method name in isolation we
39
+ # will get too many false positives with method names matching
40
+ # methods in Ruby itself and other older features.
41
+ # We try to match names that are unlikely to cause much noise.
42
+ return unless checkable_instance_method?(node)
43
+
44
+ feature_name = "##{node.method_name}"
45
+ end
46
+ check_feature(node, :method, feature_name)
47
+ end
48
+
49
+ def on_const(node)
50
+ if node.parent && module_definition?(node.parent)
51
+ # This catches definition of classes and modules.
52
+ namespace = Namespace.new(node.parent_module_name)
53
+ return unless namespace.top_level?
54
+ end
55
+
56
+ feature_name = node.const_name
57
+ [:class, :module, :constant].each { |type|
58
+ check_feature(node, type, feature_name)
59
+ }
60
+ end
61
+
62
+ private
63
+
64
+ def check_feature(node, type, feature_name)
65
+ return unless sketchup_target_version?
66
+
67
+ full_feature_name = feature_name
68
+ FEATURES.each { |feature_set|
69
+ version = feature_set[:version]
70
+ feature_version = SketchUp::SketchUpVersion.new(version)
71
+ next unless feature_version > sketchup_target_version
72
+
73
+ objects = feature_set[:types][type] || []
74
+ if type == :method && instance_method?(feature_name)
75
+ # Instance methods are simply matching the method name since it's
76
+ # very difficult to determine the type of the receiver.
77
+ full_feature_name = objects.find { |object|
78
+ object.end_with?(feature_name)
79
+ }
80
+ next unless full_feature_name
81
+ else
82
+ next unless objects.include?(feature_name)
83
+ end
84
+ report(node, full_feature_name, feature_version, type)
85
+ }
86
+ end
87
+
88
+ def report(node, feature_name, feature_version, feature_type)
89
+ message = "The #{feature_type} `#{feature_name}` was added in " \
90
+ "#{feature_version} which is incompatible with target " \
91
+ "#{sketchup_target_version}."
92
+ location = find_node_location(node)
93
+ add_offense(node, location: location, message: message)
94
+ end
95
+
96
+ def find_node_location(node)
97
+ # Highlight the most pertinent piece of the expression.
98
+ if node.const_type?
99
+ :expression
100
+ elsif node.send_type?
101
+ :selector
102
+ elsif node.def_type?
103
+ :name
104
+ else # rubocop:disable Lint/DuplicateBranch
105
+ :expression
106
+ end
107
+ end
108
+
109
+ def module_method?(node)
110
+ node.receiver&.const_type?
111
+ end
112
+
113
+ def instance_method?(feature_name)
114
+ feature_name.start_with?('#')
115
+ end
116
+
117
+ def checkable_instance_method?(node)
118
+ INSTANCE_METHODS.include?(node.method_name)
119
+ end
120
+
121
+ def observer_method?(node)
122
+ OBSERVER_METHODS.include?(node.method_name)
123
+ end
124
+
125
+ end
126
+ end
127
+ end
128
+ end
@@ -1,34 +1,34 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupSuggestions
6
- # Tapping into the internals of Dynamic Components is risky. It could
7
- # change at any time. If you create an extension that depend on the
8
- # internal logic of another extension you are at the mercy of change and
9
- # luck!
10
- class DynamicComponentInternals < SketchUp::Cop
11
-
12
- include SketchUp::DynamicComponentGlobals
13
-
14
- MSG = 'Avoid relying on internal logic of Dynamic Components.'
15
-
16
- def on_gvar(node)
17
- check_global(node)
18
- end
19
-
20
- def on_gvasgn(node)
21
- check_global(node)
22
- end
23
-
24
- def check_global(node)
25
- global_var, = *node
26
- return unless dc_global_var?(global_var)
27
-
28
- add_offense(node, location: :name, severity: :warning)
29
- end
30
-
31
- end
32
- end
33
- end
34
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupSuggestions
6
+ # Tapping into the internals of Dynamic Components is risky. It could
7
+ # change at any time. If you create an extension that depend on the
8
+ # internal logic of another extension you are at the mercy of change and
9
+ # luck!
10
+ class DynamicComponentInternals < SketchUp::Cop
11
+
12
+ include SketchUp::DynamicComponentGlobals
13
+
14
+ MSG = 'Avoid relying on internal logic of Dynamic Components.'
15
+
16
+ def on_gvar(node)
17
+ check_global(node)
18
+ end
19
+
20
+ def on_gvasgn(node)
21
+ check_global(node)
22
+ end
23
+
24
+ def check_global(node)
25
+ global_var, = *node
26
+ return unless dc_global_var?(global_var)
27
+
28
+ add_offense(node, location: :name, severity: :warning)
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,78 +1,78 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupSuggestions
6
- # When using __FILE__ and __dir__, beware that Ruby doesn't apply the
7
- # correct encoding to the strings under Windows. When they contain
8
- # non-english characters it will lead to exceptions being raised when the
9
- # strings are used. Force encoding to work around this.
10
- #
11
- # @example Might fail
12
- # basename = File.basename(__FILE__, '.*')
13
- #
14
- # @example Workaround
15
- # file = __FILE__.dup
16
- # file.force_encoding('UTF-8') if file.respond_to?(:force_encoding)
17
- # basename = File.basename(file, '.*')
18
- class FileEncoding < SketchUp::Cop
19
-
20
- MSG = 'Beware encoding bug with `__FILE__` and `__dir__`.'
21
-
22
- def_node_matcher :file_loaded?, <<-PATTERN
23
- (send nil? {:file_loaded? :file_loaded} ...)
24
- PATTERN
25
-
26
- def_node_matcher :magic_dir?, <<-PATTERN
27
- (send nil? :__dir__)
28
- PATTERN
29
-
30
- def magic_file?(node)
31
- node.respond_to?(:str_type?) &&
32
- node.str_type? &&
33
- node.source_range.is?('__FILE__')
34
- end
35
-
36
- def magic_file_or_dir?(node)
37
- magic_file?(node) || magic_dir?(node)
38
- end
39
-
40
- def on_send(node)
41
- return if file_loaded?(node)
42
- return if node.arguments.none?(&method(:magic_file_or_dir?))
43
-
44
- add_offense(node, location: :expression)
45
- end
46
-
47
-
48
- def_node_search :force_encoding, <<-PATTERN
49
- (send ({lvar ivar cvar} $_) :force_encoding ...)
50
- PATTERN
51
-
52
- def on_assign(node)
53
- lhs, value = *node
54
- return unless magic_file_or_dir?(value)
55
- # After assigning __FILE__ or __dir_ to a variable, check the parent
56
- # scope to whether .force_encoding is called on the variable.
57
- return if node.parent.nil?
58
-
59
- encoded = force_encoding(node.parent).to_a
60
- return if encoded.include?(lhs)
61
-
62
- add_offense(node)
63
- end
64
-
65
- alias on_lvasgn on_assign
66
- alias on_masgn on_assign
67
- alias on_casgn on_assign
68
- alias on_ivasgn on_assign
69
- alias on_cvasgn on_assign
70
- alias on_gvasgn on_assign
71
- alias on_or_asgn on_assign
72
- alias on_and_asgn on_assign
73
- alias on_op_asgn on_assign
74
-
75
- end
76
- end
77
- end
78
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupSuggestions
6
+ # When using __FILE__ and __dir__, beware that Ruby doesn't apply the
7
+ # correct encoding to the strings under Windows. When they contain
8
+ # non-english characters it will lead to exceptions being raised when the
9
+ # strings are used. Force encoding to work around this.
10
+ #
11
+ # @example Might fail
12
+ # basename = File.basename(__FILE__, '.*')
13
+ #
14
+ # @example Workaround
15
+ # file = __FILE__.dup
16
+ # file.force_encoding('UTF-8') if file.respond_to?(:force_encoding)
17
+ # basename = File.basename(file, '.*')
18
+ class FileEncoding < SketchUp::Cop
19
+
20
+ MSG = 'Beware encoding bug with `__FILE__` and `__dir__`.'
21
+
22
+ def_node_matcher :file_loaded?, <<-PATTERN
23
+ (send nil? {:file_loaded? :file_loaded} ...)
24
+ PATTERN
25
+
26
+ def_node_matcher :magic_dir?, <<-PATTERN
27
+ (send nil? :__dir__)
28
+ PATTERN
29
+
30
+ def magic_file?(node)
31
+ node.respond_to?(:str_type?) &&
32
+ node.str_type? &&
33
+ node.source_range.is?('__FILE__')
34
+ end
35
+
36
+ def magic_file_or_dir?(node)
37
+ magic_file?(node) || magic_dir?(node)
38
+ end
39
+
40
+ def on_send(node)
41
+ return if file_loaded?(node)
42
+ return if node.arguments.none?(&method(:magic_file_or_dir?))
43
+
44
+ add_offense(node, location: :expression)
45
+ end
46
+
47
+
48
+ def_node_search :force_encoding, <<-PATTERN
49
+ (send ({lvar ivar cvar} $_) :force_encoding ...)
50
+ PATTERN
51
+
52
+ def on_assign(node)
53
+ lhs, value = *node
54
+ return unless magic_file_or_dir?(value)
55
+ # After assigning __FILE__ or __dir_ to a variable, check the parent
56
+ # scope to whether .force_encoding is called on the variable.
57
+ return if node.parent.nil?
58
+
59
+ encoded = force_encoding(node.parent).to_a
60
+ return if encoded.include?(lhs)
61
+
62
+ add_offense(node)
63
+ end
64
+
65
+ alias on_lvasgn on_assign
66
+ alias on_masgn on_assign
67
+ alias on_casgn on_assign
68
+ alias on_ivasgn on_assign
69
+ alias on_cvasgn on_assign
70
+ alias on_gvasgn on_assign
71
+ alias on_or_asgn on_assign
72
+ alias on_and_asgn on_assign
73
+ alias on_op_asgn on_assign
74
+
75
+ end
76
+ end
77
+ end
78
+ end