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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +7 -1
  3. data/assets/logo.png +0 -0
  4. data/assets/output.html.erb +301 -0
  5. data/config/default.yml +141 -36
  6. data/lib/rubocop/sketchup/config.rb +28 -8
  7. data/lib/rubocop/sketchup/cop/deprecations/add_separator_to_menu.rb +4 -1
  8. data/lib/rubocop/sketchup/cop/deprecations/operation_next_transparent.rb +11 -2
  9. data/lib/rubocop/sketchup/cop/deprecations/require_all.rb +7 -2
  10. data/lib/rubocop/sketchup/cop/deprecations/set_texture_projection.rb +6 -2
  11. data/lib/rubocop/sketchup/cop/deprecations/show_ruby_panel.rb +4 -1
  12. data/lib/rubocop/sketchup/cop/deprecations/sketchup_set.rb +8 -0
  13. data/lib/rubocop/sketchup/cop/performance/openssl.rb +5 -3
  14. data/lib/rubocop/sketchup/cop/performance/operation_disable_ui.rb +10 -2
  15. data/lib/rubocop/sketchup/cop/performance/selection_bulk.rb +11 -4
  16. data/lib/rubocop/sketchup/cop/performance/type_check.rb +63 -0
  17. data/lib/rubocop/sketchup/cop/performance/typename.rb +6 -1
  18. data/lib/rubocop/sketchup/cop/requirements/api_namespace.rb +8 -2
  19. data/lib/rubocop/sketchup/cop/requirements/exit.rb +7 -3
  20. data/lib/rubocop/sketchup/cop/requirements/extension_namespace.rb +32 -2
  21. data/lib/rubocop/sketchup/cop/requirements/file_structure.rb +22 -10
  22. data/lib/rubocop/sketchup/cop/requirements/gem_install.rb +45 -0
  23. data/lib/rubocop/sketchup/cop/requirements/get_extension_license.rb +95 -0
  24. data/lib/rubocop/sketchup/cop/requirements/global_constants.rb +10 -1
  25. data/lib/rubocop/sketchup/cop/requirements/global_include.rb +9 -2
  26. data/lib/rubocop/sketchup/cop/requirements/global_methods.rb +10 -1
  27. data/lib/rubocop/sketchup/cop/requirements/global_variables.rb +13 -4
  28. data/lib/rubocop/sketchup/cop/requirements/language_handler_globals.rb +6 -4
  29. data/lib/rubocop/sketchup/cop/requirements/load_path.rb +9 -6
  30. data/lib/rubocop/sketchup/cop/requirements/minimal_registration.rb +26 -2
  31. data/lib/rubocop/sketchup/cop/requirements/observers_start_operation.rb +28 -2
  32. data/lib/rubocop/sketchup/cop/requirements/register_extension.rb +12 -2
  33. data/lib/rubocop/sketchup/cop/requirements/ruby_core_namespace.rb +14 -8
  34. data/lib/rubocop/sketchup/cop/requirements/ruby_stdlib_namespace.rb +594 -588
  35. data/lib/rubocop/sketchup/cop/requirements/shipped_extensions_namespace.rb +6 -6
  36. data/lib/rubocop/sketchup/cop/requirements/sketchup_extension.rb +28 -9
  37. data/lib/rubocop/sketchup/cop/requirements/sketchup_require.rb +163 -0
  38. data/lib/rubocop/sketchup/cop/suggestions/add_group.rb +49 -0
  39. data/lib/rubocop/sketchup/cop/suggestions/compatibility.rb +35 -6
  40. data/lib/rubocop/sketchup/cop/suggestions/dc_internals.rb +6 -3
  41. data/lib/rubocop/sketchup/cop/suggestions/file_encoding.rb +3 -0
  42. data/lib/rubocop/sketchup/cop/suggestions/model_entities.rb +9 -2
  43. data/lib/rubocop/sketchup/cop/suggestions/monkey_patched_api.rb +5 -1
  44. data/lib/rubocop/sketchup/cop/suggestions/operation_name.rb +20 -9
  45. data/lib/rubocop/sketchup/cop/suggestions/sketchup_find_support_file.rb +13 -2
  46. data/lib/rubocop/sketchup/cop/suggestions/tool_drawing_bounds.rb +44 -0
  47. data/lib/rubocop/sketchup/cop/suggestions/tool_invalidate.rb +66 -0
  48. data/lib/rubocop/sketchup/cop/suggestions/tool_user_input.rb +41 -0
  49. data/lib/rubocop/sketchup/cop/suggestions/toolbar_timer.rb +65 -0
  50. data/lib/rubocop/sketchup/cop.rb +38 -18
  51. data/lib/rubocop/sketchup/dc_globals.rb +1 -1
  52. data/lib/rubocop/sketchup/dc_methods.rb +27 -27
  53. data/lib/rubocop/sketchup/extension_project.rb +19 -2
  54. data/lib/rubocop/sketchup/formatter/extension_review.rb +35 -15
  55. data/lib/rubocop/sketchup/inject.rb +1 -1
  56. data/lib/rubocop/sketchup/namespace.rb +1 -0
  57. data/lib/rubocop/sketchup/namespace_checker.rb +4 -1
  58. data/lib/rubocop/sketchup/no_comment_disable.rb +1 -1
  59. data/lib/rubocop/sketchup/range_help.rb +52 -0
  60. data/lib/rubocop/sketchup/sketchup_version.rb +4 -2
  61. data/lib/rubocop/sketchup/tool_checker.rb +43 -0
  62. data/lib/rubocop/sketchup/version.rb +1 -1
  63. data/lib/rubocop/sketchup.rb +1 -1
  64. data/lib/rubocop-sketchup.rb +9 -0
  65. data/rubocop-sketchup.gemspec +8 -11
  66. metadata +18 -6
  67. 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
