rubocop-sketchup 0.4.1 → 0.5.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -1
  3. data/assets/logo.png +0 -0
  4. data/assets/output.html.erb +301 -0
  5. data/config/default.yml +141 -36
  6. data/lib/rubocop/sketchup/config.rb +28 -8
  7. data/lib/rubocop/sketchup/cop/deprecations/add_separator_to_menu.rb +4 -1
  8. data/lib/rubocop/sketchup/cop/deprecations/operation_next_transparent.rb +11 -2
  9. data/lib/rubocop/sketchup/cop/deprecations/require_all.rb +7 -2
  10. data/lib/rubocop/sketchup/cop/deprecations/set_texture_projection.rb +6 -2
  11. data/lib/rubocop/sketchup/cop/deprecations/show_ruby_panel.rb +4 -1
  12. data/lib/rubocop/sketchup/cop/deprecations/sketchup_set.rb +8 -0
  13. data/lib/rubocop/sketchup/cop/performance/openssl.rb +5 -3
  14. data/lib/rubocop/sketchup/cop/performance/operation_disable_ui.rb +10 -2
  15. data/lib/rubocop/sketchup/cop/performance/selection_bulk.rb +11 -4
  16. data/lib/rubocop/sketchup/cop/performance/type_check.rb +63 -0
  17. data/lib/rubocop/sketchup/cop/performance/typename.rb +6 -1
  18. data/lib/rubocop/sketchup/cop/requirements/api_namespace.rb +8 -2
  19. data/lib/rubocop/sketchup/cop/requirements/exit.rb +7 -3
  20. data/lib/rubocop/sketchup/cop/requirements/extension_namespace.rb +32 -2
  21. data/lib/rubocop/sketchup/cop/requirements/file_structure.rb +22 -10
  22. data/lib/rubocop/sketchup/cop/requirements/gem_install.rb +45 -0
  23. data/lib/rubocop/sketchup/cop/requirements/get_extension_license.rb +95 -0
  24. data/lib/rubocop/sketchup/cop/requirements/global_constants.rb +10 -1
  25. data/lib/rubocop/sketchup/cop/requirements/global_include.rb +9 -2
  26. data/lib/rubocop/sketchup/cop/requirements/global_methods.rb +10 -1
  27. data/lib/rubocop/sketchup/cop/requirements/global_variables.rb +13 -4
  28. data/lib/rubocop/sketchup/cop/requirements/language_handler_globals.rb +6 -4
  29. data/lib/rubocop/sketchup/cop/requirements/load_path.rb +9 -6
  30. data/lib/rubocop/sketchup/cop/requirements/minimal_registration.rb +26 -2
  31. data/lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb +28 -2
  32. data/lib/rubocop/sketchup/cop/requirements/register_extension.rb +12 -2
  33. data/lib/rubocop/sketchup/cop/requirements/ruby_core_namespace.rb +14 -8
  34. data/lib/rubocop/sketchup/cop/requirements/ruby_stdlib_namespace.rb +594 -588
  35. data/lib/rubocop/sketchup/cop/requirements/shipped_extensions_namespace.rb +6 -6
  36. data/lib/rubocop/sketchup/cop/requirements/sketchup_extension.rb +28 -9
  37. data/lib/rubocop/sketchup/cop/requirements/sketchup_require.rb +163 -0
  38. data/lib/rubocop/sketchup/cop/suggestions/add_group.rb +49 -0
  39. data/lib/rubocop/sketchup/cop/suggestions/compatibility.rb +35 -6
  40. data/lib/rubocop/sketchup/cop/suggestions/dc_internals.rb +6 -3
  41. data/lib/rubocop/sketchup/cop/suggestions/file_encoding.rb +3 -0
  42. data/lib/rubocop/sketchup/cop/suggestions/model_entities.rb +9 -2
  43. data/lib/rubocop/sketchup/cop/suggestions/monkey_patched_api.rb +5 -1
  44. data/lib/rubocop/sketchup/cop/suggestions/operation_name.rb +20 -9
  45. data/lib/rubocop/sketchup/cop/suggestions/sketchup_find_support_file.rb +13 -2
  46. data/lib/rubocop/sketchup/cop/suggestions/tool_drawing_bounds.rb +44 -0
  47. data/lib/rubocop/sketchup/cop/suggestions/tool_invalidate.rb +66 -0
  48. data/lib/rubocop/sketchup/cop/suggestions/tool_user_input.rb +41 -0
  49. data/lib/rubocop/sketchup/cop/suggestions/toolbar_timer.rb +65 -0
  50. data/lib/rubocop/sketchup/cop.rb +38 -18
  51. data/lib/rubocop/sketchup/dc_globals.rb +1 -1
  52. data/lib/rubocop/sketchup/dc_methods.rb +27 -27
  53. data/lib/rubocop/sketchup/extension_project.rb +19 -2
  54. data/lib/rubocop/sketchup/formatter/extension_review.rb +35 -15
  55. data/lib/rubocop/sketchup/inject.rb +1 -1
  56. data/lib/rubocop/sketchup/namespace.rb +1 -0
  57. data/lib/rubocop/sketchup/namespace_checker.rb +4 -1
  58. data/lib/rubocop/sketchup/no_comment_disable.rb +1 -1
  59. data/lib/rubocop/sketchup/range_help.rb +52 -0
  60. data/lib/rubocop/sketchup/sketchup_version.rb +4 -2
  61. data/lib/rubocop/sketchup/tool_checker.rb +43 -0
  62. data/lib/rubocop/sketchup/version.rb +1 -1
  63. data/lib/rubocop/sketchup.rb +1 -1
  64. data/lib/rubocop-sketchup.rb +9 -0
  65. data/rubocop-sketchup.gemspec +8 -11
  66. metadata +18 -6
  67. data/lib/rubocop/sketchup/cop/suggestions/sketchup_require.rb +0 -67
