rubocop-sketchup 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem 'rake', '~> 10.0', require: false
7
+ gem 'rspec', '~> 3.4', require: false
8
+ end
@@ -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