mt-lang 0.3.9 → 0.3.11
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/README.md +2 -0
- data/docs/language-design.md +1 -2
- data/docs/language-manual.md +12 -1
- 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 +109 -51
- 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 +5 -3
- 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 +7 -9
- data/lib/milk_tea/core/parser/expressions.rb +15 -10
- data/lib/milk_tea/core/parser/recovery.rb +0 -2
- data/lib/milk_tea/core/parser/statements.rb +8 -2
- data/lib/milk_tea/core/parser/types.rb +12 -14
- data/lib/milk_tea/core/parser.rb +0 -2
- 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 +14 -17
- 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 +106 -109
- 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 +1376 -1314
- 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/cli.rb +10 -4
- 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 +112 -54
- 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,1741 +4,1803 @@ module MilkTea
|
|
|
4
4
|
module LSP
|
|
5
5
|
class Server
|
|
6
6
|
module ServerSemanticTokens
|
|
7
|
-
|
|
7
|
+
def handle_semantic_tokens_full(params)
|
|
8
|
+
uri = params.dig('textDocument', 'uri')
|
|
9
|
+
return { data: [] } unless uri
|
|
10
|
+
|
|
11
|
+
total_start = monotonic_time
|
|
12
|
+
|
|
13
|
+
content = @workspace.get_content(uri)
|
|
14
|
+
cache_key = content.hash
|
|
15
|
+
cached = @semantic_tokens_cache[uri]
|
|
16
|
+
if cached && cached[:content_hash] == cache_key
|
|
17
|
+
elapsed = elapsed_ms(total_start)
|
|
18
|
+
short_uri = shorten_uri(uri) || uri
|
|
19
|
+
log_perf_breakdown('textDocument/semanticTokens/full', elapsed,
|
|
20
|
+
"uri=#{short_uri} bytes=#{content.bytesize} lines=#{content.count("\n") + 1} cache=hit data_len=#{cached[:data].length}")
|
|
21
|
+
return { data: cached[:data] }
|
|
22
|
+
end
|
|
8
23
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
24
|
+
tokens_start = monotonic_time
|
|
25
|
+
tokens = @workspace.get_tokens(uri) || []
|
|
26
|
+
tokens_ms = elapsed_ms(tokens_start)
|
|
12
27
|
|
|
13
|
-
|
|
28
|
+
facts_start = monotonic_time
|
|
29
|
+
facts = @workspace.get_facts(uri, allow_last_good_fallback: semantic_tokens_allow_last_good_fallback?(uri))
|
|
30
|
+
facts_ms = elapsed_ms(facts_start)
|
|
14
31
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if cached && cached[:content_hash] == cache_key
|
|
19
|
-
elapsed = elapsed_ms(total_start)
|
|
20
|
-
short_uri = shorten_uri(uri) || uri
|
|
21
|
-
log_perf_breakdown('textDocument/semanticTokens/full', elapsed,
|
|
22
|
-
"uri=#{short_uri} bytes=#{content.bytesize} lines=#{content.count("\n") + 1} cache=hit data_len=#{cached[:data].length}")
|
|
23
|
-
return { data: cached[:data] }
|
|
24
|
-
end
|
|
32
|
+
build_start = monotonic_time
|
|
33
|
+
semantic_entries = build_semantic_token_entries(tokens, facts)
|
|
34
|
+
build_ms = elapsed_ms(build_start)
|
|
25
35
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
encode_start = monotonic_time
|
|
37
|
+
data = encode_semantic_tokens(semantic_entries)
|
|
38
|
+
encode_ms = elapsed_ms(encode_start)
|
|
29
39
|
|
|
30
|
-
|
|
31
|
-
facts = @workspace.get_facts(uri, allow_last_good_fallback: semantic_tokens_allow_last_good_fallback?(uri))
|
|
32
|
-
facts_ms = elapsed_ms(facts_start)
|
|
40
|
+
@semantic_tokens_cache[uri] = { content_hash: cache_key, data: data }
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
42
|
+
result_id = next_semantic_token_result_id(uri)
|
|
43
|
+
@semantic_tokens_delta_cache[uri] = {
|
|
44
|
+
result_id: result_id,
|
|
45
|
+
content_hash: cache_key,
|
|
46
|
+
entries: semantic_entries,
|
|
47
|
+
}
|
|
37
48
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
49
|
+
elapsed = elapsed_ms(total_start)
|
|
50
|
+
short_uri = shorten_uri(uri) || uri
|
|
51
|
+
log_perf_breakdown('textDocument/semanticTokens/full', elapsed,
|
|
52
|
+
"uri=#{short_uri} bytes=#{content.bytesize} lines=#{content.count("\n") + 1} cache=miss tokens=#{tokens.length} entries=#{semantic_entries.length} data_len=#{data.length} facts=on stages_ms=tokens:#{tokens_ms},facts:#{facts_ms},build:#{build_ms},encode:#{encode_ms}")
|
|
41
53
|
|
|
42
|
-
|
|
54
|
+
{ data: data }
|
|
55
|
+
rescue StandardError => e
|
|
56
|
+
warn "Error in semanticTokens/full handler: #{e.message}"
|
|
57
|
+
{ data: [] }
|
|
58
|
+
end
|
|
43
59
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
entries: semantic_entries,
|
|
49
|
-
}
|
|
60
|
+
def handle_semantic_tokens_delta(params)
|
|
61
|
+
uri = params.dig('textDocument', 'uri')
|
|
62
|
+
previous_result_id = params['previousResultId']
|
|
63
|
+
return handle_semantic_tokens_full(params) unless uri && previous_result_id
|
|
50
64
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
cached = @semantic_tokens_delta_cache[uri]
|
|
66
|
+
unless cached && cached[:result_id] == previous_result_id
|
|
67
|
+
return handle_semantic_tokens_full(params)
|
|
68
|
+
end
|
|
55
69
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
content = @workspace.get_content(uri)
|
|
71
|
+
cache_key = content.hash
|
|
72
|
+
if cached[:content_hash] == cache_key
|
|
73
|
+
return { resultId: cached[:result_id], edits: [] }
|
|
74
|
+
end
|
|
61
75
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return handle_semantic_tokens_full(params) unless uri && previous_result_id
|
|
76
|
+
tokens = @workspace.get_tokens(uri) || []
|
|
77
|
+
facts = @workspace.get_facts(uri, allow_last_good_fallback: semantic_tokens_allow_last_good_fallback?(uri))
|
|
78
|
+
new_entries = build_semantic_token_entries(tokens, facts)
|
|
66
79
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
80
|
+
new_result_id = next_semantic_token_result_id(uri)
|
|
81
|
+
@semantic_tokens_delta_cache[uri] = {
|
|
82
|
+
result_id: new_result_id,
|
|
83
|
+
content_hash: cache_key,
|
|
84
|
+
entries: new_entries,
|
|
85
|
+
}
|
|
71
86
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
87
|
+
edits = compute_semantic_tokens_edits(cached[:entries], new_entries)
|
|
88
|
+
{ resultId: new_result_id, edits: edits }
|
|
89
|
+
rescue StandardError => e
|
|
90
|
+
warn "Error in semanticTokens/full/delta handler: #{e.message}"
|
|
91
|
+
handle_semantic_tokens_full(params)
|
|
76
92
|
end
|
|
77
93
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
94
|
+
def handle_semantic_tokens_range(params)
|
|
95
|
+
uri = params.dig("textDocument", "uri")
|
|
96
|
+
range = params["range"]
|
|
97
|
+
return { data: [] } unless uri && range
|
|
81
98
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
result_id: new_result_id,
|
|
85
|
-
content_hash: cache_key,
|
|
86
|
-
entries: new_entries,
|
|
87
|
-
}
|
|
99
|
+
content = @workspace.get_content(uri)
|
|
100
|
+
return { data: [] } unless content
|
|
88
101
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
rescue StandardError => e
|
|
92
|
-
warn "Error in semanticTokens/full/delta handler: #{e.message}"
|
|
93
|
-
handle_semantic_tokens_full(params)
|
|
94
|
-
end
|
|
102
|
+
tokens = @workspace.get_tokens(uri) || []
|
|
103
|
+
return { data: [] } if tokens.empty?
|
|
95
104
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
range = params["range"]
|
|
99
|
-
return { data: [] } unless uri && range
|
|
105
|
+
start_line = range.dig("start", "line") + 1
|
|
106
|
+
end_line = range.dig("end", "line") + 1
|
|
100
107
|
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
range_tokens = tokens.select do |t|
|
|
109
|
+
t.line >= start_line && t.line <= end_line &&
|
|
110
|
+
![:newline, :indent, :dedent, :eof].include?(t.type)
|
|
111
|
+
end
|
|
103
112
|
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
facts = @workspace.get_facts(uri, allow_last_good_fallback: semantic_tokens_allow_last_good_fallback?(uri))
|
|
114
|
+
semantic_entries = build_semantic_token_entries(range_tokens, facts)
|
|
106
115
|
|
|
107
|
-
|
|
108
|
-
|
|
116
|
+
entries_in_range = semantic_entries.select do |entry|
|
|
117
|
+
entry[:line] >= start_line && entry[:line] <= end_line
|
|
118
|
+
end
|
|
109
119
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
120
|
+
data = encode_semantic_tokens(entries_in_range)
|
|
121
|
+
{ data: data }
|
|
122
|
+
rescue StandardError => e
|
|
123
|
+
warn "Error in semanticTokens/range handler: #{e.message}"
|
|
124
|
+
{ data: [] }
|
|
113
125
|
end
|
|
114
126
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
127
|
+
def build_semantic_token_entries(tokens, facts = nil)
|
|
128
|
+
# Precompute line → non-trivia tokens index so non_trivia_tokens_on_line
|
|
129
|
+
# is O(1) per call instead of O(n), turning the overall build from O(n²) to O(n).
|
|
130
|
+
trivia_types = Set[:newline, :indent, :dedent, :eof]
|
|
131
|
+
@tokens_by_line_cache = Hash.new { |h, k| h[k] = [] }
|
|
132
|
+
tokens.each { |t| @tokens_by_line_cache[t.line] << t unless trivia_types.include?(t.type) }
|
|
133
|
+
@attribute_name_semantic_overrides = build_attribute_name_semantic_overrides(tokens, facts)
|
|
121
134
|
|
|
122
|
-
|
|
123
|
-
{ data: data }
|
|
124
|
-
rescue StandardError => e
|
|
125
|
-
warn "Error in semanticTokens/range handler: #{e.message}"
|
|
126
|
-
{ data: [] }
|
|
127
|
-
end
|
|
135
|
+
entries = []
|
|
128
136
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
# is O(1) per call instead of O(n), turning the overall build from O(n²) to O(n).
|
|
132
|
-
trivia_types = Set[:newline, :indent, :dedent, :eof]
|
|
133
|
-
@tokens_by_line_cache = Hash.new { |h, k| h[k] = [] }
|
|
134
|
-
tokens.each { |t| @tokens_by_line_cache[t.line] << t unless trivia_types.include?(t.type) }
|
|
135
|
-
@attribute_name_semantic_overrides = build_attribute_name_semantic_overrides(tokens, facts)
|
|
137
|
+
tokens.each_with_index do |tok, index|
|
|
138
|
+
next if [:newline, :indent, :dedent, :eof].include?(tok.type)
|
|
136
139
|
|
|
137
|
-
|
|
140
|
+
if tok.type == :fstring
|
|
141
|
+
next if embedded_heredoc_token?(tok)
|
|
142
|
+
fstring_interpolation_entries(tok, facts).each { |e| entries << e }
|
|
143
|
+
next
|
|
144
|
+
end
|
|
138
145
|
|
|
139
|
-
|
|
140
|
-
|
|
146
|
+
semantic_type, modifiers = classify_semantic_token(tokens, index, facts)
|
|
147
|
+
next unless semantic_type
|
|
141
148
|
|
|
142
|
-
|
|
143
|
-
next if embedded_heredoc_token?(tok)
|
|
144
|
-
fstring_interpolation_entries(tok, facts).each { |e| entries << e }
|
|
145
|
-
next
|
|
149
|
+
token_semantic_entries(tok, semantic_type, modifiers).each { |entry| entries << entry }
|
|
146
150
|
end
|
|
147
151
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
+
entries.sort_by { |entry| [entry[:line], entry[:start_char]] }
|
|
153
|
+
ensure
|
|
154
|
+
@tokens_by_line_cache = nil
|
|
155
|
+
@attribute_name_semantic_overrides = nil
|
|
152
156
|
end
|
|
153
157
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
@attribute_name_semantic_overrides = nil
|
|
158
|
-
end
|
|
158
|
+
def fstring_interpolation_entries(fstring_tok, facts)
|
|
159
|
+
parts = fstring_tok.literal
|
|
160
|
+
return [{ line: fstring_tok.line - 1, start_char: fstring_tok.column - 1, length: fstring_tok.lexeme.length, type: :string, modifiers: [] }] unless parts.is_a?(Array)
|
|
159
161
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
cursor = fstr_col0
|
|
168
|
-
|
|
169
|
-
parts.each do |part|
|
|
170
|
-
next unless part[:kind] == :expr
|
|
171
|
-
|
|
172
|
-
# part[:column] is 1-indexed column of the first char of the expression source
|
|
173
|
-
# (i.e. the char right after `#{`).
|
|
174
|
-
expr_col0 = part[:column] - 1 # 0-indexed
|
|
175
|
-
hash_col0 = expr_col0 - 2 # 0-indexed position of `#`
|
|
176
|
-
|
|
177
|
-
raw_len = part[:source].length + (part[:format_spec] ? 1 + part[:format_spec].length : 0)
|
|
178
|
-
rbrace_col0 = expr_col0 + raw_len # 0-indexed position of `}`
|
|
179
|
-
|
|
180
|
-
# :string for everything from cursor up to (but not including) `#`
|
|
181
|
-
text_len = hash_col0 - cursor
|
|
182
|
-
result << { line: fstr_line, start_char: cursor, length: text_len, type: :string, modifiers: [] } if text_len > 0
|
|
183
|
-
|
|
184
|
-
# classified entries for the expression source only (not format spec).
|
|
185
|
-
source = part[:source]
|
|
186
|
-
unless source.nil? || source.strip.empty?
|
|
187
|
-
begin
|
|
188
|
-
sub_tokens = interpolation_expression_tokens(part)
|
|
189
|
-
sub_tokens.each_with_index do |sub_tok, i|
|
|
190
|
-
sem_type, modifiers = classify_semantic_token(sub_tokens, i, facts)
|
|
191
|
-
next unless sem_type
|
|
192
|
-
result << {
|
|
193
|
-
line: sub_tok.line - 1,
|
|
194
|
-
start_char: sub_tok.column - 1,
|
|
195
|
-
length: sub_tok.lexeme.length,
|
|
196
|
-
type: sem_type,
|
|
197
|
-
modifiers: modifiers
|
|
198
|
-
}
|
|
199
|
-
end
|
|
200
|
-
rescue MilkTea::LexError
|
|
201
|
-
# Fall back to string coloring for malformed expression.
|
|
202
|
-
result << {
|
|
203
|
-
line: fstr_line,
|
|
204
|
-
start_char: expr_col0,
|
|
205
|
-
length: source.length,
|
|
206
|
-
type: :string,
|
|
207
|
-
modifiers: [],
|
|
208
|
-
}
|
|
209
|
-
end
|
|
210
|
-
end
|
|
162
|
+
result = []
|
|
163
|
+
fstr_line = fstring_tok.line - 1 # 0-indexed
|
|
164
|
+
fstr_col0 = fstring_tok.column - 1 # 0-indexed start of `f`
|
|
165
|
+
cursor = fstr_col0
|
|
166
|
+
|
|
167
|
+
parts.each do |part|
|
|
168
|
+
next unless part[:kind] == :expr
|
|
211
169
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
170
|
+
# part[:column] is 1-indexed column of the first char of the expression source
|
|
171
|
+
# (i.e. the char right after `#{`).
|
|
172
|
+
expr_col0 = part[:column] - 1 # 0-indexed
|
|
173
|
+
hash_col0 = expr_col0 - 2 # 0-indexed position of `#`
|
|
174
|
+
|
|
175
|
+
raw_len = part[:source].length + (part[:format_spec] ? 1 + part[:format_spec].length : 0)
|
|
176
|
+
rbrace_col0 = expr_col0 + raw_len # 0-indexed position of `}`
|
|
177
|
+
|
|
178
|
+
# :string for everything from cursor up to (but not including) `#`
|
|
179
|
+
text_len = hash_col0 - cursor
|
|
180
|
+
result << { line: fstr_line, start_char: cursor, length: text_len, type: :string, modifiers: [] } if text_len > 0
|
|
181
|
+
|
|
182
|
+
# classified entries for the expression source only (not format spec).
|
|
183
|
+
source = part[:source]
|
|
184
|
+
unless source.nil? || source.strip.empty?
|
|
220
185
|
begin
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
next unless spec_sem_type
|
|
186
|
+
sub_tokens = interpolation_expression_tokens(part)
|
|
187
|
+
sub_tokens.each_with_index do |sub_tok, i|
|
|
188
|
+
sem_type, modifiers = classify_semantic_token(sub_tokens, i, facts)
|
|
189
|
+
next unless sem_type
|
|
226
190
|
result << {
|
|
227
|
-
line:
|
|
228
|
-
start_char:
|
|
229
|
-
length:
|
|
230
|
-
type:
|
|
231
|
-
modifiers:
|
|
191
|
+
line: sub_tok.line - 1,
|
|
192
|
+
start_char: sub_tok.column - 1,
|
|
193
|
+
length: sub_tok.lexeme.length,
|
|
194
|
+
type: sem_type,
|
|
195
|
+
modifiers: modifiers
|
|
232
196
|
}
|
|
233
197
|
end
|
|
234
198
|
rescue MilkTea::LexError
|
|
235
|
-
# Fall back
|
|
199
|
+
# Fall back to string coloring for malformed expression.
|
|
236
200
|
result << {
|
|
237
201
|
line: fstr_line,
|
|
238
|
-
start_char:
|
|
239
|
-
length:
|
|
240
|
-
type: :
|
|
241
|
-
modifiers: []
|
|
202
|
+
start_char: expr_col0,
|
|
203
|
+
length: source.length,
|
|
204
|
+
type: :string,
|
|
205
|
+
modifiers: [],
|
|
242
206
|
}
|
|
243
207
|
end
|
|
244
208
|
end
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
cursor = rbrace_col0 + 1
|
|
248
|
-
end
|
|
249
209
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
210
|
+
# classified entries for format spec (if present), excluding the
|
|
211
|
+
# delimiter token so TextMate interpolation punctuation can style it.
|
|
212
|
+
if part[:format_spec]
|
|
213
|
+
spec_col0 = expr_col0 + source.length
|
|
214
|
+
# Format spec content (e.g., ".0", "3", ".5f") as individual token-like entries.
|
|
215
|
+
# Treat it as lexable content or just string for simplicity.
|
|
216
|
+
spec = part[:format_spec]
|
|
217
|
+
unless spec.empty?
|
|
218
|
+
begin
|
|
219
|
+
spec_tokens = MilkTea::Lexer.new(spec).lex
|
|
220
|
+
.reject { |t| [:newline, :indent, :dedent, :eof].include?(t.type) }
|
|
221
|
+
spec_tokens.each_with_index do |spec_tok, i|
|
|
222
|
+
spec_sem_type, spec_modifiers = classify_semantic_token(spec_tokens, i, facts)
|
|
223
|
+
next unless spec_sem_type
|
|
224
|
+
result << {
|
|
225
|
+
line: fstr_line,
|
|
226
|
+
start_char: spec_col0 + 1 + (spec_tok.column - 1),
|
|
227
|
+
length: spec_tok.lexeme.length,
|
|
228
|
+
type: spec_sem_type,
|
|
229
|
+
modifiers: spec_modifiers
|
|
230
|
+
}
|
|
231
|
+
end
|
|
232
|
+
rescue MilkTea::LexError
|
|
233
|
+
# Fall back: treat spec as a number/string token.
|
|
234
|
+
result << {
|
|
235
|
+
line: fstr_line,
|
|
236
|
+
start_char: spec_col0 + 1,
|
|
237
|
+
length: spec.length,
|
|
238
|
+
type: :number,
|
|
239
|
+
modifiers: []
|
|
240
|
+
}
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
254
244
|
|
|
255
|
-
|
|
256
|
-
|
|
245
|
+
cursor = rbrace_col0 + 1
|
|
246
|
+
end
|
|
257
247
|
|
|
258
|
-
|
|
259
|
-
|
|
248
|
+
# :string for tail text + closing `"`
|
|
249
|
+
fstr_end_col0 = fstr_col0 + fstring_tok.lexeme.length - 1
|
|
250
|
+
tail_len = fstr_end_col0 - cursor + 1
|
|
251
|
+
result << { line: fstr_line, start_char: cursor, length: tail_len, type: :string, modifiers: [] } if tail_len > 0
|
|
260
252
|
|
|
261
|
-
|
|
262
|
-
return classify_name_semantic(tok.lexeme, tokens, index, facts)
|
|
253
|
+
result
|
|
263
254
|
end
|
|
264
255
|
|
|
265
|
-
|
|
266
|
-
|
|
256
|
+
def classify_semantic_token(tokens, index, facts = nil)
|
|
257
|
+
tok = tokens[index]
|
|
267
258
|
|
|
268
|
-
|
|
269
|
-
|
|
259
|
+
if tok.type == :identifier || namespace_keyword_token?(tokens, index)
|
|
260
|
+
return classify_name_semantic(tok.lexeme, tokens, index, facts)
|
|
261
|
+
end
|
|
270
262
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
end
|
|
263
|
+
if [:string, :cstring].include?(tok.type)
|
|
264
|
+
return [nil, []] if embedded_heredoc_token?(tok)
|
|
274
265
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
end
|
|
266
|
+
return [:string, []]
|
|
267
|
+
end
|
|
278
268
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
269
|
+
if tok.type == :comment
|
|
270
|
+
return [:comment, []]
|
|
271
|
+
end
|
|
282
272
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
273
|
+
if [:integer, :float].include?(tok.type)
|
|
274
|
+
return [:number, []]
|
|
275
|
+
end
|
|
286
276
|
|
|
287
|
-
|
|
288
|
-
|
|
277
|
+
if KEYWORD_TOKEN_TYPES.include?(tok.type)
|
|
278
|
+
return [:typeParameter, []] if keyword_lifetime_or_type_param?(tokens, index)
|
|
279
|
+
return [:type, []] if keyword_type_annotation?(tokens, index)
|
|
280
|
+
return [:enumMember, [:declaration]] if variant_enum_member_declaration?(tokens, index)
|
|
281
|
+
return [:property, [:declaration]] if keyword_field_declaration_token?(tokens, index)
|
|
282
|
+
return [:property, []] if keyword_member_access?(tokens, index)
|
|
283
|
+
return [:parameter, []] if keyword_named_argument_token?(tokens, index)
|
|
284
|
+
return [:keyword, []]
|
|
285
|
+
end
|
|
289
286
|
|
|
290
|
-
|
|
291
|
-
|
|
287
|
+
if OPERATOR_TOKEN_TYPES.include?(tok.type)
|
|
288
|
+
return [:operator, []]
|
|
289
|
+
end
|
|
292
290
|
|
|
293
|
-
|
|
294
|
-
|
|
291
|
+
[nil, []]
|
|
292
|
+
end
|
|
295
293
|
|
|
296
|
-
|
|
297
|
-
|
|
294
|
+
def embedded_heredoc_token?(token)
|
|
295
|
+
return false unless [:string, :cstring, :fstring].include?(token.type)
|
|
298
296
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
next if segment.empty?
|
|
297
|
+
tag = token.lexeme[/\A(?:f|c)?<<-([A-Za-z_][A-Za-z0-9_]*)[ \t]*\n/, 1]
|
|
298
|
+
return false if tag.nil?
|
|
302
299
|
|
|
303
|
-
|
|
304
|
-
line: token.line - 1 + index,
|
|
305
|
-
start_char: index.zero? ? (token.column - 1) : 0,
|
|
306
|
-
length: segment.length,
|
|
307
|
-
type: semantic_type,
|
|
308
|
-
modifiers: modifiers
|
|
309
|
-
}
|
|
300
|
+
%w[GLSL VERT FRAG COMP JSON JSONC SQL HTML MT].include?(tag)
|
|
310
301
|
end
|
|
311
|
-
end
|
|
312
302
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
317
|
-
parameter_declaration = parameter_declaration_token?(tokens, index)
|
|
318
|
-
user_defined_function = facts ? facts.functions.key?(name) : lexically_declared_free_function_name?(tokens, name)
|
|
303
|
+
def token_semantic_entries(token, semantic_type, modifiers)
|
|
304
|
+
token.lexeme.split("\n", -1).each_with_index.filter_map do |segment, index|
|
|
305
|
+
next if segment.empty?
|
|
319
306
|
|
|
320
|
-
|
|
321
|
-
|
|
307
|
+
{
|
|
308
|
+
line: token.line - 1 + index,
|
|
309
|
+
start_char: index.zero? ? (token.column - 1) : 0,
|
|
310
|
+
length: segment.length,
|
|
311
|
+
type: semantic_type,
|
|
312
|
+
modifiers: modifiers
|
|
313
|
+
}
|
|
314
|
+
end
|
|
322
315
|
end
|
|
323
316
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
317
|
+
def classify_name_semantic(name, tokens, index, facts = nil)
|
|
318
|
+
tok = tokens[index]
|
|
319
|
+
prev_tok = previous_non_trivia_token(tokens, index)
|
|
320
|
+
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
321
|
+
parameter_declaration = parameter_declaration_token?(tokens, index)
|
|
322
|
+
user_defined_function = facts ? facts.functions.key?(name) : lexically_declared_free_function_name?(tokens, name)
|
|
329
323
|
|
|
330
|
-
|
|
324
|
+
if @attribute_name_semantic_overrides && (override = @attribute_name_semantic_overrides[[tok.line, tok.column]])
|
|
325
|
+
return override
|
|
326
|
+
end
|
|
331
327
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
328
|
+
if (import_info = import_path_info_at(tokens, index, allow_keywords: true))
|
|
329
|
+
modifiers = []
|
|
330
|
+
modifiers << 'declaration' if import_info[:role] == :alias
|
|
331
|
+
return [:namespace, modifiers]
|
|
332
|
+
end
|
|
335
333
|
|
|
336
|
-
|
|
337
|
-
return [:type, ['declaration']]
|
|
338
|
-
end
|
|
334
|
+
return [:namespace, []] if module_declaration_path_token?(tokens, index, allow_keywords: true)
|
|
339
335
|
|
|
340
|
-
|
|
336
|
+
if prev_tok && [:function, :fn, :proc].include?(prev_tok.type)
|
|
337
|
+
return [:function, ['declaration']]
|
|
338
|
+
end
|
|
341
339
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
340
|
+
if prev_tok && [:struct, :union, :enum, :flags, :variant, :type, :opaque, :interface].include?(prev_tok.type)
|
|
341
|
+
return [:type, ['declaration']]
|
|
342
|
+
end
|
|
345
343
|
|
|
346
|
-
|
|
347
|
-
return [:variable, ['declaration', 'readonly']]
|
|
348
|
-
end
|
|
344
|
+
return [:variable, []] if name == "_"
|
|
349
345
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
346
|
+
if prev_tok&.type == :event
|
|
347
|
+
return struct_event_declaration_token?(tokens, index) ? [:property, ['declaration']] : [:variable, ['declaration']]
|
|
348
|
+
end
|
|
353
349
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
350
|
+
if prev_tok&.type == :const
|
|
351
|
+
return [:variable, ['declaration', 'readonly']]
|
|
352
|
+
end
|
|
357
353
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
354
|
+
if prev_tok&.type == :let
|
|
355
|
+
return [:variable, ['declaration', 'readonly']] unless next_tok&.type == :lparen
|
|
356
|
+
end
|
|
361
357
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
return [:property, ['declaration']] if field_declaration_token?(tokens, index)
|
|
358
|
+
if prev_tok&.type == :var
|
|
359
|
+
return [:variable, ['declaration']] unless next_tok&.type == :lparen
|
|
360
|
+
end
|
|
366
361
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
362
|
+
if prev_tok&.type == :for
|
|
363
|
+
return [:variable, ['declaration', 'readonly']]
|
|
364
|
+
end
|
|
370
365
|
|
|
371
|
-
|
|
372
|
-
return [:
|
|
373
|
-
return [:
|
|
374
|
-
|
|
366
|
+
return [:variable, ['declaration', 'readonly']] if match_arm_binding_token?(tokens, index)
|
|
367
|
+
return [:parameter, ['declaration']] if callable_parameter_declaration_token?(tokens, index)
|
|
368
|
+
return [:property, ['declaration']] if variant_payload_field_declaration_token?(tokens, index)
|
|
369
|
+
return [:property, ['declaration']] if field_declaration_token?(tokens, index)
|
|
375
370
|
|
|
376
|
-
|
|
377
|
-
|
|
371
|
+
if destructure_let_binding?(tokens, index)
|
|
372
|
+
return [:variable, ['declaration', 'readonly']]
|
|
373
|
+
end
|
|
378
374
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
375
|
+
if facts
|
|
376
|
+
return [:typeParameter, ['declaration']] if type_parameter_declaration_token?(facts, tokens, index)
|
|
377
|
+
return [:typeParameter, []] if type_parameter_reference_token?(facts, tokens, index)
|
|
378
|
+
end
|
|
382
379
|
|
|
383
|
-
|
|
384
|
-
return [:
|
|
385
|
-
return [:type, []] if facts.interfaces.key?(name)
|
|
386
|
-
return [:namespace, []] if facts.imports.key?(name)
|
|
380
|
+
return [:property, []] if named_argument_label_token?(tokens, index) && named_argument_label_in_type_constructor?(tokens, index, facts)
|
|
381
|
+
return [:parameter, []] if named_argument_label_token?(tokens, index)
|
|
387
382
|
|
|
388
|
-
if (
|
|
389
|
-
return
|
|
383
|
+
if facts && prev_tok&.type != :dot && (generic_binding = generic_function_lexical_binding_semantic(facts, tok))
|
|
384
|
+
return generic_binding
|
|
390
385
|
end
|
|
391
386
|
|
|
392
|
-
if
|
|
393
|
-
return
|
|
394
|
-
|
|
395
|
-
|
|
387
|
+
if next_tok&.type == :dot && facts
|
|
388
|
+
return [:type, []] if known_type_name?(facts, name)
|
|
389
|
+
return [:type, []] if facts.interfaces.key?(name)
|
|
390
|
+
return [:namespace, []] if facts.imports.key?(name)
|
|
396
391
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
392
|
+
if (binding = local_semantic_value_binding(facts, tok, allow_same_line_future: parameter_declaration))
|
|
393
|
+
return semantic_value_binding_entry(binding, declaration: binding.kind == :param && parameter_declaration)
|
|
394
|
+
end
|
|
400
395
|
|
|
401
|
-
|
|
396
|
+
if (binding = facts.values[name])
|
|
397
|
+
return semantic_value_binding_entry(binding)
|
|
398
|
+
end
|
|
399
|
+
end
|
|
402
400
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
401
|
+
if facts && (known_type_name?(facts, name) || facts.interfaces.key?(name)) && identifier_in_type_argument_position?(tokens, index)
|
|
402
|
+
return [:type, []]
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
return [:enumMember, ['declaration']] if variant_enum_member_declaration?(tokens, index)
|
|
406
|
+
|
|
407
|
+
if prev_tok&.type == :dot
|
|
408
|
+
if facts
|
|
409
|
+
module_binding = imported_module_binding_for_member(tokens, index, facts)
|
|
410
|
+
if module_binding
|
|
411
|
+
if module_binding.functions.key?(name)
|
|
412
|
+
return [:function, []] if next_tok&.type == :lparen || specialized_call_with_type_args?(tokens, index)
|
|
413
|
+
return [:function, []] if next_tok&.type == :lbracket
|
|
414
|
+
return [:function, []] if imported_module_function_value_member_access_site?(facts, tokens, index)
|
|
415
|
+
return [:property, []]
|
|
416
|
+
end
|
|
417
|
+
return [:type, []] if module_binding.types.key?(name)
|
|
418
|
+
return [:type, []] if module_binding.interfaces.key?(name)
|
|
419
|
+
if (value_binding = module_binding.values[name])
|
|
420
|
+
modifiers = []
|
|
421
|
+
modifiers << 'readonly' if value_binding.respond_to?(:mutable) && value_binding.mutable == false
|
|
422
|
+
return [:variable, modifiers]
|
|
423
|
+
end
|
|
424
|
+
return [:namespace, []] if facts.imports.key?(name)
|
|
419
425
|
end
|
|
420
|
-
|
|
426
|
+
|
|
427
|
+
return [:type, []] if dot_nested_type_member?(tokens, index, facts)
|
|
428
|
+
return [:property, []] if callable_field_member_access?(name, tokens, index, facts)
|
|
429
|
+
return [:method, []] if static_type_member_access?(tokens, index, facts)
|
|
421
430
|
end
|
|
422
431
|
|
|
423
|
-
return [:
|
|
424
|
-
return [:
|
|
425
|
-
return [:
|
|
432
|
+
return [:enumMember, []] if type_name_member_access?(tokens, index, facts)
|
|
433
|
+
return [:method, []] if next_tok&.type == :lparen || specialized_call_with_type_args?(tokens, index)
|
|
434
|
+
return [:property, []]
|
|
426
435
|
end
|
|
427
436
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
437
|
+
if next_tok&.type == :lparen || specialized_call_with_type_args?(tokens, index)
|
|
438
|
+
if facts && (resolved = resolved_call_callee_semantic(name, tok, parameter_declaration, facts))
|
|
439
|
+
return resolved
|
|
440
|
+
end
|
|
432
441
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
442
|
+
return [:function, []] if user_defined_function
|
|
443
|
+
|
|
444
|
+
modifiers = []
|
|
445
|
+
modifiers << 'defaultLibrary' if BUILTIN_FUNCTION_NAMES.include?(name)
|
|
446
|
+
if BUILTIN_ASSOCIATED_HOOK_NAMES.include?(name) && specialized_call_with_type_args?(tokens, index) && !user_defined_function
|
|
447
|
+
modifiers << 'defaultLibrary'
|
|
448
|
+
end
|
|
449
|
+
return [:function, modifiers]
|
|
436
450
|
end
|
|
437
451
|
|
|
438
|
-
return [:function, []] if user_defined_function
|
|
452
|
+
return [:function, []] if next_tok&.type == :lbracket && user_defined_function
|
|
439
453
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
454
|
+
if facts && identifier_in_type_reference_position?(tokens, index)
|
|
455
|
+
if known_type_name?(facts, name)
|
|
456
|
+
modifiers = []
|
|
457
|
+
modifiers << 'defaultLibrary' if DEFAULT_LIBRARY_TYPE_NAMES.include?(name)
|
|
458
|
+
return [:type, modifiers]
|
|
459
|
+
end
|
|
460
|
+
return [:type, []] if facts.interfaces.key?(name)
|
|
461
|
+
|
|
462
|
+
if DEFAULT_LIBRARY_TYPE_NAMES.include?(name)
|
|
463
|
+
return [:type, ['defaultLibrary']]
|
|
464
|
+
end
|
|
444
465
|
end
|
|
445
|
-
return [:function, modifiers]
|
|
446
|
-
end
|
|
447
466
|
|
|
448
|
-
|
|
467
|
+
if facts
|
|
449
468
|
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
469
|
+
if (binding = local_semantic_value_binding(facts, tok, allow_same_line_future: parameter_declaration))
|
|
470
|
+
return semantic_value_binding_entry(binding, declaration: binding.kind == :param && parameter_declaration)
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
if known_type_name?(facts, name)
|
|
474
|
+
modifiers = []
|
|
475
|
+
modifiers << 'defaultLibrary' if DEFAULT_LIBRARY_TYPE_NAMES.include?(name)
|
|
476
|
+
return [:type, modifiers]
|
|
477
|
+
end
|
|
478
|
+
return [:type, []] if facts.interfaces.key?(name)
|
|
479
|
+
|
|
480
|
+
return [:namespace, []] if facts.imports.key?(name)
|
|
481
|
+
|
|
482
|
+
if (binding = facts.values[name])
|
|
483
|
+
return semantic_value_binding_entry(binding)
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
return [:function, []] if bare_function_value_identifier_site?(facts, tok)
|
|
455
487
|
end
|
|
456
|
-
return [:type, []] if facts.interfaces.key?(name)
|
|
457
488
|
|
|
458
489
|
if DEFAULT_LIBRARY_TYPE_NAMES.include?(name)
|
|
459
490
|
return [:type, ['defaultLibrary']]
|
|
460
491
|
end
|
|
492
|
+
|
|
493
|
+
return [:function, ['defaultLibrary']] if bare_builtin_specialization?(name, tokens, index)
|
|
494
|
+
|
|
495
|
+
[:variable, []]
|
|
461
496
|
end
|
|
462
497
|
|
|
463
|
-
|
|
498
|
+
def named_argument_label_token?(tokens, index)
|
|
499
|
+
prev_tok = previous_non_trivia_token(tokens, index)
|
|
500
|
+
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
501
|
+
next_tok&.type == :equal && prev_tok && [:lparen, :comma].include?(prev_tok.type)
|
|
502
|
+
end
|
|
464
503
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
end
|
|
504
|
+
def named_argument_label_in_type_constructor?(tokens, index, facts)
|
|
505
|
+
return false unless facts
|
|
468
506
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
507
|
+
opener_index = parameter_list_opener_index(tokens, index)
|
|
508
|
+
return false unless opener_index
|
|
509
|
+
|
|
510
|
+
callee_index = previous_non_trivia_token_index(tokens, opener_index)
|
|
511
|
+
return false unless callee_index
|
|
512
|
+
|
|
513
|
+
if tokens[callee_index].type == :rbracket
|
|
514
|
+
lbracket_index = matching_opener_index(tokens, callee_index)
|
|
515
|
+
return false unless lbracket_index
|
|
516
|
+
callee_index = previous_non_trivia_token_index(tokens, lbracket_index)
|
|
473
517
|
end
|
|
474
|
-
return [:type, []] if facts.interfaces.key?(name)
|
|
475
518
|
|
|
476
|
-
return
|
|
519
|
+
return false unless callee_index && tokens[callee_index].type == :identifier
|
|
477
520
|
|
|
478
|
-
|
|
479
|
-
|
|
521
|
+
callee_name = tokens[callee_index].lexeme
|
|
522
|
+
return true if facts.types.key?(callee_name) || facts.interfaces.key?(callee_name)
|
|
523
|
+
|
|
524
|
+
dot_index = previous_non_trivia_token_index(tokens, callee_index)
|
|
525
|
+
return false unless dot_index && tokens[dot_index].type == :dot
|
|
526
|
+
|
|
527
|
+
receiver_index = previous_non_trivia_token_index(tokens, dot_index)
|
|
528
|
+
return false unless receiver_index
|
|
529
|
+
|
|
530
|
+
if tokens[receiver_index].type == :rbracket
|
|
531
|
+
lbracket_index = matching_opener_index(tokens, receiver_index)
|
|
532
|
+
return false unless lbracket_index
|
|
533
|
+
receiver_index = previous_non_trivia_token_index(tokens, lbracket_index)
|
|
480
534
|
end
|
|
481
535
|
|
|
482
|
-
return
|
|
483
|
-
end
|
|
536
|
+
return false unless receiver_index && tokens[receiver_index].type == :identifier
|
|
484
537
|
|
|
485
|
-
|
|
486
|
-
|
|
538
|
+
receiver_name = tokens[receiver_index].lexeme
|
|
539
|
+
facts.types.key?(receiver_name) || facts.interfaces.key?(receiver_name)
|
|
487
540
|
end
|
|
488
541
|
|
|
489
|
-
|
|
542
|
+
def match_arm_binding_token?(tokens, index)
|
|
543
|
+
prev_tok = previous_non_trivia_token(tokens, index)
|
|
544
|
+
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
545
|
+
prev_tok&.type == :as && next_tok&.type == :colon
|
|
546
|
+
end
|
|
490
547
|
|
|
491
|
-
|
|
492
|
-
|
|
548
|
+
def field_declaration_token?(tokens, index)
|
|
549
|
+
tok = tokens[index]
|
|
550
|
+
return false unless tok&.type == :identifier
|
|
551
|
+
return false unless first_non_trivia_token_on_line?(tokens, index)
|
|
552
|
+
return false if parameter_declaration_token?(tokens, index)
|
|
553
|
+
return false if match_arm_binding_token?(tokens, index)
|
|
493
554
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
next_tok&.type == :equal && prev_tok && [:lparen, :comma].include?(prev_tok.type)
|
|
498
|
-
end
|
|
555
|
+
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
556
|
+
next_tok&.type == :colon
|
|
557
|
+
end
|
|
499
558
|
|
|
500
|
-
|
|
501
|
-
|
|
559
|
+
def keyword_field_declaration_token?(tokens, index)
|
|
560
|
+
return false if match_arm_binding_token?(tokens, index)
|
|
561
|
+
return false if destructure_let_binding?(tokens, index)
|
|
502
562
|
|
|
503
|
-
|
|
504
|
-
|
|
563
|
+
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
564
|
+
next_tok&.type == :colon
|
|
565
|
+
end
|
|
505
566
|
|
|
506
|
-
|
|
507
|
-
|
|
567
|
+
def keyword_member_access?(tokens, index)
|
|
568
|
+
prev_index = previous_non_trivia_token_index(tokens, index)
|
|
569
|
+
return false unless prev_index
|
|
508
570
|
|
|
509
|
-
|
|
510
|
-
lbracket_index = matching_opener_index(tokens, callee_index)
|
|
511
|
-
return false unless lbracket_index
|
|
512
|
-
callee_index = previous_non_trivia_token_index(tokens, lbracket_index)
|
|
571
|
+
tokens[prev_index].type == :dot
|
|
513
572
|
end
|
|
514
573
|
|
|
515
|
-
|
|
574
|
+
def keyword_lifetime_or_type_param?(tokens, index)
|
|
575
|
+
prev_index = previous_non_trivia_token_index(tokens, index)
|
|
576
|
+
return false unless prev_index
|
|
516
577
|
|
|
517
|
-
|
|
518
|
-
|
|
578
|
+
prev_type = tokens[prev_index].type
|
|
579
|
+
return true if prev_type == :at
|
|
580
|
+
return true if prev_type == :lbracket
|
|
581
|
+
return true if prev_type == :comma && inside_type_params?(tokens, prev_index)
|
|
582
|
+
false
|
|
583
|
+
end
|
|
519
584
|
|
|
520
|
-
|
|
521
|
-
|
|
585
|
+
def inside_type_params?(tokens, comma_index)
|
|
586
|
+
i = comma_index - 1
|
|
587
|
+
while i >= 0
|
|
588
|
+
t = tokens[i]
|
|
589
|
+
break if t.type == :lbracket
|
|
590
|
+
return false if t.type == :newline || t.type == :rbracket || t.type == :lparen
|
|
591
|
+
i -= 1
|
|
592
|
+
end
|
|
593
|
+
return false if i < 0
|
|
522
594
|
|
|
523
|
-
|
|
524
|
-
|
|
595
|
+
prev = previous_non_trivia_token_index(tokens, i)
|
|
596
|
+
return true if prev && %i[struct variant enum flags function fn proc].include?(tokens[prev].type)
|
|
597
|
+
return true if prev && tokens[prev].type == :rbracket
|
|
598
|
+
return true if prev && tokens[prev].type == :identifier
|
|
525
599
|
|
|
526
|
-
|
|
527
|
-
lbracket_index = matching_opener_index(tokens, receiver_index)
|
|
528
|
-
return false unless lbracket_index
|
|
529
|
-
receiver_index = previous_non_trivia_token_index(tokens, lbracket_index)
|
|
600
|
+
false
|
|
530
601
|
end
|
|
531
602
|
|
|
532
|
-
|
|
603
|
+
def keyword_named_argument_token?(tokens, index)
|
|
604
|
+
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
605
|
+
next_tok&.type == :equal
|
|
606
|
+
end
|
|
533
607
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
608
|
+
def keyword_type_annotation?(tokens, index)
|
|
609
|
+
tok = tokens[index]
|
|
610
|
+
prev_index = previous_non_trivia_token_index(tokens, index)
|
|
611
|
+
return false unless prev_index
|
|
612
|
+
return false unless %i[colon arrow].include?(tokens[prev_index].type)
|
|
537
613
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
541
|
-
prev_tok&.type == :as && next_tok&.type == :colon
|
|
542
|
-
end
|
|
614
|
+
tokens[prev_index].line == tok.line
|
|
615
|
+
end
|
|
543
616
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
return false unless first_non_trivia_token_on_line?(tokens, index)
|
|
548
|
-
return false if parameter_declaration_token?(tokens, index)
|
|
549
|
-
return false if match_arm_binding_token?(tokens, index)
|
|
617
|
+
def destructure_let_binding?(tokens, index)
|
|
618
|
+
tok = tokens[index]
|
|
619
|
+
return false unless tok&.type == :identifier
|
|
550
620
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
end
|
|
621
|
+
line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
|
|
622
|
+
return false unless line_tokens.length >= 3
|
|
554
623
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
return false unless tok&.type == :identifier
|
|
624
|
+
first = line_tokens[0]
|
|
625
|
+
return false unless [:let, :var].include?(first.type)
|
|
558
626
|
|
|
559
|
-
|
|
560
|
-
|
|
627
|
+
eq_idx = line_tokens.index { |t| t.type == :equal }
|
|
628
|
+
lparen_idx = line_tokens.index { |t| t.type == :lparen }
|
|
629
|
+
return false unless lparen_idx
|
|
561
630
|
|
|
562
|
-
|
|
563
|
-
return false unless [:let, :var].include?(first.type)
|
|
631
|
+
return false if eq_idx && lparen_idx >= eq_idx
|
|
564
632
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
633
|
+
# let (a, b) = ...
|
|
634
|
+
if line_tokens[1]&.type == :lparen
|
|
635
|
+
return first.type == :let
|
|
636
|
+
end
|
|
568
637
|
|
|
569
|
-
|
|
638
|
+
# let Vec2(x, y) = ... — identifier then lparen adjacency
|
|
639
|
+
return false unless line_tokens[1]&.type == :identifier && lparen_idx == 2
|
|
570
640
|
|
|
571
|
-
|
|
572
|
-
if line_tokens[1]&.type == :lparen
|
|
573
|
-
return first.type == :let
|
|
641
|
+
first.type == :let
|
|
574
642
|
end
|
|
575
643
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
first.type == :let
|
|
580
|
-
end
|
|
644
|
+
def struct_event_declaration_token?(tokens, index)
|
|
645
|
+
tok = tokens[index]
|
|
646
|
+
return false unless tok&.type == :identifier
|
|
581
647
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
return false unless tok&.type == :identifier
|
|
648
|
+
prev_tok = previous_non_trivia_token(tokens, index)
|
|
649
|
+
return false unless prev_tok&.type == :event
|
|
585
650
|
|
|
586
|
-
|
|
587
|
-
|
|
651
|
+
line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
|
|
652
|
+
line_start = line_tokens.first
|
|
653
|
+
return false unless line_start && line_start.column > 1
|
|
588
654
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
655
|
+
i = index - 1
|
|
656
|
+
while i >= 0
|
|
657
|
+
current = tokens[i]
|
|
658
|
+
i -= 1
|
|
659
|
+
next if [:newline, :indent, :dedent, :eof].include?(current.type)
|
|
660
|
+
next if current.line == tok.line
|
|
661
|
+
next if current.column >= line_start.column
|
|
592
662
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
i -= 1
|
|
597
|
-
next if [:newline, :indent, :dedent, :eof].include?(current.type)
|
|
598
|
-
next if current.line == tok.line
|
|
599
|
-
next if current.column >= line_start.column
|
|
663
|
+
header_line_toks = non_trivia_tokens_on_line(tokens, current.line)
|
|
664
|
+
return header_line_toks.first&.type == :struct
|
|
665
|
+
end
|
|
600
666
|
|
|
601
|
-
|
|
602
|
-
return header_line_toks.first&.type == :struct
|
|
667
|
+
false
|
|
603
668
|
end
|
|
604
669
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
def variant_payload_field_declaration_token?(tokens, index)
|
|
609
|
-
return false unless parameter_declaration_token?(tokens, index)
|
|
670
|
+
def variant_payload_field_declaration_token?(tokens, index)
|
|
671
|
+
return false unless parameter_declaration_token?(tokens, index)
|
|
610
672
|
|
|
611
|
-
|
|
612
|
-
|
|
673
|
+
opener_index = parameter_list_opener_index(tokens, index)
|
|
674
|
+
return false unless opener_index
|
|
613
675
|
|
|
614
|
-
|
|
615
|
-
|
|
676
|
+
head_index = previous_non_trivia_token_index(tokens, opener_index)
|
|
677
|
+
return false unless head_index
|
|
616
678
|
|
|
617
|
-
|
|
618
|
-
|
|
679
|
+
variant_enum_member_declaration?(tokens, head_index)
|
|
680
|
+
end
|
|
619
681
|
|
|
620
|
-
|
|
621
|
-
|
|
682
|
+
FOREIGN_PARAM_MODE_TOKENS = [:out, :in, :inout, :consuming].freeze
|
|
683
|
+
private_constant :FOREIGN_PARAM_MODE_TOKENS
|
|
622
684
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
685
|
+
def parameter_declaration_token?(tokens, index)
|
|
686
|
+
prev_tok = previous_non_trivia_token(tokens, index)
|
|
687
|
+
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
688
|
+
next_tok&.type == :colon && prev_tok && (
|
|
689
|
+
[:lparen, :comma].include?(prev_tok.type) ||
|
|
690
|
+
FOREIGN_PARAM_MODE_TOKENS.include?(prev_tok.type)
|
|
691
|
+
)
|
|
692
|
+
end
|
|
631
693
|
|
|
632
|
-
|
|
633
|
-
|
|
694
|
+
def callable_parameter_declaration_token?(tokens, index)
|
|
695
|
+
return false unless parameter_declaration_token?(tokens, index)
|
|
634
696
|
|
|
635
|
-
|
|
636
|
-
|
|
697
|
+
opener_index = parameter_list_opener_index(tokens, index)
|
|
698
|
+
return false unless opener_index
|
|
637
699
|
|
|
638
|
-
|
|
639
|
-
|
|
700
|
+
head_index = previous_non_trivia_token_index(tokens, opener_index)
|
|
701
|
+
return false unless head_index
|
|
640
702
|
|
|
641
|
-
|
|
642
|
-
|
|
703
|
+
head = tokens[head_index]
|
|
704
|
+
return true if [:fn, :proc].include?(head.type)
|
|
643
705
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
706
|
+
if head.type == :rbracket
|
|
707
|
+
lbracket_index = matching_opener_index(tokens, head_index)
|
|
708
|
+
return false unless lbracket_index
|
|
647
709
|
|
|
648
|
-
|
|
649
|
-
|
|
710
|
+
head_index = previous_non_trivia_token_index(tokens, lbracket_index)
|
|
711
|
+
return false unless head_index
|
|
650
712
|
|
|
651
|
-
|
|
652
|
-
|
|
713
|
+
head = tokens[head_index]
|
|
714
|
+
end
|
|
653
715
|
|
|
654
|
-
|
|
716
|
+
return false unless head.type == :identifier
|
|
655
717
|
|
|
656
|
-
|
|
657
|
-
|
|
718
|
+
previous_non_trivia_token(tokens, head_index)&.type == :function
|
|
719
|
+
end
|
|
658
720
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
721
|
+
def parameter_list_opener_index(tokens, index)
|
|
722
|
+
depth = 0
|
|
723
|
+
i = index - 1
|
|
724
|
+
while i >= 0
|
|
725
|
+
tok = tokens[i]
|
|
726
|
+
if tok.type == :rparen
|
|
727
|
+
depth += 1
|
|
728
|
+
elsif tok.type == :lparen
|
|
729
|
+
return i if depth.zero?
|
|
668
730
|
|
|
669
|
-
|
|
731
|
+
depth -= 1
|
|
732
|
+
end
|
|
733
|
+
i -= 1
|
|
670
734
|
end
|
|
671
|
-
|
|
735
|
+
|
|
736
|
+
nil
|
|
672
737
|
end
|
|
673
738
|
|
|
674
|
-
|
|
675
|
-
|
|
739
|
+
def lexically_declared_free_function_name?(tokens, name)
|
|
740
|
+
lexically_declared_free_function_names(tokens).include?(name)
|
|
741
|
+
end
|
|
676
742
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
743
|
+
def lexically_declared_free_function_names(tokens)
|
|
744
|
+
cache = @lexically_declared_free_function_name_cache ||= {}
|
|
745
|
+
cached = cache[tokens.object_id]
|
|
746
|
+
return cached if cached
|
|
680
747
|
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
cached = cache[tokens.object_id]
|
|
684
|
-
return cached if cached
|
|
748
|
+
cache[tokens.object_id] = tokens.each_with_index.each_with_object(Set.new) do |(token, index), names|
|
|
749
|
+
next unless token.type == :identifier
|
|
685
750
|
|
|
686
|
-
|
|
687
|
-
|
|
751
|
+
prev_index = previous_non_trivia_token_index(tokens, index)
|
|
752
|
+
next unless prev_index
|
|
688
753
|
|
|
689
|
-
|
|
690
|
-
|
|
754
|
+
prev_tok = tokens[prev_index]
|
|
755
|
+
next unless [:function, :fn, :proc].include?(prev_tok.type)
|
|
756
|
+
next unless first_non_trivia_token_on_line?(tokens, prev_index)
|
|
691
757
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
758
|
+
names << token.lexeme
|
|
759
|
+
end
|
|
760
|
+
end
|
|
695
761
|
|
|
696
|
-
|
|
762
|
+
def generic_function_lexical_binding_semantic(facts, token)
|
|
763
|
+
kind = generic_function_lexical_binding_kind_at(facts, token.line, token.column, token.lexeme)
|
|
764
|
+
case kind
|
|
765
|
+
when :param
|
|
766
|
+
[:parameter, []]
|
|
767
|
+
when :variable
|
|
768
|
+
[:variable, []]
|
|
769
|
+
else
|
|
770
|
+
nil
|
|
771
|
+
end
|
|
697
772
|
end
|
|
698
|
-
end
|
|
699
773
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
774
|
+
def generic_function_lexical_binding_kind_at(facts, line, column, name)
|
|
775
|
+
generic_function_lexical_binding_scopes(facts).reverse_each do |scope|
|
|
776
|
+
next if line < scope[:start_line] || line > scope[:end_line]
|
|
777
|
+
next if line == scope[:start_line] && column < scope[:start_column]
|
|
778
|
+
|
|
779
|
+
kind = scope[:bindings][name]
|
|
780
|
+
return kind if kind
|
|
781
|
+
end
|
|
782
|
+
|
|
708
783
|
nil
|
|
709
784
|
end
|
|
710
|
-
end
|
|
711
785
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
786
|
+
def generic_function_lexical_binding_scopes(facts)
|
|
787
|
+
scopes = @generic_function_lexical_binding_scope_cache ||= {}
|
|
788
|
+
cached = scopes[facts.object_id]
|
|
789
|
+
unless cached
|
|
790
|
+
decls = Array(facts.ast&.declarations)
|
|
791
|
+
cached = decls.each_with_index.flat_map do |decl, index|
|
|
792
|
+
generic_function_lexical_scopes_for_declaration(
|
|
793
|
+
decl,
|
|
794
|
+
end_line: declaration_scope_end_line(decls, index),
|
|
795
|
+
)
|
|
796
|
+
end
|
|
797
|
+
scopes[facts.object_id] = cached
|
|
798
|
+
end
|
|
716
799
|
|
|
717
|
-
|
|
718
|
-
return kind if kind
|
|
800
|
+
cached
|
|
719
801
|
end
|
|
720
802
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
end_line: declaration_scope_end_line(decls, index),
|
|
733
|
-
)
|
|
803
|
+
def generic_function_lexical_scopes_for_declaration(decl, end_line: Float::INFINITY)
|
|
804
|
+
if decl.is_a?(AST::ExtendingBlock)
|
|
805
|
+
receiver_type_params = generic_type_parameter_names_for_extending_block(decl)
|
|
806
|
+
methods = Array(decl.methods)
|
|
807
|
+
return methods.each_with_index.flat_map do |method, index|
|
|
808
|
+
generic_method_lexical_scopes(
|
|
809
|
+
method,
|
|
810
|
+
receiver_type_params: receiver_type_params,
|
|
811
|
+
end_line: nested_declaration_scope_end_line(methods, index, fallback_end_line: end_line),
|
|
812
|
+
)
|
|
813
|
+
end
|
|
734
814
|
end
|
|
735
|
-
|
|
815
|
+
|
|
816
|
+
return [] unless generic_function_declaration?(decl)
|
|
817
|
+
|
|
818
|
+
generic_callable_lexical_scopes(decl, end_line: generic_statement_list_end_line(decl.body, decl.line))
|
|
736
819
|
end
|
|
737
820
|
|
|
738
|
-
|
|
739
|
-
|
|
821
|
+
def generic_method_lexical_scopes(method, receiver_type_params:, end_line:)
|
|
822
|
+
return [] unless method.respond_to?(:body) && !method.body.nil?
|
|
823
|
+
return [] if receiver_type_params.empty? && Array(method.type_params).empty?
|
|
740
824
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
generic_method_lexical_scopes(
|
|
747
|
-
method,
|
|
748
|
-
receiver_type_params: receiver_type_params,
|
|
749
|
-
end_line: nested_declaration_scope_end_line(methods, index, fallback_end_line: end_line),
|
|
750
|
-
)
|
|
751
|
-
end
|
|
825
|
+
generic_callable_lexical_scopes(
|
|
826
|
+
method,
|
|
827
|
+
end_line:,
|
|
828
|
+
include_receiver: method.respond_to?(:kind) && method.kind != :static,
|
|
829
|
+
)
|
|
752
830
|
end
|
|
753
831
|
|
|
754
|
-
|
|
832
|
+
def generic_callable_lexical_scopes(decl, end_line:, include_receiver: false)
|
|
833
|
+
scopes = []
|
|
834
|
+
current_bindings = {}
|
|
835
|
+
current_bindings['this'] = :param if include_receiver
|
|
836
|
+
Array(decl.params).each do |param|
|
|
837
|
+
next unless param.respond_to?(:name)
|
|
755
838
|
|
|
756
|
-
|
|
757
|
-
|
|
839
|
+
current_bindings[param.name] = :param
|
|
840
|
+
end
|
|
758
841
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
842
|
+
unless current_bindings.empty?
|
|
843
|
+
scopes << {
|
|
844
|
+
start_line: decl.line,
|
|
845
|
+
start_column: 0,
|
|
846
|
+
end_line: end_line,
|
|
847
|
+
bindings: current_bindings.dup,
|
|
848
|
+
}
|
|
849
|
+
end
|
|
762
850
|
|
|
763
|
-
|
|
764
|
-
method,
|
|
765
|
-
end_line:,
|
|
766
|
-
include_receiver: method.respond_to?(:kind) && method.kind != :static,
|
|
767
|
-
)
|
|
768
|
-
end
|
|
851
|
+
collect_generic_function_local_scopes(Array(decl.body), current_bindings, end_line, scopes)
|
|
769
852
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
current_bindings = {}
|
|
773
|
-
current_bindings['this'] = :param if include_receiver
|
|
774
|
-
Array(decl.params).each do |param|
|
|
775
|
-
next unless param.respond_to?(:name)
|
|
853
|
+
scopes
|
|
854
|
+
end
|
|
776
855
|
|
|
777
|
-
|
|
856
|
+
def generic_function_declaration?(decl)
|
|
857
|
+
decl.respond_to?(:type_params) &&
|
|
858
|
+
Array(decl.type_params).any? &&
|
|
859
|
+
decl.respond_to?(:params) &&
|
|
860
|
+
decl.respond_to?(:body) &&
|
|
861
|
+
!decl.body.nil?
|
|
778
862
|
end
|
|
779
863
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
864
|
+
def collect_generic_function_local_scopes(statements, current_bindings, block_end_line, scopes)
|
|
865
|
+
active_bindings = current_bindings.dup
|
|
866
|
+
Array(statements).each do |statement|
|
|
867
|
+
case statement
|
|
868
|
+
when AST::LocalDecl
|
|
869
|
+
active_bindings[statement.name] = statement.kind == :var ? :var : :let
|
|
870
|
+
scopes << generic_binding_scope(statement, active_bindings, block_end_line)
|
|
871
|
+
when AST::IfStmt
|
|
872
|
+
Array(statement.branches).each do |branch|
|
|
873
|
+
branch_body = Array(branch.body)
|
|
874
|
+
branch_end_line = generic_statement_list_end_line(branch_body, statement.line)
|
|
875
|
+
collect_generic_function_local_scopes(branch_body, active_bindings, branch_end_line, scopes)
|
|
876
|
+
end
|
|
877
|
+
|
|
878
|
+
else_body = Array(statement.else_body)
|
|
879
|
+
unless else_body.empty?
|
|
880
|
+
else_end_line = generic_statement_list_end_line(else_body, statement.line)
|
|
881
|
+
collect_generic_function_local_scopes(else_body, active_bindings, else_end_line, scopes)
|
|
882
|
+
end
|
|
883
|
+
when AST::MatchStmt
|
|
884
|
+
Array(statement.arms).each do |arm|
|
|
885
|
+
arm_bindings = active_bindings.dup
|
|
886
|
+
arm_body = Array(arm.body)
|
|
887
|
+
arm_end_line = generic_statement_list_end_line(arm_body, statement.line)
|
|
888
|
+
if arm.respond_to?(:binding_name) && arm.binding_name
|
|
889
|
+
arm_bindings[arm.binding_name] = :let
|
|
890
|
+
scopes << generic_binding_scope(arm, arm_bindings, arm_end_line)
|
|
891
|
+
end
|
|
892
|
+
collect_generic_function_local_scopes(arm_body, arm_bindings, arm_end_line, scopes)
|
|
893
|
+
end
|
|
894
|
+
when AST::UnsafeStmt, AST::WhileStmt, AST::DeferStmt
|
|
895
|
+
body = Array(statement.body)
|
|
896
|
+
body_end_line = generic_statement_list_end_line(body, statement.line)
|
|
897
|
+
collect_generic_function_local_scopes(body, active_bindings, body_end_line, scopes)
|
|
898
|
+
when AST::ForStmt
|
|
899
|
+
next unless statement.respond_to?(:name) && statement.name
|
|
900
|
+
|
|
901
|
+
body = Array(statement.body)
|
|
902
|
+
body_end_line = generic_statement_list_end_line(body, statement.line)
|
|
903
|
+
for_bindings = active_bindings.dup
|
|
904
|
+
for_bindings[statement.name] = :let
|
|
905
|
+
scopes << generic_binding_scope(statement, for_bindings, body_end_line)
|
|
906
|
+
collect_generic_function_local_scopes(body, for_bindings, body_end_line, scopes)
|
|
907
|
+
end
|
|
908
|
+
end
|
|
909
|
+
end
|
|
910
|
+
|
|
911
|
+
def generic_binding_scope(node, bindings, end_line)
|
|
912
|
+
{
|
|
913
|
+
start_line: node.line ? node.line : 0,
|
|
914
|
+
start_column: node.column ? node.column : 0,
|
|
784
915
|
end_line: end_line,
|
|
785
|
-
bindings:
|
|
916
|
+
bindings: bindings.dup,
|
|
786
917
|
}
|
|
787
918
|
end
|
|
788
919
|
|
|
789
|
-
|
|
920
|
+
def generic_statement_list_end_line(statements, fallback_line)
|
|
921
|
+
Array(statements).reduce(fallback_line || 0) do |max_line, statement|
|
|
922
|
+
[max_line, generic_statement_end_line(statement)].compact.max
|
|
923
|
+
end
|
|
924
|
+
end
|
|
790
925
|
|
|
791
|
-
|
|
792
|
-
|
|
926
|
+
def generic_statement_end_line(statement)
|
|
927
|
+
return 0 unless statement
|
|
793
928
|
|
|
794
|
-
def generic_function_declaration?(decl)
|
|
795
|
-
decl.respond_to?(:type_params) &&
|
|
796
|
-
Array(decl.type_params).any? &&
|
|
797
|
-
decl.respond_to?(:params) &&
|
|
798
|
-
decl.respond_to?(:body) &&
|
|
799
|
-
!decl.body.nil?
|
|
800
|
-
end
|
|
801
|
-
|
|
802
|
-
def collect_generic_function_local_scopes(statements, current_bindings, block_end_line, scopes)
|
|
803
|
-
active_bindings = current_bindings.dup
|
|
804
|
-
Array(statements).each do |statement|
|
|
805
929
|
case statement
|
|
806
|
-
when AST::LocalDecl
|
|
807
|
-
active_bindings[statement.name] = statement.kind == :var ? :var : :let
|
|
808
|
-
scopes << generic_binding_scope(statement, active_bindings, block_end_line)
|
|
809
930
|
when AST::IfStmt
|
|
810
|
-
Array(statement.branches).
|
|
811
|
-
|
|
812
|
-
branch_end_line = generic_statement_list_end_line(branch_body, statement.line)
|
|
813
|
-
collect_generic_function_local_scopes(branch_body, active_bindings, branch_end_line, scopes)
|
|
814
|
-
end
|
|
815
|
-
|
|
816
|
-
else_body = Array(statement.else_body)
|
|
817
|
-
unless else_body.empty?
|
|
818
|
-
else_end_line = generic_statement_list_end_line(else_body, statement.line)
|
|
819
|
-
collect_generic_function_local_scopes(else_body, active_bindings, else_end_line, scopes)
|
|
931
|
+
branch_lines = Array(statement.branches).map do |branch|
|
|
932
|
+
generic_statement_list_end_line(Array(branch.body), branch.line || statement.line)
|
|
820
933
|
end
|
|
934
|
+
else_line = generic_statement_list_end_line(Array(statement.else_body), statement.line)
|
|
935
|
+
([statement.line, else_line] + branch_lines).compact.max
|
|
821
936
|
when AST::MatchStmt
|
|
822
|
-
Array(statement.arms).
|
|
823
|
-
|
|
824
|
-
arm_body = Array(arm.body)
|
|
825
|
-
arm_end_line = generic_statement_list_end_line(arm_body, statement.line)
|
|
826
|
-
if arm.respond_to?(:binding_name) && arm.binding_name
|
|
827
|
-
arm_bindings[arm.binding_name] = :let
|
|
828
|
-
scopes << generic_binding_scope(arm, arm_bindings, arm_end_line)
|
|
829
|
-
end
|
|
830
|
-
collect_generic_function_local_scopes(arm_body, arm_bindings, arm_end_line, scopes)
|
|
937
|
+
arm_lines = Array(statement.arms).map do |arm|
|
|
938
|
+
generic_statement_list_end_line(Array(arm.body), arm.line || statement.line)
|
|
831
939
|
end
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
next unless statement.respond_to?(:name) && statement.name
|
|
838
|
-
|
|
839
|
-
body = Array(statement.body)
|
|
840
|
-
body_end_line = generic_statement_list_end_line(body, statement.line)
|
|
841
|
-
for_bindings = active_bindings.dup
|
|
842
|
-
for_bindings[statement.name] = :let
|
|
843
|
-
scopes << generic_binding_scope(statement, for_bindings, body_end_line)
|
|
844
|
-
collect_generic_function_local_scopes(body, for_bindings, body_end_line, scopes)
|
|
940
|
+
([statement.line] + arm_lines).compact.max
|
|
941
|
+
when AST::UnsafeStmt, AST::WhileStmt, AST::ForStmt, AST::DeferStmt
|
|
942
|
+
[statement.line, generic_statement_list_end_line(Array(statement.body), statement.line)].compact.max
|
|
943
|
+
else
|
|
944
|
+
statement.line || 0
|
|
845
945
|
end
|
|
846
946
|
end
|
|
847
|
-
end
|
|
848
947
|
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
start_column: node.respond_to?(:column) && node.column ? node.column : 0,
|
|
853
|
-
end_line: end_line,
|
|
854
|
-
bindings: bindings.dup,
|
|
855
|
-
}
|
|
856
|
-
end
|
|
857
|
-
|
|
858
|
-
def generic_statement_list_end_line(statements, fallback_line)
|
|
859
|
-
Array(statements).reduce(fallback_line || 0) do |max_line, statement|
|
|
860
|
-
[max_line, generic_statement_end_line(statement)].compact.max
|
|
861
|
-
end
|
|
862
|
-
end
|
|
948
|
+
def namespace_keyword_token?(tokens, index)
|
|
949
|
+
tok = tokens[index]
|
|
950
|
+
return false unless tok && Token::KEYWORDS.value?(tok.type)
|
|
863
951
|
|
|
864
|
-
|
|
865
|
-
|
|
952
|
+
import_path_info_at(tokens, index, allow_keywords: true) ||
|
|
953
|
+
module_declaration_path_token?(tokens, index, allow_keywords: true)
|
|
866
954
|
|
|
867
|
-
case statement
|
|
868
|
-
when AST::IfStmt
|
|
869
|
-
branch_lines = Array(statement.branches).map do |branch|
|
|
870
|
-
generic_statement_list_end_line(Array(branch.body), branch.respond_to?(:line) ? branch.line : statement.line)
|
|
871
|
-
end
|
|
872
|
-
else_line = generic_statement_list_end_line(Array(statement.else_body), statement.line)
|
|
873
|
-
([statement.line, else_line] + branch_lines).compact.max
|
|
874
|
-
when AST::MatchStmt
|
|
875
|
-
arm_lines = Array(statement.arms).map do |arm|
|
|
876
|
-
generic_statement_list_end_line(Array(arm.body), arm.respond_to?(:line) ? arm.line : statement.line)
|
|
877
|
-
end
|
|
878
|
-
([statement.line] + arm_lines).compact.max
|
|
879
|
-
when AST::UnsafeStmt, AST::WhileStmt, AST::ForStmt, AST::DeferStmt
|
|
880
|
-
[statement.line, generic_statement_list_end_line(Array(statement.body), statement.line)].compact.max
|
|
881
|
-
else
|
|
882
|
-
statement.respond_to?(:line) ? statement.line : 0
|
|
883
955
|
end
|
|
884
|
-
end
|
|
885
|
-
|
|
886
|
-
def namespace_keyword_token?(tokens, index)
|
|
887
|
-
tok = tokens[index]
|
|
888
|
-
return false unless tok && Token::KEYWORDS.value?(tok.type)
|
|
889
956
|
|
|
890
|
-
|
|
891
|
-
|
|
957
|
+
def local_semantic_value_binding(facts, token, allow_same_line_future: false)
|
|
958
|
+
char = token.column - 1
|
|
959
|
+
[token.line - 1, token.line].uniq.each do |line|
|
|
960
|
+
frame = enclosing_completion_frame(facts, line)
|
|
961
|
+
next unless frame
|
|
892
962
|
|
|
893
|
-
|
|
963
|
+
snapshot = latest_completion_snapshot(frame, line, char)
|
|
964
|
+
binding = snapshot&.bindings&.dig(token.lexeme)
|
|
965
|
+
return binding if binding
|
|
894
966
|
|
|
895
|
-
|
|
896
|
-
char = token.column - 1
|
|
897
|
-
[token.line - 1, token.line].uniq.each do |line|
|
|
898
|
-
frame = enclosing_completion_frame(facts, line)
|
|
899
|
-
next unless frame
|
|
967
|
+
next unless allow_same_line_future
|
|
900
968
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
969
|
+
future_snapshot = same_line_future_completion_snapshot(frame, line, char)
|
|
970
|
+
binding = future_snapshot&.bindings&.dig(token.lexeme)
|
|
971
|
+
return binding if binding
|
|
972
|
+
end
|
|
904
973
|
|
|
905
|
-
|
|
974
|
+
nil
|
|
975
|
+
end
|
|
906
976
|
|
|
907
|
-
|
|
908
|
-
binding
|
|
909
|
-
|
|
977
|
+
def semantic_value_binding_entry(binding, declaration: false)
|
|
978
|
+
case binding.kind
|
|
979
|
+
when :param
|
|
980
|
+
modifiers = []
|
|
981
|
+
modifiers << 'declaration' if declaration
|
|
982
|
+
[:parameter, modifiers]
|
|
983
|
+
when :const, :let
|
|
984
|
+
[:variable, ['readonly']]
|
|
985
|
+
else
|
|
986
|
+
modifiers = []
|
|
987
|
+
modifiers << 'declaration' if declaration
|
|
988
|
+
[:variable, modifiers]
|
|
989
|
+
end
|
|
910
990
|
end
|
|
911
991
|
|
|
912
|
-
|
|
913
|
-
|
|
992
|
+
def resolved_call_callee_semantic(name, token, parameter_declaration, facts)
|
|
993
|
+
if (binding = local_semantic_value_binding(facts, token, allow_same_line_future: parameter_declaration))
|
|
994
|
+
return semantic_value_binding_entry(binding, declaration: binding.kind == :param && parameter_declaration)
|
|
995
|
+
end
|
|
996
|
+
|
|
997
|
+
if (binding = facts.values[name])
|
|
998
|
+
return semantic_value_binding_entry(binding)
|
|
999
|
+
end
|
|
914
1000
|
|
|
915
|
-
def semantic_value_binding_entry(binding, declaration: false)
|
|
916
|
-
case binding.kind
|
|
917
|
-
when :param
|
|
918
|
-
modifiers = []
|
|
919
|
-
modifiers << 'declaration' if declaration
|
|
920
|
-
[:parameter, modifiers]
|
|
921
|
-
when :const, :let
|
|
922
|
-
[:variable, ['readonly']]
|
|
923
|
-
else
|
|
924
1001
|
modifiers = []
|
|
925
|
-
modifiers << '
|
|
926
|
-
[:
|
|
927
|
-
|
|
928
|
-
|
|
1002
|
+
modifiers << 'defaultLibrary' if BUILTIN_FUNCTION_NAMES.include?(name)
|
|
1003
|
+
return [:function, modifiers] if BUILTIN_FUNCTION_NAMES.include?(name)
|
|
1004
|
+
return [:function, modifiers] if facts.functions.key?(name)
|
|
1005
|
+
return [:type, []] if constructible_semantic_type?(facts.types[name])
|
|
929
1006
|
|
|
930
|
-
|
|
931
|
-
if (binding = local_semantic_value_binding(facts, token, allow_same_line_future: parameter_declaration))
|
|
932
|
-
return semantic_value_binding_entry(binding, declaration: binding.kind == :param && parameter_declaration)
|
|
1007
|
+
nil
|
|
933
1008
|
end
|
|
934
1009
|
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1010
|
+
def callable_field_member_access?(name, tokens, index, facts)
|
|
1011
|
+
next_tok = next_non_trivia_token(tokens, index + 1)
|
|
1012
|
+
return false unless next_tok&.type == :lparen
|
|
938
1013
|
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
return [:function, modifiers] if BUILTIN_FUNCTION_NAMES.include?(name)
|
|
942
|
-
return [:function, modifiers] if facts.functions.key?(name)
|
|
943
|
-
return [:type, []] if constructible_semantic_type?(facts.types[name])
|
|
1014
|
+
dot_index = previous_non_trivia_token_index(tokens, index)
|
|
1015
|
+
return false unless dot_index && tokens[dot_index].type == :dot
|
|
944
1016
|
|
|
945
|
-
|
|
946
|
-
|
|
1017
|
+
receiver_index = previous_non_trivia_token_index(tokens, dot_index)
|
|
1018
|
+
return false unless receiver_index
|
|
947
1019
|
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
return false unless next_tok&.type == :lparen
|
|
1020
|
+
receiver_tok = tokens[receiver_index]
|
|
1021
|
+
return false unless receiver_tok.type == :identifier
|
|
951
1022
|
|
|
952
|
-
|
|
953
|
-
|
|
1023
|
+
resolve_receiver_value_type(facts, receiver_tok).then do |receiver_type|
|
|
1024
|
+
next false unless receiver_type
|
|
954
1025
|
|
|
955
|
-
|
|
956
|
-
|
|
1026
|
+
field_receiver_type = project_field_receiver_type_for_completion(receiver_type, facts)
|
|
1027
|
+
next false unless field_receiver_type.respond_to?(:field)
|
|
957
1028
|
|
|
958
|
-
|
|
959
|
-
|
|
1029
|
+
callable_semantic_type?(field_receiver_type.field(name))
|
|
1030
|
+
end
|
|
1031
|
+
end
|
|
960
1032
|
|
|
961
|
-
resolve_receiver_value_type(facts,
|
|
962
|
-
|
|
1033
|
+
def resolve_receiver_value_type(facts, token)
|
|
1034
|
+
char = token.column
|
|
963
1035
|
|
|
964
|
-
|
|
965
|
-
|
|
1036
|
+
[token.line - 1, token.line].uniq.each do |line|
|
|
1037
|
+
receiver_type = resolve_dot_receiver_value_type(facts, token.lexeme, line, char)
|
|
1038
|
+
return receiver_type if receiver_type
|
|
1039
|
+
end
|
|
966
1040
|
|
|
967
|
-
|
|
1041
|
+
nil
|
|
968
1042
|
end
|
|
969
|
-
end
|
|
970
1043
|
|
|
971
|
-
|
|
972
|
-
|
|
1044
|
+
def callable_semantic_type?(type)
|
|
1045
|
+
type.is_a?(Types::Function) || type.is_a?(Types::Proc)
|
|
1046
|
+
end
|
|
973
1047
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
return
|
|
1048
|
+
def known_type_name?(facts, name)
|
|
1049
|
+
return false unless facts
|
|
1050
|
+
return true if facts.types.key?(name)
|
|
1051
|
+
facts.types.each_value do |type|
|
|
1052
|
+
return true if type.respond_to?(:nested_types) && type.nested_types.key?(name)
|
|
1053
|
+
end
|
|
1054
|
+
false
|
|
977
1055
|
end
|
|
978
1056
|
|
|
979
|
-
|
|
980
|
-
|
|
1057
|
+
def dot_nested_type_member?(tokens, index, facts)
|
|
1058
|
+
return false unless facts
|
|
981
1059
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1060
|
+
dot_index = index - 1
|
|
1061
|
+
return false unless dot_index >= 0 && tokens[dot_index].type == :dot
|
|
1062
|
+
|
|
1063
|
+
receiver_index = previous_non_trivia_token_index(tokens, dot_index)
|
|
1064
|
+
return false unless receiver_index && tokens[receiver_index].type == :identifier
|
|
985
1065
|
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1066
|
+
receiver_name = tokens[receiver_index].lexeme
|
|
1067
|
+
type = resolve_struct_type_name(facts, receiver_name)
|
|
1068
|
+
return false unless type.is_a?(Types::Struct)
|
|
1069
|
+
|
|
1070
|
+
member_name = tokens[index].lexeme
|
|
1071
|
+
type.nested_types.key?(member_name)
|
|
991
1072
|
end
|
|
992
|
-
false
|
|
993
|
-
end
|
|
994
1073
|
|
|
995
|
-
|
|
996
|
-
|
|
1074
|
+
def resolve_struct_type_name(facts, name)
|
|
1075
|
+
type = facts.types[name]
|
|
1076
|
+
return type if type.is_a?(Types::Struct)
|
|
1077
|
+
facts.types.each_value do |t|
|
|
1078
|
+
next unless t.respond_to?(:nested_types)
|
|
1079
|
+
found = t.nested_types[name]
|
|
1080
|
+
return found if found.is_a?(Types::Struct)
|
|
1081
|
+
end
|
|
1082
|
+
nil
|
|
1083
|
+
end
|
|
997
1084
|
|
|
998
|
-
|
|
999
|
-
|
|
1085
|
+
def constructible_semantic_type?(type)
|
|
1086
|
+
type.is_a?(Types::Struct) || type.is_a?(Types::GenericStructDefinition) || type.is_a?(Types::StringView) || type.is_a?(Types::Task) || type.is_a?(Types::Vector) || type.is_a?(Types::Matrix) || type.is_a?(Types::Quaternion)
|
|
1087
|
+
end
|
|
1000
1088
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1089
|
+
def bare_builtin_specialization?(name, tokens, index)
|
|
1090
|
+
return false unless name == 'zero' || name == 'default'
|
|
1003
1091
|
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
return false unless type.is_a?(Types::Struct)
|
|
1092
|
+
next_index = next_non_trivia_token_index(tokens, index + 1)
|
|
1093
|
+
return false unless next_index && tokens[next_index].type == :lbracket
|
|
1007
1094
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
end
|
|
1095
|
+
rbracket_index = matching_closer_index(tokens, next_index, :lbracket, :rbracket)
|
|
1096
|
+
return false unless rbracket_index
|
|
1011
1097
|
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
return type if type.is_a?(Types::Struct)
|
|
1015
|
-
facts.types.each_value do |t|
|
|
1016
|
-
next unless t.respond_to?(:nested_types)
|
|
1017
|
-
found = t.nested_types[name]
|
|
1018
|
-
return found if found.is_a?(Types::Struct)
|
|
1098
|
+
after_bracket_index = next_non_trivia_token_index(tokens, rbracket_index + 1)
|
|
1099
|
+
after_bracket_index.nil? || tokens[after_bracket_index].type != :lparen
|
|
1019
1100
|
end
|
|
1020
|
-
nil
|
|
1021
|
-
end
|
|
1022
1101
|
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1102
|
+
def bare_function_value_identifier_site?(facts, token)
|
|
1103
|
+
facts.functions.key?(token.lexeme) &&
|
|
1104
|
+
facts.callable_value_identifier_sites.fetch([token.line, token.column], false)
|
|
1105
|
+
end
|
|
1026
1106
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1107
|
+
def imported_module_function_value_member_access_site?(facts, tokens, index)
|
|
1108
|
+
dot_index = previous_non_trivia_token_index(tokens, index)
|
|
1109
|
+
return false unless dot_index && tokens[dot_index].type == :dot
|
|
1029
1110
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1111
|
+
receiver_index = previous_non_trivia_token_index(tokens, dot_index)
|
|
1112
|
+
return false unless receiver_index
|
|
1032
1113
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1114
|
+
receiver = tokens[receiver_index]
|
|
1115
|
+
return false unless receiver.type == :identifier
|
|
1035
1116
|
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1117
|
+
facts.callable_value_member_access_sites.fetch(
|
|
1118
|
+
[receiver.lexeme, receiver.line, receiver.column, tokens[index].lexeme],
|
|
1119
|
+
false,
|
|
1120
|
+
)
|
|
1121
|
+
end
|
|
1039
1122
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
end
|
|
1123
|
+
def imported_module_binding_for_member(tokens, index, facts)
|
|
1124
|
+
dot_index = previous_non_trivia_token_index(tokens, index)
|
|
1125
|
+
return nil unless dot_index && tokens[dot_index].type == :dot
|
|
1044
1126
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
return false unless dot_index && tokens[dot_index].type == :dot
|
|
1127
|
+
receiver_index = previous_non_trivia_token_index(tokens, dot_index)
|
|
1128
|
+
return nil unless receiver_index
|
|
1048
1129
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1130
|
+
receiver = tokens[receiver_index]
|
|
1131
|
+
return nil unless receiver.type == :identifier
|
|
1051
1132
|
|
|
1052
|
-
|
|
1053
|
-
|
|
1133
|
+
facts.imports[receiver.lexeme]
|
|
1134
|
+
end
|
|
1054
1135
|
|
|
1055
|
-
facts
|
|
1056
|
-
|
|
1057
|
-
false
|
|
1058
|
-
)
|
|
1059
|
-
end
|
|
1136
|
+
def static_type_member_access?(tokens, index, facts)
|
|
1137
|
+
receiver_info = dot_type_receiver_info(tokens, index, facts)
|
|
1138
|
+
return false unless receiver_info
|
|
1060
1139
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
return nil unless dot_index && tokens[dot_index].type == :dot
|
|
1140
|
+
!static_method_binding_for_receiver(facts, receiver_info[:type], tokens[index].lexeme).nil?
|
|
1141
|
+
end
|
|
1064
1142
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1143
|
+
def dot_type_receiver_info(tokens, index, facts)
|
|
1144
|
+
dot_index = previous_non_trivia_token_index(tokens, index)
|
|
1145
|
+
return nil unless dot_index && tokens[dot_index].type == :dot
|
|
1067
1146
|
|
|
1068
|
-
|
|
1069
|
-
|
|
1147
|
+
receiver_index = previous_non_trivia_token_index(tokens, dot_index)
|
|
1148
|
+
return nil unless receiver_index
|
|
1070
1149
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1150
|
+
if tokens[receiver_index].type == :rbracket
|
|
1151
|
+
lbracket_index = matching_opener_index(tokens, receiver_index)
|
|
1152
|
+
return nil unless lbracket_index
|
|
1073
1153
|
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1154
|
+
receiver_index = previous_non_trivia_token_index(tokens, lbracket_index)
|
|
1155
|
+
return nil unless receiver_index
|
|
1156
|
+
end
|
|
1077
1157
|
|
|
1078
|
-
|
|
1079
|
-
|
|
1158
|
+
receiver = tokens[receiver_index]
|
|
1159
|
+
return nil unless receiver.type == :identifier
|
|
1080
1160
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
return nil unless dot_index && tokens[dot_index].type == :dot
|
|
1161
|
+
receiver_name = receiver.lexeme
|
|
1162
|
+
receiver_path = receiver_name
|
|
1084
1163
|
|
|
1085
|
-
|
|
1086
|
-
|
|
1164
|
+
module_dot_index = previous_non_trivia_token_index(tokens, receiver_index)
|
|
1165
|
+
if module_dot_index && tokens[module_dot_index].type == :dot
|
|
1166
|
+
module_index = previous_non_trivia_token_index(tokens, module_dot_index)
|
|
1167
|
+
return nil unless module_index && tokens[module_index].type == :identifier
|
|
1087
1168
|
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
return nil unless lbracket_index
|
|
1169
|
+
receiver_path = "#{tokens[module_index].lexeme}.#{receiver_name}"
|
|
1170
|
+
end
|
|
1091
1171
|
|
|
1092
|
-
|
|
1093
|
-
return nil unless receiver_index
|
|
1172
|
+
resolve_type_receiver_info(facts, receiver_name, receiver_path)
|
|
1094
1173
|
end
|
|
1095
1174
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
receiver_name = receiver.lexeme
|
|
1100
|
-
receiver_path = receiver_name
|
|
1175
|
+
def specialized_call_with_type_args?(tokens, index)
|
|
1176
|
+
next_index = next_non_trivia_token_index(tokens, index + 1)
|
|
1177
|
+
return false unless next_index && tokens[next_index].type == :lbracket
|
|
1101
1178
|
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
module_index = previous_non_trivia_token_index(tokens, module_dot_index)
|
|
1105
|
-
return nil unless module_index && tokens[module_index].type == :identifier
|
|
1179
|
+
rbracket_index = matching_closer_index(tokens, next_index, :lbracket, :rbracket)
|
|
1180
|
+
return false unless rbracket_index
|
|
1106
1181
|
|
|
1107
|
-
|
|
1182
|
+
after_bracket_index = next_non_trivia_token_index(tokens, rbracket_index + 1)
|
|
1183
|
+
after_bracket_index && tokens[after_bracket_index].type == :lparen
|
|
1108
1184
|
end
|
|
1109
1185
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1186
|
+
def identifier_in_type_argument_position?(tokens, index)
|
|
1187
|
+
lbracket_index = previous_non_trivia_token_index(tokens, index)
|
|
1188
|
+
return false unless lbracket_index
|
|
1112
1189
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1190
|
+
if tokens[lbracket_index].type == :comma
|
|
1191
|
+
depth = 0
|
|
1192
|
+
i = lbracket_index - 1
|
|
1193
|
+
lbracket_index = nil
|
|
1194
|
+
while i >= 0
|
|
1195
|
+
tok = tokens[i]
|
|
1196
|
+
if tok.type == :rbracket
|
|
1197
|
+
depth += 1
|
|
1198
|
+
elsif tok.type == :lbracket
|
|
1199
|
+
if depth.zero?
|
|
1200
|
+
lbracket_index = i
|
|
1201
|
+
break
|
|
1202
|
+
end
|
|
1116
1203
|
|
|
1117
|
-
|
|
1118
|
-
|
|
1204
|
+
depth -= 1
|
|
1205
|
+
end
|
|
1206
|
+
i -= 1
|
|
1207
|
+
end
|
|
1208
|
+
end
|
|
1119
1209
|
|
|
1120
|
-
|
|
1121
|
-
after_bracket_index && tokens[after_bracket_index].type == :lparen
|
|
1122
|
-
end
|
|
1210
|
+
return false unless lbracket_index && tokens[lbracket_index].type == :lbracket
|
|
1123
1211
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
return false unless lbracket_index
|
|
1212
|
+
rbracket_index = matching_closer_index(tokens, lbracket_index, :lbracket, :rbracket)
|
|
1213
|
+
return false unless rbracket_index
|
|
1127
1214
|
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
i = lbracket_index - 1
|
|
1131
|
-
lbracket_index = nil
|
|
1132
|
-
while i >= 0
|
|
1133
|
-
tok = tokens[i]
|
|
1134
|
-
if tok.type == :rbracket
|
|
1135
|
-
depth += 1
|
|
1136
|
-
elsif tok.type == :lbracket
|
|
1137
|
-
if depth.zero?
|
|
1138
|
-
lbracket_index = i
|
|
1139
|
-
break
|
|
1140
|
-
end
|
|
1215
|
+
next_index = next_non_trivia_token_index(tokens, index + 1)
|
|
1216
|
+
return false unless next_index
|
|
1141
1217
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
i -= 1
|
|
1145
|
-
end
|
|
1218
|
+
# Type argument entries should stay inside the current [] pair.
|
|
1219
|
+
next_index <= rbracket_index
|
|
1146
1220
|
end
|
|
1147
1221
|
|
|
1148
|
-
|
|
1222
|
+
def type_parameter_declaration_token?(facts, tokens, index)
|
|
1223
|
+
info = type_parameter_declaration_info_on_line(tokens, tokens[index].line)
|
|
1224
|
+
info && info[:tokens].any? { |token| token.equal?(tokens[index]) }
|
|
1225
|
+
end
|
|
1149
1226
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1227
|
+
def type_parameter_reference_token?(facts, tokens, index)
|
|
1228
|
+
tok = tokens[index]
|
|
1229
|
+
return false unless type_parameter_names_in_scope(facts, tok.line).include?(tok.lexeme)
|
|
1230
|
+
return false if type_parameter_declaration_token?(facts, tokens, index)
|
|
1152
1231
|
|
|
1153
|
-
|
|
1154
|
-
|
|
1232
|
+
identifier_in_type_parameter_reference_position?(tokens, index)
|
|
1233
|
+
end
|
|
1155
1234
|
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
end
|
|
1235
|
+
def identifier_in_type_parameter_reference_position?(tokens, index)
|
|
1236
|
+
return true if identifier_in_type_argument_position?(tokens, index)
|
|
1159
1237
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
end
|
|
1238
|
+
prev_tok = previous_non_trivia_token(tokens, index)
|
|
1239
|
+
[:colon, :arrow].include?(prev_tok&.type)
|
|
1240
|
+
end
|
|
1164
1241
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
return false unless type_parameter_names_in_scope(facts, tok.line).include?(tok.lexeme)
|
|
1168
|
-
return false if type_parameter_declaration_token?(facts, tokens, index)
|
|
1242
|
+
def identifier_in_type_reference_position?(tokens, index)
|
|
1243
|
+
return true if identifier_in_type_argument_position?(tokens, index)
|
|
1169
1244
|
|
|
1170
|
-
|
|
1171
|
-
|
|
1245
|
+
prev_tok = previous_non_trivia_token(tokens, index)
|
|
1246
|
+
return true if [:colon, :arrow, :as].include?(prev_tok&.type)
|
|
1172
1247
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1248
|
+
line_tokens = non_trivia_tokens_on_line(tokens, tokens[index].line)
|
|
1249
|
+
return true if prev_tok&.type == :equal && line_tokens.first&.type == :type
|
|
1175
1250
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
end
|
|
1251
|
+
next_index = next_non_trivia_token_index(tokens, index + 1)
|
|
1252
|
+
return false unless next_index && tokens[next_index].type == :less
|
|
1179
1253
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1254
|
+
minus_index = next_non_trivia_token_index(tokens, next_index + 1)
|
|
1255
|
+
return false unless minus_index && tokens[minus_index].type == :minus
|
|
1182
1256
|
|
|
1183
|
-
|
|
1184
|
-
|
|
1257
|
+
tokens[next_index].line == tokens[index].line &&
|
|
1258
|
+
tokens[next_index].column == (tokens[index].column + tokens[index].lexeme.length) &&
|
|
1259
|
+
tokens[minus_index].line == tokens[next_index].line &&
|
|
1260
|
+
tokens[minus_index].column == (tokens[next_index].column + tokens[next_index].lexeme.length)
|
|
1261
|
+
end
|
|
1185
1262
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1263
|
+
def type_parameter_declaration_info_on_line(tokens, line)
|
|
1264
|
+
line_tokens = non_trivia_tokens_on_line(tokens, line)
|
|
1265
|
+
return nil if line_tokens.empty?
|
|
1188
1266
|
|
|
1189
|
-
|
|
1190
|
-
|
|
1267
|
+
header_index = line_tokens.index { |line_tok| generic_type_parameter_header_token?(line_tok.type) }
|
|
1268
|
+
return nil unless header_index
|
|
1191
1269
|
|
|
1192
|
-
|
|
1193
|
-
|
|
1270
|
+
name_index = ((header_index + 1)...line_tokens.length).find { |i| line_tokens[i].type == :identifier }
|
|
1271
|
+
return nil unless name_index
|
|
1194
1272
|
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
tokens[minus_index].line == tokens[next_index].line &&
|
|
1198
|
-
tokens[minus_index].column == (tokens[next_index].column + tokens[next_index].lexeme.length)
|
|
1199
|
-
end
|
|
1273
|
+
lbracket_index = name_index + 1
|
|
1274
|
+
return nil unless line_tokens[lbracket_index]&.type == :lbracket
|
|
1200
1275
|
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
tokens: type_param_tokens,
|
|
1229
|
-
} if depth.zero?
|
|
1230
|
-
when :comma
|
|
1231
|
-
expect_name = true if depth == 1
|
|
1232
|
-
when :at
|
|
1233
|
-
expect_name = false if depth == 1
|
|
1234
|
-
when :implements
|
|
1235
|
-
expect_name = false if depth == 1
|
|
1236
|
-
else
|
|
1237
|
-
if depth == 1 && expect_name && tok.type == :identifier
|
|
1238
|
-
type_param_tokens << tok
|
|
1239
|
-
expect_name = false
|
|
1276
|
+
depth = 0
|
|
1277
|
+
type_param_tokens = []
|
|
1278
|
+
expect_name = false
|
|
1279
|
+
i = lbracket_index
|
|
1280
|
+
while i < line_tokens.length
|
|
1281
|
+
tok = line_tokens[i]
|
|
1282
|
+
case tok.type
|
|
1283
|
+
when :lbracket
|
|
1284
|
+
depth += 1
|
|
1285
|
+
expect_name = true if depth == 1
|
|
1286
|
+
when :rbracket
|
|
1287
|
+
depth -= 1
|
|
1288
|
+
return {
|
|
1289
|
+
names: type_param_tokens.map(&:lexeme),
|
|
1290
|
+
tokens: type_param_tokens,
|
|
1291
|
+
} if depth.zero?
|
|
1292
|
+
when :comma
|
|
1293
|
+
expect_name = true if depth == 1
|
|
1294
|
+
when :at
|
|
1295
|
+
expect_name = false if depth == 1
|
|
1296
|
+
when :implements
|
|
1297
|
+
expect_name = false if depth == 1
|
|
1298
|
+
else
|
|
1299
|
+
if depth == 1 && expect_name && tok.type == :identifier
|
|
1300
|
+
type_param_tokens << tok
|
|
1301
|
+
expect_name = false
|
|
1302
|
+
end
|
|
1240
1303
|
end
|
|
1304
|
+
i += 1
|
|
1241
1305
|
end
|
|
1242
|
-
|
|
1306
|
+
|
|
1307
|
+
nil
|
|
1243
1308
|
end
|
|
1244
1309
|
|
|
1245
|
-
|
|
1246
|
-
|
|
1310
|
+
def generic_type_parameter_header_token?(type)
|
|
1311
|
+
[:function, :struct, :union, :enum, :flags, :variant, :type, :extending].include?(type)
|
|
1312
|
+
end
|
|
1247
1313
|
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1314
|
+
def type_parameter_names_in_scope(facts, line)
|
|
1315
|
+
scopes = @type_parameter_scope_cache ||= {}
|
|
1316
|
+
cached = scopes[facts.object_id]
|
|
1317
|
+
unless cached
|
|
1318
|
+
decls = Array(facts.ast&.declarations)
|
|
1319
|
+
cached = decls.each_with_index.flat_map do |decl, index|
|
|
1320
|
+
type_parameter_scopes_for_declaration(
|
|
1321
|
+
decl,
|
|
1322
|
+
end_line: declaration_scope_end_line(decls, index),
|
|
1323
|
+
)
|
|
1324
|
+
end
|
|
1325
|
+
scopes[facts.object_id] = cached
|
|
1326
|
+
end
|
|
1251
1327
|
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
cached = scopes[facts.object_id]
|
|
1255
|
-
unless cached
|
|
1256
|
-
decls = Array(facts.ast&.declarations)
|
|
1257
|
-
cached = decls.each_with_index.flat_map do |decl, index|
|
|
1258
|
-
type_parameter_scopes_for_declaration(
|
|
1259
|
-
decl,
|
|
1260
|
-
end_line: declaration_scope_end_line(decls, index),
|
|
1261
|
-
)
|
|
1328
|
+
cached.reverse_each do |scope|
|
|
1329
|
+
return scope[:names] if line >= scope[:start_line] && line <= scope[:end_line]
|
|
1262
1330
|
end
|
|
1263
|
-
scopes[facts.object_id] = cached
|
|
1264
|
-
end
|
|
1265
1331
|
|
|
1266
|
-
|
|
1267
|
-
return scope[:names] if line >= scope[:start_line] && line <= scope[:end_line]
|
|
1332
|
+
[]
|
|
1268
1333
|
end
|
|
1269
1334
|
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
return methods.each_with_index.filter_map do |method, index|
|
|
1278
|
-
names = receiver_names + generic_type_parameter_names_for_declaration(method)
|
|
1279
|
-
next if names.empty? || method.line.nil?
|
|
1335
|
+
def type_parameter_scopes_for_declaration(decl, end_line: Float::INFINITY)
|
|
1336
|
+
if decl.is_a?(AST::ExtendingBlock)
|
|
1337
|
+
receiver_names = generic_type_parameter_names_for_extending_block(decl)
|
|
1338
|
+
methods = Array(decl.methods)
|
|
1339
|
+
return methods.each_with_index.filter_map do |method, index|
|
|
1340
|
+
names = receiver_names + generic_type_parameter_names_for_declaration(method)
|
|
1341
|
+
next if names.empty? || method.line.nil?
|
|
1280
1342
|
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1343
|
+
{
|
|
1344
|
+
start_line: method.line,
|
|
1345
|
+
end_line: nested_declaration_scope_end_line(methods, index, fallback_end_line: end_line),
|
|
1346
|
+
names: names.uniq,
|
|
1347
|
+
}
|
|
1348
|
+
end
|
|
1286
1349
|
end
|
|
1287
|
-
end
|
|
1288
1350
|
|
|
1289
|
-
|
|
1290
|
-
|
|
1351
|
+
names = generic_type_parameter_names_for_declaration(decl)
|
|
1352
|
+
return [] if names.empty? || decl.line.nil?
|
|
1291
1353
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1354
|
+
[{
|
|
1355
|
+
start_line: decl.line,
|
|
1356
|
+
end_line: end_line,
|
|
1357
|
+
names: names,
|
|
1358
|
+
}]
|
|
1359
|
+
end
|
|
1298
1360
|
|
|
1299
|
-
|
|
1300
|
-
|
|
1361
|
+
def generic_type_parameter_names_for_declaration(decl)
|
|
1362
|
+
return [] unless decl.respond_to?(:type_params)
|
|
1301
1363
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1364
|
+
Array(decl.type_params).filter_map { |type_param| type_param.respond_to?(:name) ? type_param.name : nil }
|
|
1365
|
+
end
|
|
1304
1366
|
|
|
1305
|
-
|
|
1306
|
-
|
|
1367
|
+
def generic_type_parameter_names_for_extending_block(decl)
|
|
1368
|
+
return [] unless decl.respond_to?(:type_name)
|
|
1307
1369
|
|
|
1308
|
-
|
|
1309
|
-
|
|
1370
|
+
type_ref = decl.type_name
|
|
1371
|
+
return [] unless type_ref.is_a?(AST::TypeRef)
|
|
1310
1372
|
|
|
1311
|
-
|
|
1312
|
-
|
|
1373
|
+
Array(type_ref.arguments).filter_map do |argument|
|
|
1374
|
+
simple_type_parameter_name_from_type_argument(argument)
|
|
1375
|
+
end
|
|
1313
1376
|
end
|
|
1314
|
-
end
|
|
1315
1377
|
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1378
|
+
def simple_type_parameter_name_from_type_argument(argument)
|
|
1379
|
+
value = argument.respond_to?(:value) ? argument.value : nil
|
|
1380
|
+
return nil unless value.is_a?(AST::TypeRef)
|
|
1381
|
+
return nil unless value.arguments.empty? && !value.nullable && value.name.parts.length == 1
|
|
1320
1382
|
|
|
1321
|
-
|
|
1322
|
-
|
|
1383
|
+
value.name.parts.first
|
|
1384
|
+
end
|
|
1323
1385
|
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1386
|
+
def declaration_scope_end_line(decls, index)
|
|
1387
|
+
nested_declaration_scope_end_line(decls, index, fallback_end_line: Float::INFINITY)
|
|
1388
|
+
end
|
|
1327
1389
|
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1390
|
+
def nested_declaration_scope_end_line(decls, index, fallback_end_line:)
|
|
1391
|
+
next_decl = decls[(index + 1)..]&.find { |candidate| candidate.line }
|
|
1392
|
+
next_decl ? next_decl.line - 1 : fallback_end_line
|
|
1393
|
+
end
|
|
1332
1394
|
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1395
|
+
def matching_closer_index(tokens, opener_index, opener_type, closer_type)
|
|
1396
|
+
depth = 0
|
|
1397
|
+
i = opener_index
|
|
1398
|
+
while i < tokens.length
|
|
1399
|
+
tok = tokens[i]
|
|
1400
|
+
if tok.type == opener_type
|
|
1401
|
+
depth += 1
|
|
1402
|
+
elsif tok.type == closer_type
|
|
1403
|
+
depth -= 1
|
|
1404
|
+
return i if depth.zero?
|
|
1405
|
+
end
|
|
1406
|
+
i += 1
|
|
1343
1407
|
end
|
|
1344
|
-
|
|
1408
|
+
nil
|
|
1345
1409
|
end
|
|
1346
|
-
nil
|
|
1347
|
-
end
|
|
1348
1410
|
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1411
|
+
def import_path_info_at(tokens, index, allow_keywords: false)
|
|
1412
|
+
tok = tokens[index]
|
|
1413
|
+
return nil unless tok
|
|
1414
|
+
return nil unless tok.type == :identifier || (allow_keywords && Token::KEYWORDS.value?(tok.type))
|
|
1353
1415
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1416
|
+
line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
|
|
1417
|
+
return nil if line_tokens.empty? || line_tokens.first.type != :import
|
|
1356
1418
|
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1419
|
+
as_index = line_tokens.index { |line_tok| line_tok.type == :as }
|
|
1420
|
+
module_tokens = line_tokens[1...(as_index || line_tokens.length)] || []
|
|
1421
|
+
alias_token = as_index ? line_tokens[as_index + 1] : nil
|
|
1360
1422
|
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1423
|
+
module_identifiers = module_tokens.select do |line_tok|
|
|
1424
|
+
line_tok.type == :identifier || (allow_keywords && Token::KEYWORDS.value?(line_tok.type))
|
|
1425
|
+
end
|
|
1426
|
+
return nil if module_identifiers.empty?
|
|
1365
1427
|
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1428
|
+
module_name = module_identifiers.map(&:lexeme).join('.')
|
|
1429
|
+
return { module_name: module_name, role: :module_path } if module_identifiers.include?(tok)
|
|
1430
|
+
return { module_name: module_name, role: :alias } if alias_token == tok
|
|
1369
1431
|
|
|
1370
|
-
|
|
1371
|
-
|
|
1432
|
+
nil
|
|
1433
|
+
end
|
|
1372
1434
|
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1435
|
+
def variant_enum_member_declaration?(tokens, index)
|
|
1436
|
+
tok = tokens[index]
|
|
1437
|
+
line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
|
|
1438
|
+
return false unless line_tokens.first.equal?(tok) && tok.column > 1
|
|
1377
1439
|
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1440
|
+
i = index - 1
|
|
1441
|
+
while i >= 0
|
|
1442
|
+
t = tokens[i]
|
|
1443
|
+
i -= 1
|
|
1444
|
+
next if [:newline, :indent, :dedent, :eof].include?(t.type)
|
|
1445
|
+
next if t.line == tok.line
|
|
1446
|
+
next if t.column >= tok.column
|
|
1385
1447
|
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1448
|
+
header_line_toks = non_trivia_tokens_on_line(tokens, t.line)
|
|
1449
|
+
header_kind = header_line_toks.find { |header_tok| [:variant, :enum, :flags].include?(header_tok.type) }
|
|
1450
|
+
return !header_kind.nil?
|
|
1451
|
+
end
|
|
1452
|
+
false
|
|
1389
1453
|
end
|
|
1390
|
-
false
|
|
1391
|
-
end
|
|
1392
1454
|
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1455
|
+
def type_name_member_access?(tokens, index, facts = nil)
|
|
1456
|
+
dot_index = previous_non_trivia_token_index(tokens, index)
|
|
1457
|
+
return false unless dot_index && tokens[dot_index].type == :dot
|
|
1396
1458
|
|
|
1397
|
-
|
|
1398
|
-
|
|
1459
|
+
receiver_index = previous_non_trivia_token_index(tokens, dot_index)
|
|
1460
|
+
return false unless receiver_index
|
|
1399
1461
|
|
|
1400
|
-
|
|
1401
|
-
|
|
1462
|
+
type_name_receiver_token?(tokens, receiver_index, facts)
|
|
1463
|
+
end
|
|
1402
1464
|
|
|
1403
|
-
|
|
1404
|
-
|
|
1465
|
+
def type_name_receiver_token?(tokens, index, facts = nil)
|
|
1466
|
+
receiver = tokens[index]
|
|
1405
1467
|
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1468
|
+
if receiver.type == :identifier
|
|
1469
|
+
return true if receiver.lexeme.match?(/\A[A-Z]/)
|
|
1470
|
+
return true if facts && facts.types.key?(receiver.lexeme)
|
|
1409
1471
|
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1472
|
+
if facts
|
|
1473
|
+
module_binding = imported_module_binding_for_member(tokens, index, facts)
|
|
1474
|
+
return true if module_binding && module_binding.types.key?(receiver.lexeme)
|
|
1475
|
+
end
|
|
1476
|
+
|
|
1477
|
+
return false
|
|
1413
1478
|
end
|
|
1414
1479
|
|
|
1415
|
-
|
|
1416
|
-
|
|
1480
|
+
if receiver.type == :rbracket
|
|
1481
|
+
lbracket_i = matching_opener_index(tokens, index)
|
|
1482
|
+
return false unless lbracket_i
|
|
1417
1483
|
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
return false unless lbracket_i
|
|
1484
|
+
base_index = previous_non_trivia_token_index(tokens, lbracket_i)
|
|
1485
|
+
return false unless base_index
|
|
1421
1486
|
|
|
1422
|
-
|
|
1423
|
-
|
|
1487
|
+
return type_name_receiver_token?(tokens, base_index, facts)
|
|
1488
|
+
end
|
|
1424
1489
|
|
|
1425
|
-
|
|
1490
|
+
false
|
|
1426
1491
|
end
|
|
1427
1492
|
|
|
1428
|
-
|
|
1429
|
-
|
|
1493
|
+
def matching_opener_index(tokens, closer_index)
|
|
1494
|
+
closer = tokens[closer_index]
|
|
1495
|
+
return nil unless closer
|
|
1430
1496
|
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1497
|
+
opener_type, closer_type = case closer.type
|
|
1498
|
+
when :rbracket then [:lbracket, :rbracket]
|
|
1499
|
+
when :rparen then [:lparen, :rparen]
|
|
1500
|
+
else return nil
|
|
1501
|
+
end
|
|
1434
1502
|
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1503
|
+
depth = 0
|
|
1504
|
+
i = closer_index
|
|
1505
|
+
while i >= 0
|
|
1506
|
+
t = tokens[i]
|
|
1507
|
+
if t.type == closer_type
|
|
1508
|
+
depth += 1
|
|
1509
|
+
elsif t.type == opener_type
|
|
1510
|
+
depth -= 1
|
|
1511
|
+
return i if depth.zero?
|
|
1512
|
+
end
|
|
1513
|
+
i -= 1
|
|
1514
|
+
end
|
|
1515
|
+
nil
|
|
1439
1516
|
end
|
|
1440
1517
|
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
depth += 1
|
|
1447
|
-
elsif t.type == opener_type
|
|
1448
|
-
depth -= 1
|
|
1449
|
-
return i if depth.zero?
|
|
1518
|
+
def non_trivia_tokens_on_line(tokens, line)
|
|
1519
|
+
return @tokens_by_line_cache[line] if @tokens_by_line_cache
|
|
1520
|
+
|
|
1521
|
+
tokens.select do |tok|
|
|
1522
|
+
tok.line == line && ![:newline, :indent, :dedent, :eof].include?(tok.type)
|
|
1450
1523
|
end
|
|
1451
|
-
i -= 1
|
|
1452
1524
|
end
|
|
1453
|
-
nil
|
|
1454
|
-
end
|
|
1455
1525
|
|
|
1456
|
-
|
|
1457
|
-
|
|
1526
|
+
def build_attribute_name_semantic_overrides(tokens, facts)
|
|
1527
|
+
return {} unless facts&.respond_to?(:ast) && facts.ast
|
|
1528
|
+
|
|
1529
|
+
token_indices_by_position = tokens.each_with_index.each_with_object({}) do |(token, index), positions|
|
|
1530
|
+
positions[[token.line, token.column]] = index
|
|
1531
|
+
end
|
|
1532
|
+
overrides = {}
|
|
1533
|
+
|
|
1534
|
+
walk_ast_nodes(facts.ast) do |node|
|
|
1535
|
+
case node
|
|
1536
|
+
when AST::AttributeDecl
|
|
1537
|
+
mark_attribute_name_override(
|
|
1538
|
+
overrides,
|
|
1539
|
+
token_indices_by_position,
|
|
1540
|
+
tokens,
|
|
1541
|
+
[node.name],
|
|
1542
|
+
line: node.line,
|
|
1543
|
+
column: node.column,
|
|
1544
|
+
declaration: true,
|
|
1545
|
+
)
|
|
1546
|
+
when AST::AttributeApplication
|
|
1547
|
+
mark_attribute_name_override(
|
|
1548
|
+
overrides,
|
|
1549
|
+
token_indices_by_position,
|
|
1550
|
+
tokens,
|
|
1551
|
+
node.name.parts,
|
|
1552
|
+
line: node.line,
|
|
1553
|
+
column: node.column,
|
|
1554
|
+
)
|
|
1555
|
+
when AST::Call
|
|
1556
|
+
mark_attribute_reflection_name_overrides(overrides, token_indices_by_position, tokens, node)
|
|
1557
|
+
end
|
|
1558
|
+
end
|
|
1458
1559
|
|
|
1459
|
-
|
|
1460
|
-
tok.line == line && ![:newline, :indent, :dedent, :eof].include?(tok.type)
|
|
1560
|
+
overrides
|
|
1461
1561
|
end
|
|
1462
|
-
end
|
|
1463
1562
|
|
|
1464
|
-
|
|
1465
|
-
|
|
1563
|
+
def walk_ast_nodes(node, &block)
|
|
1564
|
+
case node
|
|
1565
|
+
when Array
|
|
1566
|
+
node.each { |entry| walk_ast_nodes(entry, &block) }
|
|
1567
|
+
when String, Symbol, Numeric, TrueClass, FalseClass, NilClass
|
|
1568
|
+
nil
|
|
1569
|
+
else
|
|
1570
|
+
return unless node.class.name&.start_with?("MilkTea::AST::")
|
|
1466
1571
|
|
|
1467
|
-
|
|
1468
|
-
|
|
1572
|
+
yield node
|
|
1573
|
+
node.to_h.each_value { |value| walk_ast_nodes(value, &block) }
|
|
1574
|
+
end
|
|
1469
1575
|
end
|
|
1470
|
-
overrides = {}
|
|
1471
1576
|
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1577
|
+
def mark_attribute_reflection_name_overrides(overrides, token_indices_by_position, tokens, call_expression)
|
|
1578
|
+
callee = call_expression.callee
|
|
1579
|
+
return unless callee.is_a?(AST::Identifier)
|
|
1580
|
+
return unless %w[has_attribute attribute_of].include?(callee.name)
|
|
1581
|
+
return unless call_expression.arguments.length >= 2
|
|
1582
|
+
|
|
1583
|
+
attribute_name_expression = call_expression.arguments[1].value
|
|
1584
|
+
|
|
1585
|
+
case attribute_name_expression
|
|
1586
|
+
when AST::Identifier
|
|
1475
1587
|
mark_attribute_name_override(
|
|
1476
1588
|
overrides,
|
|
1477
1589
|
token_indices_by_position,
|
|
1478
1590
|
tokens,
|
|
1479
|
-
[
|
|
1480
|
-
line:
|
|
1481
|
-
column:
|
|
1482
|
-
declaration: true,
|
|
1591
|
+
[attribute_name_expression.name],
|
|
1592
|
+
line: attribute_name_expression.line,
|
|
1593
|
+
column: attribute_name_expression.column,
|
|
1483
1594
|
)
|
|
1484
|
-
when AST::
|
|
1595
|
+
when AST::MemberAccess
|
|
1596
|
+
return unless attribute_name_expression.receiver.is_a?(AST::Identifier)
|
|
1597
|
+
|
|
1485
1598
|
mark_attribute_name_override(
|
|
1486
1599
|
overrides,
|
|
1487
1600
|
token_indices_by_position,
|
|
1488
1601
|
tokens,
|
|
1489
|
-
|
|
1490
|
-
line:
|
|
1491
|
-
column:
|
|
1602
|
+
[attribute_name_expression.receiver.name, attribute_name_expression.member],
|
|
1603
|
+
line: attribute_name_expression.receiver.line,
|
|
1604
|
+
column: attribute_name_expression.receiver.column,
|
|
1492
1605
|
)
|
|
1493
|
-
when AST::Call
|
|
1494
|
-
mark_attribute_reflection_name_overrides(overrides, token_indices_by_position, tokens, node)
|
|
1495
1606
|
end
|
|
1496
1607
|
end
|
|
1497
1608
|
|
|
1498
|
-
overrides
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
def walk_ast_nodes(node, &block)
|
|
1502
|
-
case node
|
|
1503
|
-
when Array
|
|
1504
|
-
node.each { |entry| walk_ast_nodes(entry, &block) }
|
|
1505
|
-
when String, Symbol, Numeric, TrueClass, FalseClass, NilClass
|
|
1506
|
-
nil
|
|
1507
|
-
else
|
|
1508
|
-
return unless node.class.name&.start_with?("MilkTea::AST::")
|
|
1509
|
-
|
|
1510
|
-
yield node
|
|
1511
|
-
node.to_h.each_value { |value| walk_ast_nodes(value, &block) }
|
|
1512
|
-
end
|
|
1513
|
-
end
|
|
1609
|
+
def mark_attribute_name_override(overrides, token_indices_by_position, tokens, parts, line:, column:, declaration: false)
|
|
1610
|
+
current_index = token_indices_by_position[[line, column]]
|
|
1611
|
+
return unless current_index
|
|
1514
1612
|
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
return unless %w[has_attribute attribute_of].include?(callee.name)
|
|
1519
|
-
return unless call_expression.arguments.length >= 2
|
|
1520
|
-
|
|
1521
|
-
attribute_name_expression = call_expression.arguments[1].value
|
|
1522
|
-
|
|
1523
|
-
case attribute_name_expression
|
|
1524
|
-
when AST::Identifier
|
|
1525
|
-
mark_attribute_name_override(
|
|
1526
|
-
overrides,
|
|
1527
|
-
token_indices_by_position,
|
|
1528
|
-
tokens,
|
|
1529
|
-
[attribute_name_expression.name],
|
|
1530
|
-
line: attribute_name_expression.line,
|
|
1531
|
-
column: attribute_name_expression.column,
|
|
1532
|
-
)
|
|
1533
|
-
when AST::MemberAccess
|
|
1534
|
-
return unless attribute_name_expression.receiver.is_a?(AST::Identifier)
|
|
1535
|
-
|
|
1536
|
-
mark_attribute_name_override(
|
|
1537
|
-
overrides,
|
|
1538
|
-
token_indices_by_position,
|
|
1539
|
-
tokens,
|
|
1540
|
-
[attribute_name_expression.receiver.name, attribute_name_expression.member],
|
|
1541
|
-
line: attribute_name_expression.receiver.line,
|
|
1542
|
-
column: attribute_name_expression.receiver.column,
|
|
1543
|
-
)
|
|
1544
|
-
end
|
|
1545
|
-
end
|
|
1613
|
+
parts.each_with_index do |part, part_index|
|
|
1614
|
+
token = tokens[current_index]
|
|
1615
|
+
return unless token&.lexeme == part
|
|
1546
1616
|
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1617
|
+
if part_index == parts.length - 1
|
|
1618
|
+
modifiers = []
|
|
1619
|
+
modifiers << 'declaration' if declaration
|
|
1620
|
+
overrides[[token.line, token.column]] = [:decorator, modifiers]
|
|
1621
|
+
return
|
|
1622
|
+
end
|
|
1550
1623
|
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1624
|
+
overrides[[token.line, token.column]] = [:namespace, []]
|
|
1625
|
+
dot_index = next_non_trivia_token_index(tokens, current_index + 1)
|
|
1626
|
+
return unless dot_index && tokens[dot_index].type == :dot
|
|
1554
1627
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
modifiers << 'declaration' if declaration
|
|
1558
|
-
overrides[[token.line, token.column]] = [:decorator, modifiers]
|
|
1559
|
-
return
|
|
1628
|
+
current_index = next_non_trivia_token_index(tokens, dot_index + 1)
|
|
1629
|
+
return unless current_index
|
|
1560
1630
|
end
|
|
1631
|
+
end
|
|
1561
1632
|
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
return unless dot_index && tokens[dot_index].type == :dot
|
|
1565
|
-
|
|
1566
|
-
current_index = next_non_trivia_token_index(tokens, dot_index + 1)
|
|
1567
|
-
return unless current_index
|
|
1633
|
+
def module_declaration_path_token?(tokens, index, allow_keywords: false)
|
|
1634
|
+
!module_declaration_info_at(tokens, index, allow_keywords:).nil?
|
|
1568
1635
|
end
|
|
1569
|
-
end
|
|
1570
1636
|
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1637
|
+
def module_declaration_info_at(tokens, index, allow_keywords: false)
|
|
1638
|
+
tok = tokens[index]
|
|
1639
|
+
return nil unless tok&.type == :identifier || (allow_keywords && Token::KEYWORDS.value?(tok.type))
|
|
1574
1640
|
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
return nil unless tok&.type == :identifier || (allow_keywords && Token::KEYWORDS.value?(tok.type))
|
|
1641
|
+
line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
|
|
1642
|
+
return nil if line_tokens.empty? || line_tokens.first.type != :module
|
|
1578
1643
|
|
|
1579
|
-
|
|
1580
|
-
|
|
1644
|
+
path_tokens = line_tokens[1..].to_a.select do |line_tok|
|
|
1645
|
+
line_tok.type == :identifier || (allow_keywords && Token::KEYWORDS.value?(line_tok.type))
|
|
1646
|
+
end
|
|
1647
|
+
return nil unless path_tokens.any? { |line_tok| line_tok.equal?(tok) }
|
|
1581
1648
|
|
|
1582
|
-
|
|
1583
|
-
|
|
1649
|
+
{
|
|
1650
|
+
module_name: path_tokens.map(&:lexeme).join('.'),
|
|
1651
|
+
}
|
|
1584
1652
|
end
|
|
1585
|
-
return nil unless path_tokens.any? { |line_tok| line_tok.equal?(tok) }
|
|
1586
1653
|
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
end
|
|
1654
|
+
def previous_non_trivia_token(tokens, index)
|
|
1655
|
+
prev_index = previous_non_trivia_token_index(tokens, index)
|
|
1656
|
+
return nil unless prev_index
|
|
1591
1657
|
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
return nil unless prev_index
|
|
1658
|
+
tokens[prev_index]
|
|
1659
|
+
end
|
|
1595
1660
|
|
|
1596
|
-
tokens
|
|
1597
|
-
|
|
1661
|
+
def first_non_trivia_token_on_line?(tokens, index)
|
|
1662
|
+
token = tokens[index]
|
|
1663
|
+
return false unless token
|
|
1598
1664
|
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1665
|
+
i = index - 1
|
|
1666
|
+
while i >= 0
|
|
1667
|
+
previous = tokens[i]
|
|
1668
|
+
return true if previous.type == :newline
|
|
1669
|
+
return false if previous.line == token.line && ![:indent, :dedent].include?(previous.type)
|
|
1602
1670
|
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
previous = tokens[i]
|
|
1606
|
-
return true if previous.type == :newline
|
|
1607
|
-
return false if previous.line == token.line && ![:indent, :dedent].include?(previous.type)
|
|
1671
|
+
i -= 1
|
|
1672
|
+
end
|
|
1608
1673
|
|
|
1609
|
-
|
|
1674
|
+
true
|
|
1610
1675
|
end
|
|
1611
1676
|
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
i -= 1
|
|
1677
|
+
def previous_non_trivia_token_index(tokens, index)
|
|
1678
|
+
i = index - 1
|
|
1679
|
+
while i >= 0
|
|
1680
|
+
tok = tokens[i]
|
|
1681
|
+
return i unless [:newline, :indent, :dedent].include?(tok.type)
|
|
1682
|
+
i -= 1
|
|
1683
|
+
end
|
|
1684
|
+
nil
|
|
1621
1685
|
end
|
|
1622
|
-
nil
|
|
1623
|
-
end
|
|
1624
1686
|
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1687
|
+
def next_non_trivia_token_index(tokens, index)
|
|
1688
|
+
i = index
|
|
1689
|
+
while i < tokens.length
|
|
1690
|
+
tok = tokens[i]
|
|
1691
|
+
return i unless [:newline, :indent, :dedent].include?(tok.type)
|
|
1692
|
+
i += 1
|
|
1693
|
+
end
|
|
1694
|
+
nil
|
|
1631
1695
|
end
|
|
1632
|
-
nil
|
|
1633
|
-
end
|
|
1634
1696
|
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1697
|
+
def encode_semantic_tokens(entries)
|
|
1698
|
+
data = []
|
|
1699
|
+
prev_line = 0
|
|
1700
|
+
prev_char = 0
|
|
1639
1701
|
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1702
|
+
entries.each do |entry|
|
|
1703
|
+
delta_line = entry[:line] - prev_line
|
|
1704
|
+
delta_start = delta_line.zero? ? entry[:start_char] - prev_char : entry[:start_char]
|
|
1705
|
+
type_index = SEMANTIC_TOKEN_TYPES.index(entry[:type].to_s) || 0
|
|
1706
|
+
modifiers_bitset = semantic_modifiers_bitset(entry[:modifiers])
|
|
1645
1707
|
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1708
|
+
data << delta_line
|
|
1709
|
+
data << delta_start
|
|
1710
|
+
data << entry[:length]
|
|
1711
|
+
data << type_index
|
|
1712
|
+
data << modifiers_bitset
|
|
1651
1713
|
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
data
|
|
1657
|
-
end
|
|
1714
|
+
prev_line = entry[:line]
|
|
1715
|
+
prev_char = entry[:start_char]
|
|
1716
|
+
end
|
|
1658
1717
|
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
@semantic_token_result_counter += 1
|
|
1662
|
-
"#{uri}:#{@semantic_token_result_counter}"
|
|
1663
|
-
end
|
|
1718
|
+
data
|
|
1719
|
+
end
|
|
1664
1720
|
|
|
1665
|
-
|
|
1666
|
-
|
|
1721
|
+
def next_semantic_token_result_id(uri)
|
|
1722
|
+
@semantic_token_result_counter ||= 0
|
|
1723
|
+
@semantic_token_result_counter += 1
|
|
1724
|
+
"#{uri}:#{@semantic_token_result_counter}"
|
|
1725
|
+
end
|
|
1667
1726
|
|
|
1668
|
-
|
|
1669
|
-
|
|
1727
|
+
def compute_semantic_tokens_edits(old_entries, new_entries)
|
|
1728
|
+
return [] if old_entries == new_entries
|
|
1670
1729
|
|
|
1671
|
-
|
|
1672
|
-
|
|
1730
|
+
prefix = find_semantic_token_common_prefix(old_entries, new_entries)
|
|
1731
|
+
suffix = find_semantic_token_common_suffix(old_entries, new_entries, prefix)
|
|
1673
1732
|
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
end
|
|
1733
|
+
old_mid = old_entries.length - prefix - suffix
|
|
1734
|
+
new_mid = new_entries.length - prefix - suffix
|
|
1677
1735
|
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1736
|
+
if old_mid.zero? && new_mid.zero?
|
|
1737
|
+
return []
|
|
1738
|
+
end
|
|
1681
1739
|
|
|
1682
|
-
|
|
1683
|
-
|
|
1740
|
+
start_offset = prefix * 5
|
|
1741
|
+
delete_count = old_mid * 5
|
|
1742
|
+
insert_tokens = encode_semantic_tokens(new_entries[prefix...(new_entries.length - suffix)])
|
|
1684
1743
|
|
|
1685
|
-
|
|
1686
|
-
limit = [old_entries.length, new_entries.length].min
|
|
1687
|
-
prefix = 0
|
|
1688
|
-
while prefix < limit && semantic_token_entry_equal?(old_entries[prefix], new_entries[prefix])
|
|
1689
|
-
prefix += 1
|
|
1744
|
+
[{ start: start_offset, deleteCount: delete_count, data: insert_tokens }]
|
|
1690
1745
|
end
|
|
1691
|
-
prefix
|
|
1692
|
-
end
|
|
1693
1746
|
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1747
|
+
def find_semantic_token_common_prefix(old_entries, new_entries)
|
|
1748
|
+
limit = [old_entries.length, new_entries.length].min
|
|
1749
|
+
prefix = 0
|
|
1750
|
+
while prefix < limit && semantic_token_entry_equal?(old_entries[prefix], new_entries[prefix])
|
|
1751
|
+
prefix += 1
|
|
1752
|
+
end
|
|
1753
|
+
prefix
|
|
1754
|
+
end
|
|
1755
|
+
|
|
1756
|
+
def find_semantic_token_common_suffix(old_entries, new_entries, prefix)
|
|
1757
|
+
old_limit = old_entries.length - prefix
|
|
1758
|
+
new_limit = new_entries.length - prefix
|
|
1759
|
+
limit = [old_limit, new_limit].min
|
|
1760
|
+
suffix = 0
|
|
1761
|
+
while suffix < limit &&
|
|
1762
|
+
semantic_token_entry_equal?(old_entries[old_entries.length - 1 - suffix],
|
|
1763
|
+
new_entries[new_entries.length - 1 - suffix])
|
|
1764
|
+
suffix += 1
|
|
1765
|
+
end
|
|
1766
|
+
suffix
|
|
1767
|
+
end
|
|
1706
1768
|
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1769
|
+
def semantic_token_entry_equal?(a, b)
|
|
1770
|
+
a[:line] == b[:line] &&
|
|
1771
|
+
a[:start_char] == b[:start_char] &&
|
|
1772
|
+
a[:length] == b[:length] &&
|
|
1773
|
+
a[:type] == b[:type] &&
|
|
1774
|
+
a[:modifiers] == b[:modifiers]
|
|
1775
|
+
end
|
|
1714
1776
|
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1777
|
+
def semantic_modifiers_bitset(modifiers)
|
|
1778
|
+
bits = 0
|
|
1779
|
+
Array(modifiers).each do |modifier|
|
|
1780
|
+
idx = SEMANTIC_TOKEN_MODIFIERS.index(modifier.to_s)
|
|
1781
|
+
next unless idx
|
|
1720
1782
|
|
|
1721
|
-
|
|
1783
|
+
bits |= (1 << idx)
|
|
1784
|
+
end
|
|
1785
|
+
bits
|
|
1722
1786
|
end
|
|
1723
|
-
bits
|
|
1724
|
-
end
|
|
1725
1787
|
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1788
|
+
def generic_function_binding_for_line(facts, line)
|
|
1789
|
+
generic_function_bindings(facts).filter_map do |binding|
|
|
1790
|
+
next unless binding.ast.respond_to?(:body) && binding.ast.line
|
|
1729
1791
|
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1792
|
+
start_line = binding.ast.line
|
|
1793
|
+
end_line = generic_statement_list_end_line(Array(binding.ast.body), start_line)
|
|
1794
|
+
next unless start_line <= line && line <= end_line
|
|
1733
1795
|
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1796
|
+
[end_line - start_line, -start_line, binding]
|
|
1797
|
+
end.min_by { |span, start_line, _binding| [span, start_line] }&.last
|
|
1798
|
+
end
|
|
1737
1799
|
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1800
|
+
def generic_function_bindings(facts)
|
|
1801
|
+
facts.functions.each_value.select { |binding| binding.type_params.any? } +
|
|
1802
|
+
facts.methods.each_value.flat_map(&:values).select { |binding| binding.type_params.any? }
|
|
1803
|
+
end
|
|
1742
1804
|
end
|
|
1743
1805
|
end
|
|
1744
1806
|
end
|