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.
- checksums.yaml +4 -4
- data/Gemfile +7 -1
- data/assets/logo.png +0 -0
- data/assets/output.html.erb +301 -0
- data/config/default.yml +141 -36
- data/lib/rubocop/sketchup/config.rb +28 -8
- data/lib/rubocop/sketchup/cop/deprecations/add_separator_to_menu.rb +4 -1
- data/lib/rubocop/sketchup/cop/deprecations/operation_next_transparent.rb +11 -2
- data/lib/rubocop/sketchup/cop/deprecations/require_all.rb +7 -2
- data/lib/rubocop/sketchup/cop/deprecations/set_texture_projection.rb +6 -2
- data/lib/rubocop/sketchup/cop/deprecations/show_ruby_panel.rb +4 -1
- data/lib/rubocop/sketchup/cop/deprecations/sketchup_set.rb +8 -0
- data/lib/rubocop/sketchup/cop/performance/openssl.rb +5 -3
- data/lib/rubocop/sketchup/cop/performance/operation_disable_ui.rb +10 -2
- data/lib/rubocop/sketchup/cop/performance/selection_bulk.rb +11 -4
- data/lib/rubocop/sketchup/cop/performance/type_check.rb +63 -0
- data/lib/rubocop/sketchup/cop/performance/typename.rb +6 -1
- data/lib/rubocop/sketchup/cop/requirements/api_namespace.rb +8 -2
- data/lib/rubocop/sketchup/cop/requirements/exit.rb +7 -3
- data/lib/rubocop/sketchup/cop/requirements/extension_namespace.rb +32 -2
- data/lib/rubocop/sketchup/cop/requirements/file_structure.rb +22 -10
- data/lib/rubocop/sketchup/cop/requirements/gem_install.rb +45 -0
- data/lib/rubocop/sketchup/cop/requirements/get_extension_license.rb +95 -0
- data/lib/rubocop/sketchup/cop/requirements/global_constants.rb +10 -1
- data/lib/rubocop/sketchup/cop/requirements/global_include.rb +9 -2
- data/lib/rubocop/sketchup/cop/requirements/global_methods.rb +10 -1
- data/lib/rubocop/sketchup/cop/requirements/global_variables.rb +13 -4
- data/lib/rubocop/sketchup/cop/requirements/language_handler_globals.rb +6 -4
- data/lib/rubocop/sketchup/cop/requirements/load_path.rb +9 -6
- data/lib/rubocop/sketchup/cop/requirements/minimal_registration.rb +26 -2
- data/lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb +28 -2
- data/lib/rubocop/sketchup/cop/requirements/register_extension.rb +12 -2
- data/lib/rubocop/sketchup/cop/requirements/ruby_core_namespace.rb +14 -8
- data/lib/rubocop/sketchup/cop/requirements/ruby_stdlib_namespace.rb +594 -588
- data/lib/rubocop/sketchup/cop/requirements/shipped_extensions_namespace.rb +6 -6
- data/lib/rubocop/sketchup/cop/requirements/sketchup_extension.rb +28 -9
- data/lib/rubocop/sketchup/cop/requirements/sketchup_require.rb +163 -0
- data/lib/rubocop/sketchup/cop/suggestions/add_group.rb +49 -0
- data/lib/rubocop/sketchup/cop/suggestions/compatibility.rb +35 -6
- data/lib/rubocop/sketchup/cop/suggestions/dc_internals.rb +6 -3
- data/lib/rubocop/sketchup/cop/suggestions/file_encoding.rb +3 -0
- data/lib/rubocop/sketchup/cop/suggestions/model_entities.rb +9 -2
- data/lib/rubocop/sketchup/cop/suggestions/monkey_patched_api.rb +5 -1
- data/lib/rubocop/sketchup/cop/suggestions/operation_name.rb +20 -9
- data/lib/rubocop/sketchup/cop/suggestions/sketchup_find_support_file.rb +13 -2
- data/lib/rubocop/sketchup/cop/suggestions/tool_drawing_bounds.rb +44 -0
- data/lib/rubocop/sketchup/cop/suggestions/tool_invalidate.rb +66 -0
- data/lib/rubocop/sketchup/cop/suggestions/tool_user_input.rb +41 -0
- data/lib/rubocop/sketchup/cop/suggestions/toolbar_timer.rb +65 -0
- data/lib/rubocop/sketchup/cop.rb +38 -18
- data/lib/rubocop/sketchup/dc_globals.rb +1 -1
- data/lib/rubocop/sketchup/dc_methods.rb +27 -27
- data/lib/rubocop/sketchup/extension_project.rb +19 -2
- data/lib/rubocop/sketchup/formatter/extension_review.rb +35 -15
- data/lib/rubocop/sketchup/inject.rb +1 -1
- data/lib/rubocop/sketchup/namespace.rb +1 -0
- data/lib/rubocop/sketchup/namespace_checker.rb +4 -1
- data/lib/rubocop/sketchup/no_comment_disable.rb +1 -1
- data/lib/rubocop/sketchup/range_help.rb +52 -0
- data/lib/rubocop/sketchup/sketchup_version.rb +4 -2
- data/lib/rubocop/sketchup/tool_checker.rb +43 -0
- data/lib/rubocop/sketchup/version.rb +1 -1
- data/lib/rubocop/sketchup.rb +1 -1
- data/lib/rubocop-sketchup.rb +9 -0
- data/rubocop-sketchup.gemspec +8 -11
- metadata +18 -6
- 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
|
-
#
|
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
|
-
|
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
|
-
|
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: :
|
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
|
-
|
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
|
-
#
|
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 = '
|
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
|
-
|
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
|
-
|
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.
|
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 =
|
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
|
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 =
|
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
|
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
|
-
|
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
|
-
|
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
|
-
[
|
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
|
-
|
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
|
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
|
-
|
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
|
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 =
|
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
|
-
|
39
|
+
|
40
|
+
add_offense(node, location: :name)
|
39
41
|
end
|
40
42
|
|
41
43
|
end
|