theme-check 1.7.0 → 1.9.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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +49 -0
  4. data/README.md +10 -0
  5. data/RELEASING.md +13 -0
  6. data/config/default.yml +5 -0
  7. data/data/shopify_liquid/deprecated_filters.yml +4 -0
  8. data/data/shopify_liquid/filters.yml +3 -1
  9. data/data/shopify_liquid/tags.yml +9 -9
  10. data/docs/checks/TEMPLATE.md.erb +24 -19
  11. data/docs/checks/schema_json_format.md +76 -0
  12. data/docs/language_server/code-action-command-palette.png +0 -0
  13. data/docs/language_server/code-action-flow.png +0 -0
  14. data/docs/language_server/code-action-keyboard.png +0 -0
  15. data/docs/language_server/code-action-light-bulb.png +0 -0
  16. data/docs/language_server/code-action-problem.png +0 -0
  17. data/docs/language_server/code-action-quickfix.png +0 -0
  18. data/docs/language_server/how_to_correct_code_with_code_actions_and_execute_command.md +197 -0
  19. data/exe/theme-check-language-server +0 -4
  20. data/lib/theme_check/checks/asset_size_app_block_css.rb +2 -3
  21. data/lib/theme_check/checks/asset_size_app_block_javascript.rb +2 -3
  22. data/lib/theme_check/checks/asset_url_filters.rb +2 -0
  23. data/lib/theme_check/checks/default_locale.rb +1 -1
  24. data/lib/theme_check/checks/deprecated_filter.rb +79 -4
  25. data/lib/theme_check/checks/deprecated_global_app_block_type.rb +2 -3
  26. data/lib/theme_check/checks/matching_schema_translations.rb +14 -9
  27. data/lib/theme_check/checks/matching_translations.rb +1 -0
  28. data/lib/theme_check/checks/missing_required_template_files.rb +3 -3
  29. data/lib/theme_check/checks/missing_template.rb +1 -1
  30. data/lib/theme_check/checks/pagination_size.rb +2 -3
  31. data/lib/theme_check/checks/remote_asset.rb +5 -0
  32. data/lib/theme_check/checks/required_directories.rb +1 -1
  33. data/lib/theme_check/checks/required_layout_theme_object.rb +9 -4
  34. data/lib/theme_check/checks/schema_json_format.rb +29 -0
  35. data/lib/theme_check/checks/space_inside_braces.rb +132 -87
  36. data/lib/theme_check/checks/translation_key_exists.rb +33 -25
  37. data/lib/theme_check/checks/unused_assign.rb +3 -2
  38. data/lib/theme_check/checks/unused_snippet.rb +1 -1
  39. data/lib/theme_check/checks/valid_html_translation.rb +1 -1
  40. data/lib/theme_check/checks/valid_schema.rb +2 -2
  41. data/lib/theme_check/corrector.rb +34 -23
  42. data/lib/theme_check/exceptions.rb +1 -0
  43. data/lib/theme_check/file_system_storage.rb +8 -3
  44. data/lib/theme_check/html_node.rb +99 -6
  45. data/lib/theme_check/html_visitor.rb +1 -32
  46. data/lib/theme_check/in_memory_storage.rb +9 -0
  47. data/lib/theme_check/json_helpers.rb +14 -0
  48. data/lib/theme_check/language_server/bridge.rb +142 -0
  49. data/lib/theme_check/language_server/channel.rb +69 -0
  50. data/lib/theme_check/language_server/client_capabilities.rb +27 -0
  51. data/lib/theme_check/language_server/code_action_engine.rb +32 -0
  52. data/lib/theme_check/language_server/code_action_provider.rb +42 -0
  53. data/lib/theme_check/language_server/code_action_providers/quickfix_code_action_provider.rb +83 -0
  54. data/lib/theme_check/language_server/code_action_providers/source_fix_all_code_action_provider.rb +40 -0
  55. data/lib/theme_check/language_server/completion_providers/tag_completion_provider.rb +3 -1
  56. data/lib/theme_check/language_server/configuration.rb +69 -0
  57. data/lib/theme_check/language_server/diagnostic.rb +124 -0
  58. data/lib/theme_check/language_server/diagnostics_engine.rb +80 -0
  59. data/lib/theme_check/language_server/diagnostics_manager.rb +136 -0
  60. data/lib/theme_check/language_server/document_change_corrector.rb +267 -0
  61. data/lib/theme_check/language_server/document_link_provider.rb +6 -6
  62. data/lib/theme_check/language_server/execute_command_engine.rb +19 -0
  63. data/lib/theme_check/language_server/execute_command_provider.rb +30 -0
  64. data/lib/theme_check/language_server/execute_command_providers/correction_execute_command_provider.rb +48 -0
  65. data/lib/theme_check/language_server/execute_command_providers/run_checks_execute_command_provider.rb +22 -0
  66. data/lib/theme_check/language_server/handler.rb +92 -217
  67. data/lib/theme_check/language_server/io_messenger.rb +112 -0
  68. data/lib/theme_check/language_server/messenger.rb +12 -42
  69. data/lib/theme_check/language_server/protocol.rb +4 -0
  70. data/lib/theme_check/language_server/server.rb +54 -110
  71. data/lib/theme_check/language_server/uri_helper.rb +1 -0
  72. data/lib/theme_check/language_server/versioned_in_memory_storage.rb +69 -0
  73. data/lib/theme_check/language_server.rb +28 -6
  74. data/lib/theme_check/liquid_node.rb +255 -12
  75. data/lib/theme_check/locale_diff.rb +48 -10
  76. data/lib/theme_check/node.rb +16 -0
  77. data/lib/theme_check/offense.rb +27 -23
  78. data/lib/theme_check/position.rb +4 -4
  79. data/lib/theme_check/regex_helpers.rb +1 -1
  80. data/lib/theme_check/schema_helper.rb +70 -0
  81. data/lib/theme_check/shopify_liquid/system_translations.rb +35 -0
  82. data/lib/theme_check/shopify_liquid/tag.rb +19 -1
  83. data/lib/theme_check/shopify_liquid.rb +1 -0
  84. data/lib/theme_check/storage.rb +4 -0
  85. data/lib/theme_check/tags.rb +0 -1
  86. data/lib/theme_check/theme.rb +1 -1
  87. data/lib/theme_check/theme_file.rb +8 -1
  88. data/lib/theme_check/theme_file_rewriter.rb +28 -6
  89. data/lib/theme_check/version.rb +1 -1
  90. data/lib/theme_check.rb +11 -2
  91. metadata +31 -3
  92. data/lib/theme_check/language_server/diagnostics_tracker.rb +0 -66
