rubocop-sketchup 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|