mt-lang 0.3.8 → 0.3.10
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/lib/milk_tea/base.rb +1 -2
- data/lib/milk_tea/bindings/bindgen/ast_parser.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/declaration.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/emitter.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/overrides.rb +0 -2
- data/lib/milk_tea/bindings/bindgen/type_mapper.rb +51 -53
- data/lib/milk_tea/bindings/imported_bindings/generator.rb +7 -9
- data/lib/milk_tea/bindings/imported_bindings/method_source.rb +0 -2
- data/lib/milk_tea/bindings/imported_bindings/naming.rb +6 -8
- data/lib/milk_tea/bindings/imported_bindings.rb +0 -2
- data/lib/milk_tea/bindings/opengl_registry.rb +3 -7
- data/lib/milk_tea/bindings/steamworks.rb +12 -16
- data/lib/milk_tea/bindings/upstream_sources.rb +10 -14
- data/lib/milk_tea/bindings/vendored_box2d.rb +10 -12
- data/lib/milk_tea/bindings/vendored_cjson.rb +6 -8
- data/lib/milk_tea/bindings/vendored_flecs.rb +10 -12
- data/lib/milk_tea/bindings/vendored_glfw.rb +11 -13
- data/lib/milk_tea/bindings/vendored_libuv.rb +11 -13
- data/lib/milk_tea/bindings/vendored_pcre2.rb +11 -13
- data/lib/milk_tea/bindings/vendored_raylib.rb +6 -10
- data/lib/milk_tea/bindings/vendored_sdl3.rb +11 -13
- data/lib/milk_tea/bindings/vendored_steamworks.rb +1 -5
- data/lib/milk_tea/core/ast.rb +103 -45
- data/lib/milk_tea/core/async_runtime_installer.rb +0 -2
- data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -3
- data/lib/milk_tea/core/c_backend/aggregate_utils.rb +147 -84
- data/lib/milk_tea/core/c_backend/control_flow_emission.rb +394 -396
- data/lib/milk_tea/core/c_backend/expressions.rb +489 -476
- data/lib/milk_tea/core/c_backend/feature_detection.rb +446 -437
- data/lib/milk_tea/core/c_backend/format_helpers.rb +0 -2
- data/lib/milk_tea/core/c_backend/reachability.rb +339 -341
- data/lib/milk_tea/core/c_backend/reinterpret.rb +231 -217
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +531 -526
- data/lib/milk_tea/core/c_backend/statements.rb +528 -530
- data/lib/milk_tea/core/c_backend/type_collectors.rb +1344 -1346
- data/lib/milk_tea/core/c_backend/type_declaration.rb +215 -213
- data/lib/milk_tea/core/c_backend/type_system.rb +347 -349
- data/lib/milk_tea/core/c_backend.rb +17 -9
- data/lib/milk_tea/core/compatibility_helpers.rb +0 -2
- data/lib/milk_tea/core/compile_time/const_eval.rb +7 -12
- data/lib/milk_tea/core/compile_time.rb +32 -38
- data/lib/milk_tea/core/control_flow/builder.rb +3 -5
- data/lib/milk_tea/core/control_flow/constant_propagation.rb +14 -17
- data/lib/milk_tea/core/control_flow/definite_assignment.rb +0 -1
- data/lib/milk_tea/core/ir.rb +10 -10
- data/lib/milk_tea/core/lexer/character_classes.rb +5 -7
- data/lib/milk_tea/core/lexer/format_strings.rb +7 -9
- data/lib/milk_tea/core/lexer/heredocs.rb +22 -22
- data/lib/milk_tea/core/lexer/indentation.rb +0 -2
- data/lib/milk_tea/core/lexer/numbers.rb +0 -2
- data/lib/milk_tea/core/lexer/recovery.rb +0 -2
- data/lib/milk_tea/core/lexer/strings.rb +0 -2
- data/lib/milk_tea/core/lexer/symbols.rb +0 -2
- data/lib/milk_tea/core/lexer/trivia.rb +0 -2
- data/lib/milk_tea/core/lexer.rb +0 -2
- data/lib/milk_tea/core/lowering/async/analysis.rb +0 -2
- data/lib/milk_tea/core/lowering/async/lowering.rb +1264 -1265
- data/lib/milk_tea/core/lowering/async/normalization.rb +0 -2
- data/lib/milk_tea/core/lowering/async.rb +627 -630
- data/lib/milk_tea/core/lowering/block.rb +413 -416
- data/lib/milk_tea/core/lowering/calls.rb +1381 -1384
- data/lib/milk_tea/core/lowering/declarations.rb +180 -183
- data/lib/milk_tea/core/lowering/dyn.rb +48 -50
- data/lib/milk_tea/core/lowering/events.rb +983 -985
- data/lib/milk_tea/core/lowering/expressions.rb +1513 -1518
- data/lib/milk_tea/core/lowering/foreign_cstr.rb +181 -184
- data/lib/milk_tea/core/lowering/functions.rb +185 -188
- data/lib/milk_tea/core/lowering/loops.rb +1028 -1031
- data/lib/milk_tea/core/lowering/proc.rb +363 -366
- data/lib/milk_tea/core/lowering/resolve.rb +2133 -2135
- data/lib/milk_tea/core/lowering/scans.rb +179 -181
- data/lib/milk_tea/core/lowering/str_buffer.rb +102 -105
- data/lib/milk_tea/core/lowering/utils.rb +1040 -1044
- data/lib/milk_tea/core/lowering.rb +5 -7
- data/lib/milk_tea/core/module_binder.rb +0 -2
- data/lib/milk_tea/core/module_loader/errors.rb +4 -2
- data/lib/milk_tea/core/module_loader.rb +113 -20
- data/lib/milk_tea/core/module_path_resolver.rb +0 -2
- data/lib/milk_tea/core/module_roots.rb +6 -8
- data/lib/milk_tea/core/parser/attributes.rb +0 -2
- data/lib/milk_tea/core/parser/blocks.rb +0 -2
- data/lib/milk_tea/core/parser/declarations.rb +0 -2
- data/lib/milk_tea/core/parser/expressions.rb +31 -14
- data/lib/milk_tea/core/parser/recovery.rb +0 -2
- data/lib/milk_tea/core/parser/statements.rb +0 -2
- data/lib/milk_tea/core/parser/types.rb +8 -10
- data/lib/milk_tea/core/parser.rb +1 -3
- data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +31 -33
- data/lib/milk_tea/core/pretty_printer/base_formatter.rb +0 -2
- data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/attributes.rb +14 -16
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -14
- data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +18 -21
- data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +0 -3
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +12 -15
- data/lib/milk_tea/core/semantic_analyzer/generics.rb +57 -59
- data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +0 -2
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +5 -9
- data/lib/milk_tea/core/semantic_analyzer/nullability.rb +0 -3
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +35 -40
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +10 -12
- data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -6
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +102 -105
- data/lib/milk_tea/core/semantic_analyzer.rb +17 -8
- data/lib/milk_tea/core/types/layout.rb +21 -22
- data/lib/milk_tea/core/types/predicates.rb +0 -2
- data/lib/milk_tea/core/types/registry.rb +16 -18
- data/lib/milk_tea/core/types/visitor.rb +0 -4
- data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -2
- data/lib/milk_tea/dap/protocol.rb +1 -1
- data/lib/milk_tea/dap/server/breakpoints.rb +0 -2
- data/lib/milk_tea/dap/server/debug_map.rb +0 -2
- data/lib/milk_tea/dap/server/handlers.rb +0 -2
- data/lib/milk_tea/dap/server/launch.rb +0 -2
- data/lib/milk_tea/dap/server/lldb_backend.rb +8 -10
- data/lib/milk_tea/dap/server/pause_diagnostics.rb +14 -16
- data/lib/milk_tea/dap/server/utilities.rb +0 -2
- data/lib/milk_tea/dap/server/wire.rb +0 -2
- data/lib/milk_tea/dap/server.rb +0 -2
- data/lib/milk_tea/lsp/diagnostics.rb +16 -16
- data/lib/milk_tea/lsp/server/call_hierarchy.rb +11 -12
- data/lib/milk_tea/lsp/server/code_actions.rb +355 -357
- data/lib/milk_tea/lsp/server/code_lens.rb +23 -25
- data/lib/milk_tea/lsp/server/completion.rb +873 -875
- data/lib/milk_tea/lsp/server/configuration.rb +129 -131
- data/lib/milk_tea/lsp/server/debug_info.rb +0 -2
- data/lib/milk_tea/lsp/server/definition.rb +564 -565
- data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +191 -193
- data/lib/milk_tea/lsp/server/execute_command.rb +0 -2
- data/lib/milk_tea/lsp/server/folding_range.rb +0 -4
- data/lib/milk_tea/lsp/server/formatting.rb +478 -480
- data/lib/milk_tea/lsp/server/hover.rb +1282 -1284
- data/lib/milk_tea/lsp/server/inlay_hints.rb +179 -181
- data/lib/milk_tea/lsp/server/lifecycle.rb +192 -194
- data/lib/milk_tea/lsp/server/linked_editing_range.rb +0 -2
- data/lib/milk_tea/lsp/server/on_type_formatting.rb +0 -2
- data/lib/milk_tea/lsp/server/progress.rb +0 -2
- data/lib/milk_tea/lsp/server/references.rb +316 -318
- data/lib/milk_tea/lsp/server/rename.rb +445 -447
- data/lib/milk_tea/lsp/server/selection_range.rb +0 -4
- data/lib/milk_tea/lsp/server/semantic_tokens.rb +1318 -1320
- data/lib/milk_tea/lsp/server/signature_help.rb +146 -148
- data/lib/milk_tea/lsp/server/text_documents.rb +99 -101
- data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -4
- data/lib/milk_tea/lsp/server/utilities.rb +397 -399
- data/lib/milk_tea/lsp/server.rb +0 -3
- data/lib/milk_tea/lsp/workspace/analysis.rb +40 -42
- data/lib/milk_tea/lsp/workspace/dependency_graph.rb +4 -10
- data/lib/milk_tea/lsp/workspace/utilities.rb +19 -19
- data/lib/milk_tea/packages/atomic_write.rb +4 -5
- data/lib/milk_tea/packages/dependency_solver.rb +15 -15
- data/lib/milk_tea/packages/lock.rb +4 -4
- data/lib/milk_tea/packages/manager_cli.rb +1 -1
- data/lib/milk_tea/packages/manifest.rb +3 -3
- data/lib/milk_tea/packages/registry_store.rb +4 -6
- data/lib/milk_tea/packages/services.rb +16 -16
- data/lib/milk_tea/packages/source_cache.rb +4 -6
- data/lib/milk_tea/packages/source_resolver.rb +44 -44
- data/lib/milk_tea/packages/version.rb +8 -8
- data/lib/milk_tea/tooling/build.rb +3 -7
- data/lib/milk_tea/tooling/build_cache.rb +0 -2
- data/lib/milk_tea/tooling/debug_info_formatter.rb +31 -33
- data/lib/milk_tea/tooling/debug_map.rb +8 -10
- data/lib/milk_tea/tooling/docs_app.rb +0 -2
- data/lib/milk_tea/tooling/linter/doc_tags.rb +25 -27
- data/lib/milk_tea/tooling/linter/fix_engine.rb +87 -24
- data/lib/milk_tea/tooling/linter/flow_rules.rb +44 -46
- data/lib/milk_tea/tooling/linter/imports_platform.rb +14 -16
- data/lib/milk_tea/tooling/linter/release_rules.rb +3 -5
- data/lib/milk_tea/tooling/linter/reserved_names.rb +23 -25
- data/lib/milk_tea/tooling/linter/rules.rb +87 -89
- data/lib/milk_tea/tooling/linter/source_helpers.rb +40 -42
- data/lib/milk_tea/tooling/linter/trailing_comma.rb +17 -19
- data/lib/milk_tea/tooling/linter/visitors.rb +162 -50
- data/lib/milk_tea/tooling/linter.rb +0 -2
- data/lib/milk_tea/tooling/project_scaffold.rb +0 -2
- data/lib/milk_tea/tooling/run.rb +0 -2
- data/lib/milk_tea/tooling/toolchain_cli.rb +0 -2
- data/std/cli.mt +13 -32
- data/std/color.mt +28 -28
- data/std/encoding.mt +4 -4
- data/std/graph.mt +1 -2
- data/std/hash.mt +14 -14
- data/std/http/server.mt +3 -3
- data/std/input.mt +1 -1
- data/std/json.mt +1 -1
- data/std/linear_algebra.mt +6 -6
- data/std/net/mux.mt +1 -1
- data/std/noise.mt +23 -23
- data/std/parse.mt +2 -2
- data/std/process.mt +3 -4
- data/std/sparse_set.mt +1 -1
- data/std/steering.mt +5 -5
- data/std/str.mt +1 -1
- data/std/tween.mt +4 -4
- data/std/utility.mt +3 -3
- metadata +2 -2
|
@@ -4,516 +4,514 @@ module MilkTea
|
|
|
4
4
|
module LSP
|
|
5
5
|
class Server
|
|
6
6
|
module ServerUtilities
|
|
7
|
-
|
|
7
|
+
def perf_logging?
|
|
8
|
+
@perf_logging ||= !ENV.fetch('MILK_TEA_LSP_PERF', nil).to_s.empty?
|
|
9
|
+
end
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
def perf_verbose?
|
|
12
|
+
@perf_verbose ||= ENV.fetch('MILK_TEA_LSP_PERF', nil).to_s == 'verbose'
|
|
13
|
+
end
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
def perf_breakdown_logging?(elapsed_ms)
|
|
16
|
+
perf_logging? && (perf_verbose? || elapsed_ms > Workspace::PERF_LOG_THRESHOLD_MS)
|
|
17
|
+
end
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
def monotonic_time
|
|
20
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
21
|
+
end
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
def elapsed_ms(start_time)
|
|
24
|
+
((monotonic_time - start_time) * 1000).round(1)
|
|
25
|
+
end
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
end
|
|
27
|
+
def log_perf_breakdown(method_name, elapsed_ms_value, detail)
|
|
28
|
+
return unless perf_breakdown_logging?(elapsed_ms_value)
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
id_detail = @current_request_id ? " id=#{@current_request_id}" : ''
|
|
31
|
+
warn "[LSP perf] breakdown #{method_name} #{elapsed_ms_value}ms#{id_detail} #{detail}"
|
|
32
|
+
end
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
def new_perf_stages
|
|
35
|
+
perf_logging? ? [] : nil
|
|
36
|
+
end
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
38
|
+
def measure_perf_stage(stages, name)
|
|
39
|
+
return yield unless stages
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
start_time = monotonic_time
|
|
42
|
+
result = yield
|
|
43
|
+
stages << [name, elapsed_ms(start_time)]
|
|
44
|
+
result
|
|
45
|
+
end
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
stages << [name, elapsed_ms(start_time)]
|
|
46
|
-
result
|
|
47
|
-
end
|
|
47
|
+
def log_request_stage_breakdown(method_name, total_start, uri: nil, stages: nil, summary: nil)
|
|
48
|
+
return unless total_start
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
detail = []
|
|
51
|
+
detail << "uri=#{shorten_uri(uri) || uri}" if uri
|
|
52
|
+
detail << summary if summary && !summary.empty?
|
|
53
|
+
unless stages.nil? || stages.empty?
|
|
54
|
+
detail << "stages_ms=#{stages.map { |name, ms| "#{name}:#{ms}" }.join(',')}"
|
|
55
|
+
end
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
detail << "uri=#{shorten_uri(uri) || uri}" if uri
|
|
54
|
-
detail << summary if summary && !summary.empty?
|
|
55
|
-
unless stages.nil? || stages.empty?
|
|
56
|
-
detail << "stages_ms=#{stages.map { |name, ms| "#{name}:#{ms}" }.join(',')}"
|
|
57
|
+
log_perf_breakdown(method_name, elapsed_ms(total_start), detail.join(' '))
|
|
57
58
|
end
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
def perf_log_context(method_name, params, verbose: false)
|
|
61
|
+
return "" unless params.is_a?(Hash)
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
summary = summarize_lsp_params(method_name, params)
|
|
64
|
+
return summary.empty? ? "" : " #{summary}" if verbose
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
text_document = hget(params, 'textDocument')
|
|
67
|
+
uri = text_document.is_a?(Hash) ? hget(text_document, 'uri') : nil
|
|
68
|
+
bits = []
|
|
69
|
+
bits << "uri=#{shorten_uri(uri) || uri}" if uri
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
if method_name == 'textDocument/didChange'
|
|
72
|
+
changes = hget(params, 'contentChanges')
|
|
73
|
+
bits << "changes=#{changes.length}" if changes.respond_to?(:length)
|
|
74
|
+
end
|
|
72
75
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
bits.empty? ? "" : " #{bits.join(' ')}"
|
|
77
|
+
rescue StandardError
|
|
78
|
+
""
|
|
76
79
|
end
|
|
77
80
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
81
|
+
def summarize_lsp_params(method_name, params)
|
|
82
|
+
return "" unless params.is_a?(Hash)
|
|
83
|
+
|
|
84
|
+
text_document = hget(params, 'textDocument')
|
|
85
|
+
uri = text_document.is_a?(Hash) ? hget(text_document, 'uri') : nil
|
|
86
|
+
file_path = uri_to_path(uri)
|
|
87
|
+
short_uri = shorten_uri(uri)
|
|
88
|
+
position = hget(params, 'position')
|
|
89
|
+
line = position.is_a?(Hash) ? hget(position, 'line') : nil
|
|
90
|
+
char = position.is_a?(Hash) ? hget(position, 'character') : nil
|
|
91
|
+
pos = "#{line}:#{char}" if line && char
|
|
92
|
+
query = hget(params, 'query')
|
|
93
|
+
|
|
94
|
+
bits = []
|
|
95
|
+
bits << "uri=#{short_uri || uri}" if uri
|
|
96
|
+
bits << "pos=#{pos}" if pos
|
|
97
|
+
if file_path && line.is_a?(Integer) && char.is_a?(Integer)
|
|
98
|
+
bits << "loc=#{file_path}:#{line + 1}:#{char + 1}"
|
|
99
|
+
end
|
|
100
|
+
bits << "query=#{query.inspect}" if query
|
|
101
|
+
bits << "keys=#{params.keys.map(&:to_s).sort.join(',')}" unless params.empty?
|
|
95
102
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
bits << "loc=#{file_path}:#{line + 1}:#{char + 1}"
|
|
101
|
-
end
|
|
102
|
-
bits << "query=#{query.inspect}" if query
|
|
103
|
-
bits << "keys=#{params.keys.map(&:to_s).sort.join(',')}" unless params.empty?
|
|
103
|
+
if method_name == 'textDocument/didChange'
|
|
104
|
+
changes = hget(params, 'contentChanges')
|
|
105
|
+
bits << "changes=#{changes.length}" if changes.respond_to?(:length)
|
|
106
|
+
end
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
bits.join(' ')
|
|
109
|
+
rescue StandardError
|
|
110
|
+
""
|
|
108
111
|
end
|
|
109
112
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
""
|
|
113
|
-
end
|
|
113
|
+
def hget(hash, key)
|
|
114
|
+
return nil unless hash.is_a?(Hash)
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
hash[key] || hash[key.to_sym]
|
|
117
|
+
end
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
def shorten_uri(uri)
|
|
120
|
+
return nil unless uri
|
|
121
|
+
return uri unless uri.is_a?(String) && uri.start_with?('file://')
|
|
120
122
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return uri unless uri.is_a?(String) && uri.start_with?('file://')
|
|
123
|
+
file_path = uri_to_path(uri)
|
|
124
|
+
return uri unless file_path
|
|
124
125
|
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
root_path = uri_to_path(@root_uri)
|
|
127
|
+
return uri unless root_path
|
|
127
128
|
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
begin
|
|
130
|
+
relative = Pathname.new(file_path).relative_path_from(Pathname.new(root_path)).to_s
|
|
131
|
+
return relative unless relative.start_with?('..')
|
|
132
|
+
rescue StandardError
|
|
133
|
+
# Keep the original URI if path normalization fails.
|
|
134
|
+
end
|
|
130
135
|
|
|
131
|
-
|
|
132
|
-
relative = Pathname.new(file_path).relative_path_from(Pathname.new(root_path)).to_s
|
|
133
|
-
return relative unless relative.start_with?('..')
|
|
134
|
-
rescue StandardError
|
|
135
|
-
# Keep the original URI if path normalization fails.
|
|
136
|
+
uri
|
|
136
137
|
end
|
|
137
138
|
|
|
138
|
-
uri
|
|
139
|
-
|
|
139
|
+
def uri_to_path(uri)
|
|
140
|
+
parsed = URI.parse(uri)
|
|
141
|
+
return nil unless parsed.scheme == 'file'
|
|
140
142
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
CGI.unescape(parsed.path)
|
|
144
|
+
rescue URI::InvalidURIError
|
|
145
|
+
nil
|
|
146
|
+
end
|
|
144
147
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
nil
|
|
148
|
-
end
|
|
148
|
+
def library_uri?(uri)
|
|
149
|
+
return false unless @root_uri
|
|
149
150
|
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
file_path = uri_to_path(uri)
|
|
152
|
+
root_path = uri_to_path(@root_uri)
|
|
153
|
+
return false unless file_path && root_path
|
|
152
154
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
!file_path.start_with?(root_path)
|
|
156
|
+
rescue StandardError
|
|
157
|
+
false
|
|
158
|
+
end
|
|
156
159
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
160
|
+
def skip_expensive_source_fix_all?(uri, content)
|
|
161
|
+
!skip_expensive_work_reason(uri, content).nil?
|
|
162
|
+
rescue StandardError
|
|
163
|
+
false
|
|
164
|
+
end
|
|
161
165
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
rescue StandardError
|
|
165
|
-
false
|
|
166
|
-
end
|
|
166
|
+
def skip_expensive_work_reason(uri, content)
|
|
167
|
+
return 'library-uri' if library_uri?(uri)
|
|
167
168
|
|
|
168
|
-
|
|
169
|
-
|
|
169
|
+
# Heuristic thresholds to avoid expensive full-file lint-fix runs.
|
|
170
|
+
return 'large-bytes' if content.bytesize > 200_000
|
|
171
|
+
return 'large-lines' if content.count("\n") > 1200
|
|
170
172
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
173
|
+
nil
|
|
174
|
+
rescue StandardError
|
|
175
|
+
nil
|
|
176
|
+
end
|
|
174
177
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
def handle_did_change_watched_files(params)
|
|
179
|
+
changes = params['changes'] || []
|
|
180
|
+
affected_uris = Set.new
|
|
181
|
+
changes.each do |change|
|
|
182
|
+
uri = change['uri']
|
|
183
|
+
type = change['type']
|
|
184
|
+
next unless uri
|
|
179
185
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
affected_uris = Set.new
|
|
183
|
-
changes.each do |change|
|
|
184
|
-
uri = change['uri']
|
|
185
|
-
type = change['type']
|
|
186
|
-
next unless uri
|
|
186
|
+
affected_uris.merge(@workspace.apply_watched_file_change(uri, type))
|
|
187
|
+
end
|
|
187
188
|
|
|
188
|
-
affected_uris
|
|
189
|
+
invalidate_document_caches_for(affected_uris)
|
|
190
|
+
affected_uris.each do |affected_uri|
|
|
191
|
+
schedule_diagnostics(affected_uri, force: true, lint_tier: :full) unless @workspace.background_document?(affected_uri)
|
|
192
|
+
end
|
|
193
|
+
refresh_client_semantic_tokens if affected_uris.any?
|
|
194
|
+
nil
|
|
189
195
|
end
|
|
190
196
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
197
|
+
def invalidate_document_caches(uri)
|
|
198
|
+
@semantic_tokens_cache.delete(uri)
|
|
199
|
+
@semantic_tokens_delta_cache.delete(uri)
|
|
200
|
+
@fixall_cache.delete(uri)
|
|
201
|
+
path = uri_to_path(uri)
|
|
202
|
+
if path
|
|
203
|
+
prefix = "#{path}:"
|
|
204
|
+
@definition_file_token_cache.delete_if { |key, _| key.start_with?(prefix) }
|
|
205
|
+
@definition_file_ast_cache.delete_if { |key, _| key.start_with?(prefix) }
|
|
206
|
+
end
|
|
194
207
|
end
|
|
195
|
-
refresh_client_semantic_tokens if affected_uris.any?
|
|
196
|
-
nil
|
|
197
|
-
end
|
|
198
208
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
@semantic_tokens_delta_cache.delete(uri)
|
|
202
|
-
@fixall_cache.delete(uri)
|
|
203
|
-
path = uri_to_path(uri)
|
|
204
|
-
if path
|
|
205
|
-
prefix = "#{path}:"
|
|
206
|
-
@definition_file_token_cache.delete_if { |key, _| key.start_with?(prefix) }
|
|
207
|
-
@definition_file_ast_cache.delete_if { |key, _| key.start_with?(prefix) }
|
|
209
|
+
def invalidate_document_caches_for(uris)
|
|
210
|
+
uris.each { |uri| invalidate_document_caches(uri) }
|
|
208
211
|
end
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
def invalidate_document_caches_for(uris)
|
|
212
|
-
uris.each { |uri| invalidate_document_caches(uri) }
|
|
213
|
-
end
|
|
214
212
|
|
|
215
|
-
|
|
216
|
-
|
|
213
|
+
def refresh_open_document_dependency_state(changed_uri, previous_content: nil, current_content: nil)
|
|
214
|
+
return [] unless dependency_refresh_required_for_edit?(changed_uri, previous_content, current_content)
|
|
217
215
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
216
|
+
affected_uris = @workspace.refresh_open_document_dependency_caches(changed_uri)
|
|
217
|
+
invalidate_document_caches_for(affected_uris)
|
|
218
|
+
affected_uris.each do |affected_uri|
|
|
219
|
+
schedule_diagnostics(affected_uri, force: true, lint_tier: :full) unless @workspace.background_document?(affected_uri)
|
|
220
|
+
end
|
|
221
|
+
affected_uris
|
|
222
222
|
end
|
|
223
|
-
affected_uris
|
|
224
|
-
end
|
|
225
223
|
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
def request_cancelled?(id)
|
|
225
|
+
return false if id.nil?
|
|
228
226
|
|
|
229
|
-
|
|
230
|
-
|
|
227
|
+
@cancelled_requests_mutex.synchronize do
|
|
228
|
+
@cancelled_request_ids.include?(id)
|
|
229
|
+
end
|
|
231
230
|
end
|
|
232
|
-
end
|
|
233
231
|
|
|
234
|
-
|
|
235
|
-
|
|
232
|
+
def clear_cancelled_request(id)
|
|
233
|
+
return if id.nil?
|
|
236
234
|
|
|
237
|
-
|
|
238
|
-
|
|
235
|
+
@cancelled_requests_mutex.synchronize do
|
|
236
|
+
@cancelled_request_ids.delete(id)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def format_symbol(sym, uri)
|
|
241
|
+
line = sym[:line].to_i
|
|
242
|
+
col = sym[:column].to_i
|
|
243
|
+
|
|
244
|
+
{
|
|
245
|
+
name: sym[:name],
|
|
246
|
+
kind: symbol_kind(sym[:kind]),
|
|
247
|
+
location: {
|
|
248
|
+
uri: uri,
|
|
249
|
+
range: {
|
|
250
|
+
start: { line: line - 1, character: col - 1 },
|
|
251
|
+
end: { line: line - 1, character: col - 1 + sym[:name].length }
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
239
255
|
end
|
|
240
|
-
end
|
|
241
256
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
257
|
+
def format_document_symbol(sym)
|
|
258
|
+
line = sym[:line].to_i
|
|
259
|
+
col = sym[:column].to_i
|
|
245
260
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
261
|
+
{
|
|
262
|
+
name: sym[:name],
|
|
263
|
+
kind: symbol_kind(sym[:kind]),
|
|
264
|
+
range: {
|
|
265
|
+
start: { line: line - 1, character: col - 1 },
|
|
266
|
+
end: { line: line - 1, character: col - 1 + sym[:name].length }
|
|
267
|
+
},
|
|
268
|
+
selectionRange: {
|
|
252
269
|
start: { line: line - 1, character: col - 1 },
|
|
253
270
|
end: { line: line - 1, character: col - 1 + sym[:name].length }
|
|
254
271
|
}
|
|
255
272
|
}
|
|
256
|
-
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def format_document_symbol(sym)
|
|
260
|
-
line = sym[:line].to_i
|
|
261
|
-
col = sym[:column].to_i
|
|
262
|
-
|
|
263
|
-
{
|
|
264
|
-
name: sym[:name],
|
|
265
|
-
kind: symbol_kind(sym[:kind]),
|
|
266
|
-
range: {
|
|
267
|
-
start: { line: line - 1, character: col - 1 },
|
|
268
|
-
end: { line: line - 1, character: col - 1 + sym[:name].length }
|
|
269
|
-
},
|
|
270
|
-
selectionRange: {
|
|
271
|
-
start: { line: line - 1, character: col - 1 },
|
|
272
|
-
end: { line: line - 1, character: col - 1 + sym[:name].length }
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
end
|
|
273
|
+
end
|
|
276
274
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
275
|
+
def symbol_kind(kind)
|
|
276
|
+
case kind
|
|
277
|
+
when 'function' then 12 # Function
|
|
278
|
+
when 'interface' then 11 # Interface
|
|
279
|
+
when 'struct' then 23 # Struct
|
|
280
|
+
when 'union' then 23 # Struct (union is a struct variant)
|
|
281
|
+
when 'enum' then 10 # Enum
|
|
282
|
+
when 'flags' then 10 # Enum (flags is an enum variant)
|
|
283
|
+
when 'variant' then 23 # Struct (variant is a struct variant)
|
|
284
|
+
when 'type_alias' then 5 # Class
|
|
285
|
+
when 'constant' then 14 # Constant
|
|
286
|
+
when 'variable' then 13 # Variable
|
|
287
|
+
when 'event' then 24 # Event
|
|
288
|
+
when 'type_param' then 26 # TypeParameter
|
|
289
|
+
else 1 # File
|
|
290
|
+
end
|
|
292
291
|
end
|
|
293
|
-
end
|
|
294
292
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
293
|
+
def current_word_prefix(uri, lsp_line, lsp_char)
|
|
294
|
+
content = @workspace.get_content(uri)
|
|
295
|
+
lines = content.split("\n", -1)
|
|
296
|
+
line = lines[lsp_line] || ''
|
|
297
|
+
# Walk backwards from cursor to find start of current word
|
|
298
|
+
char_idx = [lsp_char - 1, line.length - 1].min
|
|
299
|
+
return '' if char_idx < 0
|
|
300
|
+
|
|
301
|
+
start = char_idx
|
|
302
|
+
start -= 1 while start >= 0 && line[start] =~ /[A-Za-z0-9_]/
|
|
303
|
+
line[(start + 1)..char_idx] || ''
|
|
304
|
+
end
|
|
307
305
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
306
|
+
def token_to_range(token)
|
|
307
|
+
end_line, end_character = token_end_position(token)
|
|
308
|
+
start_line = token.line - 1
|
|
309
|
+
start_char = encode_char_for_client(start_line, token.column - 1)
|
|
310
|
+
end_char = encode_char_for_client(end_line, end_character)
|
|
313
311
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
312
|
+
{
|
|
313
|
+
start: { line: start_line, character: start_char },
|
|
314
|
+
end: { line: end_line, character: end_char }
|
|
315
|
+
}
|
|
316
|
+
end
|
|
319
317
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
318
|
+
def token_end_position(token)
|
|
319
|
+
segments = token.lexeme.split("\n", -1)
|
|
320
|
+
if segments.length == 1
|
|
321
|
+
[token.line - 1, token.column - 1 + segments.first.length]
|
|
322
|
+
else
|
|
323
|
+
[token.line - 1 + segments.length - 1, segments.last.length]
|
|
324
|
+
end
|
|
326
325
|
end
|
|
327
|
-
end
|
|
328
326
|
|
|
329
|
-
|
|
330
|
-
|
|
327
|
+
def encode_char_for_client(lsp_line, internal_char)
|
|
328
|
+
return internal_char if @position_encoding == 'utf-16'
|
|
331
329
|
|
|
332
|
-
|
|
333
|
-
|
|
330
|
+
internal_char
|
|
331
|
+
end
|
|
334
332
|
|
|
335
|
-
|
|
336
|
-
|
|
333
|
+
def decode_client_char(uri, lsp_line, client_char)
|
|
334
|
+
return client_char if @position_encoding == 'utf-16'
|
|
337
335
|
|
|
338
|
-
|
|
339
|
-
|
|
336
|
+
content = @workspace.get_content(uri)
|
|
337
|
+
return client_char unless content
|
|
340
338
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
339
|
+
lines = content.split("\n", -1)
|
|
340
|
+
line_text = lines[lsp_line]
|
|
341
|
+
return client_char unless line_text
|
|
344
342
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
343
|
+
if @position_encoding == 'utf-8'
|
|
344
|
+
utf8_to_utf16_char(line_text, client_char)
|
|
345
|
+
elsif @position_encoding == 'utf-32'
|
|
346
|
+
utf32_to_utf16_char(line_text, client_char)
|
|
347
|
+
else
|
|
348
|
+
client_char
|
|
349
|
+
end
|
|
351
350
|
end
|
|
352
|
-
end
|
|
353
351
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
352
|
+
def utf8_to_utf16_char(line_text, utf8_offset)
|
|
353
|
+
bytes_seen = 0
|
|
354
|
+
utf16_count = 0
|
|
355
|
+
line_text.each_char do |ch|
|
|
356
|
+
break if bytes_seen >= utf8_offset
|
|
357
|
+
bytes_seen += ch.bytesize
|
|
358
|
+
utf16_count += ch.ord > 0xFFFF ? 2 : 1
|
|
359
|
+
end
|
|
360
|
+
utf16_count
|
|
361
361
|
end
|
|
362
|
-
utf16_count
|
|
363
|
-
end
|
|
364
362
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
363
|
+
def utf32_to_utf16_char(line_text, utf32_offset)
|
|
364
|
+
utf16_count = 0
|
|
365
|
+
line_text.each_char.with_index do |ch, idx|
|
|
366
|
+
break if idx >= utf32_offset
|
|
367
|
+
utf16_count += ch.ord > 0xFFFF ? 2 : 1
|
|
368
|
+
end
|
|
369
|
+
utf16_count
|
|
370
370
|
end
|
|
371
|
-
utf16_count
|
|
372
|
-
end
|
|
373
371
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
372
|
+
def diagnostics_fingerprint(content, diagnostics)
|
|
373
|
+
[content, diagnostics].hash.to_s(16)
|
|
374
|
+
end
|
|
377
375
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
376
|
+
def next_diagnostic_result_id(uri, fingerprint)
|
|
377
|
+
"#{uri}:#{fingerprint}"
|
|
378
|
+
end
|
|
381
379
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
380
|
+
def path_to_uri(path)
|
|
381
|
+
escaped_path = path.split('/').map { |seg| CGI.escape(seg).gsub('+', '%20') }.join('/')
|
|
382
|
+
"file://#{escaped_path}"
|
|
383
|
+
end
|
|
386
384
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
385
|
+
def collect_call_argument_starts(tokens, lparen_index)
|
|
386
|
+
starts = []
|
|
387
|
+
depth = 1
|
|
388
|
+
j = lparen_index + 1
|
|
389
|
+
|
|
390
|
+
first = next_non_trivia_token(tokens, j)
|
|
391
|
+
starts << first if first && first.type != :rparen
|
|
392
|
+
|
|
393
|
+
while j < tokens.length
|
|
394
|
+
tok = tokens[j]
|
|
395
|
+
case tok.type
|
|
396
|
+
when :lparen
|
|
397
|
+
depth += 1
|
|
398
|
+
when :rparen
|
|
399
|
+
depth -= 1
|
|
400
|
+
return [starts, j] if depth.zero?
|
|
401
|
+
when :comma
|
|
402
|
+
if depth == 1
|
|
403
|
+
next_tok = next_non_trivia_token(tokens, j + 1)
|
|
404
|
+
starts << next_tok if next_tok && next_tok.type != :rparen
|
|
405
|
+
end
|
|
407
406
|
end
|
|
407
|
+
j += 1
|
|
408
408
|
end
|
|
409
|
-
|
|
409
|
+
|
|
410
|
+
[starts, nil]
|
|
410
411
|
end
|
|
411
412
|
|
|
412
|
-
|
|
413
|
-
|
|
413
|
+
def self_describing_argument_expression?(tokens, arg_tok)
|
|
414
|
+
arg_index = tokens.index(arg_tok)
|
|
415
|
+
return false unless arg_index
|
|
414
416
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
return false unless arg_index
|
|
417
|
+
simple_identifier_like_argument_expression?(tokens, arg_index)
|
|
418
|
+
end
|
|
418
419
|
|
|
419
|
-
simple_identifier_like_argument_expression?(tokens,
|
|
420
|
-
|
|
420
|
+
def simple_identifier_like_argument_expression?(tokens, start_index)
|
|
421
|
+
saw_identifier = false
|
|
422
|
+
expect_identifier = true
|
|
423
|
+
i = start_index
|
|
421
424
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
425
|
+
while i < tokens.length
|
|
426
|
+
tok = tokens[i]
|
|
427
|
+
break if [:comma, :rparen].include?(tok.type)
|
|
428
|
+
return false if [:newline, :indent, :dedent].include?(tok.type)
|
|
426
429
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
break if [:comma, :rparen].include?(tok.type)
|
|
430
|
-
return false if [:newline, :indent, :dedent].include?(tok.type)
|
|
430
|
+
if expect_identifier
|
|
431
|
+
return false unless tok.type == :identifier
|
|
431
432
|
|
|
432
|
-
|
|
433
|
-
|
|
433
|
+
saw_identifier = true
|
|
434
|
+
expect_identifier = false
|
|
435
|
+
else
|
|
436
|
+
return false unless tok.type == :dot
|
|
434
437
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
else
|
|
438
|
-
return false unless tok.type == :dot
|
|
438
|
+
expect_identifier = true
|
|
439
|
+
end
|
|
439
440
|
|
|
440
|
-
|
|
441
|
+
i += 1
|
|
441
442
|
end
|
|
442
443
|
|
|
443
|
-
|
|
444
|
+
saw_identifier && !expect_identifier
|
|
444
445
|
end
|
|
445
446
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
i += 1
|
|
447
|
+
def next_non_trivia_token(tokens, index)
|
|
448
|
+
i = index
|
|
449
|
+
while i < tokens.length
|
|
450
|
+
tok = tokens[i]
|
|
451
|
+
return tok unless [:newline, :indent, :dedent].include?(tok.type)
|
|
452
|
+
i += 1
|
|
453
|
+
end
|
|
454
|
+
nil
|
|
455
455
|
end
|
|
456
|
-
nil
|
|
457
|
-
end
|
|
458
|
-
|
|
459
|
-
def position_in_range?(line, char, start_line, start_char, end_line, end_char)
|
|
460
|
-
after_start = (line > start_line) || (line == start_line && char >= start_char)
|
|
461
|
-
before_end = (line < end_line) || (line == end_line && char <= end_char)
|
|
462
|
-
after_start && before_end
|
|
463
|
-
end
|
|
464
456
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
end
|
|
471
|
-
|
|
472
|
-
def log_message(type, message)
|
|
473
|
-
@protocol.write_notification("window/logMessage", {
|
|
474
|
-
type: MESSAGE_TYPES[type] || type,
|
|
475
|
-
message: message,
|
|
476
|
-
})
|
|
477
|
-
end
|
|
457
|
+
def position_in_range?(line, char, start_line, start_char, end_line, end_char)
|
|
458
|
+
after_start = (line > start_line) || (line == start_line && char >= start_char)
|
|
459
|
+
before_end = (line < end_line) || (line == end_line && char <= end_char)
|
|
460
|
+
after_start && before_end
|
|
461
|
+
end
|
|
478
462
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
@protocol.send_request('window/showMessageRequest', {
|
|
463
|
+
def show_message(type, message)
|
|
464
|
+
@protocol.write_notification("window/showMessage", {
|
|
482
465
|
type: MESSAGE_TYPES[type] || type,
|
|
483
466
|
message: message,
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
callback.call(result['title'])
|
|
490
|
-
else
|
|
491
|
-
callback.call(nil)
|
|
492
|
-
end
|
|
493
|
-
end
|
|
494
|
-
else
|
|
495
|
-
Protocol.send_request('window/showMessageRequest', {
|
|
467
|
+
})
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
def log_message(type, message)
|
|
471
|
+
@protocol.write_notification("window/logMessage", {
|
|
496
472
|
type: MESSAGE_TYPES[type] || type,
|
|
497
473
|
message: message,
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
474
|
+
})
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
def show_message_request(type, message, actions:, &callback)
|
|
478
|
+
if @protocol.respond_to?(:send_request)
|
|
479
|
+
@protocol.send_request('window/showMessageRequest', {
|
|
480
|
+
type: MESSAGE_TYPES[type] || type,
|
|
481
|
+
message: message,
|
|
482
|
+
actions: actions.map { |title| { title: title } }
|
|
483
|
+
}) do |result, error|
|
|
484
|
+
if error
|
|
485
|
+
callback.call(nil)
|
|
486
|
+
elsif result.is_a?(Hash) && result['title']
|
|
487
|
+
callback.call(result['title'])
|
|
488
|
+
else
|
|
489
|
+
callback.call(nil)
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
else
|
|
493
|
+
Protocol.send_request('window/showMessageRequest', {
|
|
494
|
+
type: MESSAGE_TYPES[type] || type,
|
|
495
|
+
message: message,
|
|
496
|
+
actions: actions.map { |title| { title: title } }
|
|
497
|
+
}) do |result, error|
|
|
498
|
+
if error
|
|
499
|
+
callback.call(nil)
|
|
500
|
+
elsif result.is_a?(Hash) && result['title']
|
|
501
|
+
callback.call(result['title'])
|
|
502
|
+
else
|
|
503
|
+
callback.call(nil)
|
|
504
|
+
end
|
|
506
505
|
end
|
|
507
506
|
end
|
|
508
507
|
end
|
|
509
|
-
end
|
|
510
508
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
509
|
+
MESSAGE_TYPES = {
|
|
510
|
+
error: 1,
|
|
511
|
+
warning: 2,
|
|
512
|
+
info: 3,
|
|
513
|
+
log: 4,
|
|
514
|
+
}.freeze
|
|
517
515
|
end
|
|
518
516
|
end
|
|
519
517
|
end
|