@@ -14,24 +14,55 @@ module ThemeCheck
14
14
  visit_object(@default, @other, [])
15
15
  end
16
16
 
17
- def add_as_offenses(check, key_prefix: [], node: nil, theme_file: nil)
17
+ def add_as_offenses(check, key_prefix: [], node: nil, theme_file: nil, schema: {})
18
18
  if extra_keys.any?
19
- add_keys_offense(check, "Extra translation keys", extra_keys,
20
- key_prefix: key_prefix, node: node, theme_file: theme_file)
19
+ remove_extra_keys_offense(check, "Extra translation keys", extra_keys,
20
+ key_prefix: key_prefix, node: node, theme_file: theme_file, schema: schema)
21
21
  end
22
22
 
23
23
  if missing_keys.any?
24
- add_keys_offense(check, "Missing translation keys", missing_keys,
25
- key_prefix: key_prefix, node: node, theme_file: theme_file)
24
+ add_missing_keys_offense(check, "Missing translation keys", missing_keys,
25
+ key_prefix: key_prefix, node: node, theme_file: theme_file, schema: schema)
26
26
  end
27
27
  end
28
28
 
29
29
  private
30
30
 
31
- def add_keys_offense(check, cause, keys, key_prefix:, node: nil, theme_file: nil)
32
- message = "#{cause}: #{format_keys(key_prefix, keys)}"
31
+ def remove_extra_keys_offense(check, cause, extra_keys, key_prefix:, node: nil, theme_file: nil, schema: {})
32
+ message = "#{cause}: #{format_keys(key_prefix, extra_keys)}"
33
33
  if node
