rubocop-sketchup 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +21 -20
  3. data/assets/output.html.erb +301 -301
  4. data/config/default.yml +400 -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/debug_mode.rb +27 -0
  22. data/lib/rubocop/sketchup/cop/requirements/exit.rb +33 -33
  23. data/lib/rubocop/sketchup/cop/requirements/extension_namespace.rb +125 -125
  24. data/lib/rubocop/sketchup/cop/requirements/file_structure.rb +97 -97
  25. data/lib/rubocop/sketchup/cop/requirements/gem_install.rb +45 -45
  26. data/lib/rubocop/sketchup/cop/requirements/get_extension_license.rb +95 -95
  27. data/lib/rubocop/sketchup/cop/requirements/global_constants.rb +38 -38
  28. data/lib/rubocop/sketchup/cop/requirements/global_include.rb +42 -42
  29. data/lib/rubocop/sketchup/cop/requirements/global_methods.rb +65 -65
  30. data/lib/rubocop/sketchup/cop/requirements/global_variables.rb +95 -95
  31. data/lib/rubocop/sketchup/cop/requirements/initialize_entity.rb +76 -0
  32. data/lib/rubocop/sketchup/cop/requirements/language_handler_globals.rb +46 -46
  33. data/lib/rubocop/sketchup/cop/requirements/load_path.rb +83 -83
  34. data/lib/rubocop/sketchup/cop/requirements/minimal_registration.rb +73 -73
  35. data/lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb +161 -161
  36. data/lib/rubocop/sketchup/cop/requirements/register_extension.rb +45 -45
  37. data/lib/rubocop/sketchup/cop/requirements/ruby_core_namespace.rb +291 -291
  38. data/lib/rubocop/sketchup/cop/requirements/ruby_stdlib_namespace.rb +634 -634
  39. data/lib/rubocop/sketchup/cop/requirements/shipped_extensions_namespace.rb +61 -61
  40. data/lib/rubocop/sketchup/cop/requirements/sketchup_extension.rb +119 -119
  41. data/lib/rubocop/sketchup/cop/requirements/sketchup_require.rb +150 -150
  42. data/lib/rubocop/sketchup/cop/suggestions/add_group.rb +49 -49
  43. data/lib/rubocop/sketchup/cop/suggestions/compatibility.rb +128 -128
  44. data/lib/rubocop/sketchup/cop/suggestions/dc_internals.rb +34 -34
  45. data/lib/rubocop/sketchup/cop/suggestions/file_encoding.rb +78 -78
  46. data/lib/rubocop/sketchup/cop/suggestions/model_entities.rb +58 -58
  47. data/lib/rubocop/sketchup/cop/suggestions/monkey_patched_api.rb +45 -45
  48. data/lib/rubocop/sketchup/cop/suggestions/operation_name.rb +137 -137
  49. data/lib/rubocop/sketchup/cop/suggestions/sketchup_find_support_file.rb +39 -39
  50. data/lib/rubocop/sketchup/cop/suggestions/sleep.rb +25 -0
  51. data/lib/rubocop/sketchup/cop/suggestions/tool_drawing_bounds.rb +45 -45
  52. data/lib/rubocop/sketchup/cop/suggestions/tool_invalidate.rb +68 -68
  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/cop.rb +110 -110
  56. data/lib/rubocop/sketchup/dc_globals.rb +24 -24
  57. data/lib/rubocop/sketchup/dc_methods.rb +130 -130
  58. data/lib/rubocop/sketchup/extension_project.rb +65 -65
  59. data/lib/rubocop/sketchup/features.rb +1514 -1477
  60. data/lib/rubocop/sketchup/formatter/extension_review.rb +269 -269
  61. data/lib/rubocop/sketchup/generator.rb +21 -0
  62. data/lib/rubocop/sketchup/inject.rb +19 -19
  63. data/lib/rubocop/sketchup/namespace.rb +49 -49
  64. data/lib/rubocop/sketchup/namespace_checker.rb +103 -103
  65. data/lib/rubocop/sketchup/no_comment_disable.rb +17 -17
  66. data/lib/rubocop/sketchup/range_help.rb +52 -52
  67. data/lib/rubocop/sketchup/sketchup_target_range.rb +75 -75
  68. data/lib/rubocop/sketchup/sketchup_version.rb +131 -129
  69. data/lib/rubocop/sketchup/tool_checker.rb +41 -41
  70. data/lib/rubocop/sketchup/version.rb +7 -7
  71. data/lib/rubocop/sketchup.rb +14 -14
  72. data/lib/rubocop-sketchup.rb +53 -53
  73. data/rubocop-sketchup.gemspec +28 -29
  74. metadata +7 -23
