klenod-lsp 0.0.16 → 0.0.18
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d759a6c56f2fae5f3fc2508aefc25cbb2c710728b6b25e9967b5f981931d26bc
|
|
4
|
+
data.tar.gz: eba78d09c5055a0a93b8daa7433b836e83c32d95832f7dca444285cbf683b9e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 987861aafeb188197a09e899ab5258c75a6655b65a0cf14da361217dd6dabec5c64cc1baf92df64e9562ef71dbf5d5598d13474928596d271d3c501b78d542c9
|
|
7
|
+
data.tar.gz: cf9bfad79548f6ce194490cd26c4524918fe25033c381d0e80078d24918315e5a439415849b8a44e0f0e62648c856b454cd40b23b7b7be2f30c7fdb91e604af9
|
|
@@ -8,7 +8,7 @@ require_relative "text"
|
|
|
8
8
|
module Klenod
|
|
9
9
|
module LSP
|
|
10
10
|
# Turns the errors in an Analysis into LSP diagnostics on the original
|
|
11
|
-
# document.
|
|
11
|
+
# document.
|
|
12
12
|
module Diagnostics
|
|
13
13
|
Interface = LanguageServer::Protocol::Interface
|
|
14
14
|
Constant = LanguageServer::Protocol::Constant
|
|
@@ -58,6 +58,29 @@ module Klenod
|
|
|
58
58
|
}.uniq { |diagnostic| [diagnostic.range.start.line, diagnostic.message] }
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
+
# A failure the graph index recorded while collecting this module that
|
|
62
|
+
# analysis alone cannot see, such as a named import of a constant the
|
|
63
|
+
# target does not define: analysis only transforms and resolves, it never
|
|
64
|
+
# collects the target's record. The index refreshes on save, so the
|
|
65
|
+
# diagnostic is only shown while the document still contains the import
|
|
66
|
+
# it refers to.
|
|
67
|
+
def index_failure(analysis, index, syntax: Languages::Syntax::Ruby)
|
|
68
|
+
error = index&.failed&.[](analysis.module_id.to_s)
|
|
69
|
+
return [] unless error.is_a?(Klenod::Build::MissingExportError)
|
|
70
|
+
return [] unless error.module_id.to_s == analysis.module_id.to_s
|
|
71
|
+
|
|
72
|
+
lines = analysis.lines
|
|
73
|
+
report = error.cause
|
|
74
|
+
span = literal_spans(report.dependency.specifier.to_s, lines, syntax: syntax).find do |candidate|
|
|
75
|
+
named_import_span?(candidate, report.name, lines)
|
|
76
|
+
end
|
|
77
|
+
return [] unless span
|
|
78
|
+
|
|
79
|
+
message = "#{error.kind}: #{error.detail}"
|
|
80
|
+
message = "#{message}\n#{error.hints.join("\n")}" unless error.hints.empty?
|
|
81
|
+
[diagnostic(span, message)]
|
|
82
|
+
end
|
|
83
|
+
|
|
61
84
|
def resolve_errors(analysis, lines, syntax)
|
|
62
85
|
analysis.resolve_errors.map do |error|
|
|
63
86
|
diagnostic(resolve_error_span(error, lines, syntax), error.message)
|
|
@@ -93,10 +116,26 @@ module Klenod
|
|
|
93
116
|
spans
|
|
94
117
|
end
|
|
95
118
|
|
|
119
|
+
# The same module can be imported more than once with different names.
|
|
120
|
+
# Match the name immediately following this literal rather than selecting
|
|
121
|
+
# the first matching specifier and inspecting its whole line.
|
|
122
|
+
def named_import_span?(span, name, lines)
|
|
123
|
+
suffix = lines[span.start.line].to_s[span.end.character..]
|
|
124
|
+
suffix&.match?(%r{\A["']\s*,\s*:#{Regexp.escape(name.to_s)}(?=\s*\))})
|
|
125
|
+
end
|
|
126
|
+
|
|
96
127
|
def diagnostic(span, message)
|
|
128
|
+
diagnostic_with_severity(span, message, Constant::DiagnosticSeverity::ERROR)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def warning(span, message)
|
|
132
|
+
diagnostic_with_severity(span, message, Constant::DiagnosticSeverity::WARNING)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def diagnostic_with_severity(span, message, severity)
|
|
97
136
|
Interface::Diagnostic.new(
|
|
98
137
|
range: span.to_range,
|
|
99
|
-
severity:
|
|
138
|
+
severity: severity,
|
|
100
139
|
source: SOURCE,
|
|
101
140
|
message: message
|
|
102
141
|
)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Klenod
|
|
4
|
+
module LSP
|
|
5
|
+
module Languages
|
|
6
|
+
class Haml
|
|
7
|
+
# Detects scripts whose nested Haml will not produce output. Haml's
|
|
8
|
+
# parser retains the body as children of the script node, which avoids
|
|
9
|
+
# guessing from indentation or warning about ordinary Ruby source in
|
|
10
|
+
# a filter.
|
|
11
|
+
module Iteration
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
ITERATOR = /\.(?<method>each|map)\b(?:\s*\([^\n]*\))?\s+do\b/
|
|
15
|
+
|
|
16
|
+
def diagnostics(analysis)
|
|
17
|
+
root = Klenod::Build::Plugins::HamlPlugin.parse_haml(analysis.source, module_id: analysis.module_id)
|
|
18
|
+
nodes = root.children.dup
|
|
19
|
+
diagnostics = []
|
|
20
|
+
|
|
21
|
+
until nodes.empty?
|
|
22
|
+
node = nodes.shift
|
|
23
|
+
nodes.concat(node.children)
|
|
24
|
+
case node.type
|
|
25
|
+
when :script
|
|
26
|
+
match = ITERATOR.match(node.value.fetch(:text))
|
|
27
|
+
diagnostics << each_diagnostic(node, match, analysis.lines) if match&.[](:method) == "each" && rendered_content?(node)
|
|
28
|
+
when :silent_script
|
|
29
|
+
diagnostics << silent_script_diagnostic(node, analysis.lines) if rendered_content?(node)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
diagnostics
|
|
34
|
+
rescue Klenod::Build::Plugins::HamlPlugin::ParseError
|
|
35
|
+
[]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def rendered_content?(node)
|
|
39
|
+
node.children.any? do |child|
|
|
40
|
+
[:plain, :script, :tag].include?(child.type) || (child.type == :filter && child.value.fetch(:name) != "ruby") || rendered_content?(child)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def each_diagnostic(node, match, lines)
|
|
45
|
+
line = node.line - 1
|
|
46
|
+
line_text = lines.fetch(line, "")
|
|
47
|
+
method_start = line_text.index(".#{match[:method]}") || 0
|
|
48
|
+
span = Text::Span.new(line, method_start, method_start + match[:method].length + 1)
|
|
49
|
+
|
|
50
|
+
Diagnostics.warning(span, "`= ...each do` returns the original collection, not the rendered Haml children; use `map` instead")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def silent_script_diagnostic(node, lines)
|
|
54
|
+
line = node.line - 1
|
|
55
|
+
line_text = lines.fetch(line, "")
|
|
56
|
+
start_character = line_text.index("-") || 0
|
|
57
|
+
span = Text::Span.new(line, start_character, start_character + 1)
|
|
58
|
+
|
|
59
|
+
Diagnostics.warning(span, "A silent `-` script discards its nested Haml content; use `=` when it should render")
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -6,6 +6,7 @@ require_relative "../text"
|
|
|
6
6
|
require_relative "imports"
|
|
7
7
|
require_relative "haml/classes"
|
|
8
8
|
require_relative "haml/completion"
|
|
9
|
+
require_relative "haml/iteration"
|
|
9
10
|
require_relative "haml/props"
|
|
10
11
|
require_relative "haml/rename"
|
|
11
12
|
|
|
@@ -23,9 +24,12 @@ module Klenod
|
|
|
23
24
|
|
|
24
25
|
def diagnostics(analysis, workspace = nil, index = nil)
|
|
25
26
|
diagnostics = Diagnostics.for_analysis(analysis)
|
|
27
|
+
diagnostics.concat(Diagnostics.index_failure(analysis, index))
|
|
26
28
|
diagnostics.concat(Classes.diagnostics(analysis, workspace, index)) if workspace && index
|
|
27
29
|
diagnostics.concat(Props.diagnostics(analysis, workspace, index)) if workspace && index
|
|
28
30
|
diagnostics.concat(unused_binding_diagnostics(analysis))
|
|
31
|
+
diagnostics.concat(Iteration.diagnostics(analysis)) unless analysis.build_error
|
|
32
|
+
diagnostics
|
|
29
33
|
end
|
|
30
34
|
|
|
31
35
|
def completion(analysis, position, workspace, index = nil)
|
|
@@ -15,8 +15,8 @@ module Klenod
|
|
|
15
15
|
|
|
16
16
|
Interface = LanguageServer::Protocol::Interface
|
|
17
17
|
|
|
18
|
-
def diagnostics(analysis, _workspace = nil,
|
|
19
|
-
Diagnostics.for_analysis(analysis) + unused_binding_diagnostics(analysis)
|
|
18
|
+
def diagnostics(analysis, _workspace = nil, index = nil)
|
|
19
|
+
Diagnostics.for_analysis(analysis) + Diagnostics.index_failure(analysis, index) + unused_binding_diagnostics(analysis)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def document_symbols(analysis)
|
data/lib/klenod/lsp/server.rb
CHANGED
|
@@ -371,11 +371,11 @@ module Klenod
|
|
|
371
371
|
|
|
372
372
|
@pending_collections.delete(document.uri)&.stop
|
|
373
373
|
@pending_collections[document.uri] =
|
|
374
|
-
@task.async do
|
|
375
|
-
|
|
374
|
+
@task.async do
|
|
375
|
+
Kernel.sleep(DIAGNOSTICS_DEBOUNCE)
|
|
376
376
|
publish_diagnostics(document)
|
|
377
377
|
overlay(document)
|
|
378
|
-
|
|
378
|
+
Kernel.sleep(COLLECTION_DEBOUNCE - DIAGNOSTICS_DEBOUNCE)
|
|
379
379
|
@pending_collections.delete(document.uri)
|
|
380
380
|
@index.ensure_collected(document.module_id, force: true)
|
|
381
381
|
end
|
data/lib/klenod/lsp/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: klenod-lsp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.18
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrés Alin
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.0.
|
|
18
|
+
version: 0.0.18
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.0.
|
|
25
|
+
version: 0.0.18
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: language_server-protocol
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -57,6 +57,7 @@ files:
|
|
|
57
57
|
- lib/klenod/lsp/languages/haml.rb
|
|
58
58
|
- lib/klenod/lsp/languages/haml/classes.rb
|
|
59
59
|
- lib/klenod/lsp/languages/haml/completion.rb
|
|
60
|
+
- lib/klenod/lsp/languages/haml/iteration.rb
|
|
60
61
|
- lib/klenod/lsp/languages/haml/props.rb
|
|
61
62
|
- lib/klenod/lsp/languages/haml/rename.rb
|
|
62
63
|
- lib/klenod/lsp/languages/haml/ruby_regions.rb
|