@@ -3,8 +3,9 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module SketchupPerformance
6
- # Avoid modifying the selection set within loops. It's much faster to
7
- # change the selection in bulk.
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.
8
9
  #
9
10
  # @example Poor performance
10
11
  # model = Sketchup.active_model
@@ -24,7 +25,11 @@ module RuboCop
24
25
  # faces = model.active_entities.grep(Sketchup::Face)
25
26
  # model.selection.add(faces)
26
27
  class SelectionBulkChanges < SketchUp::Cop
27
- MSG = 'Avoid modifying selecting within loops.'.freeze
28
+
29
+ include RangeHelp
30
+
31
+ MSG = 'Prefer changing selection in bulk instead of modifying '\
32
+ 'selection within loops.'.freeze
28
33
 
29
34
  # http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
30
35
  # https://rubocop.readthedocs.io/en/latest/node_pattern/
@@ -64,8 +69,10 @@ module RuboCop
64
69
  def on_send(node)
65
70
  return unless selection?(node)
66
71
  return unless node.ancestors.any?(&method(:iterator?))
67
- add_offense(node, location: :expression)
72
+
73
+ add_offense(node, location: range_with_receiver(node))
68
74
  end
75
+
69
76
  end
70
77
  end
71
78
  end
@@ -0,0 +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.'.freeze
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
@@ -3,15 +3,20 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module SketchupPerformance
6
+ # `.typename` is very slow, prefer `.is_a?` instead.
7
+ #
8
+ # `entity.typename == 'Face'` is slow because it performs a string
9
+ # comparison. `is_a?` is much faster because it's a simple type check.
6
10
  class Typename < SketchUp::Cop
7
11
  MSG = '`.typename` is very slow, prefer `.is_a?` instead.'.freeze
8
12
 
9
13
  def on_send(node)
10
14
  _, method_name = *node
11
15
  return unless method_name == :typename
16
+
12
17
  # TODO(thomthom): Should we try to detect use of #typename