34
- check.add_offense(message, node: node)
34
+ check.add_offense(message, node: node) do |corrector|
35
+ extra_keys.each do |k|
36
+ SchemaHelper.delete(schema, key_prefix + k)
37
+ end
38
+ corrector.replace_inner_json(node, schema)
39
+ end
40
+ elsif theme_file.is_a?(JsonFile)
41
+ check.add_offense(message, theme_file: theme_file) do |corrector|
42
+ extra_keys.each do |k|
43
+ corrector.remove_translation(theme_file, key_prefix + k)
44
+ end
45
+ end
46
+ else
47
+ check.add_offense(message, theme_file: theme_file)
48
+ end
49
+ end
50
+
51
+ def add_missing_keys_offense(check, cause, missing_keys, key_prefix:, node: nil, theme_file: nil, schema: {})
52
+ message = "#{cause}: #{format_keys(key_prefix, missing_keys)}"
53
+ if node
54
+ check.add_offense(message, node: node) do |corrector|
55
+ missing_keys.each do |k|
56
+ SchemaHelper.set(schema, key_prefix + k, "TODO")
57
+ end
58
+ corrector.replace_inner_json(node, schema)
59
+ end
60
+ elsif theme_file.is_a?(JsonFile)
61
+ check.add_offense(message, theme_file: theme_file) do |corrector|
62
+ missing_keys.each do |k|
63
+ corrector.add_translation(theme_file, key_prefix + k, "TODO")
64
+ end
65
+ end
35
66
  else
36
67
  check.add_offense(message, theme_file: theme_file)
37
68
  end
@@ -46,10 +77,12 @@ module ThemeCheck
46
77
  other = {} unless other.is_a?(Hash)
47
78
  return if pluralization?(default) && pluralization?(other)
48
79
 
49
- @extra_keys += (other.keys - default.keys).map { |key| path + [key] }
80
+ shopify_translations = system_translations(path)
81
+
82
+ @extra_keys += (other.keys - default.keys - shopify_translations.keys).map { |key| path + [key] }
50
83
 
51
84
  default.each do |key, default_value|
52
- translated_value = other[key]
85
+ translated_value = other[key] || shopify_translations[key]
53
86
  new_path = path + [key]
54
87
 
55
88
  if translated_value.nil?
@@ -65,5 +98,10 @@ module ThemeCheck
65
98
  PLURALIZATION_KEYS.include?(key) && !value.is_a?(Hash)
66
99
  end
67
100
  end
101
+
102
+ def system_translations(path)
103
+ return ShopifyLiquid::SystemTranslations.translations_hash if path.empty?
104
+ ShopifyLiquid::SystemTranslations.translations_hash.dig(*path) || {}
105
+ end
68
106
  end
69
107
  end
@@ -30,8 +30,24 @@ module ThemeCheck
30
30
  raise NotImplementedError
31
31
  end
32
32
 
33
+ def start_row
34
+ raise NotImplementedError
35
+ end
36
+
37
+ def start_column
38
+ raise NotImplementedError
39
+ end
40
+
33
41
  def end_index
34
42
  raise NotImplementedError
35
43
  end
44
+
45
+ def end_row
46
+ raise NotImplementedError
47
+ end
48
+
49
+ def end_column
50
+ raise NotImplementedError
51
+ end
36
52
  end
37
53
  end
@@ -39,26 +39,12 @@ module ThemeCheck
39
39
  end
40
40
 
41
41
  @node = node
42
- @theme_file = nil
43
- if node
44
- @theme_file = node.theme_file
45
- elsif theme_file
46
- @theme_file = theme_file
47
- end
48
-
49
- @markup = if markup
50
- markup
51
- else
52
- node&.markup
53
- end
42
+ @theme_file = node&.theme_file || theme_file
43
+ @markup = markup || node&.markup
54
44
 
55
45
  raise ArgumentError, "Offense markup cannot be an empty string" if @markup.is_a?(String) && @markup.empty?
56
46
 
57
- @line_number = if line_number
58
- line_number
59
- elsif @node
60
- @node.line_number
61
- end
47
+ @line_number = line_number || @node&.line_number
62
48
 
