haml_lint 0.74.0 → 0.75.0
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/config/default.yml +2 -2
- data/config/forced_rubocop_config.yml +13 -13
- data/lib/haml_lint/document.rb +3 -3
- data/lib/haml_lint/exceptions.rb +2 -2
- data/lib/haml_lint/extensions/haml_util_unescape_interpolation_tracking.rb +2 -2
- data/lib/haml_lint/haml_visitor.rb +1 -1
- data/lib/haml_lint/lint.rb +1 -1
- data/lib/haml_lint/linter/rubocop.rb +6 -6
- data/lib/haml_lint/linter/ruby_comments.rb +1 -1
- data/lib/haml_lint/linter/space_before_script.rb +1 -1
- data/lib/haml_lint/linter/unescaped_html.rb +1 -1
- data/lib/haml_lint/linter/unnecessary_string_output.rb +3 -3
- data/lib/haml_lint/linter.rb +2 -2
- data/lib/haml_lint/node_transformer.rb +2 -2
- data/lib/haml_lint/ruby_extraction/base_chunk.rb +3 -3
- data/lib/haml_lint/ruby_extraction/chunk_extractor.rb +11 -11
- data/lib/haml_lint/ruby_extraction/coordinator.rb +2 -2
- data/lib/haml_lint/ruby_extraction/implicit_end_chunk.rb +1 -1
- data/lib/haml_lint/ruby_extraction/non_ruby_filter_chunk.rb +1 -1
- data/lib/haml_lint/ruby_extraction/placeholder_marker_chunk.rb +1 -1
- data/lib/haml_lint/ruby_extraction/script_chunk.rb +1 -1
- data/lib/haml_lint/runner.rb +15 -1
- data/lib/haml_lint/spec/matchers/report_lint.rb +2 -2
- data/lib/haml_lint/tree/comment_node.rb +1 -1
- data/lib/haml_lint/tree/doctype_node.rb +1 -1
- data/lib/haml_lint/tree/filter_node.rb +1 -1
- data/lib/haml_lint/tree/haml_comment_node.rb +2 -2
- data/lib/haml_lint/tree/node.rb +3 -3
- data/lib/haml_lint/tree/root_node.rb +2 -2
- data/lib/haml_lint/tree/silent_script_node.rb +1 -1
- data/lib/haml_lint/tree/tag_node.rb +2 -2
- data/lib/haml_lint/utils.rb +1 -1
- data/lib/haml_lint/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8bb347cd92b5e23b37b8beb59d2c67f23eecd1e5778fdc45a7c4fbd73d14f854
|
|
4
|
+
data.tar.gz: 93836aaa95ab3bde6932969c81fb9e409c9806ab9057a1162580e1771f1edff7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c5789d9ca6de3d2cae48ef91277b374ed84b477323389ccc7049d1d4e690ef1cb2252781074c902c7b82fa9dd332a36ace0d25652723841e170c89c9c805e15
|
|
7
|
+
data.tar.gz: 325df8db407db7567bf88db824dc2a071af3457c827b5268e96e6e2e17f0a63b6192974082ed8e4bab9ca0b645aacfbec981d7a25e6e9e7330d28f8c60df2123
|
data/config/default.yml
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# This is an opinionated list of which hooks are valuable to run and what their
|
|
4
4
|
# out of the box settings should be.
|
|
5
5
|
|
|
6
|
-
# Whether to ignore frontmatter at the beginning of
|
|
6
|
+
# Whether to ignore frontmatter at the beginning of Haml documents for
|
|
7
7
|
# frameworks such as Jekyll/Middleman
|
|
8
8
|
skip_frontmatter: false
|
|
9
9
|
|
|
@@ -89,7 +89,7 @@ linters:
|
|
|
89
89
|
RuboCop:
|
|
90
90
|
enabled: true
|
|
91
91
|
# Cops listed here are skipped entirely (passed to RuboCop via `--except`), both when
|
|
92
|
-
# reporting and when auto-correcting. This is the way to disable a cop only for
|
|
92
|
+
# reporting and when auto-correcting. This is the way to disable a cop only for Haml files,
|
|
93
93
|
# and the only way to disable a forced cop (see config/forced_rubocop_config.yml), since the
|
|
94
94
|
# forced configuration always overrides `Enabled: false` set in your own .rubocop.yml.
|
|
95
95
|
ignored_cops: []
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# These are some configurations that are required for RuboCop because:
|
|
2
|
-
# *
|
|
3
|
-
#
|
|
4
|
-
# *
|
|
2
|
+
# * Haml-Lint compiles ruby code with a particular format. If the rules mis-match that format,
|
|
3
|
+
# Haml-Lint would generate lints that the user cannot fix.
|
|
4
|
+
# * Haml-Lint can autocorrect code only if the result matches some specific format
|
|
5
5
|
#
|
|
6
6
|
# So these configuration should not be overwritable by users.
|
|
7
7
|
|
|
@@ -31,17 +31,17 @@ Layout/CaseIndentation:
|
|
|
31
31
|
IndentOneStep: false # Need to force the `false`
|
|
32
32
|
|
|
33
33
|
# Need this cop so that code gets formatted similarly to Haml's indentation,
|
|
34
|
-
# since
|
|
34
|
+
# since Haml-Lint relies on Ruby's indentation being the same as Haml's.
|
|
35
35
|
Layout/ElseAlignment:
|
|
36
36
|
Enabled: true
|
|
37
37
|
|
|
38
38
|
# Need this cop so that code gets formatted similarly to Haml's indentation,
|
|
39
|
-
# since
|
|
39
|
+
# since Haml-Lint relies on Ruby's indentation being the same as Haml's.
|
|
40
40
|
Layout/EndAlignment:
|
|
41
41
|
EnforcedStyleAlignWith: start_of_line
|
|
42
42
|
Enabled: true
|
|
43
43
|
|
|
44
|
-
# We generate the ruby content, this is basically useless and should be a lint in
|
|
44
|
+
# We generate the ruby content, this is basically useless and should be a lint in Haml-Lint
|
|
45
45
|
Layout/EndOfLine:
|
|
46
46
|
Enabled: false
|
|
47
47
|
|
|
@@ -90,14 +90,14 @@ Metrics/BlockNesting:
|
|
|
90
90
|
Naming/FileName:
|
|
91
91
|
Enabled: false
|
|
92
92
|
|
|
93
|
-
#
|
|
93
|
+
# Haml doesn't properly support multiline blocks using { }, only using do/end.
|
|
94
94
|
# If you don't consider the { } block for indentation, things "works", but the indentation is misleading.
|
|
95
95
|
# For example, this works:
|
|
96
96
|
# - a = lambda {
|
|
97
97
|
# - if abc
|
|
98
98
|
# - something
|
|
99
99
|
# - }
|
|
100
|
-
# But if you indented the 2 lines within { }, then
|
|
100
|
+
# But if you indented the 2 lines within { }, then Haml would add an extra `end` and the generated
|
|
101
101
|
# ruby would be invalid.
|
|
102
102
|
Style/BlockDelimiters:
|
|
103
103
|
# So we need this cop to cleanup those cases and turn them to `end`.
|
|
@@ -106,7 +106,7 @@ Style/BlockDelimiters:
|
|
|
106
106
|
# We don't allow the default "Can be anything" exception for lambda/proc
|
|
107
107
|
<%= rubocop_version < '1.33' ? 'IgnoredMethods' : 'AllowedMethods' %>: []
|
|
108
108
|
|
|
109
|
-
# We don't support correcting
|
|
109
|
+
# We don't support correcting Haml comments
|
|
110
110
|
Style/CommentAnnotation:
|
|
111
111
|
AutoCorrect: false
|
|
112
112
|
|
|
@@ -144,7 +144,7 @@ Style/RedundantStringEscape:
|
|
|
144
144
|
<% end %>
|
|
145
145
|
|
|
146
146
|
# In some case, this cop can cause a change in the spacing.
|
|
147
|
-
# In
|
|
147
|
+
# In Haml 5.2, going from (absurd example for clarity):
|
|
148
148
|
# = 'abc' rescue nil
|
|
149
149
|
# = 'def'
|
|
150
150
|
# to:
|
|
@@ -161,7 +161,7 @@ Style/RescueModifier:
|
|
|
161
161
|
|
|
162
162
|
# Cops that remove commas can be a problem when lines are split on multiple ones.
|
|
163
163
|
# If we have a big array on more than one line, the removal of the comma generates
|
|
164
|
-
# invalid
|
|
164
|
+
# invalid Haml
|
|
165
165
|
Style/SymbolArray:
|
|
166
166
|
Enabled: false
|
|
167
167
|
|
|
@@ -170,7 +170,7 @@ Style/UnlessElse:
|
|
|
170
170
|
AutoCorrect: false
|
|
171
171
|
|
|
172
172
|
# If an array of strings was on multiple lines, this cop will make a %w(...) on multiple lines.
|
|
173
|
-
# Without the comma at the end of the first line, there the resulting
|
|
173
|
+
# Without the comma at the end of the first line, there the resulting Haml will be invalid, since the only
|
|
174
174
|
# case where a script can change line is after a comma.
|
|
175
175
|
Style/WordArray:
|
|
176
176
|
AutoCorrect: false
|
|
@@ -181,7 +181,7 @@ Layout/TrailingEmptyLines:
|
|
|
181
181
|
|
|
182
182
|
<% if rubocop_version < '1.8.1' %>
|
|
183
183
|
# There were a few bugs with this cop that got fixed in this version.
|
|
184
|
-
# Before, those bugs would generate invalid Ruby code and that would make it look like
|
|
184
|
+
# Before, those bugs would generate invalid Ruby code and that would make it look like Haml-lint is
|
|
185
185
|
# responsible, at least from the user's point of view.
|
|
186
186
|
Style/StringConcatenation:
|
|
187
187
|
Enabled: false
|
data/lib/haml_lint/document.rb
CHANGED
|
@@ -132,8 +132,8 @@ module HamlLint
|
|
|
132
132
|
# @param original_tree [Haml::Parser::ParseNode]
|
|
133
133
|
# @return [Haml::Tree::Node]
|
|
134
134
|
def process_tree(original_tree)
|
|
135
|
-
# Remove the trailing empty
|
|
136
|
-
# the end of the
|
|
135
|
+
# Remove the trailing empty Haml comment that the parser creates to signal
|
|
136
|
+
# the end of the Haml document
|
|
137
137
|
if Gem::Requirement.new('~> 4.0.0').satisfied_by?(Gem.loaded_specs['haml'].version)
|
|
138
138
|
original_tree.children.pop
|
|
139
139
|
end
|
|
@@ -142,7 +142,7 @@ module HamlLint
|
|
|
142
142
|
convert_tree(original_tree)
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
# Converts a
|
|
145
|
+
# Converts a Haml parse tree to a tree of {HamlLint::Tree::Node} objects.
|
|
146
146
|
#
|
|
147
147
|
# This provides a cleaner interface with which the linters can interact with
|
|
148
148
|
# the parse tree.
|
data/lib/haml_lint/exceptions.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Collection of exceptions that can be raised by the
|
|
3
|
+
# Collection of exceptions that can be raised by the Haml Lint application.
|
|
4
4
|
module HamlLint::Exceptions
|
|
5
5
|
# Raised when a {Configuration} could not be loaded from a file.
|
|
6
6
|
class ConfigurationError < StandardError; end
|
|
@@ -17,7 +17,7 @@ module HamlLint::Exceptions
|
|
|
17
17
|
# Raised when an invalid file path is specified
|
|
18
18
|
class InvalidFilePath < StandardError; end
|
|
19
19
|
|
|
20
|
-
# Raised when a problem occurs parsing a
|
|
20
|
+
# Raised when a problem occurs parsing a Haml document.
|
|
21
21
|
class ParseError < ::Haml::SyntaxError; end
|
|
22
22
|
|
|
23
23
|
# Raised when attempting to execute `Runner` with options that would result in
|
|
@@ -14,8 +14,8 @@ module Haml::Util
|
|
|
14
14
|
Thread.current[:haml_lint_unescape_interpolation_to_original_cache] ||= {}
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
# As soon as a HamlLint::Document has finished processing a
|
|
18
|
-
# get a copy of this cache and clear up for the next
|
|
17
|
+
# As soon as a HamlLint::Document has finished processing a Haml source, this gets called to
|
|
18
|
+
# get a copy of this cache and clear up for the next Haml processing
|
|
19
19
|
def self.unescape_interpolation_to_original_cache_take_and_wipe
|
|
20
20
|
value = unescape_interpolation_to_original_cache.dup
|
|
21
21
|
unescape_interpolation_to_original_cache.clear
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module HamlLint
|
|
4
4
|
# Provides an interface which when included allows a class to visit nodes in
|
|
5
|
-
# the parse tree of a
|
|
5
|
+
# the parse tree of a Haml document.
|
|
6
6
|
module HamlVisitor
|
|
7
7
|
def visit(node)
|
|
8
8
|
# Keep track of whether this block was consumed by the visitor. This
|
data/lib/haml_lint/lint.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module HamlLint
|
|
4
|
-
# Contains information about a problem or issue with a
|
|
4
|
+
# Contains information about a problem or issue with a Haml document.
|
|
5
5
|
class Lint
|
|
6
6
|
# @return [Boolean] If the error was corrected by auto-correct
|
|
7
7
|
attr_reader :corrected
|
|
@@ -4,14 +4,14 @@ require 'rubocop'
|
|
|
4
4
|
require 'tempfile'
|
|
5
5
|
|
|
6
6
|
module HamlLint
|
|
7
|
-
# Runs RuboCop on the Ruby code contained within
|
|
7
|
+
# Runs RuboCop on the Ruby code contained within Haml templates.
|
|
8
8
|
#
|
|
9
9
|
# The processing is done by extracting a Ruby file that matches the content, including
|
|
10
|
-
# the indentation, of the
|
|
11
|
-
# and get new Ruby code which should be
|
|
10
|
+
# the indentation, of the Haml file. This way, we can run RuboCop with autocorrect
|
|
11
|
+
# and get new Ruby code which should be Haml compatible.
|
|
12
12
|
#
|
|
13
|
-
# The ruby extraction makes "Chunks" which wrap each
|
|
14
|
-
# use the corrected Ruby code to apply the corrections back in the
|
|
13
|
+
# The ruby extraction makes "Chunks" which wrap each Haml constructs. The Chunks can then
|
|
14
|
+
# use the corrected Ruby code to apply the corrections back in the Haml using logic specific
|
|
15
15
|
# to each type of Chunk.
|
|
16
16
|
#
|
|
17
17
|
# The work is spread across the classes in the HamlLint::RubyExtraction module.
|
|
@@ -24,7 +24,7 @@ module HamlLint
|
|
|
24
24
|
@offenses = []
|
|
25
25
|
@config_store.instance_variable_set(:@options_config, config)
|
|
26
26
|
# Using stdin also disables RuboCop's result cache, which is intentional:
|
|
27
|
-
# it reconstructs offense positions from the on-disk
|
|
27
|
+
# it reconstructs offense positions from the on-disk Haml, not the Ruby we
|
|
28
28
|
# inspected, so reusing it misreports lines (sds/haml-lint#593).
|
|
29
29
|
@options[:stdin] = ruby_code
|
|
30
30
|
super([haml_path])
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module HamlLint
|
|
4
|
-
# Checks for Ruby script in
|
|
4
|
+
# Checks for Ruby script in Haml templates with no space after the `=`/`-`.
|
|
5
5
|
class Linter::SpaceBeforeScript < Linter
|
|
6
6
|
include LinterRegistry
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module HamlLint
|
|
4
|
-
# Flags
|
|
4
|
+
# Flags Haml's unescaped-output markers (`!=`, `!~`, and the unescaped
|
|
5
5
|
# plain-text `!`), which bypass HTML escaping.
|
|
6
6
|
#
|
|
7
7
|
# Like `raw`, `html_safe`, and `h()` in Rails, these make it easy to
|
|
@@ -20,7 +20,7 @@ module HamlLint
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def visit_script(node)
|
|
23
|
-
# Some script nodes created by the
|
|
23
|
+
# Some script nodes created by the Haml parser aren't actually script
|
|
24
24
|
# nodes declared via the `=` marker. Check for it.
|
|
25
25
|
return unless /\A\s*=/.match?(node.source_code)
|
|
26
26
|
|
|
@@ -57,7 +57,7 @@ module HamlLint
|
|
|
57
57
|
|
|
58
58
|
# Returns whether any literal portion of the string contains a backslash
|
|
59
59
|
# escape (e.g. `\n`, `\t`, `\u202F`). Such escapes are interpreted inside
|
|
60
|
-
# a Ruby string but would be emitted verbatim as
|
|
60
|
+
# a Ruby string but would be emitted verbatim as Haml plain text, so the
|
|
61
61
|
# `= "..."` form is not equivalent to the unwrapped plain text.
|
|
62
62
|
def contains_escape_sequence?(tree)
|
|
63
63
|
string_segments(tree).any? do |segment|
|
|
@@ -65,7 +65,7 @@ module HamlLint
|
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
# Returns whether the string begins or ends with whitespace.
|
|
68
|
+
# Returns whether the string begins or ends with whitespace. Haml strips
|
|
69
69
|
# trailing whitespace from plain text (and leading whitespace denotes
|
|
70
70
|
# indentation), so unwrapping such a string would change the output.
|
|
71
71
|
def contains_significant_whitespace?(tree)
|
data/lib/haml_lint/linter.rb
CHANGED
|
@@ -56,7 +56,7 @@ module HamlLint
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
# Runs the linter against the given Haml document, raises if the file cannot be processed due to
|
|
59
|
-
# Syntax or
|
|
59
|
+
# Syntax or Haml-Lint internal errors. (For testing purposes)
|
|
60
60
|
#
|
|
61
61
|
# @param document [HamlLint::Document]
|
|
62
62
|
def run_or_raise(document, autocorrect: nil)
|
|
@@ -164,7 +164,7 @@ module HamlLint
|
|
|
164
164
|
# mutation path (`Document#change_source`), but only when the safety gate permits.
|
|
165
165
|
# No-ops otherwise; `change_source` itself also no-ops when the source is unchanged.
|
|
166
166
|
#
|
|
167
|
-
# @param new_source [String] the corrected
|
|
167
|
+
# @param new_source [String] the corrected Haml source
|
|
168
168
|
def apply_autocorrect(new_source)
|
|
169
169
|
return unless autocorrect?
|
|
170
170
|
document.change_source(new_source)
|
|
@@ -4,7 +4,7 @@ module HamlLint
|
|
|
4
4
|
# Responsible for transforming {Haml::Parser::ParseNode} objects into
|
|
5
5
|
# corresponding {HamlLint::Tree::Node} objects.
|
|
6
6
|
#
|
|
7
|
-
# The parse tree generated by
|
|
7
|
+
# The parse tree generated by Haml has a number of strange cases where certain
|
|
8
8
|
# types of nodes are created that don't necessarily correspond to what one
|
|
9
9
|
# would expect. This class is intended to isolate and handle these cases so
|
|
10
10
|
# that linters don't have to deal with them.
|
|
@@ -16,7 +16,7 @@ module HamlLint
|
|
|
16
16
|
@document = document
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
# Converts the given
|
|
19
|
+
# Converts the given Haml parse node into its corresponding Haml-Lint parse
|
|
20
20
|
# node.
|
|
21
21
|
#
|
|
22
22
|
# @param haml_node [Haml::Parser::ParseNode]
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
module HamlLint::RubyExtraction
|
|
4
4
|
# This is the base class for all of the Chunks of HamlLint::RubyExtraction.
|
|
5
|
-
# A Chunk represents a part of the
|
|
5
|
+
# A Chunk represents a part of the Haml file that HamlLint::Linter::RuboCop
|
|
6
6
|
# is processing and will insert some Ruby code in a file passed to RuboCop.
|
|
7
7
|
#
|
|
8
|
-
# There are chunks for most
|
|
8
|
+
# There are chunks for most Haml concepts, even if they don't represent Ruby
|
|
9
9
|
# code. For example, there is a chunk that represents a `%div` tag, which
|
|
10
10
|
# uses a `begin` in the generated Ruby to add indentation for the children
|
|
11
|
-
# of the %div in the Ruby file just like there is in the
|
|
11
|
+
# of the %div in the Ruby file just like there is in the Haml file.
|
|
12
12
|
class BaseChunk
|
|
13
13
|
COMMA_CHANGES_LINES = true
|
|
14
14
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
module HamlLint::RubyExtraction
|
|
5
5
|
# Extracts "chunks" of the haml file into instances of subclasses of HamlLint::RubyExtraction::BaseChunk.
|
|
6
6
|
#
|
|
7
|
-
# This is the first step of generating Ruby code from a
|
|
7
|
+
# This is the first step of generating Ruby code from a Haml file to then be processed by RuboCop.
|
|
8
8
|
# See HamlLint::RubyExtraction::BaseChunk for more details.
|
|
9
9
|
class ChunkExtractor
|
|
10
10
|
include HamlLint::HamlVisitor
|
|
@@ -17,7 +17,7 @@ module HamlLint::RubyExtraction
|
|
|
17
17
|
::Haml::Parser.new('', {})
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
#
|
|
20
|
+
# Haml strips newlines when handling multi-line statements (using pipes or trailing comma)
|
|
21
21
|
# We don't. So the regex must be fixed to correctly detect the start of the string.
|
|
22
22
|
BLOCK_KEYWORD_REGEX = Regexp.new(Haml::Parser::BLOCK_KEYWORD_REGEX.source.sub('^', '\A'))
|
|
23
23
|
|
|
@@ -124,7 +124,7 @@ module HamlLint::RubyExtraction
|
|
|
124
124
|
def visit_script(node, &block)
|
|
125
125
|
raw_first_line = @original_haml_lines[node.line - 1]
|
|
126
126
|
|
|
127
|
-
# ==, !, !==, &, &== means interpolation (was needed before
|
|
127
|
+
# ==, !, !==, &, &== means interpolation (was needed before Haml 2.2... it's still supported)
|
|
128
128
|
# =, !=, &= mean actual ruby code is coming
|
|
129
129
|
# Anything else is interpolation
|
|
130
130
|
# The regex lists the case for Ruby Code. The 3 cases and making sure they are not followed by another = sign
|
|
@@ -169,20 +169,20 @@ module HamlLint::RubyExtraction
|
|
|
169
169
|
prev_chunk.node == node.parent
|
|
170
170
|
# When an outputting script is nested under another outputting script,
|
|
171
171
|
# we want to block them from being merged together by rubocop, because
|
|
172
|
-
# this doesn't make sense in
|
|
172
|
+
# this doesn't make sense in Haml.
|
|
173
173
|
# Example:
|
|
174
174
|
# = if this_is_short
|
|
175
175
|
# = this_is_short_too
|
|
176
176
|
# Could become (after RuboCop):
|
|
177
177
|
# HL.out = (HL.out = this_is_short_too if this_is_short)
|
|
178
|
-
# Or in (broken)
|
|
178
|
+
# Or in (broken) Haml style:
|
|
179
179
|
# = this_is_short_too = if this_is_short
|
|
180
180
|
# By forcing this to start a chunk, there will be extra placeholders which
|
|
181
181
|
# blocks rubocop from merging the lines.
|
|
182
182
|
must_start_chunk = true
|
|
183
183
|
elsif script_prefix != '='
|
|
184
184
|
# In the few cases where &= and != are used to start the script,
|
|
185
|
-
# We need to remember and put it back in the final
|
|
185
|
+
# We need to remember and put it back in the final Haml. Fusing scripts together
|
|
186
186
|
# would make that basically impossible. Instead, a script has a "first_output_prefix"
|
|
187
187
|
# field for this specific case
|
|
188
188
|
must_start_chunk = true
|
|
@@ -301,7 +301,7 @@ module HamlLint::RubyExtraction
|
|
|
301
301
|
|
|
302
302
|
if attributes_code&.start_with?('{')
|
|
303
303
|
# HTML-style (parens) attributes, e.g. %div(foo=foo), arrive as a synthesized hash string
|
|
304
|
-
# like '{"foo" => foo,}'. That text isn't present verbatim in the
|
|
304
|
+
# like '{"foo" => foo,}'. That text isn't present verbatim in the Haml, so we can't map
|
|
305
305
|
# RuboCop corrections back and intentionally don't autocorrect it. We still extract the
|
|
306
306
|
# attribute *values* as a non-correctable chunk so RuboCop sees variables used here;
|
|
307
307
|
# otherwise they look unused (false Lint/UselessAssignment, plus unsafe autocorrect that
|
|
@@ -406,7 +406,7 @@ module HamlLint::RubyExtraction
|
|
|
406
406
|
end
|
|
407
407
|
end
|
|
408
408
|
|
|
409
|
-
# Visiting a
|
|
409
|
+
# Visiting a Haml filter. Lines looking like ` :javascript` and the following lines
|
|
410
410
|
# that are nested.
|
|
411
411
|
def visit_filter(node)
|
|
412
412
|
# For unknown reasons, haml doesn't escape interpolations in filters.
|
|
@@ -521,14 +521,14 @@ module HamlLint::RubyExtraction
|
|
|
521
521
|
# The first and last lines may not be the complete lines from the Haml, only the Ruby parts
|
|
522
522
|
# and the indentation between the first and last list.
|
|
523
523
|
|
|
524
|
-
#
|
|
524
|
+
# Haml transforms the ruby code in many ways as it parses a document. Often removing lines and/or
|
|
525
525
|
# indentation. This is quite annoying for us since we want the exact layout of the code to analyze it.
|
|
526
526
|
#
|
|
527
527
|
# This function receives the code as haml provides it and the line where it starts. It returns
|
|
528
528
|
# the actual code as it is in the haml file, keeping breaks and indentation for the following lines.
|
|
529
529
|
# In addition, the start position of the code in the first line.
|
|
530
530
|
#
|
|
531
|
-
# The rules for handling multiline code in
|
|
531
|
+
# The rules for handling multiline code in Haml are as follow:
|
|
532
532
|
# * if the line being processed ends with a space and a pipe, then append to the line (without
|
|
533
533
|
# newlines) every following lines that also end with a space and a pipe. This means the last line of
|
|
534
534
|
# the "block" also needs a pipe at the end.
|
|
@@ -727,7 +727,7 @@ module HamlLint::RubyExtraction
|
|
|
727
727
|
|
|
728
728
|
LOOP_KEYWORDS = %w[for until while].freeze
|
|
729
729
|
def self.block_keyword(code)
|
|
730
|
-
# Need to handle 'for'/'while' since regex stolen from
|
|
730
|
+
# Need to handle 'for'/'while' since regex stolen from Haml parser doesn't
|
|
731
731
|
if (keyword = code[/\A\s*([^\s]+)\s+/, 1]) && LOOP_KEYWORDS.include?(keyword)
|
|
732
732
|
return keyword
|
|
733
733
|
end
|
|
@@ -9,7 +9,7 @@ module HamlLint::RubyExtraction
|
|
|
9
9
|
# * Preprocess the chunks to cleanup/fuse some of them.
|
|
10
10
|
# * Generates the extracted ruby code from the Chunks.
|
|
11
11
|
# * Handles the markers (see below)
|
|
12
|
-
# * Use the chunks to transfer corrections from corrected Ruby code back to
|
|
12
|
+
# * Use the chunks to transfer corrections from corrected Ruby code back to Haml
|
|
13
13
|
#
|
|
14
14
|
# The generated Ruby code uses markers to wrap around the Ruby code from the chunks.
|
|
15
15
|
# Those markers look like function calls, like: `haml_lint_marker_1`, so are valid ruby.
|
|
@@ -22,7 +22,7 @@ module HamlLint::RubyExtraction
|
|
|
22
22
|
# @return [String] The prefix used for markers in the Ruby code
|
|
23
23
|
attr_reader :marker_prefix
|
|
24
24
|
|
|
25
|
-
# @return [Array<String>] The ruby lines after extraction from
|
|
25
|
+
# @return [Array<String>] The ruby lines after extraction from Haml (before RuboCop)
|
|
26
26
|
attr_reader :assembled_ruby_lines
|
|
27
27
|
|
|
28
28
|
# @return [Array<String>] The ruby lines after correction by RuboCop
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module HamlLint::RubyExtraction
|
|
4
|
-
#
|
|
4
|
+
# Haml adds a `end` when code gets outdented. We need to add that to the Ruby too, this
|
|
5
5
|
# is the chunk for it.
|
|
6
6
|
# However:
|
|
7
7
|
# * we can't apply fixes to it, so there are no markers
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module HamlLint::RubyExtraction
|
|
4
|
-
# Chunk for dealing with every
|
|
4
|
+
# Chunk for dealing with every Haml filter other than `:ruby`
|
|
5
5
|
# The generated Ruby for these is just a HEREDOC, so interpolation is corrected at
|
|
6
6
|
# the same time by RuboCop.
|
|
7
7
|
class NonRubyFilterChunk < BaseChunk
|
|
@@ -5,7 +5,7 @@ module HamlLint::RubyExtraction
|
|
|
5
5
|
# transfer the corrections it receives to the indentation of the associated lines.
|
|
6
6
|
#
|
|
7
7
|
# Also used so that Rubocop doesn't think that there is nothing in `if` and other such structures,
|
|
8
|
-
# so that it does corrections that make sense for the
|
|
8
|
+
# so that it does corrections that make sense for the Haml.
|
|
9
9
|
class PlaceholderMarkerChunk < BaseChunk
|
|
10
10
|
def initialize(node, marker_name, indent:, nb_lines: 1, **kwargs)
|
|
11
11
|
@marker_name = marker_name
|
|
@@ -18,7 +18,7 @@ module HamlLint::RubyExtraction
|
|
|
18
18
|
attr_reader :must_start_chunk
|
|
19
19
|
|
|
20
20
|
# @return [Array<Integer>] Line indexes to ignore when building the source_map. For examples,
|
|
21
|
-
# implicit `end` are on their own line in the Ruby file, but in the
|
|
21
|
+
# implicit `end` are on their own line in the Ruby file, but in the Haml, they are absent.
|
|
22
22
|
attr_reader :skip_line_indexes_in_source_map
|
|
23
23
|
|
|
24
24
|
# @return [HamlLint::RubyExtraction::BaseChunk] The previous chunk can affect how
|
data/lib/haml_lint/runner.rb
CHANGED
|
@@ -62,6 +62,8 @@ module HamlLint
|
|
|
62
62
|
# @return [HamlLint::LinterSelector]
|
|
63
63
|
attr_reader :linter_selector
|
|
64
64
|
|
|
65
|
+
PARALLEL_LINTER_SELECTOR_THREAD_KEY = :haml_lint_runner_parallel_linter_selectors
|
|
66
|
+
|
|
65
67
|
# Returns a fresh selector for this run.
|
|
66
68
|
#
|
|
67
69
|
# LinterSelector memoizes linter instances, and linters mutate instance
|
|
@@ -73,6 +75,18 @@ module HamlLint
|
|
|
73
75
|
HamlLint::LinterSelector.new(config, @options)
|
|
74
76
|
end
|
|
75
77
|
|
|
78
|
+
# Returns a selector scoped to the current parallel worker.
|
|
79
|
+
#
|
|
80
|
+
# MRI runs Parallel.map in forked processes, so each worker can safely reuse
|
|
81
|
+
# its own linter instances. JRuby runs Parallel.map in threads, so this must
|
|
82
|
+
# be isolated per thread to avoid sharing mutable linter state.
|
|
83
|
+
#
|
|
84
|
+
# @return [HamlLint::LinterSelector]
|
|
85
|
+
def parallel_linter_selector
|
|
86
|
+
selectors = Thread.current[PARALLEL_LINTER_SELECTOR_THREAD_KEY] ||= {}.compare_by_identity
|
|
87
|
+
selectors[self] ||= build_linter_selector
|
|
88
|
+
end
|
|
89
|
+
|
|
76
90
|
# Returns the {HamlLint::Configuration} that should be used given the
|
|
77
91
|
# specified options.
|
|
78
92
|
#
|
|
@@ -205,7 +219,7 @@ module HamlLint
|
|
|
205
219
|
# @return [void]
|
|
206
220
|
def warm_cache
|
|
207
221
|
results = Parallel.map(sources) do |source|
|
|
208
|
-
lints = collect_lints(source,
|
|
222
|
+
lints = collect_lints(source, parallel_linter_selector, config)
|
|
209
223
|
[source.path, lints]
|
|
210
224
|
end
|
|
211
225
|
@cache = results.to_h
|
|
@@ -65,7 +65,7 @@ module HamlLint
|
|
|
65
65
|
(expected_severity ? " with severity '#{expected_severity}'" : '')
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
-
def has_lints?(linter, expected_line, count, expected_message, expected_severity, # rubocop:disable Metrics/ParameterLists
|
|
68
|
+
def has_lints?(linter, expected_line, count, expected_message, expected_severity, # rubocop:disable Metrics/ParameterLists,Naming
|
|
69
69
|
expected_corrected)
|
|
70
70
|
if expected_line
|
|
71
71
|
has_expected_line_lints?(linter,
|
|
@@ -83,7 +83,7 @@ module HamlLint
|
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
def has_expected_line_lints?(linter, # rubocop:disable Metrics/ParameterLists
|
|
86
|
+
def has_expected_line_lints?(linter, # rubocop:disable Metrics/ParameterLists,Naming
|
|
87
87
|
expected_line,
|
|
88
88
|
count,
|
|
89
89
|
expected_message,
|
|
@@ -9,7 +9,7 @@ module HamlLint::Tree
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def text
|
|
12
|
-
# Seems
|
|
12
|
+
# Seems Haml strips the starting blank lines... without them, line numbers become offset,
|
|
13
13
|
# breaking the source_map and auto-correct
|
|
14
14
|
|
|
15
15
|
nb_blank_lines = 0
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require_relative '../directive'
|
|
4
4
|
|
|
5
5
|
module HamlLint::Tree
|
|
6
|
-
# Represents a
|
|
6
|
+
# Represents a Haml comment node.
|
|
7
7
|
class HamlCommentNode < Node
|
|
8
8
|
def directives
|
|
9
9
|
directives = super
|
|
@@ -28,7 +28,7 @@ module HamlLint::Tree
|
|
|
28
28
|
# Returns whether this comment contains a `locals` directive.
|
|
29
29
|
#
|
|
30
30
|
# @return [Boolean]
|
|
31
|
-
def is_strict_locals?
|
|
31
|
+
def is_strict_locals? # rubocop:disable Naming
|
|
32
32
|
text.lstrip.start_with?('locals:')
|
|
33
33
|
end
|
|
34
34
|
|
data/lib/haml_lint/tree/node.rb
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
require_relative '../comment_configuration'
|
|
4
4
|
|
|
5
5
|
module HamlLint::Tree
|
|
6
|
-
# Decorator class that provides a convenient set of helpers for
|
|
6
|
+
# Decorator class that provides a convenient set of helpers for Haml's
|
|
7
7
|
# {Haml::Parser::ParseNode} struct.
|
|
8
8
|
#
|
|
9
9
|
# The goal is to abstract away the details of the underlying struct and
|
|
10
10
|
# provide a cleaner and more uniform interface for getting information about a
|
|
11
11
|
# node, as there are a number of weird/special cases in the struct returned by
|
|
12
|
-
# the
|
|
12
|
+
# the Haml parser.
|
|
13
13
|
#
|
|
14
14
|
# @abstract
|
|
15
15
|
class Node
|
|
@@ -21,7 +21,7 @@ module HamlLint::Tree
|
|
|
21
21
|
# Creates a node wrapping the given {Haml::Parser::ParseNode} struct.
|
|
22
22
|
#
|
|
23
23
|
# @param document [HamlLint::Document] Haml document that created this node
|
|
24
|
-
# @param parse_node [Haml::Parser::ParseNode] parse node created by
|
|
24
|
+
# @param parse_node [Haml::Parser::ParseNode] parse node created by Haml's parser
|
|
25
25
|
def initialize(document, parse_node)
|
|
26
26
|
@line = parse_node.line
|
|
27
27
|
@document = document
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require_relative 'null_node'
|
|
4
4
|
|
|
5
5
|
module HamlLint::Tree
|
|
6
|
-
# Represents the root node of a
|
|
6
|
+
# Represents the root node of a Haml document that contains all other nodes.
|
|
7
7
|
class RootNode < Node
|
|
8
8
|
# The name of the file parsed to build this tree.
|
|
9
9
|
#
|
|
@@ -21,7 +21,7 @@ module HamlLint::Tree
|
|
|
21
21
|
return node if node.line_numbers.cover?(line) && node != self
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
# Because
|
|
24
|
+
# Because Haml doesn't leave any trace in the nodes when it merges lines that
|
|
25
25
|
# end with a comma, it's harder to assign a node to the second line here:
|
|
26
26
|
# = some_call user,
|
|
27
27
|
# foo, bar
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module HamlLint::Tree
|
|
4
|
-
# Represents a
|
|
4
|
+
# Represents a Haml silent script node (`- some_expression`) which executes
|
|
5
5
|
# code without producing output.
|
|
6
6
|
class SilentScriptNode < Node
|
|
7
7
|
# The Ruby script contents parsed into a syntax tree.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module HamlLint::Tree
|
|
4
|
-
# Represents a tag node in a
|
|
4
|
+
# Represents a tag node in a Haml document.
|
|
5
5
|
class TagNode < Node
|
|
6
6
|
# Computed set of attribute hashes code.
|
|
7
7
|
#
|
|
@@ -46,7 +46,7 @@ module HamlLint::Tree
|
|
|
46
46
|
# Returns whether this tag has a specified attribute.
|
|
47
47
|
#
|
|
48
48
|
# @return [true,false]
|
|
49
|
-
def has_hash_attribute?(attribute)
|
|
49
|
+
def has_hash_attribute?(attribute) # rubocop:disable Naming
|
|
50
50
|
hash_attributes? && existing_attributes.include?(attribute)
|
|
51
51
|
end
|
|
52
52
|
|
data/lib/haml_lint/utils.rb
CHANGED
|
@@ -233,7 +233,7 @@ module HamlLint
|
|
|
233
233
|
|
|
234
234
|
# Returns true if line is only whitespace.
|
|
235
235
|
# Note, this is not like blank? is rails. For nil, this returns false.
|
|
236
|
-
def is_blank_line?(line)
|
|
236
|
+
def is_blank_line?(line) # rubocop:disable Naming
|
|
237
237
|
line && line.index(/\S/).nil?
|
|
238
238
|
end
|
|
239
239
|
|
data/lib/haml_lint/version.rb
CHANGED