13
18
  # in context of comparing against a string?
14
- add_offense(node, location: :expression)
19
+ add_offense(node, location: :selector)
15
20
  end
16
21
  end
17
22
  end
@@ -3,6 +3,12 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module SketchupRequirements
6
+ # Do not modify the Sketch API. This will affect other extensions and
7
+ # very likely cause them to fail.
8
+ #
9
+ # This requirement also include adding things into the SketchUp API
10
+ # namespace. The API namespace is reserved for future additions to the
11
+ # API.
6
12
  class ApiNamespace < SketchUp::Cop
7
13
 
8
14
  include SketchUp::NoCommentDisable
@@ -10,9 +16,9 @@ module RuboCop
10
16
 
11
17
  MSG = 'Do not modify the SketchUp API.'.freeze
12
18
 
13
- NAMESPACES = %w(
19
+ NAMESPACES = %w[
14
20
  Geom Layout Sketchup SketchupExtension UI
15
- ).freeze
21
+ ].freeze
16
22
 
17
23
  def namespaces
18
24
  NAMESPACES
@@ -7,12 +7,14 @@ module RuboCop
7
7
  # SketchUp will trap `exit` and prevent that, with a message in the
8
8
  # console. But `exit!` is not trapped and with terminate SketchUp without
9
9
  # shutting down cleanly.
10
- # Use `return`, `next` or `break` instead.
10
+ #
11
+ # Use `return`, `next`, `break` or `raise` instead.
11
12
  class Exit < SketchUp::Cop
12
13
 
13
14
  include SketchUp::NoCommentDisable
14
15
 
15
- MSG = 'Exit attempts to kill the Ruby interpreter. Use return, next or break instead.'.freeze
16
+ MSG = '`exit` attempts to kill the Ruby interpreter. Use `return`, '\
17
+ '`next`, `break` or `raise` instead.'.freeze
16
18
 
17
19
  # Reference: http://rubocop.readthedocs.io/en/latest/development/
18
20
  def_node_matcher :exit?, <<-PATTERN
@@ -20,7 +22,9 @@ module RuboCop
20
22
  PATTERN
21
23
 
22
24
  def on_send(node)
23
- add_offense(node, location: :expression, severity: :error) if exit?(node)
25
+ return unless exit?(node)
26
+
27
+ add_offense(node, location: :selector)
24
28
  end
25
29
  end
26
30
  end
@@ -7,6 +7,30 @@ require 'rubocop/sketchup/cop/requirements/ruby_stdlib_namespace'
7
7
  module RuboCop
8
8
  module Cop
9
9
  module SketchupRequirements
10
+ # Extensions in SketchUp all share the same Ruby environment on the user's
11
+ # machine. Because of this it's important that each extension isolate
12
+ # itself to avoid clashing with other extensions.
13
+ #
14
+ # Extensions submitted to Extension Warehouse is expected to use only one
15
+ # root module.
16
+ #
17
+ # @example Good - this contains everything in the extension.
18
+ # module MyExtension
19
+ # class Foo
20
+ # end
21
+ # class Bar
22
+ # end
23
+ # end
24
+ #
25
+ # @example Better - this further reduce chance of clashing.
26
+ # module MyCompany
27
+ # module MyExtension
28
+ # class Foo
29
+ # end
30
+ # class Bar
31
+ # end
32
+ # end
33
+ # end
10
34
  class ExtensionNamespace < SketchUp::Cop
11
35
 
12
36
  include SketchUp::NoCommentDisable
@@ -28,6 +52,7 @@ module RuboCop
28
52
  return unless parent.top_level?
29
53
  # Don't check excluded namespaces.
30
54
  return if exempted?(namespace)
55
+
31
56
  check_namespace(node, namespace)
32
57
  end
33
58
 
@@ -40,12 +65,14 @@ module RuboCop
40
65
  # Make sure the namespace isn't part of reserved namespaces that other
41
66
  # cops are checking.
42
67
  return if reserved?(namespace)