63
49
  @position = Position.new(
64
50
  @markup,
@@ -81,11 +67,25 @@ module ThemeCheck
81
67
  end
82
68
  end
83
69
 
70
+ def in_range?(other_range)
71
+ # Zero length ranges are OK and considered the same as size 1 ranges
72
+ other_range = other_range.first..other_range.end if other_range.size == 0 # rubocop:disable Style/ZeroLengthPredicate
73
+ range.cover?(other_range) || other_range.cover?(range)
74
+ end
75
+
76
+ def range
77
+ @range ||= if start_index == end_index
78
+ (start_index..end_index)
79
+ else
80
+ (start_index...end_index) # end_index is excluded
81
+ end
82
+ end
83
+
84
84
  def start_index
85
85
  @position.start_index
86
86
  end
87
87
 
88
- def start_line
88
+ def start_row
89
89
  @position.start_row
90
90
  end
91
91
 
@@ -97,7 +97,7 @@ module ThemeCheck
97
97
  @position.end_index
98
98
  end
99
99
 
100
- def end_line
100
+ def end_row
101
101
  @position.end_row
102
102
  end
103
103
 
@@ -121,6 +121,10 @@ module ThemeCheck
121
121
  StringHelpers.demodulize(check.class.name)
122
122
  end
123
123
 
124
+ def version
125
+ theme_file&.version
126
+ end
127
+
124
128
  def doc
125
129
  check.doc
126
130
  end
@@ -139,9 +143,9 @@ module ThemeCheck
139
143
  !!correction
140
144
  end
141
145
 
142
- def correct
146
+ def correct(corrector = nil)
143
147
  if correctable?
144
- corrector = Corrector.new(theme_file: theme_file)
148
+ corrector ||= Corrector.new(theme_file: theme_file)
145
149
  correction.call(corrector)
146
150
  end
147
151
  rescue => e
@@ -211,9 +215,9 @@ module ThemeCheck
211
215
  check: check.code_name,
212
216
  path: theme_file&.relative_path,
213
217
  severity: check.severity_value,
214
- start_line: start_line,
218
+ start_row: start_row,
215
219
  start_column: start_column,
216
- end_line: end_line,
220
+ end_row: end_row,
217
221
  end_column: end_column,
218
222
  message: message,
219
223
  }
@@ -64,6 +64,10 @@ module ThemeCheck
64
64
  strict_position.end_column
65
65
  end
66
66
 
67
+ def content_line_count
68
+ @content_line_count ||= contents.count("\n")
69
+ end
70
+
67
71
  private
68
72
 
69
73
  def compute_start_offset
@@ -78,10 +82,6 @@ module ThemeCheck
78
82
  @contents
79
83
  end
80
84
 
81
- def content_line_count
82
- @content_line_count ||= contents.count("\n")
83
- end
84
-
85
85
  def line_number
86
86
  return 0 if @line_number_1_indexed.nil?
87
87
  bounded(0, @line_number_1_indexed - 1, content_line_count)
@@ -5,7 +5,7 @@ module ThemeCheck
5
5
  LIQUID_TAG = /#{Liquid::TagStart}.*?#{Liquid::TagEnd}/om
6
6
  LIQUID_VARIABLE = /#{Liquid::VariableStart}.*?#{Liquid::VariableEnd}/om
7
7
  LIQUID_TAG_OR_VARIABLE = /#{LIQUID_TAG}|#{LIQUID_VARIABLE}/om
