rubocop-sketchup 0.0.1
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 +7 -0
- data/Gemfile +8 -0
- data/lib/rubocop-sketchup.rb +12 -0
- data/lib/rubocop/sketchup/deprecations/operation_next_transparent.rb +21 -0
- data/lib/rubocop/sketchup/namespace.rb +47 -0
- data/lib/rubocop/sketchup/namespace_checker.rb +43 -0
- data/lib/rubocop/sketchup/no_comment_disable.rb +17 -0
- data/lib/rubocop/sketchup/performance/operation_disable_ui.rb +25 -0
- data/lib/rubocop/sketchup/performance/typename.rb +19 -0
- data/lib/rubocop/sketchup/requirements/api_namespace.rb +24 -0
- data/lib/rubocop/sketchup/requirements/extension_namespace.rb +64 -0
- data/lib/rubocop/sketchup/requirements/global_constants.rb +22 -0
- data/lib/rubocop/sketchup/requirements/global_methods.rb +53 -0
- data/lib/rubocop/sketchup/requirements/global_variables.rb +67 -0
- data/lib/rubocop/sketchup/requirements/load_path.rb +80 -0
- data/lib/rubocop/sketchup/requirements/ruby_core_namespace.rb +285 -0
- data/lib/rubocop/sketchup/requirements/ruby_stdlib_namespace.rb +628 -0
- data/lib/rubocop/sketchup/suggestions/model_entities.rb +33 -0
- data/lib/rubocop/sketchup/suggestions/operation_name.rb +32 -0
- data/lib/rubocop/sketchup/version.rb +5 -0
- data/rubocop-sketchup.gemspec +27 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fba3184334c70efb554cf67e75f076c52364e70e
|
4
|
+
data.tar.gz: f6e53f835f85a1a6a431901a0a4b9ee734a205df
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e3f65b200bc51f212498cfd5fde5d311e3b0279f92c44832d60a5ceb2d54828bd423c0aa4e24abdc3abc8ccdd10d890d2df38cefb9c399cf8a486248b16d62fc
|
7
|
+
data.tar.gz: 6ed3c4b0f7203e628108d688a4ee5a11e2be2c40abb6e1d4e4dfd67e9c3464aeb5df893876aa4b288cdc0c7faca2f7e9dd8c516c833971382fc0cef87d20bf67
|
data/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubocop'
|
2
|
+
require 'rubocop/sketchup/version'
|
3
|
+
|
4
|
+
require 'rubocop/sketchup/namespace'
|
5
|
+
require 'rubocop/sketchup/namespace_checker'
|
6
|
+
require 'rubocop/sketchup/no_comment_disable'
|
7
|
+
|
8
|
+
# Load all custom cops.
|
9
|
+
pattern = File.join(__dir__, 'rubocop', 'sketchup', '**/*rb')
|
10
|
+
Dir.glob(pattern) { |file|
|
11
|
+
require file
|
12
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupDeprecations
|
6
|
+
# Weak warning. (Question?)
|
7
|
+
class OperationNextTransparent < Cop
|
8
|
+
MSG = 'Third argument is deprecated.'.freeze
|
9
|
+
|
10
|
+
def on_send(node)
|
11
|
+
_, method_name, *args = *node
|
12
|
+
return unless method_name == :start_operation
|
13
|
+
return if args.size < 3
|
14
|
+
argument = args[2]
|
15
|
+
next_transparent = argument.type == :true
|
16
|
+
add_offense(argument, :expression) if next_transparent
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchUp
|
6
|
+
class Namespace
|
7
|
+
|
8
|
+
attr_reader :namespace
|
9
|
+
|
10
|
+
SEPARATOR = '::'.freeze
|
11
|
+
|
12
|
+
# @param [String] namespace
|
13
|
+
def initialize(namespace)
|
14
|
+
@namespace = namespace
|
15
|
+
end
|
16
|
+
|
17
|
+
# Get the first component of a namespace relative to Object.
|
18
|
+
# May return 'Object' if the namespace is in the global namespace.
|
19
|
+
def first
|
20
|
+
parts.find { |name| name != 'Object' } || 'Object'
|
21
|
+
end
|
22
|
+
|
23
|
+
# Get a namespace string that is relative to Object.
|
24
|
+
def from_root
|
25
|
+
items = parts
|
26
|
+
items.shift if items.size > 1 && items.first == 'Object'
|
27
|
+
items.join(SEPARATOR)
|
28
|
+
end
|
29
|
+
|
30
|
+
def join(other)
|
31
|
+
self.class.new("#{@namespace}#{SEPARATOR}#{other}")
|
32
|
+
end
|
33
|
+
|
34
|
+
# Get the first component of a namespace relative to Object.
|
35
|
+
# May return 'Object' if the namespace is in the global namespace.
|
36
|
+
def parts
|
37
|
+
namespace.split(SEPARATOR)
|
38
|
+
end
|
39
|
+
|
40
|
+
def top_level?
|
41
|
+
parts.last == 'Object'
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sketchup
|
6
|
+
module NamespaceChecker
|
7
|
+
|
8
|
+
include OnMethodDef
|
9
|
+
|
10
|
+
def on_class(node)
|
11
|
+
check_namespace(node)
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_module(node)
|
15
|
+
check_namespace(node)
|
16
|
+
end
|
17
|
+
|
18
|
+
def on_method_def(node, method_name, _args, _body)
|
19
|
+
check_namespace(node)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Constant assignment.
|
23
|
+
def on_casgn(node)
|
24
|
+
check_namespace(node)
|
25
|
+
end
|
26
|
+
|
27
|
+
def check_namespace(node)
|
28
|
+
add_offense(node, :name, nil, :error) if in_namespace?(node)
|
29
|
+
end
|
30
|
+
|
31
|
+
def in_namespace?(node)
|
32
|
+
namespace = SketchUp::Namespace.new(node.parent_module_name)
|
33
|
+
namespaces.include?(namespace.first)
|
34
|
+
end
|
35
|
+
|
36
|
+
def namespaces
|
37
|
+
raise NotImplementedError
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module NoCommentDisable
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
# This forces the cop to be run even if there is a source code comment
|
10
|
+
# that tries to disable it.
|
11
|
+
def enabled_line?(line_number)
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupPerformance
|
6
|
+
# Weak warning. (Question?)
|
7
|
+
class OperationDisableUI < Cop
|
8
|
+
MSG = 'Operations should disable the UI for performance gain.'.freeze
|
9
|
+
|
10
|
+
def on_send(node)
|
11
|
+
_, method_name, *args = *node
|
12
|
+
return unless method_name == :start_operation
|
13
|
+
if args.size < 2
|
14
|
+
add_offense(node, :expression)
|
15
|
+
return
|
16
|
+
end
|
17
|
+
argument = args[1]
|
18
|
+
disable_ui = argument.children.first
|
19
|
+
return if disable_ui
|
20
|
+
add_offense(argument, :expression)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupPerformance
|
6
|
+
class Typename < Cop
|
7
|
+
MSG = '.typename is very slow, prefer .is_a? instead.'.freeze
|
8
|
+
|
9
|
+
def on_send(node)
|
10
|
+
_, method_name = *node
|
11
|
+
return unless method_name == :typename
|
12
|
+
# TODO(thomthom): Should we try to detect use of #typename
|
13
|
+
# in context of comparing against a string?
|
14
|
+
add_offense(node, :expression)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupRequirements
|
6
|
+
class ApiNamespace < Cop
|
7
|
+
|
8
|
+
include NoCommentDisable
|
9
|
+
include Sketchup::NamespaceChecker
|
10
|
+
|
11
|
+
MSG = 'Do not modify the SketchUp API.'.freeze
|
12
|
+
|
13
|
+
NAMESPACES = %w(
|
14
|
+
Geom Layout Sketchup SketchupExtension UI
|
15
|
+
).freeze
|
16
|
+
|
17
|
+
def namespaces
|
18
|
+
NAMESPACES
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubocop/sketchup/requirements/api_namespace'
|
4
|
+
require 'rubocop/sketchup/requirements/ruby_core_namespace'
|
5
|
+
require 'rubocop/sketchup/requirements/ruby_stdlib_namespace'
|
6
|
+
|
7
|
+
module RuboCop
|
8
|
+
module Cop
|
9
|
+
module SketchupRequirements
|
10
|
+
class ExtensionNamespace < Cop
|
11
|
+
|
12
|
+
include NoCommentDisable
|
13
|
+
include SketchUp
|
14
|
+
|
15
|
+
def on_class(node)
|
16
|
+
check_class_or_module(node)
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_module(node)
|
20
|
+
check_class_or_module(node)
|
21
|
+
end
|
22
|
+
|
23
|
+
def check_class_or_module(node)
|
24
|
+
name = node.defined_module_name
|
25
|
+
parent = Namespace.new(node.parent_module_name)
|
26
|
+
# Don't want to process anything that aren't top level namespaces.
|
27
|
+
return unless parent.top_level?
|
28
|
+
check_namespace(node, parent.join(name))
|
29
|
+
end
|
30
|
+
|
31
|
+
# Class variables are normally frowned upon since they leak through all
|
32
|
+
# instances. However, in this case this is exactly what we want.
|
33
|
+
# The Cop picks up the first top level namespace it encounters and then
|
34
|
+
# keep track of whether it detects more top level namespaces.
|
35
|
+
@@namespace = nil
|
36
|
+
def check_namespace(node, namespace)
|
37
|
+
# Make sure the namespace isn't part of reserved namespaces that other
|
38
|
+
# cops are checking.
|
39
|
+
return if reserved?(namespace)
|
40
|
+
# Remember the first namespace encountered and log an offence if
|
41
|
+
# more top level namespaces are registered.
|
42
|
+
top = namespace.first
|
43
|
+
@@namespace ||= top
|
44
|
+
return if @@namespace == top
|
45
|
+
add_offense(node, :name, nil, :error)
|
46
|
+
end
|
47
|
+
|
48
|
+
def reserved?(namespace)
|
49
|
+
top = namespace.first
|
50
|
+
return true if RubyCoreNamespace::NAMESPACES.include?(top)
|
51
|
+
return true if RubyStdLibNamespace::NAMESPACES.include?(top)
|
52
|
+
return true if ApiNamespace::NAMESPACES.include?(top)
|
53
|
+
false
|
54
|
+
end
|
55
|
+
|
56
|
+
def message(node)
|
57
|
+
namespace = Namespace.new(node.defined_module_name).from_root
|
58
|
+
format('Use a single root namespace. (Found %s; Previously found %s)', namespace, @@namespace)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupRequirements
|
6
|
+
class GlobalConstants < Cop
|
7
|
+
|
8
|
+
include NoCommentDisable
|
9
|
+
include SketchUp
|
10
|
+
|
11
|
+
MSG = 'Do not introduce global constants.'.freeze
|
12
|
+
|
13
|
+
# Constant assignment.
|
14
|
+
def on_casgn(node)
|
15
|
+
namespace = Namespace.new(node.parent_module_name)
|
16
|
+
add_offense(node, :name, nil, :error) if namespace.top_level?
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupRequirements
|
6
|
+
class GlobalMethods < Cop
|
7
|
+
|
8
|
+
include NoCommentDisable
|
9
|
+
include OnMethodDef
|
10
|
+
include SketchUp
|
11
|
+
|
12
|
+
MSG = 'Do not introduce global methods.'.freeze
|
13
|
+
|
14
|
+
# Reference: http://www.rubydoc.info/gems/rubocop/RuboCop/NodePattern
|
15
|
+
#
|
16
|
+
# Matchers for methods defined with this syntax:
|
17
|
+
#
|
18
|
+
# def Example.foo
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# def (Example::Foo).bar
|
22
|
+
# end
|
23
|
+
|
24
|
+
def_node_matcher :class_method?, <<-PATTERN
|
25
|
+
(defs
|
26
|
+
(const _ _) ...
|
27
|
+
)
|
28
|
+
PATTERN
|
29
|
+
|
30
|
+
def_node_matcher :class_method, <<-PATTERN
|
31
|
+
(defs
|
32
|
+
{
|
33
|
+
(const nil $_)
|
34
|
+
(const (const nil $_) ...)
|
35
|
+
}
|
36
|
+
...
|
37
|
+
)
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
def on_method_def(node, method_name, _args, _body)
|
41
|
+
class_method_parent = class_method(node)
|
42
|
+
if class_method_parent
|
43
|
+
namespace = Namespace.new(class_method_parent.to_s)
|
44
|
+
else
|
45
|
+
namespace = Namespace.new(node.parent_module_name)
|
46
|
+
end
|
47
|
+
add_offense(node, :name, nil, :error) if namespace.top_level?
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module SketchupRequirements
|
6
|
+
# This cops looks for uses of global variables.
|
7
|
+
# It does not report offenses for built-in global variables.
|
8
|
+
# Built-in global variables are allowed by default. Additionally
|
9
|
+
# users can allow additional variables via the AllowedVariables option.
|
10
|
+
#
|
11
|
+
# Note that backreferences like $1, $2, etc are not global variables.
|
12
|
+
class GlobalVariables < Cop
|
13
|
+
include NoCommentDisable
|
14
|
+
MSG = 'Do not introduce global variables.'.freeze
|
15
|
+
|
16
|
+
# predefined global variables their English aliases
|
17
|
+
# http://www.zenspider.com/Languages/Ruby/QuickRef.html
|
18
|
+
BUILT_IN_VARS = %w(
|
19
|
+
$: $LOAD_PATH
|
20
|
+
$" $LOADED_FEATURES
|
21
|
+
$0 $PROGRAM_NAME
|
22
|
+
$! $ERROR_INFO
|
23
|
+
$@ $ERROR_POSITION
|
24
|
+
$; $FS $FIELD_SEPARATOR
|
25
|
+
$, $OFS $OUTPUT_FIELD_SEPARATOR
|
26
|
+
$/ $RS $INPUT_RECORD_SEPARATOR
|
27
|
+
$\\ $ORS $OUTPUT_RECORD_SEPARATOR
|
28
|
+
$. $NR $INPUT_LINE_NUMBER
|
29
|
+
$_ $LAST_READ_LINE
|
30
|
+
$> $DEFAULT_OUTPUT
|
31
|
+
$< $DEFAULT_INPUT
|
32
|
+
$$ $PID $PROCESS_ID
|
33
|
+
$? $CHILD_STATUS
|
34
|
+
$~ $LAST_MATCH_INFO
|
35
|
+
$= $IGNORECASE
|
36
|
+
$* $ARGV
|
37
|
+
$& $MATCH
|
38
|
+
$` $PREMATCH
|
39
|
+
$' $POSTMATCH
|
40
|
+
$+ $LAST_PAREN_MATCH
|
41
|
+
$stdin $stdout $stderr
|
42
|
+
$DEBUG $FILENAME $VERBOSE $SAFE
|
43
|
+
$-0 $-a $-d $-F $-i $-I $-l $-p $-v $-w
|
44
|
+
$CLASSPATH $JRUBY_VERSION $JRUBY_REVISION $ENV_JAVA
|
45
|
+
).map(&:to_sym)
|
46
|
+
|
47
|
+
def allowed_var?(global_var)
|
48
|
+
BUILT_IN_VARS.include?(global_var)
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_gvar(node)
|
52
|
+
check(node)
|
53
|
+
end
|
54
|
+
|
55
|
+
def on_gvasgn(node)
|
56
|
+
check(node)
|
57
|
+
end
|
58
|
+
|
59
|
+
def check(node)
|
60
|
+
global_var, = *node
|
61
|
+
|
62
|
+
add_offense(node, :name, nil, :error) unless allowed_var?(global_var)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|