68
+
43
69
  # Remember the first namespace encountered and log an offence if
44
70
  # more top level namespaces are registered.
45
71
  top = namespace.first
46
72
  @@namespace ||= top
47
73
  return if @@namespace == top
48
- add_offense(node, location: :name, severity: :error)
74
+
75
+ add_offense(node, location: :name)
49
76
  end
50
77
 
51
78
  def reserved?(namespace)
@@ -53,12 +80,15 @@ module RuboCop
53
80
  return true if RubyCoreNamespace::NAMESPACES.include?(top)
54
81
  return true if RubyStdLibNamespace::NAMESPACES.include?(top)
55
82
  return true if ApiNamespace::NAMESPACES.include?(top)
83
+
56
84
  false
57
85
  end
58
86
 
59
87
  def message(node)
60
88
  namespace = Namespace.new(node.defined_module_name).from_root
61
- format('Use a single root namespace. (Found `%s`; Previously found `%s`)', namespace, @@namespace)
89
+ format('Use a single root namespace. '\
90
+ '(Found `%<found>s`; Previously found `%<expected>s`)',
91
+ found: namespace, expected: @@namespace)
62
92
  end
63
93
 
64
94
  def exempted?(namespace)
@@ -5,6 +5,16 @@ module RuboCop
5
5
  module SketchupRequirements
6
6
  # Check that the extension conform to expected file structure with a
7
7
  # single root .rb file and a support folder with matching name.
8
+ #
9
+ # Make sure to match upper and lower case characters between the root .rb
10
+ # file and the support folder.
11
+ #
12
+ # @example
13
+ # SketchUp/Plugins
14
+ # + ex_hello_world.rb
15
+ # + ex_hello_world
16
+ # + main.rb
17
+ # + ...
8
18
  class FileStructure < SketchUp::Cop
9
19
 
10
20
  include SketchUp::NoCommentDisable
@@ -27,41 +37,40 @@ module RuboCop
27
37
 
28
38
  # Ensure there is only one root Ruby file.
29
39
  if root_ruby_files.size != 1
30
- msg = "Extensions must have exactly one root Ruby (.rb) file. Found: %d"
40
+ msg = 'Extensions must have exactly one root Ruby (.rb) file. '\
41
+ 'Found: %d'
31
42
  add_offense(nil,
32
43
  location: range,
33
- message: format(msg, root_ruby_files.size),
34
- severity: :error)
44
+ message: format(msg, root_ruby_files.size))
35
45
  return
36
46
  end
37
47
 
38
48
  # Find the root file and collect the sub-directories.
39
49
  root_file = root_ruby_files.first
40
50
  extension_basename = File.basename(root_file, '.*')
41
- sub_folders = source_path.children.select { |c| c.directory? }
51
+ sub_folders = source_path.children.select(&:directory?)
42
52
  sub_folders.reject! { |folder|
43
53
  IGNORED_DIRECTORIES.include?(folder.basename.to_s)
44
54
  }
45
55
 
46
56
  # Ensure there is only one sub-directory.
47
57
  if sub_folders.size != 1
48
- msg = "Extensions must have exactly one support directory. Found %d"
58
+ msg = 'Extensions must have exactly one support directory. Found %d'
49
59
  add_offense(nil,
50
60
  location: range,
51
- message: format(msg, sub_folders.size),
52
- severity: :error)
61
+ message: format(msg, sub_folders.size))
53
62
  return
54
63
  end
55
64
 
56
65
  # Ensure support directory's name match the root Ruby file.
57
66
  support_directory = sub_folders.first
58
67
  unless support_directory.basename.to_s == extension_basename
59
- msg = 'Extensions must have a support directory matching the name of the root Ruby file. Expected %s, found %s'
68
+ msg = 'Extensions must have a support directory matching the name '\
69
+ 'of the root Ruby file. Expected %s, found %s'
60
70
  msg = format(msg, extension_basename, support_directory.basename)
