platformos-check 0.4.6 → 0.4.7
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/CHANGELOG.md +5 -0
- data/config/default.yml +4 -0
- data/docs/checks/form_action.md +1 -1
- data/docs/checks/form_authenticity_token.md +1 -1
- data/docs/checks/unreachable_code.md +66 -0
- data/lib/platformos_check/checks/unreachable_code.rb +114 -0
- data/lib/platformos_check/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aebbd738b1045c874460b7f1de2cf2774297f36136fce816521dda29ce371652
|
4
|
+
data.tar.gz: c348e3afc68f2a664fe1ad313d41497ad7c977f8de72f3b82df9dda297926c38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 368d39315a05ab34eff3797012af56775ca9a5ff4d8209ed0c44aa2916f97fe5740afa859bbfbbdf34409aa40967efe4236b2394eafcdecfc313c97f62a4dba7
|
7
|
+
data.tar.gz: f912bda1de7e0be84e887ab2f19cde9072e03468ea52265f910e20ff5a7317b7f7f4e6fe83aef690350f21543ffbd495e01c72eddca5c393acfc5500055d6939
|
data/CHANGELOG.md
CHANGED
data/config/default.yml
CHANGED
data/docs/checks/form_action.md
CHANGED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Unreachable code (`UnreachableCode`)
|
2
|
+
|
3
|
+
Unreachable code reports code that will never be reached, no matter what.
|
4
|
+
|
5
|
+
## Check Details
|
6
|
+
|
7
|
+
This check is aimed at ensuring you will not accidentally write code that will never be reached.
|
8
|
+
|
9
|
+
:-1: Examples of **incorrect** code for this check:
|
10
|
+
|
11
|
+
```liquid
|
12
|
+
assign x = "hello"
|
13
|
+
break
|
14
|
+
log x
|
15
|
+
```
|
16
|
+
|
17
|
+
```liquid
|
18
|
+
if x
|
19
|
+
log x
|
20
|
+
else
|
21
|
+
break
|
22
|
+
log "Stop"
|
23
|
+
endif
|
24
|
+
```
|
25
|
+
|
26
|
+
:+1: Examples of **correct** code for this check:
|
27
|
+
|
28
|
+
```liquid
|
29
|
+
assign x = "hello"
|
30
|
+
log x
|
31
|
+
break
|
32
|
+
```
|
33
|
+
|
34
|
+
```liquid
|
35
|
+
if x
|
36
|
+
log x
|
37
|
+
else
|
38
|
+
log "Stop"
|
39
|
+
break
|
40
|
+
endif
|
41
|
+
```
|
42
|
+
|
43
|
+
## Check Options
|
44
|
+
|
45
|
+
The default configuration for this check is the following:
|
46
|
+
|
47
|
+
```yaml
|
48
|
+
UnreachableCode:
|
49
|
+
enabled: true
|
50
|
+
```
|
51
|
+
|
52
|
+
## When Not To Use It
|
53
|
+
|
54
|
+
There should be no cases where disabling this rule is needed.
|
55
|
+
|
56
|
+
## Version
|
57
|
+
|
58
|
+
This check has been introduced in PlatformOS Check 0.4.7.
|
59
|
+
|
60
|
+
## Resources
|
61
|
+
|
62
|
+
- [Rule Source][codesource]
|
63
|
+
- [Documentation Source][docsource]
|
64
|
+
|
65
|
+
[codesource]: /lib/platformos_check/checks/unreachable_code.rb
|
66
|
+
[docsource]: /docs/checks/unreachable_code.md
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PlatformosCheck
|
4
|
+
# Recommends using {% liquid ... %} if 5 or more consecutive {% ... %} are found.
|
5
|
+
class UnreachableCode < LiquidCheck
|
6
|
+
severity :error
|
7
|
+
category :liquid
|
8
|
+
doc docs_url(__FILE__)
|
9
|
+
|
10
|
+
FLOW_COMMAND = %i[break continue return]
|
11
|
+
CONDITION_TYPES = Set.new(%i[condition else_condition])
|
12
|
+
INCLUDE_FLOW_COMMAND = %w[break]
|
13
|
+
|
14
|
+
def on_document(node)
|
15
|
+
@processed_files = {}
|
16
|
+
check_unreachable_code(node.children)
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def check_unreachable_code(nodes)
|
22
|
+
nodes = sanitize_children(nodes)
|
23
|
+
nodes.each_cons(2) do |node1, _node2|
|
24
|
+
next unless flow_expression?(node1)
|
25
|
+
|
26
|
+
add_offense("Unreachable code after `#{node1.type_name}`", node: node1)
|
27
|
+
end
|
28
|
+
flow_expression?(nodes.last)
|
29
|
+
end
|
30
|
+
|
31
|
+
def sanitize_children(children)
|
32
|
+
children.reject { |c| c.value.is_a?(String) && c.value.strip == '' }
|
33
|
+
end
|
34
|
+
|
35
|
+
def flow_expression?(node)
|
36
|
+
return false if node.nil?
|
37
|
+
return true if flow_command?(node)
|
38
|
+
|
39
|
+
case node.type_name
|
40
|
+
when :if, :unless
|
41
|
+
check_if(node)
|
42
|
+
false
|
43
|
+
when :for
|
44
|
+
check_for(node)
|
45
|
+
false
|
46
|
+
when :case
|
47
|
+
check_case(node)
|
48
|
+
false
|
49
|
+
when :try_rc, :try
|
50
|
+
check_try(node)
|
51
|
+
false
|
52
|
+
when :block_body
|
53
|
+
node.children.any? { |c| flow_expression?(c) }
|
54
|
+
else
|
55
|
+
false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def check_if(node)
|
60
|
+
node.children.each do |condition|
|
61
|
+
check_unreachable_code(condition.children.detect(&:block_body?).children)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def check_for(node)
|
66
|
+
check_unreachable_code(node.children.detect(&:block_body?).children)
|
67
|
+
end
|
68
|
+
|
69
|
+
def check_case(node)
|
70
|
+
node.children.each do |condition|
|
71
|
+
next unless CONDITION_TYPES.include?(condition.type_name)
|
72
|
+
|
73
|
+
check_unreachable_code(condition.children.detect(&:block_body?).children)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def check_try(node)
|
78
|
+
node.children.each do |block_body|
|
79
|
+
check_unreachable_code(block_body.children)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def flow_command?(node)
|
84
|
+
return true if FLOW_COMMAND.include?(node.type_name)
|
85
|
+
|
86
|
+
return evaluate_include(node.value.template_name_expr) if node.type_name == :include && node.value.template_name_expr.is_a?(String)
|
87
|
+
|
88
|
+
false
|
89
|
+
end
|
90
|
+
|
91
|
+
def evaluate_include(path)
|
92
|
+
return false unless path.is_a?(String)
|
93
|
+
|
94
|
+
@processed_files[path] ||= include_node_contains_flow_command?(@platformos_app.grouped_files[PlatformosCheck::PartialFile][path]&.parse&.root)
|
95
|
+
@processed_files[path]
|
96
|
+
end
|
97
|
+
|
98
|
+
def include_node_contains_flow_command?(root)
|
99
|
+
return false if root.nil?
|
100
|
+
|
101
|
+
root.nodelist.any? do |node|
|
102
|
+
if INCLUDE_FLOW_COMMAND.include?(node.respond_to?(:tag_name) && node.tag_name)
|
103
|
+
true
|
104
|
+
elsif node.respond_to?(:nodelist) && node.nodelist
|
105
|
+
include_node_contains_flow_command?(node)
|
106
|
+
elsif node.respond_to?(:tag_name) && node.tag_name == 'include' && node.template_name_expr.is_a?(String)
|
107
|
+
evaluate_include(node.template_name_expr)
|
108
|
+
else
|
109
|
+
false
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: platformos-check
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Bliszczyk
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-12-
|
13
|
+
date: 2023-12-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: graphql
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- docs/checks/template_length.md
|
135
135
|
- docs/checks/undefined_object.md
|
136
136
|
- docs/checks/unknown_filter.md
|
137
|
+
- docs/checks/unreachable_code.md
|
137
138
|
- docs/checks/unused_assign.md
|
138
139
|
- docs/checks/unused_partial.md
|
139
140
|
- docs/checks/valid_yaml.md
|
@@ -178,6 +179,7 @@ files:
|
|
178
179
|
- lib/platformos_check/checks/template_length.rb
|
179
180
|
- lib/platformos_check/checks/undefined_object.rb
|
180
181
|
- lib/platformos_check/checks/unknown_filter.rb
|
182
|
+
- lib/platformos_check/checks/unreachable_code.rb
|
181
183
|
- lib/platformos_check/checks/unused_assign.rb
|
182
184
|
- lib/platformos_check/checks/unused_partial.rb
|
183
185
|
- lib/platformos_check/checks/valid_yaml.rb
|