rubocop-sketchup 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,27 +1,27 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupDeprecations
6
- # Method is deprecated because it adds the given path to `$LOAD_PATH`.
7
- # Modifying `$LOAD_PATH` is bad practice because it can cause extensions
8
- # to inadvertently load the wrong file.
9
- class RequireAll < SketchUp::Cop
10
-
11
- MSG = 'Method is deprecated because it adds the given path '\
12
- 'to $LOAD_PATH.'
13
-
14
- def_node_matcher :require_all?, <<-PATTERN
15
- (send nil? :require_all _)
16
- PATTERN
17
-
18
- def on_send(node)
19
- return unless require_all?(node)
20
-
21
- add_offense(node, location: :selector)
22
- end
23
-
24
- end
25
- end
26
- end
27
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupDeprecations
6
+ # Method is deprecated because it adds the given path to `$LOAD_PATH`.
7
+ # Modifying `$LOAD_PATH` is bad practice because it can cause extensions
8
+ # to inadvertently load the wrong file.
9
+ class RequireAll < SketchUp::Cop
10
+
11
+ MSG = 'Method is deprecated because it adds the given path ' \
12
+ 'to $LOAD_PATH.'
13
+
14
+ def_node_matcher :require_all?, <<-PATTERN
15
+ (send nil? :require_all _)
16
+ PATTERN
17
+
18
+ def on_send(node)
19
+ return unless require_all?(node)
20
+
21
+ add_offense(node, location: :selector)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,26 +1,26 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupDeprecations
6
- # Method is deprecated because it creates invalid UV mapping. Saving the
7
- # model will display a dialog indicating that the model needs to be
8
- # repaired. Once repaired the UV mapping will visually change.
9
- class SetTextureProjection < SketchUp::Cop
10
-
11
- MSG = 'Method is deprecated. It can create invalid UV mapping.'
12
-
13
- def_node_matcher :set_texture_projection?, <<-PATTERN
14
- (send _ :set_texture_projection ...)
15
- PATTERN
16
-
17
- def on_send(node)
18
- return unless set_texture_projection?(node)
19
-
20
- add_offense(node, location: :selector)
21
- end
22
-
23
- end
24
- end
25
- end
26
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupDeprecations
6
+ # Method is deprecated because it creates invalid UV mapping. Saving the
7
+ # model will display a dialog indicating that the model needs to be
8
+ # repaired. Once repaired the UV mapping will visually change.
9
+ class SetTextureProjection < SketchUp::Cop
10
+
11
+ MSG = 'Method is deprecated. It can create invalid UV mapping.'
12
+
13
+ def_node_matcher :set_texture_projection?, <<-PATTERN
14
+ (send _ :set_texture_projection ...)
15
+ PATTERN
16
+
17
+ def on_send(node)
18
+ return unless set_texture_projection?(node)
19
+
20
+ add_offense(node, location: :selector)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,25 +1,25 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupDeprecations
6
- # Method is deprecated. Use `SKETCHUP_CONSOLE.show` instead.
7
- class ShowRubyPanel < SketchUp::Cop
8
-
9
- MSG = 'Method is deprecated. Use `SKETCHUP_CONSOLE.show` '\
10
- 'instead.'
11
-
12
- def_node_matcher :show_ruby_panel?, <<-PATTERN
13
- (send nil? :show_ruby_panel)
14
- PATTERN
15
-
16
- def on_send(node)
17
- return unless show_ruby_panel?(node)
18
-
19
- add_offense(node, location: :expression)
20
- end
21
-
22
- end
23
- end
24
- end
25
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupDeprecations
6
+ # Method is deprecated. Use `SKETCHUP_CONSOLE.show` instead.
7
+ class ShowRubyPanel < SketchUp::Cop
8
+
9
+ MSG = 'Method is deprecated. Use `SKETCHUP_CONSOLE.show` ' \
10
+ 'instead.'
11
+
12
+ def_node_matcher :show_ruby_panel?, <<-PATTERN
13
+ (send nil? :show_ruby_panel)
14
+ PATTERN
15
+
16
+ def on_send(node)
17
+ return unless show_ruby_panel?(node)
18
+
19
+ add_offense(node, location: :expression)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,30 +1,30 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupDeprecations
6
- # From SketchUp 6 until SketchUp 2013 the SketchUp API shipped with a
7
- # `Set` class. When SketchUp started shipping with the Ruby StdLib in
8
- # SketchUp 2014 the class was changed from `Set` to `Sketchup::Set` in
9
- # order to avoid conflict with the Ruby Standard Library.
10
- #
11
- # The `Sketchup::Set` class is much slower than Ruby's own `Set` class
12
- # and less versatile.
13
- class SketchupSet < SketchUp::Cop
14
-
15
- MSG = 'Class is deprecated.'
16
-
17
- def_node_matcher :sketchup_set?, <<-PATTERN
18
- (const (const nil? :Sketchup) :Set)
19
- PATTERN
20
-
21
- def on_const(node)
22
- return unless sketchup_set?(node)
23
-
24
- add_offense(node, location: :expression)
25
- end
26
-
27
- end
28
- end
29
- end
30
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupDeprecations
6
+ # From SketchUp 6 until SketchUp 2013 the SketchUp API shipped with a
7
+ # `Set` class. When SketchUp started shipping with the Ruby StdLib in
8
+ # SketchUp 2014 the class was changed from `Set` to `Sketchup::Set` in
9
+ # order to avoid conflict with the Ruby Standard Library.
10
+ #
11
+ # The `Sketchup::Set` class is much slower than Ruby's own `Set` class
12
+ # and less versatile.
13
+ class SketchupSet < SketchUp::Cop
14
+
15
+ MSG = 'Class is deprecated.'
16
+
17
+ def_node_matcher :sketchup_set?, <<-PATTERN
18
+ (const (const nil? :Sketchup) :Set)
19
+ PATTERN
20
+
21
+ def on_const(node)
22
+ return unless sketchup_set?(node)
23
+
24
+ add_offense(node, location: :expression)
25
+ end
26
+
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,41 +1,41 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupPerformance
6
- # There are performance issue with the OpenSSL library that Ruby ship. In
7
- # a clean SU session, default model there is a small delay observed in the
8
- # Windows version of SU.
9
- #
10
- # But with a larger model loaded, or session that have had larger files
11
- # loaded the lag will be minutes.
12
- #
13
- # `SecureRandom` is also affected by this, as it uses OpenSSL to seed.
14
- #
15
- # It also affects `Net::HTTP` if making HTTPS connections.
16
- class OpenSSL < SketchUp::Cop
17
-
18
- MSG = 'Avoid use of OpenSSL within SketchUp due to severe performance '\
19
- 'issues.'
20
-
21
- # http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
22
- # https://rubocop.readthedocs.io/en/latest/node_pattern/
23
- def_node_matcher :require, <<-PATTERN
24
- (send nil? :require
25
- (str $_)
26
- )
27
- PATTERN
28
-
29
- OPEN_SSL_USAGE = %w[openssl securerandom net/https net/http].freeze
30
-
31
- def on_send(node)
32
- filename = require(node)
33
- return if filename.nil?
34
- return unless OPEN_SSL_USAGE.include?(filename.downcase)
35
-
36
- add_offense(node, location: :expression)
37
- end
38
- end
39
- end
40
- end
41
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupPerformance
6
+ # There are performance issue with the OpenSSL library that Ruby ship. In
7
+ # a clean SU session, default model there is a small delay observed in the
8
+ # Windows version of SU.
9
+ #
10
+ # But with a larger model loaded, or session that have had larger files
11
+ # loaded the lag will be minutes.
12
+ #
13
+ # `SecureRandom` is also affected by this, as it uses OpenSSL to seed.
14
+ #
15
+ # It also affects `Net::HTTP` if making HTTPS connections.
16
+ class OpenSSL < SketchUp::Cop
17
+
18
+ MSG = 'Avoid use of OpenSSL within SketchUp due to severe ' \
19
+ 'performance issues.'
20
+
21
+ # http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
22
+ # https://rubocop.readthedocs.io/en/latest/node_pattern/
23
+ def_node_matcher :require, <<-PATTERN
24
+ (send nil? :require
25
+ (str $_)
26
+ )
27
+ PATTERN
28
+
29
+ OPEN_SSL_USAGE = %w[openssl securerandom net/https net/http].freeze
30
+
31
+ def on_send(node)
32
+ filename = require(node)
33
+ return if filename.nil?
34
+ return unless OPEN_SSL_USAGE.include?(filename.downcase)
35
+
36
+ add_offense(node, location: :expression)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,33 +1,33 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupPerformance
6
- # Operations should disable the UI for performance gain.
7
- #
8
- # @example
9
- # model = Sketchup.active_model
10
- # model.start_operation('Operation Name', true)
11
- # # <model changes>
12
- # model.commit_operation
13
- class OperationDisableUI < SketchUp::Cop
14
- MSG = 'Operations should disable the UI for performance gain.'
15
-
16
- def on_send(node)
17
- _, method_name, *args = *node
18
- return unless method_name == :start_operation
19
-
20
- if args.size < 2
21
- add_offense(node, location: :selector)
22
- return
23
- end
24
- argument = args[1]
25
- disable_ui = argument.truthy_literal?
26
- return if disable_ui
27
-
28
- add_offense(argument, location: :expression)
29
- end
30
- end
31
- end
32
- end
33
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupPerformance
6
+ # Operations should disable the UI for performance gain.
7
+ #
8
+ # @example
9
+ # model = Sketchup.active_model
10
+ # model.start_operation('Operation Name', true)
11
+ # # <model changes>
12
+ # model.commit_operation
13
+ class OperationDisableUI < SketchUp::Cop
14
+ MSG = 'Operations should disable the UI for performance gain.'
15
+
16
+ def on_send(node)
17
+ _, method_name, *args = *node
18
+ return unless method_name == :start_operation
19
+
20
+ if args.size < 2
21
+ add_offense(node, location: :selector)
22
+ return
23
+ end
24
+ argument = args[1]
25
+ disable_ui = argument.truthy_literal?
26
+ return if disable_ui
27
+
28
+ add_offense(argument, location: :expression)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,79 +1,79 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupPerformance
6
- # Prefer changing selection in bulk instead of modifying selection within
7
- # loops. It's much faster to change the selection in bulk. UI updates are
8
- # triggered when you update the selection, so reduce the amount of calls.
9
- #
10
- # @example Poor performance
11
- # model = Sketchup.active_model
12
- # model.active_entities.each { |entity|
13
- # model.selection.add(entity) if entity.is_a?(Sketchup::Face)
14
- # }
15
- #
16
- # @example Better performance
17
- # model = Sketchup.active_model
18
- # faces = model.active_entities.map { |entity|
19
- # entity.is_a?(Sketchup::Face)
20
- # }
21
- # model.selection.add(faces)
22
- #
23
- # @example Better performance and simpler
24
- # model = Sketchup.active_model
25
- # faces = model.active_entities.grep(Sketchup::Face)
26
- # model.selection.add(faces)
27
- class SelectionBulkChanges < SketchUp::Cop
28
-
29
- include RangeHelp
30
-
31
- MSG = 'Prefer changing selection in bulk instead of modifying '\
32
- 'selection within loops.'
33
-
34
- # http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
35
- # https://rubocop.readthedocs.io/en/latest/node_pattern/
36
- def_node_matcher :selection?, <<-PATTERN
37
- (send
38
- (send _ {:selection :sel}) {:add :remove :toggle}
39
- ...)
40
- PATTERN
41
-
42
- def_node_matcher :block_loop?, <<-PATTERN
43
- (block
44
- (send
45
- (send _ _) {
46
- :each :each_with_index :each_with_object
47
- :each_entry :each_index :each_slice
48
- :each_key :each_pair :each_value
49
- :grep
50
- } ...)
51
- ...)
52
- PATTERN
53
-
54
- def_node_matcher :numeric_loop?, <<-PATTERN
55
- (block
56
- (send
57
- ({int float} _) {:times :upto :downto} ...)
58
- ...)
59
- PATTERN
60
-
61
- def iterator?(node)
62
- node.is_a?(RuboCop::AST::ForNode) ||
63
- node.is_a?(RuboCop::AST::UntilNode) ||
64
- node.is_a?(RuboCop::AST::WhileNode) ||
65
- block_loop?(node) ||
66
- numeric_loop?(node)
67
- end
68
-
69
- def on_send(node)
70
- return unless selection?(node)
71
- return unless node.ancestors.any?(&method(:iterator?))
72
-
73
- add_offense(node, location: range_with_receiver(node))
74
- end
75
-
76
- end
77
- end
78
- end
79
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupPerformance
6
+ # Prefer changing selection in bulk instead of modifying selection within
7
+ # loops. It's much faster to change the selection in bulk. UI updates are
8
+ # triggered when you update the selection, so reduce the amount of calls.
9
+ #
10
+ # @example Poor performance
11
+ # model = Sketchup.active_model
12
+ # model.active_entities.each { |entity|
13
+ # model.selection.add(entity) if entity.is_a?(Sketchup::Face)
14
+ # }
15
+ #
16
+ # @example Better performance
17
+ # model = Sketchup.active_model
18
+ # faces = model.active_entities.map { |entity|
19
+ # entity.is_a?(Sketchup::Face)
20
+ # }
21
+ # model.selection.add(faces)
22
+ #
23
+ # @example Better performance and simpler
24
+ # model = Sketchup.active_model
25
+ # faces = model.active_entities.grep(Sketchup::Face)
26
+ # model.selection.add(faces)
27
+ class SelectionBulkChanges < SketchUp::Cop
28
+
29
+ include RangeHelp
30
+
31
+ MSG = 'Prefer changing selection in bulk instead of modifying ' \
32
+ 'selection within loops.'
33
+
34
+ # http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
35
+ # https://rubocop.readthedocs.io/en/latest/node_pattern/
36
+ def_node_matcher :selection?, <<-PATTERN
37
+ (send
38
+ (send _ {:selection :sel}) {:add :remove :toggle}
39
+ ...)
40
+ PATTERN
41
+
42
+ def_node_matcher :block_loop?, <<-PATTERN
43
+ (block
44
+ (send
45
+ (send _ _) {
46
+ :each :each_with_index :each_with_object
47
+ :each_entry :each_index :each_slice
48
+ :each_key :each_pair :each_value
49
+ :grep
50
+ } ...)
51
+ ...)
52
+ PATTERN
53
+
54
+ def_node_matcher :numeric_loop?, <<-PATTERN
55
+ (block
56
+ (send
57
+ ({int float} _) {:times :upto :downto} ...)
58
+ ...)
59
+ PATTERN
60
+
61
+ def iterator?(node)
62
+ node.is_a?(RuboCop::AST::ForNode) ||
63
+ node.is_a?(RuboCop::AST::UntilNode) ||
64
+ node.is_a?(RuboCop::AST::WhileNode) ||
65
+ block_loop?(node) ||
66
+ numeric_loop?(node)
67
+ end
68
+
69
+ def on_send(node)
70
+ return unless selection?(node)
71
+ return unless node.ancestors.any?(&method(:iterator?))
72
+
73
+ add_offense(node, location: range_with_receiver(node))
74
+ end
75
+
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,63 +1,63 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupPerformance
6
- # String comparisons for type checks are very slow.
7
- #
8
- # `entity.class.name == 'Sketchup::Face'` is slow because it performs a
9
- # string comparison. `is_a?` is much faster because it's a simple type
10
- # check.
11
- #
12
- # If you know you need a strict type check, compare the classes directly:
13
- # `entity.class == Sketchup::Face`.
14
- #
15
- # @example Poor performance
16
- # entity.class.name == 'Sketchup::Face'
17
- #
18
- # @example Good performance
19
- # entity.class == Sketchup::Face
20
- #
21
- # @example Good performance and idiomatic Ruby convention
22
- # entity.is_a?(Sketchup::Face)
23
- class TypeCheck < SketchUp::Cop
24
-
25
- # TODO(thomthom): It probably makes sense to eventually merge the
26
- # Typename cop into this cop. But until this cop have been
27
- # battle tested they remain separate. .typename is no prevalent in
28
- # use (wrongly) that it's better to err in the name of caution, making
29
- # sure we don't miss any scenarios.
30
-
31
- include RangeHelp
32
-
33
- MSG = 'String comparisons are very slow, prefer `.is_a?` '\
34
- 'instead.'
35
-
36
- def_node_matcher :string_class_compare?, <<-PATTERN
37
- (send
38
- (send
39
- (send
40
- _ :class) :name) {:== :=== :!=}
41
- (str _))
42
- PATTERN
43
-
44
- def on_send(node)
45
- return unless string_class_compare?(node)
46
-
47
- add_offense(node, location: comparison_range(node))
48
- end
49
-
50
- private
51
-
52
- def comparison_range(node)
53
- lhs = node.receiver
54
- rhs = node.arguments.first
55
-
56
- loc_begin = lhs.receiver.loc.selector.begin_pos
57
- loc_end = rhs.loc.expression.end_pos
58
- range_between(loc_begin, loc_end)
59
- end
60
- end
61
- end
62
- end
63
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupPerformance
6
+ # String comparisons for type checks are very slow.
7
+ #
8
+ # `entity.class.name == 'Sketchup::Face'` is slow because it performs a
9
+ # string comparison. `is_a?` is much faster because it's a simple type
10
+ # check.
11
+ #
12
+ # If you know you need a strict type check, compare the classes directly:
13
+ # `entity.class == Sketchup::Face`.
14
+ #
15
+ # @example Poor performance
16
+ # entity.class.name == 'Sketchup::Face'
17
+ #
18
+ # @example Good performance
19
+ # entity.class == Sketchup::Face
20
+ #
21
+ # @example Good performance and idiomatic Ruby convention
22
+ # entity.is_a?(Sketchup::Face)
23
+ class TypeCheck < SketchUp::Cop
24
+
25
+ # TODO(thomthom): It probably makes sense to eventually merge the
26
+ # Typename cop into this cop. But until this cop have been
27
+ # battle tested they remain separate. .typename is no prevalent in
28
+ # use (wrongly) that it's better to err in the name of caution, making
29
+ # sure we don't miss any scenarios.
30
+
31
+ include RangeHelp
32
+
33
+ MSG = 'String comparisons are very slow, prefer `.is_a?` ' \
34
+ 'instead.'
35
+
36
+ def_node_matcher :string_class_compare?, <<-PATTERN
37
+ (send
38
+ (send
39
+ (send
40
+ _ :class) :name) {:== :=== :!=}
41
+ (str _))
42
+ PATTERN
43
+
44
+ def on_send(node)
45
+ return unless string_class_compare?(node)
46
+
47
+ add_offense(node, location: comparison_range(node))
48
+ end
49
+
50
+ private
51
+
52
+ def comparison_range(node)
53
+ lhs = node.receiver
54
+ rhs = node.arguments.first
55
+
56
+ loc_begin = lhs.receiver.loc.selector.begin_pos
57
+ loc_end = rhs.loc.expression.end_pos
58
+ range_between(loc_begin, loc_end)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end