61
71
  add_offense(nil,
62
72
  location: range,
63
- message: msg,
64
- severity: :error)
73
+ message: msg)
65
74
  end
66
75
  end
67
76
 
@@ -71,13 +80,16 @@ module RuboCop
71
80
 
72
81
  def already_run?
73
82
  return true if @@already_run
83
+
74
84
  @@already_run = true
75
85
  false
76
86
  end
77
87
 
88
+ # rubocop:disable Lint/IneffectiveAccessModifier
78
89
  def self.reset
79
90
  @@already_run = false
80
91
  end
92
+ # rubocop:enable Lint/IneffectiveAccessModifier
81
93
 
82
94
  end
83
95
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupRequirements
6
+ # It's tempting to use gems in an extension. However, there are issues if
7
+ # consuming them via Gem.install;
8
+ #
9
+ # * Net::HTTP is unreliable. (SSL certificate issues, OpenSSL performance
10
+ # freeze under Windows)
11
+ # * Compiled extensions cannot be installed like this as they require
12
+ # DevKit.
13
+ # * While downloading and installing SketchUp freezes. (Bad thing if done
14
+ # automatically upon loading the extensions - especially without user
15
+ # notice. It's easy to think SU have stopped working)
16
+ # * Version collisions. If multiple extensions want to use different
17
+ # versions of a gem they will clash if the versions aren't compatible
18
+ # with the features they use.
19
+ #
20
+ # They only way to ensure extensions doesn't clash is to namespace
21
+ # everything into extension namespace. This means making a copy of the
22
+ # gem you want to use and wrap it in your own namespace.
23
+ class GemInstall < SketchUp::Cop
24
+
25
+ include RangeHelp
26
+ include SketchUp::NoCommentDisable
27
+
28
+ MSG = '`Gem.install` is unreliable in SketchUp, and can cause '\
29
+ 'extensions to clash.'.freeze
30
+
31
+ # Reference: http://rubocop.readthedocs.io/en/latest/development/
32
+ def_node_matcher :gem_install?, <<-PATTERN
33
+ (send (const nil? :Gem) :install ...)
34
+ PATTERN
35
+
36
+ def on_send(node)
37
+ return unless gem_install?(node)
38
+
39
+ range = range_with_receiver(node)
40
+ add_offense(node, location: range)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module SketchupRequirements
6
+ # Don't attempt to kill the Ruby interpreter by calling `exit` or `exit!`.
7
+ # SketchUp will trap `exit` and prevent that, with a message in the
8
+ # console. But `exit!` is not trapped and with terminate SketchUp without
9
+ # shutting down cleanly.
10
+ #
11
+ # Use `return`, `next`, `break` or `raise` instead.
12
+ class GetExtensionLicense < SketchUp::Cop
13
+
14
+ include RangeHelp
15
+ include SketchUp::NoCommentDisable
16
+
17
+ MSG_INVALID = 'Invalid extension GUID'.freeze
18
+
19
+ MSG_WRONG_TYPE = 'Only pass in extension GUID from local string '\
20
+ 'literals.'.freeze
21
+
22
+ MSG_TRAILING_SPACE = 'Extra space in extension GUID'.freeze
23
+
24
+ def_node_matcher :get_extension_license, <<-PATTERN
25
+ (send
26
+ (const
27
+ (const nil? :Sketchup) :Licensing) :get_extension_license
28
+ $_)
29
+ PATTERN
30
+
31
+ # rubocop:disable Metrics/LineLength
32
+ EXTENSION_ID_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/
33
+ # rubocop:enable Metrics/LineLength
34
+
35
+ def on_send(node)
36
+ argument = get_extension_license(node)
37
+ return unless argument
38
+
39
+ if argument.lvar_type?
40
+ variable_name = argument.children.first
41
+ assignment_node = find_assignment(node, variable_name)
42
+ argument = assignment_node.children.last
43
+ end
44
+
45
+ if argument.str_type?
46
+ validate_extension_id(argument)
47
+ else
48
+ location = argument.loc.expression
49
+ add_offense(node, location: location, message: MSG_WRONG_TYPE)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def find_assignment(node, variable_name)
56
+ scope = node
57
+ until scope.parent.nil?
58
+ scope = scope.parent
59
+ scope.each_child_node { |child|
60
+ # next unless child.is_a?(RuboCop::AST::Node)
61
+ next unless child.lvasgn_type?
62
+ next unless child.children.first == variable_name
63
+
64
+ return child
65
+ }
66
+ end
67
+ nil
68
+ end
69
+
70
+ def validate_extension_id(node)
71
+ extension_id = node.str_content
72
+
73
+ # Trailing spaces
74
+ if extension_id.rstrip.size < extension_id.size
75
+ end_pos = node.loc.end.begin_pos
76
+ begin_pos = node.loc.begin.end_pos + extension_id.rstrip.size
77
+ range = range_between(begin_pos, end_pos)
78
+ add_offense(node, location: range, message: MSG_TRAILING_SPACE)
79
+ return false
80
+ end
81
+
82
+ # Invalid format.
83
+ if extension_id !~ EXTENSION_ID_PATTERN
84
+ range = string_contents_range(node)
85
+ add_offense(node, location: range, message: MSG_INVALID)
86
+ return false
87
+ end
88
+
89
+ true
90
+ end
91
+
92
+ end
93
+ end
94
+ end
95
+ end
@@ -3,6 +3,12 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module SketchupRequirements
6
+ # Extensions in SketchUp all share the same Ruby environment on the user's
7
+ # machine. Because of this it's important that each extension isolate
8
+ # itself to avoid clashing with other extensions.
9
+ #
10
+ # Extensions submitted to Extension Warehouse is expected to not define
11
+ # global constants.
6
12
  class GlobalConstants < SketchUp::Cop
