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
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupSuggestions
|
6
|
+
# After having drawn to the viewport from a tool, make sure to invalidate
|
7
|
+
# the view on `deactivate` and `suspend`.
|
8
|
+
#
|
9
|
+
# If you don't do that the things you drew might stick around for longer
|
10
|
+
# than the life-span of the tool and cause confusion for the user.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # good
|
14
|
+
# class ExampleTool
|
15
|
+
#
|
16
|
+
# def deactivate(view)
|
17
|
+
# view_invalidate
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def suspend(view)
|
21
|
+
# view_invalidate
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def draw(view)
|
25
|
+
# view.draw(GL_LINES, @points)
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# end
|
29
|
+
class ToolInvalidate < Cop
|
30
|
+
|
31
|
+
include SketchUp::ToolChecker
|
32
|
+
|
33
|
+
MSG_MISSING_INVALIDATE_METHOD = 'When drawing to the viewport, make '\
|
34
|
+
'sure to `suspend` and `deactivate` calls `view.invalidate`.'.freeze
|
35
|
+
|
36
|
+
MSG_MISSING_INVALIDATE = 'When drawing to the viewport, make sure to '\
|
37
|
+
'call `view.invalidate` when the tool becomes inactive.'.freeze
|
38
|
+
|
39
|
+
def_node_search :view_invalidate?, <<-PATTERN
|
40
|
+
(send (lvar :view) :invalidate ...)
|
41
|
+
PATTERN
|
42
|
+
|
43
|
+
def on_tool_class(class_node, body_methods)
|
44
|
+
return unless find_method(body_methods, :draw)
|
45
|
+
|
46
|
+
check_method_invalidate(:deactivate, body_methods, class_node)
|
47
|
+
check_method_invalidate(:suspend, body_methods, class_node)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def check_method_invalidate(method_name, body_methods, class_node)
|
53
|
+
method_node = find_method(body_methods, method_name)
|
54
|
+
if method_node
|
55
|
+
return if view_invalidate?(method_node)
|
56
|
+
|
57
|
+
add_offense(method_node, message: MSG_MISSING_INVALIDATE)
|
58
|
+
else
|
59
|
+
add_offense(class_node, message: MSG_MISSING_INVALIDATE_METHOD)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupSuggestions
|
6
|
+
# When a tool takes user input via `onUserText`, make sure to define
|
7
|
+
# `enableVCB?` so that the VCB is enabled.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # good
|
11
|
+
# class ExampleTool
|
12
|
+
#
|
13
|
+
# def enableVCB?
|
14
|
+
# true
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# def onUserText(text, view)
|
18
|
+
# # ...
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# end
|
22
|
+
class ToolUserInput < Cop
|
23
|
+
|
24
|
+
include SketchUp::ToolChecker
|
25
|
+
|
26
|
+
MSG_MISSING_ENABLE_VCB = 'When accepting user input, make sure to '\
|
27
|
+
'define `enableVCB?`.'.freeze
|
28
|
+
|
29
|
+
def on_tool_class(class_node, body_methods)
|
30
|
+
return unless find_method(body_methods, :onUserText)
|
31
|
+
|
32
|
+
method_node = find_method(body_methods, :enableVCB?)
|
33
|
+
return if method_node
|
34
|
+
|
35
|
+
add_offense(class_node, message: MSG_MISSING_ENABLE_VCB)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupSuggestions
|
6
|
+
# Wrapping `toolbar.restore` in `UI.start_timer` is redundant. It was a
|
7
|
+
# workaround for an issue in a very old version of SketchUp. There is no
|
8
|
+
# need to still be using this workaround.
|
9
|
+
#
|
10
|
+
# @example Creating a new toolbar
|
11
|
+
# # bad
|
12
|
+
# toolbar = UI::Toolbar.new('Example')
|
13
|
+
# # ...
|
14
|
+
# toolbar.restore
|
15
|
+
# UI.start_timer(0.1, false) {
|
16
|
+
# toolbar.restore
|
17
|
+
# }
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# toolbar = UI::Toolbar.new('Example')
|
21
|
+
# # ...
|
22
|
+
# toolbar.restore
|
23
|
+
class ToolbarTimer < Cop
|
24
|
+
|
25
|
+
include RangeHelp
|
26
|
+
|
27
|
+
MSG = 'Wrapping `toolbar.restore` in `UI.start_timer` is '\
|
28
|
+
'redundant.'.freeze
|
29
|
+
|
30
|
+
def_node_matcher :toolbar_new?, <<-PATTERN
|
31
|
+
(send (const (const nil? :UI) :Toolbar) :new _)
|
32
|
+
PATTERN
|
33
|
+
|
34
|
+
def_node_search :ui_start_timer_restore, <<-PATTERN
|
35
|
+
(block
|
36
|
+
(send
|
37
|
+
(const nil? :UI) :start_timer
|
38
|
+
(float _)
|
39
|
+
(false))
|
40
|
+
(args)
|
41
|
+
(send
|
42
|
+
$_ :restore))
|
43
|
+
PATTERN
|
44
|
+
|
45
|
+
def on_send(node)
|
46
|
+
return unless toolbar_new?(node)
|
47
|
+
return unless node.parent.assignment?
|
48
|
+
|
49
|
+
assignment_node = node.parent
|
50
|
+
toolbar_variable_name = assignment_node.children.first
|
51
|
+
|
52
|
+
receiver = ui_start_timer_restore(assignment_node.parent).first
|
53
|
+
return unless receiver && receiver.variable?
|
54
|
+
|
55
|
+
receiver_variable_name = receiver.children.first
|
56
|
+
|
57
|
+
return unless receiver_variable_name == toolbar_variable_name
|
58
|
+
|
59
|
+
add_offense(receiver.parent)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/rubocop/sketchup/cop.rb
CHANGED
@@ -53,37 +53,57 @@ module RuboCop
|
|
53
53
|
|
54
54
|
private
|
55
55
|
|
56
|
+
def default_severity
|
57
|
+
sketchup_severity || super
|
58
|
+
end
|
59
|
+
|
60
|
+
def sketchup_severity
|
61
|
+
case self.class.department
|
62
|
+
when :SketchupRequirements
|
63
|
+
:error
|
64
|
+
when :SketchupDeprecations
|
65
|
+
:warning
|
66
|
+
when :SketchupPerformance
|
67
|
+
:warning
|
68
|
+
when :SketchupSuggestions
|
69
|
+
:convention
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
56
73
|
def department_name
|
57
74
|
self.class.department.to_s
|
58
75
|
end
|
59
76
|
|
60
77
|
def relevant_rubocop_sketchup_file?(file)
|
61
|
-
!(
|
78
|
+
!sketchup_excluded?(file)
|
62
79
|
end
|
63
80
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
81
|
+
def sketchup_excluded?(file)
|
82
|
+
matches_file?(file, sketchup_exclude_pattern) ||
|
83
|
+
matches_file?(file, sketchup_department_exclude_pattern)
|
84
|
+
end
|
85
|
+
|
86
|
+
def matches_file?(file, patterns)
|
87
|
+
path = nil
|
88
|
+
patterns.any? do |pattern|
|
89
|
+
# Try to match the absolute path, as Exclude properties are absolute.
|
90
|
+
next true if match_path?(pattern, file)
|
91
|
+
|
92
|
+
# Try with relative path.
|
93
|
+
path ||= config.path_relative_to_config(file)
|
94
|
+
match_path?(pattern, path)
|
73
95
|
end
|
74
96
|
end
|
75
97
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
sketchup_config.fetch(department_name).key?('Exclude')
|
98
|
+
def sketchup_department_exclude_pattern
|
99
|
+
sketchup_cops_config
|
100
|
+
.fetch(department_name, {})
|
101
|
+
.fetch('Exclude', [])
|
81
102
|
end
|
82
103
|
|
83
|
-
def
|
104
|
+
def sketchup_exclude_pattern
|
84
105
|
sketchup_cops_config
|
85
|
-
.fetch(
|
86
|
-
.fetch('Exclude')
|
106
|
+
.fetch('Exclude', [])
|
87
107
|
end
|
88
108
|
|
89
109
|
end
|
@@ -7,123 +7,123 @@ module RuboCop
|
|
7
7
|
DC_METHODS = [
|
8
8
|
{
|
9
9
|
name: :rotx,
|
10
|
-
path: 'Geom::Transformation'
|
10
|
+
path: 'Geom::Transformation',
|
11
11
|
},
|
12
12
|
{
|
13
13
|
name: :roty,
|
14
|
-
path: 'Geom::Transformation'
|
14
|
+
path: 'Geom::Transformation',
|
15
15
|
},
|
16
16
|
{
|
17
17
|
name: :rotz,
|
18
|
-
path: 'Geom::Transformation'
|
18
|
+
path: 'Geom::Transformation',
|
19
19
|
},
|
20
20
|
{
|
21
21
|
name: :xscale,
|
22
|
-
path: 'Geom::Transformation'
|
22
|
+
path: 'Geom::Transformation',
|
23
23
|
},
|
24
24
|
{
|
25
25
|
name: :yscale,
|
26
|
-
path: 'Geom::Transformation'
|
26
|
+
path: 'Geom::Transformation',
|
27
27
|
},
|
28
28
|
{
|
29
29
|
name: :zscale,
|
30
|
-
path: 'Geom::Transformation'
|
30
|
+
path: 'Geom::Transformation',
|
31
31
|
},
|
32
32
|
|
33
33
|
{
|
34
34
|
name: :copy,
|
35
35
|
path: 'Sketchup::Camera',
|
36
|
-
variables: [:camera, :cam]
|
36
|
+
variables: [:camera, :cam],
|
37
37
|
},
|
38
38
|
{
|
39
39
|
name: :update,
|
40
40
|
path: 'Sketchup::Camera',
|
41
|
-
variables: [:camera, :cam]
|
41
|
+
variables: [:camera, :cam],
|
42
42
|
},
|
43
43
|
{
|
44
44
|
name: :same_camera_params?,
|
45
|
-
path: 'Sketchup::Camera'
|
45
|
+
path: 'Sketchup::Camera',
|
46
46
|
},
|
47
47
|
|
48
48
|
{
|
49
49
|
name: :copy,
|
50
50
|
path: 'Sketchup::ComponentInstance',
|
51
|
-
variables: [:instance, :inst]
|
51
|
+
variables: [:instance, :inst],
|
52
52
|
},
|
53
53
|
{
|
54
54
|
name: :description,
|
55
55
|
path: 'Sketchup::ComponentInstance',
|
56
|
-
variables: [:instance, :inst]
|
56
|
+
variables: [:instance, :inst],
|
57
57
|
},
|
58
58
|
|
59
59
|
{
|
60
60
|
name: :local_transformation,
|
61
|
-
path: 'Sketchup::Drawingelement'
|
61
|
+
path: 'Sketchup::Drawingelement',
|
62
62
|
},
|
63
63
|
{
|
64
64
|
name: :scaled_size,
|
65
|
-
path: 'Sketchup::Drawingelement'
|
65
|
+
path: 'Sketchup::Drawingelement',
|
66
66
|
},
|
67
67
|
{
|
68
68
|
name: :unscaled_size,
|
69
|
-
path: 'Sketchup::Drawingelement'
|
69
|
+
path: 'Sketchup::Drawingelement',
|
70
70
|
},
|
71
71
|
{
|
72
72
|
name: :set_last_size,
|
73
|
-
path: 'Sketchup::Drawingelement'
|
73
|
+
path: 'Sketchup::Drawingelement',
|
74
74
|
},
|
75
75
|
{
|
76
76
|
name: :last_scaling_factors,
|
77
|
-
path: 'Sketchup::Drawingelement'
|
77
|
+
path: 'Sketchup::Drawingelement',
|
78
78
|
},
|
79
79
|
|
80
80
|
{
|
81
81
|
name: :get_attributes,
|
82
|
-
path: 'Sketchup::Entity'
|
82
|
+
path: 'Sketchup::Entity',
|
83
83
|
},
|
84
84
|
{
|
85
85
|
name: :has_attributes?,
|
86
|
-
path: 'Sketchup::Entity'
|
86
|
+
path: 'Sketchup::Entity',
|
87
87
|
},
|
88
88
|
|
89
89
|
{
|
90
90
|
name: :typename,
|
91
91
|
path: 'Sketchup::Model',
|
92
|
-
variables: [:model, :mod]
|
92
|
+
variables: [:model, :mod],
|
93
93
|
},
|
94
94
|
{
|
95
95
|
name: :entityID,
|
96
96
|
path: 'Sketchup::Model',
|
97
|
-
variables: [:model, :mod]
|
97
|
+
variables: [:model, :mod],
|
98
98
|
},
|
99
99
|
{
|
100
100
|
name: :delete_attribute,
|
101
101
|
path: 'Sketchup::Model',
|
102
|
-
variables: [:model, :mod]
|
102
|
+
variables: [:model, :mod],
|
103
103
|
},
|
104
104
|
{
|
105
105
|
name: :layer,
|
106
106
|
path: 'Sketchup::Model',
|
107
|
-
variables: [:model, :mod]
|
107
|
+
variables: [:model, :mod],
|
108
108
|
},
|
109
109
|
|
110
110
|
{
|
111
111
|
name: :last_width=,
|
112
|
-
path: 'UI::WebDialog'
|
112
|
+
path: 'UI::WebDialog',
|
113
113
|
},
|
114
114
|
{
|
115
115
|
name: :last_height=,
|
116
|
-
path: 'UI::WebDialog'
|
116
|
+
path: 'UI::WebDialog',
|
117
117
|
},
|
118
118
|
{
|
119
119
|
name: :last_width,
|
120
|
-
path: 'UI::WebDialog'
|
120
|
+
path: 'UI::WebDialog',
|
121
121
|
},
|
122
122
|
{
|
123
123
|
name: :last_height,
|
124
|
-
path: 'UI::WebDialog'
|
124
|
+
path: 'UI::WebDialog',
|
125
125
|
},
|
126
|
-
]
|
126
|
+
].freeze
|
127
127
|
|
128
128
|
end
|
129
129
|
end
|
@@ -20,7 +20,7 @@ module RuboCop
|
|
20
20
|
|
21
21
|
# @return [Pathname]
|
22
22
|
def relative_source_path
|
23
|
-
Pathname.new(
|
23
|
+
Pathname.new(extension_source_path_config)
|
24
24
|
end
|
25
25
|
|
26
26
|
# @return [Pathname]
|
@@ -39,10 +39,27 @@ module RuboCop
|
|
39
39
|
# @param [RuboCop::ProcessedSource] processed_source
|
40
40
|
def root_file?(processed_source)
|
41
41
|
filename = path_relative_to_source(processed_source)
|
42
|
-
filename.extname.
|
42
|
+
filename.extname.casecmp('.rb').zero? &&
|
43
43
|
filename.parent.to_s == '.'
|
44
44
|
end
|
45
45
|
|
46
|
+
def extension_root_files
|
47
|
+
Dir.glob("#{source_path}/*.rb").map { |path| Pathname.new(path) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def extension_root_file
|
51
|
+
unless extension_root_files.size == 1
|
52
|
+
num_files = extension_root_files.size
|
53
|
+
raise "More than one root extension file (#{num_files})"
|
54
|
+
end
|
55
|
+
|
56
|
+
extension_root_files.first
|
57
|
+
end
|
58
|
+
|
59
|
+
def extension_directory
|
60
|
+
extension_root_file.dirname
|
61
|
+
end
|
62
|
+
|
46
63
|
end
|
47
64
|
end
|
48
65
|
end
|
@@ -12,7 +12,7 @@ module RuboCop
|
|
12
12
|
class ExtensionReviewFormatter < BaseFormatter
|
13
13
|
ELLIPSES = '<span class="extra-code">...</span>'.freeze
|
14
14
|
TEMPLATE_PATH =
|
15
|
-
|
15
|
+
File.expand_path('../../../../assets/output.html.erb', __dir__)
|
16
16
|
|
17
17
|
Color = Struct.new(:red, :green, :blue, :alpha) do
|
18
18
|
def to_s
|
@@ -42,11 +42,14 @@ module RuboCop
|
|
42
42
|
def file_finished(file, offenses)
|
43
43
|
files << file
|
44
44
|
offenses.each { |offense|
|
45
|
+
# Report only SketchUp related cops.
|
46
|
+
next unless offense.cop_name.start_with?('Sketchup')
|
47
|
+
|
45
48
|
report = OpenStruct.new(path: file, offense: offense)
|
46
49
|
categories[offense.cop_name] ||= []
|
47
50
|
categories[offense.cop_name] << report
|
51
|
+
summary.offense_count += 1
|
48
52
|
}
|
49
|
-
summary.offense_count += offenses.count
|
50
53
|
end
|
51
54
|
|
52
55
|
def finished(inspected_files)
|
@@ -71,22 +74,22 @@ module RuboCop
|
|
71
74
|
include TextUtil
|
72
75
|
|
73
76
|
SEVERITY_COLORS = {
|
74
|
-
refactor: Color.new(
|
75
|
-
convention: Color.new(
|
76
|
-
warning: Color.new(
|
77
|
+
refactor: Color.new(0x29, 0x6B, 0xF0, 1.0),
|
78
|
+
convention: Color.new(0x29, 0x6B, 0xF0, 1.0),
|
79
|
+
warning: Color.new(0xED, 0x9C, 0x28, 1.0),
|
77
80
|
error: Color.new(0xD2, 0x32, 0x2D, 1.0),
|
78
|
-
fatal: Color.new(0xD2, 0x32, 0x2D, 1.0)
|
81
|
+
fatal: Color.new(0xD2, 0x32, 0x2D, 1.0),
|
79
82
|
}.freeze
|
80
83
|
|
81
84
|
LOGO_IMAGE_PATH =
|
82
|
-
|
85
|
+
File.expand_path('../../../../assets/logo.png', __dir__)
|
83
86
|
|
84
87
|
SORT_ORDER = %w[
|
85
88
|
SketchupRequirements
|
86
89
|
SketchupDeprecations
|
87
90
|
SketchupPerformance
|
88
91
|
SketchupSuggestions
|
89
|
-
]
|
92
|
+
].freeze
|
90
93
|
|
91
94
|
DEPARTMENT_DESCRIPTIONS = {
|
92
95
|
'SketchupRequirements' => <<-DESCRIPTION,
|
@@ -125,7 +128,7 @@ module RuboCop
|
|
125
128
|
This department is not a requirement for submission to
|
126
129
|
Extension Warehouse.
|
127
130
|
DESCRIPTION
|
128
|
-
}
|
131
|
+
}.freeze
|
129
132
|
|
130
133
|
attr_reader :categories, :files, :summary
|
131
134
|
|
@@ -150,6 +153,7 @@ module RuboCop
|
|
150
153
|
count = 0
|
151
154
|
categories.each { |category, offenses|
|
152
155
|
next unless department(category) == dep
|
156
|
+
|
153
157
|
count += offenses.size
|
154
158
|
}
|
155
159
|
count
|
@@ -176,7 +180,18 @@ module RuboCop
|
|
176
180
|
# Then sort by cop name.
|
177
181
|
a_department, a_name = a[0].split('/')
|
178
182
|
b_department, b_name = b[0].split('/')
|
179
|
-
|
183
|
+
# Sort SketchUp cops at the top, then all the rest comes after.
|
184
|
+
# First sorting by department.
|
185
|
+
sort_order_a = SORT_ORDER.index(a_department)
|
186
|
+
sort_order_b = SORT_ORDER.index(b_department)
|
187
|
+
if sort_order_a.nil? && sort_order_b.nil?
|
188
|
+
n = a_department <=> b_department
|
189
|
+
else
|
190
|
+
sort_order_a ||= SORT_ORDER.size
|
191
|
+
sort_order_b ||= SORT_ORDER.size
|
192
|
+
n = sort_order_a <=> sort_order_b
|
193
|
+
end
|
194
|
+
# Them sort by name if departments match.
|
180
195
|
n == 0 ? a_name <=> b_name : n
|
181
196
|
}.to_h
|
182
197
|
end
|
@@ -187,9 +202,14 @@ module RuboCop
|
|
187
202
|
end
|
188
203
|
|
189
204
|
def decorated_message(offense)
|
190
|
-
offense.message
|
191
|
-
|
192
|
-
|
205
|
+
offense.message
|
206
|
+
.gsub(/`(.+?)`/) do
|
207
|
+
"<code>#{Regexp.last_match(1)}</code>"
|
208
|
+
end
|
209
|
+
.gsub(/\((http[^ ]+)\)/) do
|
210
|
+
url = Regexp.last_match(1)
|
211
|
+
"<br><a href=\"#{url}\">#{url}</a>"
|
212
|
+
end
|
193
213
|
end
|
194
214
|
|
195
215
|
def highlighted_source_line(offense)
|
@@ -225,8 +245,8 @@ module RuboCop
|
|
225
245
|
"offense_#{title}"
|
226
246
|
end
|
227
247
|
|
228
|
-
def escape(
|
229
|
-
CGI.escapeHTML(
|
248
|
+
def escape(string)
|
249
|
+
CGI.escapeHTML(string)
|
230
250
|
end
|
231
251
|
|
232
252
|
def base64_encoded_logo_image
|
@@ -23,13 +23,16 @@ module RuboCop
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def check_namespace(node)
|
26
|
-
|
26
|
+
return unless in_namespace?(node)
|
27
|
+
|
28
|
+
add_offense(node, location: :name, severity: :error)
|
27
29
|
end
|
28
30
|
|
29
31
|
def in_namespace?(node)
|
30
32
|
# parent_module_name might return nil if for instance a method is
|
31
33
|
# defined within a block. (Apparently that is possible...)
|
32
34
|
return false if node.parent_module_name.nil?
|
35
|
+
|
33
36
|
namespace = SketchUp::Namespace.new(node.parent_module_name)
|
34
37
|
namespaces.include?(namespace.first)
|
35
38
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# Methods that calculate and return Parser::Source::Ranges
|
6
|
+
module RangeHelp
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def range_with_receiver(node)
|
11
|
+
receiver = node.receiver
|
12
|
+
loc_begin = if receiver.send_type?
|
13
|
+
receiver.loc.selector.begin_pos
|
14
|
+
else
|
15
|
+
receiver.loc.expression.begin_pos
|
16
|
+
end
|
17
|
+
loc_end = node.loc.selector.end_pos
|
18
|
+
range_between(loc_begin, loc_end)
|
19
|
+
end
|
20
|
+
|
21
|
+
def string_contents_range(node)
|
22
|
+
begin_pos = node.loc.begin.end_pos
|
23
|
+
end_pos = node.loc.end.begin_pos
|
24
|
+
range_between(begin_pos, end_pos)
|
25
|
+
end
|
26
|
+
|
27
|
+
def arguments_range(node)
|
28
|
+
begin_pos = node.arguments.first.loc.expression.begin_pos
|
29
|
+
end_pos = node.arguments.last.loc.expression.end_pos
|
30
|
+
range_between(begin_pos, end_pos)
|
31
|
+
end
|
32
|
+
|
33
|
+
def conditional_range(node)
|
34
|
+
if node.modifier_form?
|
35
|
+
range_between(node.loc.keyword.begin_pos,
|
36
|
+
node.loc.expression.end_pos)
|
37
|
+
else
|
38
|
+
:expression
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def file_ext_range(argument_node)
|
43
|
+
filename = argument_node.str_content
|
44
|
+
ext_size = File.extname(filename).size
|
45
|
+
end_pos = argument_node.loc.end.begin_pos
|
46
|
+
begin_pos = end_pos - ext_size
|
47
|
+
range_between(begin_pos, end_pos)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -57,7 +57,7 @@ module RuboCop
|
|
57
57
|
[7.0, 1],
|
58
58
|
[7.0, 0],
|
59
59
|
[6.0, 0],
|
60
|
-
]
|
60
|
+
].freeze
|
61
61
|
|
62
62
|
def parse_version(version)
|
63
63
|
v = 0
|
@@ -71,12 +71,14 @@ module RuboCop
|
|
71
71
|
m = (result.captures[1] || '0').to_i
|
72
72
|
end
|
73
73
|
elsif version.is_a?(Numeric)
|
74
|
-
v
|
74
|
+
v = version
|
75
|
+
m = 0
|
75
76
|
end
|
76
77
|
version_parts = [v, m]
|
77
78
|
unless VALID_VERSIONS.include?(version_parts)
|
78
79
|
raise InvalidVersion, "#{version} is not a valid SketchUp version"
|
79
80
|
end
|
81
|
+
|
80
82
|
version_parts
|
81
83
|
end
|
82
84
|
|