rubocop-sketchup 0.6.0 → 0.7.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 -355
  5. data/lib/rubocop-sketchup.rb +49 -48
  6. data/lib/rubocop/sketchup.rb +12 -12
  7. data/lib/rubocop/sketchup/config.rb +63 -63
  8. data/lib/rubocop/sketchup/cop.rb +111 -111
  9. data/lib/rubocop/sketchup/cop/bugs/material_name.rb +108 -0
  10. data/lib/rubocop/sketchup/cop/bugs/render_mode.rb +72 -0
  11. data/lib/rubocop/sketchup/cop/bugs/uniform_scaling.rb +36 -0
  12. data/lib/rubocop/sketchup/cop/deprecations/add_separator_to_menu.rb +25 -25
  13. data/lib/rubocop/sketchup/cop/deprecations/operation_next_transparent.rb +30 -30
  14. data/lib/rubocop/sketchup/cop/deprecations/require_all.rb +27 -27
  15. data/lib/rubocop/sketchup/cop/deprecations/set_texture_projection.rb +26 -26
  16. data/lib/rubocop/sketchup/cop/deprecations/show_ruby_panel.rb +25 -25
  17. data/lib/rubocop/sketchup/cop/deprecations/sketchup_set.rb +30 -30
  18. data/lib/rubocop/sketchup/cop/performance/openssl.rb +41 -41
  19. data/lib/rubocop/sketchup/cop/performance/operation_disable_ui.rb +33 -33
  20. data/lib/rubocop/sketchup/cop/performance/selection_bulk.rb +79 -79
  21. data/lib/rubocop/sketchup/cop/performance/type_check.rb +63 -63
  22. data/lib/rubocop/sketchup/cop/performance/typename.rb +24 -24
  23. data/lib/rubocop/sketchup/cop/requirements/api_namespace.rb +30 -30
  24. data/lib/rubocop/sketchup/cop/requirements/exit.rb +32 -32
  25. data/lib/rubocop/sketchup/cop/requirements/extension_namespace.rb +108 -108
  26. data/lib/rubocop/sketchup/cop/requirements/file_structure.rb +97 -97
  27. data/lib/rubocop/sketchup/cop/requirements/gem_install.rb +45 -45
  28. data/lib/rubocop/sketchup/cop/requirements/get_extension_license.rb +95 -95
  29. data/lib/rubocop/sketchup/cop/requirements/global_constants.rb +38 -38
  30. data/lib/rubocop/sketchup/cop/requirements/global_include.rb +42 -42
  31. data/lib/rubocop/sketchup/cop/requirements/global_methods.rb +65 -65
  32. data/lib/rubocop/sketchup/cop/requirements/global_variables.rb +95 -95
  33. data/lib/rubocop/sketchup/cop/requirements/language_handler_globals.rb +46 -46
  34. data/lib/rubocop/sketchup/cop/requirements/load_path.rb +83 -83
  35. data/lib/rubocop/sketchup/cop/requirements/minimal_registration.rb +73 -73
  36. data/lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb +161 -161
  37. data/lib/rubocop/sketchup/cop/requirements/register_extension.rb +45 -45
  38. data/lib/rubocop/sketchup/cop/requirements/ruby_core_namespace.rb +291 -291
  39. data/lib/rubocop/sketchup/cop/requirements/ruby_stdlib_namespace.rb +634 -634
  40. data/lib/rubocop/sketchup/cop/requirements/shipped_extensions_namespace.rb +61 -61
  41. data/lib/rubocop/sketchup/cop/requirements/sketchup_extension.rb +119 -119
  42. data/lib/rubocop/sketchup/cop/requirements/sketchup_require.rb +163 -163
  43. data/lib/rubocop/sketchup/cop/suggestions/add_group.rb +49 -49
  44. data/lib/rubocop/sketchup/cop/suggestions/compatibility.rb +121 -117
  45. data/lib/rubocop/sketchup/cop/suggestions/dc_internals.rb +34 -34
  46. data/lib/rubocop/sketchup/cop/suggestions/file_encoding.rb +78 -78
  47. data/lib/rubocop/sketchup/cop/suggestions/model_entities.rb +58 -58
  48. data/lib/rubocop/sketchup/cop/suggestions/monkey_patched_api.rb +45 -45
  49. data/lib/rubocop/sketchup/cop/suggestions/operation_name.rb +137 -103
  50. data/lib/rubocop/sketchup/cop/suggestions/sketchup_find_support_file.rb +39 -39
  51. data/lib/rubocop/sketchup/cop/suggestions/tool_drawing_bounds.rb +44 -44
  52. data/lib/rubocop/sketchup/cop/suggestions/tool_invalidate.rb +66 -66
  53. data/lib/rubocop/sketchup/cop/suggestions/tool_user_input.rb +41 -41
  54. data/lib/rubocop/sketchup/cop/suggestions/toolbar_timer.rb +65 -65
  55. data/lib/rubocop/sketchup/dc_globals.rb +24 -24
  56. data/lib/rubocop/sketchup/dc_methods.rb +130 -130
  57. data/lib/rubocop/sketchup/extension_project.rb +65 -65
  58. data/lib/rubocop/sketchup/features.rb +738 -738
  59. data/lib/rubocop/sketchup/formatter/extension_review.rb +269 -259
  60. data/lib/rubocop/sketchup/inject.rb +19 -19
  61. data/lib/rubocop/sketchup/namespace.rb +47 -47
  62. data/lib/rubocop/sketchup/namespace_checker.rb +46 -46
  63. data/lib/rubocop/sketchup/no_comment_disable.rb +17 -17
  64. data/lib/rubocop/sketchup/range_help.rb +52 -52
  65. data/lib/rubocop/sketchup/sketchup_target_range.rb +75 -0
  66. data/lib/rubocop/sketchup/sketchup_version.rb +117 -87
  67. data/lib/rubocop/sketchup/tool_checker.rb +43 -43
  68. data/lib/rubocop/sketchup/version.rb +5 -5
  69. data/rubocop-sketchup.gemspec +27 -27
  70. metadata +8 -4
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupBugs
6
+ # Prior to SketchUp 2018 it was possible for the Ruby API to cause
7
+ # materials to have duplicate names. This is not a valid SketchUp model
8
+ # as SketchUp expects material names to be unique identifiers.
9
+ #
10
+ # `model.materials.add('Example')` have always made materials unique by
11
+ # appending a numeric post-fix to the name.
12
+ #
13
+ # However, `material.name = 'Example'` did not perform such check. It
14
+ # would blindly set the new name.
15
+ #
16
+ # As of SketchUp 2018 the API behavior was changed to prevent this.
17
+ # `material.name = 'Example'` will now raise an `ArgumentError` is the
18
+ # name is not unique.
19
+ #
20
+ # A new method was added to allow a unique material name to be generated:
21
+ # `model.material.unique_name('Example')`.
22
+ #
23
+ # Changing the name of materials can now follow the same pattern as layers
24
+ # and component definitions.
25
+ #
26
+ # Note that in SketchUp 2018 there was also a second bug introduced. A
27
+ # name cache was introduced to speed up the lookup and generation of
28
+ # unique names. Unfortunately this got out of sync between changing name
29
+ # via the UI versus via the API. This has been fixed in SketchUp 2019.
30
+ #
31
+ # @example Pattern for setting material name from SketchUp 2018
32
+ # material.name = model.materials.unique_name('Example')
33
+ #
34
+ # @example Pattern for setting name prior to SketchUp 2018
35
+ # # Works with SketchUp 2014 or newer:
36
+ # require 'set'
37
+ #
38
+ # module Example
39
+ #
40
+ # def self.rename_material(material, name)
41
+ # materials = material.model.materials
42
+ # material.name = self.unique_name(materials, name)
43
+ # end
44
+ #
45
+ # def self.unique_material_name(materials, name)
46
+ # if materials.respond_to?(:unique_name)
47
+ # # Use fast native implementation if possible.
48
+ # materials.unique_name(name)
49
+ # else
50
+ # # Cache names in a Set for fast lookup.
51
+ # names = Set.new(materials.map(&:name))
52
+ # unique_name = name
53
+ # # Extract the base name and post-fix.
54
+ # match = unique_name.match(/^\D.*?(\d*)$/)
55
+ # base, postfix = match ? match.captures : [unique_name, 0]
56
+ # # Ensure basename has length and postfix is an integer.
57
+ # base = unique_name if base.empty?
58
+ # postfix = postfix.to_i
59
+ # # Iteratively find a unique name.
60
+ # until !names.include?(unique_name)
61
+ # postfix = postfix.next
62
+ # unique_name = "#{base}#{postfix}"
63
+ # end
64
+ # unique_name
65
+ # end
66
+ # end
67
+ #
68
+ # end
69
+ class MaterialName < SketchUp::Cop
70
+
71
+ include SketchUp::SketchUpTargetRange
72
+
73
+ define_sketchup_target_max_version 'SketchUp 2017'
74
+
75
+ MATERIAL_VARIABLES = %i[material mat].freeze
76
+
77
+ def_node_matcher :material_set_name?, <<-PATTERN
78
+ (send #material? :name= _)
79
+ PATTERN
80
+
81
+ MSG_SET_NAME = '`material.name=` might add duplicate materials in '\
82
+ 'SU2017 and older versions.'.freeze
83
+
84
+ def on_send(node)
85
+ return unless valid_for_target_sketchup_version?
86
+ return unless material_set_name?(node)
87
+
88
+ add_offense(node, message: MSG_SET_NAME)
89
+ end
90
+
91
+ private
92
+
93
+ def material?(node)
94
+ return false unless node && (node.send_type? || node.variable?)
95
+
96
+ name = variable_name(node.children.last)
97
+ MATERIAL_VARIABLES.include?(name)
98
+ end
99
+
100
+ # Returns the name without the @ or $ prefix.
101
+ def variable_name(symbol)
102
+ symbol.to_s.tr('$@', '').to_sym
103
+ end
104
+
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupBugs
6
+ # A regression was introduced in SketchUp 2017 that cause invalid render
7
+ # modes to crash SketchUp. The crash might not happen exactly when the
8
+ # new mode is set, but later when the viewport re-draws.
9
+ #
10
+ # Valid render modes are: (Internal enum names in parentheses)
11
+ #
12
+ # * `0` (`kRenderWireframe`)
13
+ # * `1` (`kRenderHidden`)
14
+ # * `2` (`kRenderFlat`)
15
+ # * `3` (`kRenderSmooth`)
16
+ # * `5` (`kRenderNoMaterials`)
17
+ #
18
+ # @example This obsolete render mode will crash SketchUp 2017 and newer
19
+ # Sketchup.active_model.rendering_options["RenderMode"] = 4
20
+ #
21
+ # @example This invalid render mode will crash SketchUp 2017 and newer
22
+ # Sketchup.active_model.rendering_options["RenderMode"] = 99
23
+ class RenderMode < SketchUp::Cop
24
+
25
+ include SketchUp::SketchUpTargetRange
26
+
27
+ define_sketchup_target_min_version 'SketchUp 2017'
28
+
29
+ RENDER_MODE_VALID = [
30
+ 0, # kRenderWireframe,
31
+ 1, # kRenderHidden,
32
+ 2, # kRenderFlat,
33
+ 3, # kRenderSmooth,
34
+ 5, # kRenderNoMaterials
35
+ ].freeze
36
+
37
+ RENDER_MODE_OBSOLETE = [
38
+ 4, # kRenderTextureObsolete,
39
+ ].freeze
40
+
41
+ def_node_matcher :set_render_mode, <<-PATTERN
42
+ (send _ :[]= (str "RenderMode") (int $_))
43
+ PATTERN
44
+
45
+ MSG_OBSOLETE = 'Obsolete render mode will crash in SU2017 and '\
46
+ 'newer versions.'.freeze
47
+
48
+ MSG_INVALID = 'Invalid render mode will crash in SU2017 and '\
49
+ 'newer versions.'.freeze
50
+
51
+ def on_send(node)
52
+ return unless valid_for_target_sketchup_version?
53
+
54
+ value = set_render_mode(node)
55
+ return if value.nil?
56
+ return if RENDER_MODE_VALID.include?(value)
57
+
58
+ value_node = node.arguments.last
59
+ message = obsolete?(value) ? MSG_OBSOLETE : MSG_INVALID
60
+ add_offense(value_node, message: message)
61
+ end
62
+
63
+ private
64
+
65
+ def obsolete?(value)
66
+ RENDER_MODE_OBSOLETE.include?(value)
67
+ end
68
+
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupBugs
6
+ # Until SketchUp 2018 `Geom::Transformation.scaling(scale)` modified the
7
+ # 16th value in the transformation matrix. This way of scaling the matrix
8
+ # isn't fully accounted in all places in SketchUp. There are also a number
9
+ # of exporters and render engines which also doesn't fully handle this.
10
+ #
11
+ # @example Workaround for SketchUp versions older than SketchUp 2018
12
+ # tr = Geom::Transformation.scaling(scale, scale, scale)
13
+ class UniformScaling < SketchUp::Cop
14
+
15
+ include SketchUp::SketchUpTargetRange
16
+
17
+ define_sketchup_target_max_version 'SketchUp 2017'
18
+
19
+ def_node_matcher :transformation_scaling?, <<-PATTERN
20
+ (send (const (const nil? :Geom) :Transformation) :scaling _)
21
+ PATTERN
22
+
23
+ MSG = 'Resulting transformation matrix might yield unexpected '\
24
+ 'results.'.freeze
25
+
26
+ def on_send(node)
27
+ return unless valid_for_target_sketchup_version?
28
+ return unless transformation_scaling?(node)
29
+
30
+ add_offense(node.arguments.first)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,25 +1,25 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupDeprecations
6
- # Avoid adding separators to top level menus. If you require grouping use
7
- # a sub-menu instead.
8
- class AddSeparatorToMenu < SketchUp::Cop
9
-
10
- MSG = 'Method is deprecated.'.freeze
11
-
12
- def_node_matcher :add_separator_to_menu?, <<-PATTERN
13
- (send nil? :add_separator_to_menu _)
14
- PATTERN
15
-
16
- def on_send(node)
17
- return unless add_separator_to_menu?(node)
18
-
19
- add_offense(node, location: :selector)
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
+ # Avoid adding separators to top level menus. If you require grouping use
7
+ # a sub-menu instead.
8
+ class AddSeparatorToMenu < SketchUp::Cop
9
+
10
+ MSG = 'Method is deprecated.'.freeze
11
+
12
+ def_node_matcher :add_separator_to_menu?, <<-PATTERN
13
+ (send nil? :add_separator_to_menu _)
14
+ PATTERN
15
+
16
+ def on_send(node)
17
+ return unless add_separator_to_menu?(node)
18
+
19
+ add_offense(node, location: :selector)
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
- # If set to true, then whatever operation comes after this one will be
7
- # appended into one combined operation, allowing the user the undo both
8
- # actions with a single undo command.
9
- #
10
- # This flag is a highly difficult one, since there are so many ways that a
11
- # SketchUp user can interrupt a given operation with one of their own.
12
- #
13
- # Only use this flag if you have no other option, for instance to work
14
- # around bug in how `Sketchup::Model#place_component` starts operations.
15
- class OperationNextTransparent < SketchUp::Cop
16
- MSG = 'Third argument is deprecated.'.freeze
17
-
18
- def on_send(node)
19
- _, method_name, *args = *node
20
- return unless method_name == :start_operation
21
- return if args.size < 3
22
-
23
- argument = args[2]
24
- next_transparent = (argument.type == :true)
25
- add_offense(argument, location: :expression) if next_transparent
26
- end
27
- end
28
- end
29
- end
30
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupDeprecations
6
+ # If set to true, then whatever operation comes after this one will be
7
+ # appended into one combined operation, allowing the user the undo both
8
+ # actions with a single undo command.
9
+ #
10
+ # This flag is a highly difficult one, since there are so many ways that a
11
+ # SketchUp user can interrupt a given operation with one of their own.
12
+ #
13
+ # Only use this flag if you have no other option, for instance to work
14
+ # around bug in how `Sketchup::Model#place_component` starts operations.
15
+ class OperationNextTransparent < SketchUp::Cop
16
+ MSG = 'Third argument is deprecated.'.freeze
17
+
18
+ def on_send(node)
19
+ _, method_name, *args = *node
20
+ return unless method_name == :start_operation
21
+ return if args.size < 3
22
+
23
+ argument = args[2]
24
+ next_transparent = (argument.type == :true)
25
+ add_offense(argument, location: :expression) if next_transparent
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -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.'.freeze
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.'.freeze
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.'.freeze
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.'.freeze
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.'.freeze
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.'.freeze
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