7
13
 
8
14
  include SketchUp::NoCommentDisable
@@ -19,8 +25,11 @@ module RuboCop
19
25
  # Constant assignment.
20
26
  def on_casgn(node)
21
27
  return if namespaced_constant?(node)
28
+
22
29
  namespace = Namespace.new(node.parent_module_name)
23
- add_offense(node, location: :name, severity: :error) if namespace.top_level?
30
+ return unless namespace.top_level?
31
+
32
+ add_offense(node, location: :name)
24
33
  end
25
34
 
26
35
  end
@@ -3,6 +3,12 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module SketchupRequirements
6
+ # Extensions in SketchUp all share the same Ruby environment on the user's
7
+ # machine. Because of this it's important that each extension isolate
8
+ # itself to avoid clashing with other extensions.
9
+ #
10
+ # Extensions submitted to Extension Warehouse is expected to not pollute
11
+ # the global namespace by including mix-in modules.
6
12
  class GlobalInclude < SketchUp::Cop
7
13
 
8
14
  include SketchUp::NoCommentDisable
@@ -16,7 +22,8 @@ module RuboCop
16
22
 
17
23
  def on_send(node)
18
24
  return unless global_include?(node)
19
- add_offense(node, severity: :error)
25
+
26
+ add_offense(node, location: :selector)
20
27
  end
21
28
 
22
29
  private
@@ -26,7 +33,7 @@ module RuboCop
26
33
  end
27
34
 
28
35
  def global_namespace?(node)
29
- ['Kernel', 'Object'].include?(node.parent_module_name)
36
+ %w[Kernel Object].include?(node.parent_module_name)
30
37
  end
31
38
 
32
39
  end
@@ -3,6 +3,12 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module SketchupRequirements
6
+ # Extensions in SketchUp all share the same Ruby environment on the user's
7
+ # machine. Because of this it's important that each extension isolate
8
+ # itself to avoid clashing with other extensions.
9
+ #
10
+ # Extensions submitted to Extension Warehouse is expected to not define
11
+ # global methods.
6
12
  class GlobalMethods < SketchUp::Cop
