rubocop-sketchup 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/Gemfile +19 -19
- data/assets/output.html.erb +301 -301
- data/config/default.yml +355 -355
- data/lib/rubocop/sketchup/config.rb +63 -63
- data/lib/rubocop/sketchup/cop/deprecations/add_separator_to_menu.rb +25 -25
- data/lib/rubocop/sketchup/cop/deprecations/operation_next_transparent.rb +30 -30
- data/lib/rubocop/sketchup/cop/deprecations/require_all.rb +27 -27
- data/lib/rubocop/sketchup/cop/deprecations/set_texture_projection.rb +26 -26
- data/lib/rubocop/sketchup/cop/deprecations/show_ruby_panel.rb +25 -25
- data/lib/rubocop/sketchup/cop/deprecations/sketchup_set.rb +30 -30
- data/lib/rubocop/sketchup/cop/performance/openssl.rb +41 -41
- data/lib/rubocop/sketchup/cop/performance/operation_disable_ui.rb +33 -33
- data/lib/rubocop/sketchup/cop/performance/selection_bulk.rb +79 -79
- data/lib/rubocop/sketchup/cop/performance/type_check.rb +63 -63
- data/lib/rubocop/sketchup/cop/performance/typename.rb +24 -24
- data/lib/rubocop/sketchup/cop/requirements/api_namespace.rb +30 -30
- data/lib/rubocop/sketchup/cop/requirements/exit.rb +32 -32
- data/lib/rubocop/sketchup/cop/requirements/extension_namespace.rb +108 -108
- data/lib/rubocop/sketchup/cop/requirements/file_structure.rb +97 -97
- data/lib/rubocop/sketchup/cop/requirements/gem_install.rb +45 -45
- data/lib/rubocop/sketchup/cop/requirements/get_extension_license.rb +95 -95
- data/lib/rubocop/sketchup/cop/requirements/global_constants.rb +38 -38
- data/lib/rubocop/sketchup/cop/requirements/global_include.rb +42 -42
- data/lib/rubocop/sketchup/cop/requirements/global_methods.rb +65 -65
- data/lib/rubocop/sketchup/cop/requirements/global_variables.rb +95 -95
- data/lib/rubocop/sketchup/cop/requirements/language_handler_globals.rb +46 -46
- data/lib/rubocop/sketchup/cop/requirements/load_path.rb +83 -83
- data/lib/rubocop/sketchup/cop/requirements/minimal_registration.rb +73 -73
- data/lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb +161 -161
- data/lib/rubocop/sketchup/cop/requirements/register_extension.rb +45 -45
- data/lib/rubocop/sketchup/cop/requirements/ruby_core_namespace.rb +291 -291
- data/lib/rubocop/sketchup/cop/requirements/ruby_stdlib_namespace.rb +634 -634
- data/lib/rubocop/sketchup/cop/requirements/shipped_extensions_namespace.rb +61 -61
- data/lib/rubocop/sketchup/cop/requirements/sketchup_extension.rb +119 -119
- data/lib/rubocop/sketchup/cop/requirements/sketchup_require.rb +163 -163
- data/lib/rubocop/sketchup/cop/suggestions/add_group.rb +49 -49
- data/lib/rubocop/sketchup/cop/suggestions/compatibility.rb +117 -117
- data/lib/rubocop/sketchup/cop/suggestions/dc_internals.rb +34 -34
- data/lib/rubocop/sketchup/cop/suggestions/file_encoding.rb +78 -78
- data/lib/rubocop/sketchup/cop/suggestions/model_entities.rb +58 -58
- data/lib/rubocop/sketchup/cop/suggestions/monkey_patched_api.rb +45 -45
- data/lib/rubocop/sketchup/cop/suggestions/operation_name.rb +103 -103
- data/lib/rubocop/sketchup/cop/suggestions/sketchup_find_support_file.rb +39 -39
- data/lib/rubocop/sketchup/cop/suggestions/tool_drawing_bounds.rb +44 -44
- data/lib/rubocop/sketchup/cop/suggestions/tool_invalidate.rb +66 -66
- data/lib/rubocop/sketchup/cop/suggestions/tool_user_input.rb +41 -41
- data/lib/rubocop/sketchup/cop/suggestions/toolbar_timer.rb +65 -65
- data/lib/rubocop/sketchup/cop.rb +111 -111
- data/lib/rubocop/sketchup/dc_globals.rb +24 -24
- data/lib/rubocop/sketchup/dc_methods.rb +130 -130
- data/lib/rubocop/sketchup/extension_project.rb +65 -65
- data/lib/rubocop/sketchup/features.rb +738 -738
- data/lib/rubocop/sketchup/formatter/extension_review.rb +259 -259
- data/lib/rubocop/sketchup/inject.rb +19 -19
- data/lib/rubocop/sketchup/namespace.rb +47 -47
- data/lib/rubocop/sketchup/namespace_checker.rb +46 -46
- data/lib/rubocop/sketchup/no_comment_disable.rb +17 -17
- data/lib/rubocop/sketchup/range_help.rb +52 -52
- data/lib/rubocop/sketchup/sketchup_version.rb +87 -87
- data/lib/rubocop/sketchup/tool_checker.rb +43 -43
- data/lib/rubocop/sketchup/version.rb +5 -5
- data/lib/rubocop/sketchup.rb +12 -12
- data/lib/rubocop-sketchup.rb +48 -48
- data/rubocop-sketchup.gemspec +27 -27
- metadata +4 -4
@@ -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.'.freeze
|
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.'.freeze
|
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.'.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
|
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
|
@@ -1,24 +1,24 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
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.
|
10
|
-
class Typename < SketchUp::Cop
|
11
|
-
MSG = '`.typename` is very slow, prefer `.is_a?` instead.'.freeze
|
12
|
-
|
13
|
-
def on_send(node)
|
14
|
-
_, method_name = *node
|
15
|
-
return unless method_name == :typename
|
16
|
-
|
17
|
-
# TODO(thomthom): Should we try to detect use of #typename
|
18
|
-
# in context of comparing against a string?
|
19
|
-
add_offense(node, location: :selector)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
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.
|
10
|
+
class Typename < SketchUp::Cop
|
11
|
+
MSG = '`.typename` is very slow, prefer `.is_a?` instead.'.freeze
|
12
|
+
|
13
|
+
def on_send(node)
|
14
|
+
_, method_name = *node
|
15
|
+
return unless method_name == :typename
|
16
|
+
|
17
|
+
# TODO(thomthom): Should we try to detect use of #typename
|
18
|
+
# in context of comparing against a string?
|
19
|
+
add_offense(node, location: :selector)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,30 +1,30 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
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.
|
12
|
-
class ApiNamespace < SketchUp::Cop
|
13
|
-
|
14
|
-
include SketchUp::NoCommentDisable
|
15
|
-
include SketchUp::NamespaceChecker
|
16
|
-
|
17
|
-
MSG = 'Do not modify the SketchUp API.'.freeze
|
18
|
-
|
19
|
-
NAMESPACES = %w[
|
20
|
-
Geom Layout Sketchup SketchupExtension UI
|
21
|
-
].freeze
|
22
|
-
|
23
|
-
def namespaces
|
24
|
-
NAMESPACES
|
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 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.
|
12
|
+
class ApiNamespace < SketchUp::Cop
|
13
|
+
|
14
|
+
include SketchUp::NoCommentDisable
|
15
|
+
include SketchUp::NamespaceChecker
|
16
|
+
|
17
|
+
MSG = 'Do not modify the SketchUp API.'.freeze
|
18
|
+
|
19
|
+
NAMESPACES = %w[
|
20
|
+
Geom Layout Sketchup SketchupExtension UI
|
21
|
+
].freeze
|
22
|
+
|
23
|
+
def namespaces
|
24
|
+
NAMESPACES
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,32 +1,32 @@
|
|
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 Exit < SketchUp::Cop
|
13
|
-
|
14
|
-
include SketchUp::NoCommentDisable
|
15
|
-
|
16
|
-
MSG = '`exit` attempts to kill the Ruby interpreter. Use `return`, '\
|
17
|
-
'`next`, `break` or `raise` instead.'.freeze
|
18
|
-
|
19
|
-
# Reference: http://rubocop.readthedocs.io/en/latest/development/
|
20
|
-
def_node_matcher :exit?, <<-PATTERN
|
21
|
-
(send {(const nil? :Kernel) nil?} {:exit :exit!} ...)
|
22
|
-
PATTERN
|
23
|
-
|
24
|
-
def on_send(node)
|
25
|
-
return unless exit?(node)
|
26
|
-
|
27
|
-
add_offense(node, location: :selector)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
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 Exit < SketchUp::Cop
|
13
|
+
|
14
|
+
include SketchUp::NoCommentDisable
|
15
|
+
|
16
|
+
MSG = '`exit` attempts to kill the Ruby interpreter. Use `return`, '\
|
17
|
+
'`next`, `break` or `raise` instead.'.freeze
|
18
|
+
|
19
|
+
# Reference: http://rubocop.readthedocs.io/en/latest/development/
|
20
|
+
def_node_matcher :exit?, <<-PATTERN
|
21
|
+
(send {(const nil? :Kernel) nil?} {:exit :exit!} ...)
|
22
|
+
PATTERN
|
23
|
+
|
24
|
+
def on_send(node)
|
25
|
+
return unless exit?(node)
|
26
|
+
|
27
|
+
add_offense(node, location: :selector)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|