theme-check 1.7.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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