8
- HTML_LIQUID_PLACEHOLDER = /≬[0-9a-z]+#*≬/m
8
+ HTML_LIQUID_PLACEHOLDER = /≬[0-9a-z\n]+[#\n]*≬/m
9
9
  START_OR_END_QUOTE = /(^['"])|(['"]$)/
10
10
 
11
11
  def matches(s, re)
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ThemeCheck
4
+ class SchemaHelper
5
+ # Deeply sets a value in a hash. Accepts both arrays and strings for path.
6
+ def self.set(hash, path, value)
7
+ path = path.split('.') if path.is_a?(String)
8
+ path.each_with_index.reduce(hash) do |pointer, (token, index)|
9
+ if index == path.size - 1
10
+ pointer[token] = value
11
+ elsif !pointer.key?(token)
12
+ pointer[token] = {}
13
+ end
14
+ pointer[token]
15
+ end
16
+ hash
17
+ end
18
+
19
+ # Deeply delete a key from a hash
20
+ def self.delete(hash, path)
21
+ path = path.split('.') if path.is_a?(String)
22
+ path.each_with_index.reduce(hash) do |pointer, (token, index)|
23
+ break pointer.delete(token) if index == path.size - 1
24
+ pointer[token]
25
+ end
26
+ end
27
+
28
+ # Deeply add key/values inside a hash.
29
+ #
30
+ # Handles arrays by adding the key/value to all hashes inside the array.
31
+ #
32
+ # Specially handles objects that have the "id" key like this:
33
+ #
34
+ # e.g.
35
+ #
36
+ # schema = {
37
+ # "deep" => [
38
+ # { "id" => "hi" },
39
+ # { "id" => "oh" },
40
+ # ],
41
+ # }
42
+ # assert_equal(
43
+ # {
44
+ # "deep" => [
45
+ # { "id" => "hi", "ho" => "ho" },
46
+ # { "id" => "oh" },
47
+ # ],
48
+ # },
49
+ # SchemaHelper.schema_corrector(schema, "deep.hi.ho", "ho")
50
+ # )
51
+ def self.schema_corrector(schema, path, value)
52
+ return schema unless schema.is_a?(Hash)
53
+ path = path.split('.') if path.is_a?(String)
54
+ path.each_with_index.reduce(schema) do |pointer, (token, index)|
55
+ case pointer
56
+ when Array
57
+ pointer.each do |item|
58
+ schema_corrector(item, path.drop(1), value)
59
+ end
60
+
61
+ when Hash
62
+ break pointer[token] = value if index == path.size - 1
63
+ pointer[token] = {} unless pointer.key?(token) || pointer.key?("id")
64
+ pointer[token].nil? && pointer["id"] == token ? pointer : pointer[token]
65
+ end
66
+ end
67
+ schema
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+ module ThemeCheck
3
+ module ShopifyLiquid
4
+ module SystemTranslations
5
+ extend self
6
+
7
+ def translations
8
+ @translations ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_translation_keys.yml")).to_set
9
+ end
10
+
11
+ def translations_hash
12
+ @translations_hash ||= translations.reduce({}) do |acc, k|
13
+ dig_set(acc, k.split('.'), "")
14
+ end
15
+ end
16
+
17
+ def include?(key)
18
+ translations.include?(key)
19
+ end
20
+
21
+ private
22
+
23
+ def dig_set(obj, keys, value)
24
+ key = keys.first
25
+ if keys.length == 1
26
+ obj[key] = value
27
+ else
28
+ obj[key] = {} unless obj[key]
29
+ dig_set(obj[key], keys.slice(1..-1), value)
30
+ end
31
+ obj
32
+ end
33
+ end
34
+ end
35
+ end
@@ -7,10 +7,17 @@ module ThemeCheck
7
7
  extend self
8
8
 
9
9
  def labels
10
- @tags ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/tags.yml"))
10
+ @labels ||= tags_file_contents
11
+ .map { |x| to_label(x) }
11
12
  .to_set
12
13
  end
13
14
 
15
+ def end_labels
16
+ @end_labels ||= tags_file_contents
17
+ .select { |x| x.is_a?(Hash) }
18
+ .map { |x| x.values[0] }
19
+ end
20
+
14
21
  def tag_regex(tag)
15
22
  return unless labels.include?(tag)
16
23
  @tag_regexes ||= {}
@@ -22,6 +29,17 @@ module ThemeCheck
22
29
  @tag_liquid_regexes ||= {}
23
30
  @tag_liquid_regexes[tag] ||= /^\s*#{tag}/m
24
31
  end
32
+
33
+ private
34
+
35
+ def to_label(label)
36
+ return label if label.is_a?(String)
37
+ label.keys[0]
38
+ end
39
+
40
+ def tags_file_contents
41
+ @tags_file_contents ||= YAML.load(File.read("#{__dir__}/../../../data/shopify_liquid/tags.yml"))
42
+ end
25
43
  end
26
44
  end
27
45
  end
@@ -3,3 +3,4 @@ require_relative 'shopify_liquid/deprecated_filter'
3
3
  require_relative 'shopify_liquid/filter'
4
4
  require_relative 'shopify_liquid/object'
5
5
  require_relative 'shopify_liquid/tag'
6
+ require_relative 'shopify_liquid/system_translations'
@@ -21,5 +21,9 @@ module ThemeCheck
21
21
  def directories
22
22
  raise NotImplementedError
23
23
  end
24
+
25
+ def versioned?
26
+ false
27
+ end
24
28
  end
25
29
  end
@@ -66,7 +66,6 @@ module ThemeCheck
66
66
 
67
67
  def initialize(tag_name, markup, options)
68
68
  super
69
-
70
69
  if (matches = markup.match(SYNTAX))
71
70
  @liquid_variable_name = matches[:liquid_variable_name]
72
71
  @page_size = parse_expression(matches[:page_size])
@@ -3,7 +3,7 @@ require "pathname"
3
3
 
4
4
  module ThemeCheck
5
5
  class Theme
6
- DEFAULT_LOCALE_REGEXP = %r{^locales/(.*)\.default$}
6
+ DEFAULT_LOCALE_REGEXP = %r{locales/(.*)\.default$}
7
7
  LIQUID_REGEX = /\.liquid$/i
8
8
  JSON_REGEX = /\.json$/i
9
9
 
@@ -3,10 +3,13 @@ require "pathname"
3
3
 
4
4
  module ThemeCheck
5
5
  class ThemeFile
6
+ attr_reader :version, :storage
7
+
6
8
  def initialize(relative_path, storage)
7
9
  @relative_path = relative_path
8
10
  @storage = storage
9
11
  @source = nil
12
+ @version = nil
10
13
  @eol = "\n"
11
14
  end
12
15
 
@@ -36,7 +39,11 @@ module ThemeCheck
36
39
  # source file.
37
40
  def source
38
41
  return @source if @source
39
- @source = @storage.read(@relative_path)
42
+ if @storage.versioned?
43
+ @source, @version = @storage.read_version(@relative_path)
44
+ else
45
+ @source = @storage.read(@relative_path)
46
+ end
40
47
  @eol = @source.include?("\r\n") ? "\r\n" : "\n"
41
48
  @source = @source.gsub("\r\n", "\n")
42
49
  end
@@ -11,23 +11,45 @@ module ThemeCheck
11
11
  )
12
12
  end
13
13
 
14
- def insert_before(node, content)
14
+ def insert_before(node, content, character_range = nil)
15
15
  @rewriter.insert_before(
16
- range(node.start_index, node.end_index),
16
+ range(
17
+ character_range&.begin || node.start_index,
18
+ character_range&.end || node.end_index,
19
+ ),
17
20
  content
18
21
  )
19
22
  end
20
23
 
21
- def insert_after(node, content)
24
+ def insert_after(node, content, character_range = nil)
22
25
  @rewriter.insert_after(
23
- range(node.start_index, node.end_index),
26
+ range(
27
+ character_range&.begin || node.start_index,
28
+ character_range&.end || node.end_index,
29
+ ),
24
30
  content
25
31
  )
26
32
  end
27
33
 
28
- def replace(node, content)
34
+ def remove(node)
35
+ @rewriter.remove(
36
+ range(node.outer_markup_start_index, node.outer_markup_end_index)
37
+ )
38
+ end
39
+
40
+ def replace(node, content, character_range = nil)
29
41
  @rewriter.replace(
30
- range(node.start_index, node.end_index),
42
+ range(
43
+ character_range&.begin || node.start_index,
44
+ character_range&.end || node.end_index,
45
+ ),
46
+ content
47
+ )
48
+ end
49
+
50
+ def replace_inner_markup(node, content)
51
+ @rewriter.replace(
52
+ range(node.inner_markup_start_index, node.inner_markup_end_index),
31
53
  content
32
54
  )
33
55
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ThemeCheck
3
- VERSION = "1.7.0"
3
+ VERSION = "1.9.0"
4
4
  end
data/lib/theme_check.rb CHANGED
@@ -4,6 +4,7 @@ require "liquid"
4
4
  require_relative "theme_check/version"
5
5
  require_relative "theme_check/bug"
6
6
  require_relative "theme_check/exceptions"
7
+ require_relative "theme_check/schema_helper"
7
8
  require_relative "theme_check/theme_file_rewriter"
8
9
  require_relative "theme_check/theme_file"
9
10
  require_relative "theme_check/liquid_file"
@@ -24,10 +25,10 @@ require_relative "theme_check/regex_helpers"
24
25
  require_relative "theme_check/json_helpers"
25
26
  require_relative "theme_check/position_helper"
26
27
  require_relative "theme_check/position"
27
- require_relative "theme_check/language_server"
28
28
  require_relative "theme_check/checks"
29
29
  require_relative "theme_check/config"
30
30
  require_relative "theme_check/node"
31
+ require_relative "theme_check/tags"
31
32
  require_relative "theme_check/liquid_node"
32
33
  require_relative "theme_check/html_node"
33
34
  require_relative "theme_check/offense"
@@ -38,11 +39,11 @@ require_relative "theme_check/string_helpers"
38
39
  require_relative "theme_check/storage"
39
40
  require_relative "theme_check/file_system_storage"
40
41
  require_relative "theme_check/in_memory_storage"
41
- require_relative "theme_check/tags"
42
42
  require_relative "theme_check/theme"
43
43
  require_relative "theme_check/corrector"
44
44
  require_relative "theme_check/liquid_visitor"
45
45
  require_relative "theme_check/html_visitor"
46
+ require_relative "theme_check/language_server"
46
47
 
47
48
  Dir[__dir__ + "/theme_check/checks/*.rb"].each { |file| require file }
48
49
 
@@ -51,6 +52,14 @@ Encoding.default_external = Encoding::UTF_8
51
52
  Encoding.default_internal = Encoding::UTF_8
52
53
 
53
54
  module ThemeCheck
55
+ def self.debug?
56
+ ENV["THEME_CHECK_DEBUG"] == "true"
57
+ end
58
+
59
+ def self.debug_log_file
60
+ ENV["THEME_CHECK_DEBUG_LOG_FILE"]
61
+ end
62
+
54
63
  def self.with_liquid_c_disabled
55
64
  if defined?(Liquid::C)
56
65
  was_enabled = Liquid::C.enabled
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: theme-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc-André Cournoyer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-20 00:00:00.000000000 Z
11
+ date: 2021-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: liquid
@@ -121,6 +121,7 @@ files:
121
121
  - docs/checks/remote_asset.md
122
122
  - docs/checks/required_directories.md
123
123
  - docs/checks/required_layout_theme_object.md
124
+ - docs/checks/schema_json_format.md
124
125
  - docs/checks/space_inside_braces.md
125
126
  - docs/checks/syntax_error.md
126
127
  - docs/checks/template_length.md
@@ -133,6 +134,13 @@ files:
133
134
  - docs/checks/valid_json.md
134
135
  - docs/checks/valid_schema.md
135
136
  - docs/flamegraph.svg
137
+ - docs/language_server/code-action-command-palette.png
138
+ - docs/language_server/code-action-flow.png
139
+ - docs/language_server/code-action-keyboard.png
140
+ - docs/language_server/code-action-light-bulb.png
141
+ - docs/language_server/code-action-problem.png
142
+ - docs/language_server/code-action-quickfix.png
143
+ - docs/language_server/how_to_correct_code_with_code_actions_and_execute_command.md
136
144
  - docs/preview.png
137
145
  - exe/theme-check
138
146
  - exe/theme-check-language-server
@@ -173,6 +181,7 @@ files:
173
181
  - lib/theme_check/checks/remote_asset.rb
174
182
  - lib/theme_check/checks/required_directories.rb
175
183
  - lib/theme_check/checks/required_layout_theme_object.rb
184
+ - lib/theme_check/checks/schema_json_format.rb
176
185
  - lib/theme_check/checks/space_inside_braces.rb
177
186
  - lib/theme_check/checks/syntax_error.rb
178
187
  - lib/theme_check/checks/template_length.rb
@@ -201,6 +210,13 @@ files:
201
210
  - lib/theme_check/json_helpers.rb
202
211
  - lib/theme_check/json_printer.rb
203
212
  - lib/theme_check/language_server.rb
213
+ - lib/theme_check/language_server/bridge.rb
214
+ - lib/theme_check/language_server/channel.rb
215
+ - lib/theme_check/language_server/client_capabilities.rb
216
+ - lib/theme_check/language_server/code_action_engine.rb
217
+ - lib/theme_check/language_server/code_action_provider.rb
218
+ - lib/theme_check/language_server/code_action_providers/quickfix_code_action_provider.rb
219
+ - lib/theme_check/language_server/code_action_providers/source_fix_all_code_action_provider.rb
204
220
  - lib/theme_check/language_server/completion_engine.rb
205
221
  - lib/theme_check/language_server/completion_helper.rb
206
222
  - lib/theme_check/language_server/completion_provider.rb
@@ -208,21 +224,31 @@ files:
208
224
  - lib/theme_check/language_server/completion_providers/object_completion_provider.rb
209
225
  - lib/theme_check/language_server/completion_providers/render_snippet_completion_provider.rb
210
226
  - lib/theme_check/language_server/completion_providers/tag_completion_provider.rb
227
+ - lib/theme_check/language_server/configuration.rb
211
228
  - lib/theme_check/language_server/constants.rb
212
- - lib/theme_check/language_server/diagnostics_tracker.rb
229
+ - lib/theme_check/language_server/diagnostic.rb
230
+ - lib/theme_check/language_server/diagnostics_engine.rb
231
+ - lib/theme_check/language_server/diagnostics_manager.rb
232
+ - lib/theme_check/language_server/document_change_corrector.rb
213
233
  - lib/theme_check/language_server/document_link_engine.rb
214
234
  - lib/theme_check/language_server/document_link_provider.rb
215
235
  - lib/theme_check/language_server/document_link_providers/asset_document_link_provider.rb
216
236
  - lib/theme_check/language_server/document_link_providers/include_document_link_provider.rb
217
237
  - lib/theme_check/language_server/document_link_providers/render_document_link_provider.rb
218
238
  - lib/theme_check/language_server/document_link_providers/section_document_link_provider.rb
239
+ - lib/theme_check/language_server/execute_command_engine.rb
240
+ - lib/theme_check/language_server/execute_command_provider.rb
241
+ - lib/theme_check/language_server/execute_command_providers/correction_execute_command_provider.rb
242
+ - lib/theme_check/language_server/execute_command_providers/run_checks_execute_command_provider.rb
219
243
  - lib/theme_check/language_server/handler.rb
244
+ - lib/theme_check/language_server/io_messenger.rb
220
245
  - lib/theme_check/language_server/messenger.rb
221
246
  - lib/theme_check/language_server/protocol.rb
222
247
  - lib/theme_check/language_server/server.rb
223
248
  - lib/theme_check/language_server/tokens.rb
224
249
  - lib/theme_check/language_server/uri_helper.rb
225
250
  - lib/theme_check/language_server/variable_lookup_finder.rb
251
+ - lib/theme_check/language_server/versioned_in_memory_storage.rb
226
252
  - lib/theme_check/liquid_check.rb
227
253
  - lib/theme_check/liquid_file.rb
228
254
  - lib/theme_check/liquid_node.rb
@@ -238,10 +264,12 @@ files:
238
264
  - lib/theme_check/regex_helpers.rb
239
265
  - lib/theme_check/releaser.rb
240
266
  - lib/theme_check/remote_asset_file.rb
267
+ - lib/theme_check/schema_helper.rb
241
268
  - lib/theme_check/shopify_liquid.rb
242
269
  - lib/theme_check/shopify_liquid/deprecated_filter.rb
243
270
  - lib/theme_check/shopify_liquid/filter.rb
244
271
  - lib/theme_check/shopify_liquid/object.rb
272
+ - lib/theme_check/shopify_liquid/system_translations.rb
245
273
  - lib/theme_check/shopify_liquid/tag.rb
246
274
  - lib/theme_check/storage.rb
247
275
  - lib/theme_check/string_helpers.rb