@@ -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
- !(department_exclude_pattern =~ file)
78
+ !sketchup_excluded?(file)
62
79
  end
63
80
 
64
- def department_exclude_pattern
65
- if department_exclude_config?
66
- patterns = department_exclude_config.map(&Regexp.public_method(:new))
67
- Regexp.union(patterns)
68
- else
69
- DEFAULT_CONFIGURATION
70
- .fetch(department_name)
71
- .fetch('Exclude')
72
- .map(&Regexp.public_method(:new))
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 department_exclude_config?
77
- return false unless all_cops_config.key?('SketchUp')
78
- sketchup_config = all_cops_config.fetch('SketchUp')
79
- return false unless sketchup_config.key?(department_name)
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 department_exclude_config
104
+ def sketchup_exclude_pattern
84
105
  sketchup_cops_config
85
- .fetch(department_name)
86
- .fetch('Exclude')
106
+ .fetch('Exclude', [])
87
107
  end
88
108
 
89
109
  end
@@ -11,7 +11,7 @@ module RuboCop
11
11
  $dc_REPORTER_NAME
12
12
  $dc_MANAGER_NAME
13
13
  $dc_observers
14
- ]
14
+ ].freeze
15
15
 
16
16
  private
17
17
 
@@ -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(sketchup_source_path_config)
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.downcase == '.rb' &&
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
- File.expand_path('../../../../../assets/output.html.erb', __FILE__)
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(0xED, 0x9C, 0x28, 1.0),
75
- convention: Color.new(0xED, 0x9C, 0x28, 1.0),
76
- warning: Color.new(0x96, 0x28, 0xEF, 1.0),
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
- File.expand_path('../../../../../assets/logo.png', __FILE__)
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
- n = SORT_ORDER.index(a_department) <=> SORT_ORDER.index(b_department)
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.gsub(/`(.+?)`/) do
191
- "<code>#{Regexp.last_match(1)}</code>"
192
- end
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(s)
229
- CGI.escapeHTML(s)
248
+ def escape(string)
249
+ CGI.escapeHTML(string)
230
250
  end
231
251
 
232
252
  def base64_encoded_logo_image
@@ -16,4 +16,4 @@ module RuboCop
16
16
  end
17
17
  end
18
18
  end
19
- end
19
+ end
@@ -11,6 +11,7 @@ module RuboCop
11
11
  # @param [String] namespace
12
12
  def initialize(namespace)
13
13
  raise TypeError unless namespace.is_a?(String)
14
+
14
15
  @namespace = namespace
15
16
  end
16
17
 
@@ -23,13 +23,16 @@ module RuboCop
23
23
  end
24
24
 
25
25
  def check_namespace(node)
26
- add_offense(node, location: :name, severity: :error) if in_namespace?(node)
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
@@ -8,7 +8,7 @@ module RuboCop
8
8
 
9
9
  # This forces the cop to be run even if there is a source code comment
10
10
  # that tries to disable it.
11
- def enabled_line?(line_number)
11
+ def enabled_line?(_line_number)
12
12
  true
13
13
  end
14
14
 
@@ -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, m = [version, 0]
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