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,163 +1,163 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module SketchupRequirements
|
6
|
-
# Omit file extensions when using `Sketchup.require` to allow encrypted
|
7
|
-
# files to be loaded.
|
8
|
-
#
|
9
|
-
# Ruby C extensions, `.so`/`.bundle` libraries must always be loaded via
|
10
|
-
# the normal `require`. Omit the file extension to the libraries as Ruby
|
11
|
-
# will resolve the`.so`/`.bundle` automatically.
|
12
|
-
#
|
13
|
-
# @example Bad - This will fail if extension is encrypted
|
14
|
-
# Sketchup.require 'hello/world.rb'
|
15
|
-
#
|
16
|
-
# @example Good - This will work for `.rbe`, `.rbs` and `rb` files.
|
17
|
-
# Sketchup.require 'hello/world'
|
18
|
-
#
|
19
|
-
# @example Bad - This will fail if extension is encrypted
|
20
|
-
# extension = SketchupExtension.new("Example", "Example/main.rb")
|
21
|
-
#
|
22
|
-
# @example Good - This will work for `.rbe`, `.rbs` and `rb` files.
|
23
|
-
# extension = SketchupExtension.new("Example", "Example/main")
|
24
|
-
class SketchupRequire < SketchUp::Cop
|
25
|
-
|
26
|
-
include SketchUp::ExtensionProject
|
27
|
-
include SketchUp::NoCommentDisable
|
28
|
-
include RangeHelp
|
29
|
-
|
30
|
-
MSG_SKETCHUP_REQUIRE_EXT_NAME = 'Do not hard code file extensions '\
|
31
|
-
'with `Sketchup.require`.'.freeze
|
32
|
-
|
33
|
-
MSG_EXTENSION_NEW_EXT_NAME = 'Do not hard code file extensions '\
|
34
|
-
'with `SketchupExtension.new`.'.freeze
|
35
|
-
|
36
|
-
MSG_REQUIRE_FOR_BINARY = 'Use `require` instead of `Sketchup.require` '\
|
37
|
-
'to load binary Ruby libraries.'.freeze
|
38
|
-
|
39
|
-
MSG_OMIT_BINARY_EXT = 'Do not hard code .so/.bundle file '\
|
40
|
-
'extensions'.freeze
|
41
|
-
|
42
|
-
MSG_REQUIRE_ENCRYPTED = 'Use `Sketchup.require` when loading Ruby '\
|
43
|
-
'files for encrypted extensions.'.freeze
|
44
|
-
|
45
|
-
def_node_matcher :ruby_require, <<-PATTERN
|
46
|
-
(send nil? :require (str $_))
|
47
|
-
PATTERN
|
48
|
-
|
49
|
-
def_node_matcher :ruby_require?, <<-PATTERN
|
50
|
-
(send nil? :require (str _))
|
51
|
-
PATTERN
|
52
|
-
|
53
|
-
|
54
|
-
def_node_matcher :sketchup_require, <<-PATTERN
|
55
|
-
(send (const nil? :Sketchup) :require (str $_))
|
56
|
-
PATTERN
|
57
|
-
|
58
|
-
def_node_matcher :sketchup_require?, <<-PATTERN
|
59
|
-
(send (const nil? :Sketchup) :require (str _))
|
60
|
-
PATTERN
|
61
|
-
|
62
|
-
|
63
|
-
def_node_matcher :sketchup_extension_new, <<-PATTERN
|
64
|
-
(send (const nil? :SketchupExtension) :new _ (str $_))
|
65
|
-
PATTERN
|
66
|
-
|
67
|
-
def_node_matcher :sketchup_extension_new?, <<-PATTERN
|
68
|
-
(send (const nil? :SketchupExtension) :new _ (str _))
|
69
|
-
PATTERN
|
70
|
-
|
71
|
-
|
72
|
-
TOOLS_RUBY_FILES = %w[extensions.rb langhandler.rb sketchup.rb].freeze
|
73
|
-
|
74
|
-
|
75
|
-
def on_send(node)
|
76
|
-
if sketchup_require?(node)
|
77
|
-
filename = sketchup_require(node)
|
78
|
-
return if check_binary_sketchup_require(node, filename)
|
79
|
-
return if check_sketchup_require_filename(node, filename)
|
80
|
-
|
81
|
-
elsif ruby_require?(node)
|
82
|
-
filename = ruby_require(node)
|
83
|
-
return if check_binary_ruby_require(node, filename)
|
84
|
-
return if check_encrypted_require(node, filename)
|
85
|
-
|
86
|
-
elsif sketchup_extension_new?(node)
|
87
|
-
filename = sketchup_extension_new(node)
|
88
|
-
return if check_sketchup_extension_new_filename(node, filename)
|
89
|
-
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
private
|
94
|
-
|
95
|
-
def binary_require?(filename)
|
96
|
-
return unless extension_binaries?
|
97
|
-
return if extension_binaries.empty?
|
98
|
-
|
99
|
-
extension_binaries.include?(filename)
|
100
|
-
end
|
101
|
-
|
102
|
-
def check_binary_sketchup_require(node, filename)
|
103
|
-
return unless binary_require?(filename)
|
104
|
-
|
105
|
-
end_pos = node.loc.dot.end_pos
|
106
|
-
range = node.receiver.loc.expression.with(end_pos: end_pos)
|
107
|
-
add_offense(node, location: range, message: MSG_REQUIRE_FOR_BINARY)
|
108
|
-
true
|
109
|
-
end
|
110
|
-
|
111
|
-
def check_binary_ruby_require(node, filename)
|
112
|
-
ext_name = File.extname(filename)
|
113
|
-
return unless %w[.so .bundle].include?(ext_name)
|
114
|
-
|
115
|
-
add_offense(node, location: file_ext_range(node.arguments.first),
|
116
|
-
message: MSG_OMIT_BINARY_EXT)
|
117
|
-
true
|
118
|
-
end
|
119
|
-
|
120
|
-
def check_sketchup_require_filename(node, filename)
|
121
|
-
return if valid_filename?(filename)
|
122
|
-
|
123
|
-
add_offense(node, location: file_ext_range(node.arguments.first),
|
124
|
-
message: MSG_SKETCHUP_REQUIRE_EXT_NAME)
|
125
|
-
true
|
126
|
-
end
|
127
|
-
|
128
|
-
def check_sketchup_extension_new_filename(node, filename)
|
129
|
-
return if valid_filename?(filename)
|
130
|
-
|
131
|
-
add_offense(node, location: file_ext_range(node.arguments.last),
|
132
|
-
message: MSG_EXTENSION_NEW_EXT_NAME)
|
133
|
-
true
|
134
|
-
end
|
135
|
-
|
136
|
-
def check_encrypted_require(node, filename)
|
137
|
-
return unless encrypted_extension?
|
138
|
-
return unless extension_file?(filename)
|
139
|
-
|
140
|
-
add_offense(node, location: node.loc.selector,
|
141
|
-
message: MSG_REQUIRE_ENCRYPTED)
|
142
|
-
true
|
143
|
-
end
|
144
|
-
|
145
|
-
def first_directory(path)
|
146
|
-
path.to_s.split(File::SEPARATOR).first.downcase
|
147
|
-
end
|
148
|
-
|
149
|
-
def extension_file?(filename)
|
150
|
-
pathname = Pathname.new(filename).cleanpath
|
151
|
-
return false unless pathname.relative?
|
152
|
-
|
153
|
-
first_directory(extension_directory) == first_directory(pathname)
|
154
|
-
end
|
155
|
-
|
156
|
-
def valid_filename?(filename)
|
157
|
-
File.extname(filename).empty? || TOOLS_RUBY_FILES.include?(filename)
|
158
|
-
end
|
159
|
-
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupRequirements
|
6
|
+
# Omit file extensions when using `Sketchup.require` to allow encrypted
|
7
|
+
# files to be loaded.
|
8
|
+
#
|
9
|
+
# Ruby C extensions, `.so`/`.bundle` libraries must always be loaded via
|
10
|
+
# the normal `require`. Omit the file extension to the libraries as Ruby
|
11
|
+
# will resolve the`.so`/`.bundle` automatically.
|
12
|
+
#
|
13
|
+
# @example Bad - This will fail if extension is encrypted
|
14
|
+
# Sketchup.require 'hello/world.rb'
|
15
|
+
#
|
16
|
+
# @example Good - This will work for `.rbe`, `.rbs` and `rb` files.
|
17
|
+
# Sketchup.require 'hello/world'
|
18
|
+
#
|
19
|
+
# @example Bad - This will fail if extension is encrypted
|
20
|
+
# extension = SketchupExtension.new("Example", "Example/main.rb")
|
21
|
+
#
|
22
|
+
# @example Good - This will work for `.rbe`, `.rbs` and `rb` files.
|
23
|
+
# extension = SketchupExtension.new("Example", "Example/main")
|
24
|
+
class SketchupRequire < SketchUp::Cop
|
25
|
+
|
26
|
+
include SketchUp::ExtensionProject
|
27
|
+
include SketchUp::NoCommentDisable
|
28
|
+
include RangeHelp
|
29
|
+
|
30
|
+
MSG_SKETCHUP_REQUIRE_EXT_NAME = 'Do not hard code file extensions '\
|
31
|
+
'with `Sketchup.require`.'.freeze
|
32
|
+
|
33
|
+
MSG_EXTENSION_NEW_EXT_NAME = 'Do not hard code file extensions '\
|
34
|
+
'with `SketchupExtension.new`.'.freeze
|
35
|
+
|
36
|
+
MSG_REQUIRE_FOR_BINARY = 'Use `require` instead of `Sketchup.require` '\
|
37
|
+
'to load binary Ruby libraries.'.freeze
|
38
|
+
|
39
|
+
MSG_OMIT_BINARY_EXT = 'Do not hard code .so/.bundle file '\
|
40
|
+
'extensions'.freeze
|
41
|
+
|
42
|
+
MSG_REQUIRE_ENCRYPTED = 'Use `Sketchup.require` when loading Ruby '\
|
43
|
+
'files for encrypted extensions.'.freeze
|
44
|
+
|
45
|
+
def_node_matcher :ruby_require, <<-PATTERN
|
46
|
+
(send nil? :require (str $_))
|
47
|
+
PATTERN
|
48
|
+
|
49
|
+
def_node_matcher :ruby_require?, <<-PATTERN
|
50
|
+
(send nil? :require (str _))
|
51
|
+
PATTERN
|
52
|
+
|
53
|
+
|
54
|
+
def_node_matcher :sketchup_require, <<-PATTERN
|
55
|
+
(send (const nil? :Sketchup) :require (str $_))
|
56
|
+
PATTERN
|
57
|
+
|
58
|
+
def_node_matcher :sketchup_require?, <<-PATTERN
|
59
|
+
(send (const nil? :Sketchup) :require (str _))
|
60
|
+
PATTERN
|
61
|
+
|
62
|
+
|
63
|
+
def_node_matcher :sketchup_extension_new, <<-PATTERN
|
64
|
+
(send (const nil? :SketchupExtension) :new _ (str $_))
|
65
|
+
PATTERN
|
66
|
+
|
67
|
+
def_node_matcher :sketchup_extension_new?, <<-PATTERN
|
68
|
+
(send (const nil? :SketchupExtension) :new _ (str _))
|
69
|
+
PATTERN
|
70
|
+
|
71
|
+
|
72
|
+
TOOLS_RUBY_FILES = %w[extensions.rb langhandler.rb sketchup.rb].freeze
|
73
|
+
|
74
|
+
|
75
|
+
def on_send(node)
|
76
|
+
if sketchup_require?(node)
|
77
|
+
filename = sketchup_require(node)
|
78
|
+
return if check_binary_sketchup_require(node, filename)
|
79
|
+
return if check_sketchup_require_filename(node, filename)
|
80
|
+
|
81
|
+
elsif ruby_require?(node)
|
82
|
+
filename = ruby_require(node)
|
83
|
+
return if check_binary_ruby_require(node, filename)
|
84
|
+
return if check_encrypted_require(node, filename)
|
85
|
+
|
86
|
+
elsif sketchup_extension_new?(node)
|
87
|
+
filename = sketchup_extension_new(node)
|
88
|
+
return if check_sketchup_extension_new_filename(node, filename)
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def binary_require?(filename)
|
96
|
+
return unless extension_binaries?
|
97
|
+
return if extension_binaries.empty?
|
98
|
+
|
99
|
+
extension_binaries.include?(filename)
|
100
|
+
end
|
101
|
+
|
102
|
+
def check_binary_sketchup_require(node, filename)
|
103
|
+
return unless binary_require?(filename)
|
104
|
+
|
105
|
+
end_pos = node.loc.dot.end_pos
|
106
|
+
range = node.receiver.loc.expression.with(end_pos: end_pos)
|
107
|
+
add_offense(node, location: range, message: MSG_REQUIRE_FOR_BINARY)
|
108
|
+
true
|
109
|
+
end
|
110
|
+
|
111
|
+
def check_binary_ruby_require(node, filename)
|
112
|
+
ext_name = File.extname(filename)
|
113
|
+
return unless %w[.so .bundle].include?(ext_name)
|
114
|
+
|
115
|
+
add_offense(node, location: file_ext_range(node.arguments.first),
|
116
|
+
message: MSG_OMIT_BINARY_EXT)
|
117
|
+
true
|
118
|
+
end
|
119
|
+
|
120
|
+
def check_sketchup_require_filename(node, filename)
|
121
|
+
return if valid_filename?(filename)
|
122
|
+
|
123
|
+
add_offense(node, location: file_ext_range(node.arguments.first),
|
124
|
+
message: MSG_SKETCHUP_REQUIRE_EXT_NAME)
|
125
|
+
true
|
126
|
+
end
|
127
|
+
|
128
|
+
def check_sketchup_extension_new_filename(node, filename)
|
129
|
+
return if valid_filename?(filename)
|
130
|
+
|
131
|
+
add_offense(node, location: file_ext_range(node.arguments.last),
|
132
|
+
message: MSG_EXTENSION_NEW_EXT_NAME)
|
133
|
+
true
|
134
|
+
end
|
135
|
+
|
136
|
+
def check_encrypted_require(node, filename)
|
137
|
+
return unless encrypted_extension?
|
138
|
+
return unless extension_file?(filename)
|
139
|
+
|
140
|
+
add_offense(node, location: node.loc.selector,
|
141
|
+
message: MSG_REQUIRE_ENCRYPTED)
|
142
|
+
true
|
143
|
+
end
|
144
|
+
|
145
|
+
def first_directory(path)
|
146
|
+
path.to_s.split(File::SEPARATOR).first.downcase
|
147
|
+
end
|
148
|
+
|
149
|
+
def extension_file?(filename)
|
150
|
+
pathname = Pathname.new(filename).cleanpath
|
151
|
+
return false unless pathname.relative?
|
152
|
+
|
153
|
+
first_directory(extension_directory) == first_directory(pathname)
|
154
|
+
end
|
155
|
+
|
156
|
+
def valid_filename?(filename)
|
157
|
+
File.extname(filename).empty? || TOOLS_RUBY_FILES.include?(filename)
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -1,49 +1,49 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module SketchupSuggestions
|
6
|
-
# The idiomatic way to create groups via the Ruby API differ from the
|
7
|
-
# way you'd do it from the UI.
|
8
|
-
#
|
9
|
-
# Using the API you should prefer to create the group first, then add
|
10
|
-
# your geometry into the group. This is more performant and predictable.
|
11
|
-
#
|
12
|
-
# Grouping existing geometry via the API have historically been affected
|
13
|
-
# by bugs and issues.
|
14
|
-
#
|
15
|
-
# If you do have to group existing geometry via the API, make sure you
|
16
|
-
# group geometry from the active context; `model.active_entities`.
|
17
|
-
# Otherwise you might run into unexpected issues, even crashes.
|
18
|
-
#
|
19
|
-
# @example Adding new geometry
|
20
|
-
# # bad
|
21
|
-
# face1 = model.active_entities.add_face(points1)
|
22
|
-
# face2 = model.active_entities.add_face(points2)
|
23
|
-
# group = model.active_entities.add_group([face1, face2])
|
24
|
-
#
|
25
|
-
# # good
|
26
|
-
# group = model.active_entities.add_group
|
27
|
-
# face1 = group.entities.add_face(points1)
|
28
|
-
# face2 = group.entities.add_face(points2)
|
29
|
-
class AddGroup < Cop
|
30
|
-
|
31
|
-
include RangeHelp
|
32
|
-
|
33
|
-
MSG = 'Avoid creating groups out of existing entities.'.freeze
|
34
|
-
|
35
|
-
def_node_matcher :add_group?, <<-PATTERN
|
36
|
-
(send _ :add_group ...)
|
37
|
-
PATTERN
|
38
|
-
|
39
|
-
def on_send(node)
|
40
|
-
return unless add_group?(node)
|
41
|
-
return if node.arguments.empty?
|
42
|
-
|
43
|
-
add_offense(node, location: arguments_range(node))
|
44
|
-
end
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupSuggestions
|
6
|
+
# The idiomatic way to create groups via the Ruby API differ from the
|
7
|
+
# way you'd do it from the UI.
|
8
|
+
#
|
9
|
+
# Using the API you should prefer to create the group first, then add
|
10
|
+
# your geometry into the group. This is more performant and predictable.
|
11
|
+
#
|
12
|
+
# Grouping existing geometry via the API have historically been affected
|
13
|
+
# by bugs and issues.
|
14
|
+
#
|
15
|
+
# If you do have to group existing geometry via the API, make sure you
|
16
|
+
# group geometry from the active context; `model.active_entities`.
|
17
|
+
# Otherwise you might run into unexpected issues, even crashes.
|
18
|
+
#
|
19
|
+
# @example Adding new geometry
|
20
|
+
# # bad
|
21
|
+
# face1 = model.active_entities.add_face(points1)
|
22
|
+
# face2 = model.active_entities.add_face(points2)
|
23
|
+
# group = model.active_entities.add_group([face1, face2])
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# group = model.active_entities.add_group
|
27
|
+
# face1 = group.entities.add_face(points1)
|
28
|
+
# face2 = group.entities.add_face(points2)
|
29
|
+
class AddGroup < Cop
|
30
|
+
|
31
|
+
include RangeHelp
|
32
|
+
|
33
|
+
MSG = 'Avoid creating groups out of existing entities.'.freeze
|
34
|
+
|
35
|
+
def_node_matcher :add_group?, <<-PATTERN
|
36
|
+
(send _ :add_group ...)
|
37
|
+
PATTERN
|
38
|
+
|
39
|
+
def on_send(node)
|
40
|
+
return unless add_group?(node)
|
41
|
+
return if node.arguments.empty?
|
42
|
+
|
43
|
+
add_offense(node, location: arguments_range(node))
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,117 +1,117 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module RuboCop
|
4
|
-
module Cop
|
5
|
-
module SketchupSuggestions
|
6
|
-
# It's easy to lose track of what API feature was added in what version or
|
7
|
-
# SketchUp. You can configure your target SketchUp version and be notified
|
8
|
-
# if you use features introduced in newer versions.
|
9
|
-
#
|
10
|
-
# @example Add this to your .rubocop.yml
|
11
|
-
# AllCops:
|
12
|
-
# SketchUp:
|
13
|
-
# TargetSketchUpVersion: 2016 M1
|
14
|
-
class Compatibility < SketchUp::Cop
|
15
|
-
|
16
|
-
include SketchUp::Features
|
17
|
-
|
18
|
-
MSG = 'Incompatible feature with target SketchUp version'.freeze
|
19
|
-
|
20
|
-
def on_def(node)
|
21
|
-
return unless observer_method?(node)
|
22
|
-
|
23
|
-
feature_name = "##{node.method_name}"
|
24
|
-
check_feature(node, :method, feature_name)
|
25
|
-
end
|
26
|
-
|
27
|
-
def on_send(node)
|
28
|
-
feature_name = ''
|
29
|
-
if module_method?(node)
|
30
|
-
feature_name = "#{node.receiver.const_name}.#{node.method_name}"
|
31
|
-
else
|
32
|
-
# Instance methods are harder. It's difficult to infer the type of
|
33
|
-
# the receiver. If we only check the method name in isolation we
|
34
|
-
# will get too many false positives with method names matching
|
35
|
-
# methods in Ruby itself and other older features.
|
36
|
-
# We try to match names that are unlikely to cause much noise.
|
37
|
-
return unless checkable_instance_method?(node)
|
38
|
-
|
39
|
-
feature_name = "##{node.method_name}"
|
40
|
-
end
|
41
|
-
check_feature(node, :method, feature_name)
|
42
|
-
end
|
43
|
-
|
44
|
-
def on_const(node)
|
45
|
-
feature_name = node.const_name
|
46
|
-
[:class, :module, :constant].each { |type|
|
47
|
-
check_feature(node, type, feature_name)
|
48
|
-
}
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def check_feature(node, type, feature_name)
|
54
|
-
return unless sketchup_target_version?
|
55
|
-
|
56
|
-
full_feature_name = feature_name
|
57
|
-
FEATURES.each { |feature_set|
|
58
|
-
version = feature_set[:version]
|
59
|
-
feature_version = SketchUp::SketchUpVersion.new(version)
|
60
|
-
next unless feature_version > sketchup_target_version
|
61
|
-
|
62
|
-
objects = feature_set[:types][type] || []
|
63
|
-
if type == :method && instance_method?(feature_name)
|
64
|
-
# Instance methods are simply matching the method name since it's
|
65
|
-
# very difficult to determine the type of the receiver.
|
66
|
-
full_feature_name = objects.find { |object|
|
67
|
-
object.end_with?(feature_name)
|
68
|
-
}
|
69
|
-
next unless full_feature_name
|
70
|
-
else
|
71
|
-
next unless objects.include?(feature_name)
|
72
|
-
end
|
73
|
-
report(node, full_feature_name, feature_version, type)
|
74
|
-
}
|
75
|
-
end
|
76
|
-
|
77
|
-
def report(node, feature_name, feature_version, feature_type)
|
78
|
-
message = "The #{feature_type} `#{feature_name}` was added in "\
|
79
|
-
"#{feature_version} which is incompatible with target "\
|
80
|
-
"#{sketchup_target_version}."
|
81
|
-
location = find_node_location(node)
|
82
|
-
add_offense(node, location: location, message: message)
|
83
|
-
end
|
84
|
-
|
85
|
-
def find_node_location(node)
|
86
|
-
# Highlight the most pertinent piece of the expression.
|
87
|
-
if node.const_type?
|
88
|
-
:expression
|
89
|
-
elsif node.send_type?
|
90
|
-
:selector
|
91
|
-
elsif node.def_type?
|
92
|
-
:name
|
93
|
-
else
|
94
|
-
:expression
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def module_method?(node)
|
99
|
-
node.receiver && node.receiver.const_type?
|
100
|
-
end
|
101
|
-
|
102
|
-
def instance_method?(feature_name)
|
103
|
-
feature_name.start_with?('#')
|
104
|
-
end
|
105
|
-
|
106
|
-
def checkable_instance_method?(node)
|
107
|
-
INSTANCE_METHODS.include?(node.method_name)
|
108
|
-
end
|
109
|
-
|
110
|
-
def observer_method?(node)
|
111
|
-
OBSERVER_METHODS.include?(node.method_name)
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupSuggestions
|
6
|
+
# It's easy to lose track of what API feature was added in what version or
|
7
|
+
# SketchUp. You can configure your target SketchUp version and be notified
|
8
|
+
# if you use features introduced in newer versions.
|
9
|
+
#
|
10
|
+
# @example Add this to your .rubocop.yml
|
11
|
+
# AllCops:
|
12
|
+
# SketchUp:
|
13
|
+
# TargetSketchUpVersion: 2016 M1
|
14
|
+
class Compatibility < SketchUp::Cop
|
15
|
+
|
16
|
+
include SketchUp::Features
|
17
|
+
|
18
|
+
MSG = 'Incompatible feature with target SketchUp version'.freeze
|
19
|
+
|
20
|
+
def on_def(node)
|
21
|
+
return unless observer_method?(node)
|
22
|
+
|
23
|
+
feature_name = "##{node.method_name}"
|
24
|
+
check_feature(node, :method, feature_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def on_send(node)
|
28
|
+
feature_name = ''
|
29
|
+
if module_method?(node)
|
30
|
+
feature_name = "#{node.receiver.const_name}.#{node.method_name}"
|
31
|
+
else
|
32
|
+
# Instance methods are harder. It's difficult to infer the type of
|
33
|
+
# the receiver. If we only check the method name in isolation we
|
34
|
+
# will get too many false positives with method names matching
|
35
|
+
# methods in Ruby itself and other older features.
|
36
|
+
# We try to match names that are unlikely to cause much noise.
|
37
|
+
return unless checkable_instance_method?(node)
|
38
|
+
|
39
|
+
feature_name = "##{node.method_name}"
|
40
|
+
end
|
41
|
+
check_feature(node, :method, feature_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def on_const(node)
|
45
|
+
feature_name = node.const_name
|
46
|
+
[:class, :module, :constant].each { |type|
|
47
|
+
check_feature(node, type, feature_name)
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def check_feature(node, type, feature_name)
|
54
|
+
return unless sketchup_target_version?
|
55
|
+
|
56
|
+
full_feature_name = feature_name
|
57
|
+
FEATURES.each { |feature_set|
|
58
|
+
version = feature_set[:version]
|
59
|
+
feature_version = SketchUp::SketchUpVersion.new(version)
|
60
|
+
next unless feature_version > sketchup_target_version
|
61
|
+
|
62
|
+
objects = feature_set[:types][type] || []
|
63
|
+
if type == :method && instance_method?(feature_name)
|
64
|
+
# Instance methods are simply matching the method name since it's
|
65
|
+
# very difficult to determine the type of the receiver.
|
66
|
+
full_feature_name = objects.find { |object|
|
67
|
+
object.end_with?(feature_name)
|
68
|
+
}
|
69
|
+
next unless full_feature_name
|
70
|
+
else
|
71
|
+
next unless objects.include?(feature_name)
|
72
|
+
end
|
73
|
+
report(node, full_feature_name, feature_version, type)
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def report(node, feature_name, feature_version, feature_type)
|
78
|
+
message = "The #{feature_type} `#{feature_name}` was added in "\
|
79
|
+
"#{feature_version} which is incompatible with target "\
|
80
|
+
"#{sketchup_target_version}."
|
81
|
+
location = find_node_location(node)
|
82
|
+
add_offense(node, location: location, message: message)
|
83
|
+
end
|
84
|
+
|
85
|
+
def find_node_location(node)
|
86
|
+
# Highlight the most pertinent piece of the expression.
|
87
|
+
if node.const_type?
|
88
|
+
:expression
|
89
|
+
elsif node.send_type?
|
90
|
+
:selector
|
91
|
+
elsif node.def_type?
|
92
|
+
:name
|
93
|
+
else
|
94
|
+
:expression
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def module_method?(node)
|
99
|
+
node.receiver && node.receiver.const_type?
|
100
|
+
end
|
101
|
+
|
102
|
+
def instance_method?(feature_name)
|
103
|
+
feature_name.start_with?('#')
|
104
|
+
end
|
105
|
+
|
106
|
+
def checkable_instance_method?(node)
|
107
|
+
INSTANCE_METHODS.include?(node.method_name)
|
108
|
+
end
|
109
|
+
|
110
|
+
def observer_method?(node)
|
111
|
+
OBSERVER_METHODS.include?(node.method_name)
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|