@@ -1,58 +1,58 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupSuggestions
6
- # Prefer `model.active_entities` over `model.entities`.
7
- #
8
- # Most tools/actions act upon the active entities context. This could be
9
- # an opened group or component instance. Because of this, prefer
10
- # `model.active_entities` by default over `model.entities` unless you
11
- # have an explicit reason to work in the root model context.
12
- class ModelEntities < SketchUp::Cop
13
-
14
- MSG = 'Prefer `model.active_entities` over `model.entities`.'
15
-
16
- # Reference: http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
17
- def_node_matcher :active_model_entities?, <<-PATTERN
18
- (send
19
- (send (const nil? :Sketchup) :active_model) :entities)
20
- PATTERN
21
-
22
- def_node_matcher :entities_receiver, <<-PATTERN
23
- (send
24
- ({lvar ivar cvar} $_) :entities)
25
- PATTERN
26
-
27
- MODEL_VARIABLE_NAMES = %w[model mod].freeze
28
-
29
- def model_entities?(node)
30
- return true if active_model_entities?(node)
31
-
32
- name = entities_receiver(node)
33
- name && model_variable?(name)
34
- end
35
-
36
- def on_send(node)
37
- add_offense(node, location: :expression) if model_entities?(node)
38
- end
39
-
40
- private
41
-
42
- def model_variable?(name)
43
- basename = variable_basename(name)
44
- MODEL_VARIABLE_NAMES.include?(basename)
45
- end
46
-
47
- def variable_basename(name)
48
- # Extract the basename from variables:
49
- # model => model
50
- # @model => model
51
- # @@model => model
52
- name.to_s.tr('@', '')
53
- end
54
-
55
- end
56
- end
57
- end
58
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupSuggestions
6
+ # Prefer `model.active_entities` over `model.entities`.
7
+ #
8
+ # Most tools/actions act upon the active entities context. This could be
9
+ # an opened group or component instance. Because of this, prefer
10
+ # `model.active_entities` by default over `model.entities` unless you
11
+ # have an explicit reason to work in the root model context.
12
+ class ModelEntities < SketchUp::Cop
13
+
14
+ MSG = 'Prefer `model.active_entities` over `model.entities`.'
15
+
16
+ # Reference: http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
17
+ def_node_matcher :active_model_entities?, <<-PATTERN
18
+ (send
19
+ (send (const nil? :Sketchup) :active_model) :entities)
20
+ PATTERN
21
+
22
+ def_node_matcher :entities_receiver, <<-PATTERN
23
+ (send
24
+ ({lvar ivar cvar} $_) :entities)
25
+ PATTERN
26
+
27
+ MODEL_VARIABLE_NAMES = %w[model mod].freeze
28
+
29
+ def model_entities?(node)
30
+ return true if active_model_entities?(node)
31
+
32
+ name = entities_receiver(node)
33
+ name && model_variable?(name)
34
+ end
35
+
36
+ def on_send(node)
37
+ add_offense(node, location: :expression) if model_entities?(node)
38
+ end
39
+
40
+ private
41
+
42
+ def model_variable?(name)
43
+ basename = variable_basename(name)
44
+ MODEL_VARIABLE_NAMES.include?(basename)
45
+ end
46
+
47
+ def variable_basename(name)
48
+ # Extract the basename from variables:
49
+ # model => model
50
+ # @model => model
51
+ # @@model => model
52
+ name.to_s.tr('@', '')
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,45 +1,45 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupSuggestions
6
- # Some of the shipped extensions in SketchUp monkey-patch the API
7
- # namespace. This is an unfortunate no-no that was done a long time ago
8
- # before the extension best-practices were established. These functions
9
- # might change or be removed at any time. They will also not work when
10
- # the extensions are disabled. Avoid using these methods.
11
- class MonkeyPatchedApi < SketchUp::Cop
12
-
13
- include SketchUp::DynamicComponentMethods
14
-
15
- def on_send(node)
16
- # Only check instance methods.
17
- return if node.receiver&.const_type?
18
-
19
- name = node.method_name
20
-
21
- dc_method = DC_METHODS.find { |m| m[:name] == name }
22
- return unless dc_method
23
-
24
- if dc_method.key?(:variables)
25
- return unless node.receiver&.variable?
26
-
27
- receiver_name = node.receiver.children.first
28
- # Account for instance and class variables.
29
- receiver_name = receiver_name.to_s.tr('@', '').to_sym
30
- return unless dc_method[:variables].include?(receiver_name)
31
- end
32
-
33
- path = dc_method[:path]
34
- message = "#{path}##{name} is not part of the official API. " \
35
- "It's a monkey-patched addition by Dynamic Components."
36
- add_offense(node,
37
- location: :selector,
38
- severity: :warning,
39
- message: message)
40
- end
41
-
42
- end
43
- end
44
- end
45
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupSuggestions
6
+ # Some of the shipped extensions in SketchUp monkey-patch the API
7
+ # namespace. This is an unfortunate no-no that was done a long time ago
8
+ # before the extension best-practices were established. These functions
9
+ # might change or be removed at any time. They will also not work when
10
+ # the extensions are disabled. Avoid using these methods.
11
+ class MonkeyPatchedApi < SketchUp::Cop
12
+
13
+ include SketchUp::DynamicComponentMethods
14
+
15
+ def on_send(node)
16
+ # Only check instance methods.
17
+ return if node.receiver&.const_type?
18
+
19
+ name = node.method_name
20
+
21
+ dc_method = DC_METHODS.find { |m| m[:name] == name }
22
+ return unless dc_method
23
+
24
+ if dc_method.key?(:variables)
25
+ return unless node.receiver&.variable?
26
+
27
+ receiver_name = node.receiver.children.first
28
+ # Account for instance and class variables.
29
+ receiver_name = receiver_name.to_s.tr('@', '').to_sym
30
+ return unless dc_method[:variables].include?(receiver_name)
31
+ end
32
+
33
+ path = dc_method[:path]
34
+ message = "#{path}##{name} is not part of the official API. " \
35
+ "It's a monkey-patched addition by Dynamic Components."
36
+ add_offense(node,
37
+ location: :selector,
38
+ severity: :warning,
39
+ message: message)
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,137 +1,137 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupSuggestions
6
- # Operation name should be a short capitalized description. It will be
7
- # visible to the user in the Edit > Undo menu. Make sure to give it a
8
- # short human readable name, similar to SketchUp's own operation names.
9
- #
10
- # This cop make some very naive assumptions and will have more false
11
- # positives than most of the other cops. It's purpose is mainly to enable
12
- # awareness.
13
- #
14
- # @example Bad - Ends with a punctuation. Inconsistent with SketchUp.
15
- # model.start_operation('Example.', true)
16
- #
17
- # @example Good - Doesn't end with a punctuation.
18
- # model.start_operation('Example', true)
19
- #
20
- #
21
- # @example Bad - Starts with whitespace. Inconsistent with SketchUp.
22
- # model.start_operation(' Example', true)
23
- #
24
- # @example Good - Doesn't start with whitespace.
25
- # model.start_operation('Example', true)
26
- #
27
- #
28
- # @example Bad - Tabs doesn't belong in operation titles.
29
- # model.start_operation("example\tName", true)
30
- #
31
- # @example Good - Stick to space for whitespace.
32
- # model.start_operation('Example Name', true)
33
- #
34
- #
35
- # @example Bad - No capitalization. Inconsistent with SketchUp.
36
- # model.start_operation('example name', true)
37
- #
38
- # @example Good - Each word capitalized.
39
- # model.start_operation('Example Name', true)
40
- #
41
- #
42
- # @example Bad - Underscore instead of space. Inconsistent with SketchUp.
43
- # model.start_operation('example_name', true)
44
- #
45
- # @example Good - Name is for human reading.
46
- # model.start_operation('Example Name', true)
47
- class OperationName < SketchUp::Cop
48
-
49
- include RangeHelp
50
-
51
- MSG = 'Operation name should be a short capitalized description.'
52
- MSG_MAX = 'Operation names should not be short and concise. [%d/%d]'
53
-
54
- def on_send(node)
55
- _, method_name, *args = *node
56
- return unless method_name == :start_operation
57
- return if args.empty? || !args.first.str_type?
58
-
59
- # Ignore transparent operations.
60
- return if args.size == 4 && args.last.true_type?
61
-
62
- operation_name = args.first.str_content
63
- # We can only inspect string literals.
64
- return unless operation_name.is_a?(String)
65
-
66
- # Check the format of the operation name.
67
- unless acceptable_operation_name?(operation_name)
68
- msg = %(#{MSG} Expected: `"#{titleize(operation_name)}"`)
69
- add_offense(args.first, location: :expression, message: msg)
70
- end
71
- # Check the length of the operation name.
72
- unless operation_name.size <= max_operation_name_length
73
- message = format(MSG_MAX, operation_name.size, max_operation_name_length)
74
- add_offense(args.first,
75
- location: excess_range(args.first, operation_name),
76
- message: message)
77
- end
78
- # Ensure operation name is not empty.
79
- if operation_name.empty?
80
- msg = 'Operation names should not be empty.'
81
- add_offense(args.first, location: :expression, message: msg)
82
- end
83
- end
84
-
85
- private
86
-
87
- def excess_range(node, operation_name)
88
- string_start = node.source.index(operation_name)
89
- range = node.loc.expression
90
- if string_start
91
- excess_start = range.begin_pos + string_start + max_operation_name_length
92
- excess_end = range.begin_pos + string_start + operation_name.size
93
- range_between(excess_start, excess_end)
94
- else
95
- range_between(range.begin_pos, range.end_pos)
96
- end
97
- end
98
-
99
- def acceptable_operation_name?(name)
100
- # Capitalization, no programmer name, no punctuation.
101
- return false if name.end_with?('.')
102
- return false if titleize(name) != name
103
-
104
- true
105
- end
106
-
107
- def max_operation_name_length
108
- length = cop_config['Max'] || 25
109
- return length if length.is_a?(Integer) && length > 0
110
-
111
- raise 'Max needs to be a positive integer!'
112
- end
113
-
114
- TITLEIZE_EXCLUDE = %w[
115
- by for from in of to
116
- and or if
117
- ].freeze
118
-
119
- def titleize(string)
120
- string = string.gsub(/[_.]/, ' ')
121
- words = string.split.map { |word|
122
- unless TITLEIZE_EXCLUDE.include?(word)
123
- # word.capitalize won't work here, as we want to allow words like:
124
- # "HTML", "SketchUp". So instead only the first character in each
125
- # word is modified.
126
- char = word[0].upcase
127
- word[0, 1] = char
128
- end
129
- word
130
- }
131
- words.join(' ')
132
- end
133
-
134
- end
135
- end
136
- end
137
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupSuggestions
6
+ # Operation name should be a short capitalized description. It will be
7
+ # visible to the user in the Edit > Undo menu. Make sure to give it a
8
+ # short human readable name, similar to SketchUp's own operation names.
9
+ #
10
+ # This cop make some very naive assumptions and will have more false
11
+ # positives than most of the other cops. It's purpose is mainly to enable
12
+ # awareness.
13
+ #
14
+ # @example Bad - Ends with a punctuation. Inconsistent with SketchUp.
15
+ # model.start_operation('Example.', true)
16
+ #
17
+ # @example Good - Doesn't end with a punctuation.
18
+ # model.start_operation('Example', true)
19
+ #
20
+ #
21
+ # @example Bad - Starts with whitespace. Inconsistent with SketchUp.
22
+ # model.start_operation(' Example', true)
23
+ #
24
+ # @example Good - Doesn't start with whitespace.
25
+ # model.start_operation('Example', true)
26
+ #
27
+ #
28
+ # @example Bad - Tabs doesn't belong in operation titles.
29
+ # model.start_operation("example\tName", true)
30
+ #
31
+ # @example Good - Stick to space for whitespace.
32
+ # model.start_operation('Example Name', true)
33
+ #
34
+ #
35
+ # @example Bad - No capitalization. Inconsistent with SketchUp.
36
+ # model.start_operation('example name', true)
37
+ #
38
+ # @example Good - Each word capitalized.
39
+ # model.start_operation('Example Name', true)
40
+ #
41
+ #
42
+ # @example Bad - Underscore instead of space. Inconsistent with SketchUp.
43
+ # model.start_operation('example_name', true)
44
+ #
45
+ # @example Good - Name is for human reading.
46
+ # model.start_operation('Example Name', true)
47
+ class OperationName < SketchUp::Cop
48
+
49
+ include RangeHelp
50
+
51
+ MSG = 'Operation name should be a short capitalized description.'
52
+ MSG_MAX = 'Operation names should not be short and concise. [%d/%d]'
53
+
54
+ def on_send(node)
55
+ _, method_name, *args = *node
56
+ return unless method_name == :start_operation
57
+ return if args.empty? || !args.first.str_type?
58
+
59
+ # Ignore transparent operations.
60
+ return if args.size == 4 && args.last.true_type?
61
+
62
+ operation_name = args.first.str_content
63
+ # We can only inspect string literals.
64
+ return unless operation_name.is_a?(String)
65
+
66
+ # Check the format of the operation name.
67
+ unless acceptable_operation_name?(operation_name)
68
+ msg = %(#{MSG} Expected: `"#{titleize(operation_name)}"`)
69
+ add_offense(args.first, location: :expression, message: msg)
70
+ end
71
+ # Check the length of the operation name.
72
+ unless operation_name.size <= max_operation_name_length
73
+ message = format(MSG_MAX, operation_name.size, max_operation_name_length)
74
+ add_offense(args.first,
75
+ location: excess_range(args.first, operation_name),
76
+ message: message)
77
+ end
78
+ # Ensure operation name is not empty.
79
+ if operation_name.empty?
80
+ msg = 'Operation names should not be empty.'
81
+ add_offense(args.first, location: :expression, message: msg)
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def excess_range(node, operation_name)
88
+ string_start = node.source.index(operation_name)
89
+ range = node.loc.expression
90
+ if string_start
91
+ excess_start = range.begin_pos + string_start + max_operation_name_length
92
+ excess_end = range.begin_pos + string_start + operation_name.size
93
+ range_between(excess_start, excess_end)
94
+ else
95
+ range_between(range.begin_pos, range.end_pos)
96
+ end
97
+ end
98
+
99
+ def acceptable_operation_name?(name)
100
+ # Capitalization, no programmer name, no punctuation.
101
+ return false if name.end_with?('.')
102
+ return false if titleize(name) != name
103
+
104
+ true
105
+ end
106
+
107
+ def max_operation_name_length
108
+ length = cop_config['Max'] || 25
109
+ return length if length.is_a?(Integer) && length > 0
110
+
111
+ raise 'Max needs to be a positive integer!'
112
+ end
113
+
114
+ TITLEIZE_EXCLUDE = %w[
115
+ by for from in of to
116
+ and or if
117
+ ].freeze
118
+
119
+ def titleize(string)
120
+ string = string.gsub(/[_.]/, ' ')
121
+ words = string.split.map { |word|
122
+ unless TITLEIZE_EXCLUDE.include?(word)
123
+ # word.capitalize won't work here, as we want to allow words like:
124
+ # "HTML", "SketchUp". So instead only the first character in each
125
+ # word is modified.
126
+ char = word[0].upcase
127
+ word[0, 1] = char
128
+ end
129
+ word
130
+ }
131
+ words.join(' ')
132
+ end
133
+
134
+ end
135
+ end
136
+ end
137
+ end
@@ -1,39 +1,39 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module Cop
5
- module SketchupSuggestions
6
- # Avoid `Sketchup.find_support_file` to find your extension's files.
7
- #
8
- # Users might install your extension to locations other than the default
9
- # Plugins directory. If you use `Sketchup.find_support_file` to build
10
- # a path for files in your extension it will fail in these scenarios.
11
- #
12
- # Instead prefer to use `__FILE__` or `__dir__` to build paths relative
13
- # to your source files. This have the added benefit of allowing you to
14
- # load your extensions directly from external directories under version
15
- # control.
16
- class SketchupFindSupportFile < SketchUp::Cop
17
-
18
- MSG = 'Avoid `Sketchup.find_support_file` to find your ' \
19
- "extension's files."
20
-
21
- # http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
22
- # https://rubocop.readthedocs.io/en/latest/node_pattern/
23
- def_node_matcher :sketchup_find_support_file?, <<-PATTERN
24
- (send
25
- (const nil? :Sketchup) :find_support_file
26
- ...
27
- )
28
- PATTERN
29
-
30
- def on_send(node)
31
- return unless sketchup_find_support_file?(node)
32
-
33
- add_offense(node, location: :expression)
34
- end
35
-
36
- end
37
- end
38
- end
39
- end
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupSuggestions
6
+ # Avoid `Sketchup.find_support_file` to find your extension's files.
7
+ #
8
+ # Users might install your extension to locations other than the default
9
+ # Plugins directory. If you use `Sketchup.find_support_file` to build
10
+ # a path for files in your extension it will fail in these scenarios.
11
+ #
12
+ # Instead prefer to use `__FILE__` or `__dir__` to build paths relative
13
+ # to your source files. This have the added benefit of allowing you to
14
+ # load your extensions directly from external directories under version
15
+ # control.
16
+ class SketchupFindSupportFile < SketchUp::Cop
17
+
18
+ MSG = 'Avoid `Sketchup.find_support_file` to find your ' \
19
+ "extension's files."
20
+
21
+ # http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
22
+ # https://rubocop.readthedocs.io/en/latest/node_pattern/
23
+ def_node_matcher :sketchup_find_support_file?, <<-PATTERN
24
+ (send
25
+ (const nil? :Sketchup) :find_support_file
26
+ ...
27
+ )
28
+ PATTERN
29
+
30
+ def on_send(node)
31
+ return unless sketchup_find_support_file?(node)
32
+
33
+ add_offense(node, location: :expression)
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupSuggestions
6
+ # Avoid kernel `sleep` as it freezes up SketchUp.
7
+ # Prefer `UI.start_timer` or a callback from the resource you are waiting
8
+ # for.
9
+ class Sleep < SketchUp::Cop
10
+ MSG = '`sleep` freezes up SketchUp. Prefer `UI.start_timer` or a ' \
11
+ 'callback for the resource you are waiting for.'
12
+
13
+ def_node_matcher :sleep?, <<-PATTERN
14
+ (send {(const nil? :Kernel) nil?} :sleep ...)
15
+ PATTERN
16
+
17
+ def on_send(node)
18
+ return unless sleep?(node)
19
+
20
+ add_offense(node, message: MSG)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end