7
13
 
8
14
  include SketchUp::NoCommentDisable
@@ -44,9 +50,12 @@ module RuboCop
44
50
  # If a method is defined inside a block then parent_module_name
45
51
  # will return nil.
46
52
  return if node.parent_module_name.nil?
53
+
47
54
  namespace = Namespace.new(node.parent_module_name)
48
55
  end
49
- add_offense(node, location: :name, severity: :error) if namespace.top_level?
56
+ return unless namespace.top_level?
57
+
58
+ add_offense(node, location: :name)
50
59
  end
51
60
  alias on_defs on_def
52
61
 
@@ -3,12 +3,19 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module SketchupRequirements
6
+ # Extensions in SketchUp all share the same Ruby environment on the user's
7
+ # machine. Because of this it's important that each extension isolate
8
+ # itself to avoid clashing with other extensions.
9
+ #
10
+ # Extensions submitted to Extension Warehouse is expected to not define
11
+ # global variables.
12
+ #
6
13
  # This cops looks for uses of global variables.
7
14
  # It does not report offenses for built-in global variables.
8
15
  # Built-in global variables are allowed by default. Additionally
9
16
  # users can allow additional variables via the AllowedVariables option.
10
17
  #
11
- # Note that backreferences like $1, $2, etc are not global variables.
18
+ # Note that backreferences like `$1`, `$2`, etc are not global variables.
12
19
  class GlobalVariables < SketchUp::Cop
13
20
 
14
21
  include SketchUp::NoCommentDisable
@@ -45,11 +52,11 @@ module RuboCop
45
52
  $DEBUG $FILENAME $VERBOSE $SAFE
46
53
  $-0 $-a $-d $-F $-i $-I $-l $-p $-v $-w
47
54
  $CLASSPATH $JRUBY_VERSION $JRUBY_REVISION $ENV_JAVA
48
- ]
55
+ ].freeze
49
56
 
50
57
  SKETCHUP_VARS = %i[
51
58
  $loaded_files
52
- ]
59
+ ].freeze
53
60
 
54
61
  # Some globals, like DC's, are being read from so often that it's better
55
62
  # to ignore these to reduce noise.
@@ -78,7 +85,9 @@ module RuboCop
78
85
  def check(node)
79
86
  global_var, = *node
80
87
 
81
- add_offense(node, location: :name, severity: :error) unless allowed_var?(global_var)
88
+ return if allowed_var?(global_var)
89
+
90
+ add_offense(node, location: :name)
82
91
  end
83
92
  end
84
93
  end
@@ -3,14 +3,15 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module SketchupRequirements
6
- # Avoid using globals in general, but especially these which are known to
6
+ # Avoid using globals in general, but especially these which are known to
7
7
  # be in use by other extensions made by SketchUp.
8
8
  # They are still in use due to compatibility reasons.
9
9
  class LanguageHandlerGlobals < SketchUp::Cop
10
10
 
11
11
  include SketchUp::NoCommentDisable
12
12
 
13
- MSG = "Avoid globals in general, but especially these which are known to be in use.".freeze
13
+ MSG = 'Avoid globals in general, but especially these which are known '\
14
+ 'to be in use.'.freeze
14
15
 
15
16
  LH_GLOBALS = %i[
16
17
  $dc_strings
@@ -26,7 +27,7 @@ module RuboCop
26
27
  $unitsStrings
27
28
  $uStrings
28
29
  $wt_strings
29
- ]
30
+ ].freeze
30
31
 
31
32
  def hl_global_var?(global_var)
32
33
  LH_GLOBALS.include?(global_var)
@@ -35,7 +36,8 @@ module RuboCop
35
36
  def on_gvasgn(node)
36
37
  global_var, = *node
37
38
  return unless hl_global_var?(global_var)
38
- add_offense(node, location: :name, severity: :error)
39
+
40
+ add_offense(node, location: :name)
39
41
  end
40
42
 
41
43
  end