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.
Files changed (204) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -0
  3. data/docs/language-design.md +1 -2
  4. data/docs/language-manual.md +12 -1
  5. data/lib/milk_tea/base.rb +1 -2
  6. data/lib/milk_tea/bindings/bindgen/ast_parser.rb +0 -2
  7. data/lib/milk_tea/bindings/bindgen/declaration.rb +0 -2
  8. data/lib/milk_tea/bindings/bindgen/emitter.rb +0 -2
  9. data/lib/milk_tea/bindings/bindgen/overrides.rb +0 -2
  10. data/lib/milk_tea/bindings/bindgen/type_mapper.rb +51 -53
  11. data/lib/milk_tea/bindings/imported_bindings/generator.rb +7 -9
  12. data/lib/milk_tea/bindings/imported_bindings/method_source.rb +0 -2
  13. data/lib/milk_tea/bindings/imported_bindings/naming.rb +6 -8
  14. data/lib/milk_tea/bindings/imported_bindings.rb +0 -2
  15. data/lib/milk_tea/bindings/opengl_registry.rb +3 -7
  16. data/lib/milk_tea/bindings/steamworks.rb +12 -16
  17. data/lib/milk_tea/bindings/upstream_sources.rb +10 -14
  18. data/lib/milk_tea/bindings/vendored_box2d.rb +10 -12
  19. data/lib/milk_tea/bindings/vendored_cjson.rb +6 -8
  20. data/lib/milk_tea/bindings/vendored_flecs.rb +10 -12
  21. data/lib/milk_tea/bindings/vendored_glfw.rb +11 -13
  22. data/lib/milk_tea/bindings/vendored_libuv.rb +11 -13
  23. data/lib/milk_tea/bindings/vendored_pcre2.rb +11 -13
  24. data/lib/milk_tea/bindings/vendored_raylib.rb +6 -10
  25. data/lib/milk_tea/bindings/vendored_sdl3.rb +11 -13
  26. data/lib/milk_tea/bindings/vendored_steamworks.rb +1 -5
  27. data/lib/milk_tea/core/ast.rb +109 -51
  28. data/lib/milk_tea/core/async_runtime_installer.rb +0 -2
  29. data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -3
  30. data/lib/milk_tea/core/c_backend/aggregate_utils.rb +147 -84
  31. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +394 -396
  32. data/lib/milk_tea/core/c_backend/expressions.rb +489 -476
  33. data/lib/milk_tea/core/c_backend/feature_detection.rb +446 -437
  34. data/lib/milk_tea/core/c_backend/format_helpers.rb +0 -2
  35. data/lib/milk_tea/core/c_backend/reachability.rb +339 -341
  36. data/lib/milk_tea/core/c_backend/reinterpret.rb +231 -217
  37. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +531 -526
  38. data/lib/milk_tea/core/c_backend/statements.rb +528 -530
  39. data/lib/milk_tea/core/c_backend/type_collectors.rb +1344 -1346
  40. data/lib/milk_tea/core/c_backend/type_declaration.rb +215 -213
  41. data/lib/milk_tea/core/c_backend/type_system.rb +347 -349
  42. data/lib/milk_tea/core/c_backend.rb +17 -9
  43. data/lib/milk_tea/core/compatibility_helpers.rb +0 -2
  44. data/lib/milk_tea/core/compile_time/const_eval.rb +7 -12
  45. data/lib/milk_tea/core/compile_time.rb +32 -38
  46. data/lib/milk_tea/core/control_flow/builder.rb +3 -5
  47. data/lib/milk_tea/core/control_flow/constant_propagation.rb +14 -17
  48. data/lib/milk_tea/core/control_flow/definite_assignment.rb +0 -1
  49. data/lib/milk_tea/core/ir.rb +10 -10
  50. data/lib/milk_tea/core/lexer/character_classes.rb +5 -7
  51. data/lib/milk_tea/core/lexer/format_strings.rb +7 -9
  52. data/lib/milk_tea/core/lexer/heredocs.rb +22 -22
  53. data/lib/milk_tea/core/lexer/indentation.rb +0 -2
  54. data/lib/milk_tea/core/lexer/numbers.rb +0 -2
  55. data/lib/milk_tea/core/lexer/recovery.rb +0 -2
  56. data/lib/milk_tea/core/lexer/strings.rb +0 -2
  57. data/lib/milk_tea/core/lexer/symbols.rb +0 -2
  58. data/lib/milk_tea/core/lexer/trivia.rb +0 -2
  59. data/lib/milk_tea/core/lexer.rb +0 -2
  60. data/lib/milk_tea/core/lowering/async/analysis.rb +0 -2
  61. data/lib/milk_tea/core/lowering/async/lowering.rb +1264 -1265
  62. data/lib/milk_tea/core/lowering/async/normalization.rb +5 -3
  63. data/lib/milk_tea/core/lowering/async.rb +627 -630
  64. data/lib/milk_tea/core/lowering/block.rb +413 -416
  65. data/lib/milk_tea/core/lowering/calls.rb +1381 -1384
  66. data/lib/milk_tea/core/lowering/declarations.rb +180 -183
  67. data/lib/milk_tea/core/lowering/dyn.rb +48 -50
  68. data/lib/milk_tea/core/lowering/events.rb +983 -985
  69. data/lib/milk_tea/core/lowering/expressions.rb +1513 -1518
  70. data/lib/milk_tea/core/lowering/foreign_cstr.rb +181 -184
  71. data/lib/milk_tea/core/lowering/functions.rb +185 -188
  72. data/lib/milk_tea/core/lowering/loops.rb +1028 -1031
  73. data/lib/milk_tea/core/lowering/proc.rb +363 -366
  74. data/lib/milk_tea/core/lowering/resolve.rb +2133 -2135
  75. data/lib/milk_tea/core/lowering/scans.rb +179 -181
  76. data/lib/milk_tea/core/lowering/str_buffer.rb +102 -105
  77. data/lib/milk_tea/core/lowering/utils.rb +1040 -1044
  78. data/lib/milk_tea/core/lowering.rb +5 -7
  79. data/lib/milk_tea/core/module_binder.rb +0 -2
  80. data/lib/milk_tea/core/module_loader/errors.rb +4 -2
  81. data/lib/milk_tea/core/module_loader.rb +113 -20
  82. data/lib/milk_tea/core/module_path_resolver.rb +0 -2
  83. data/lib/milk_tea/core/module_roots.rb +6 -8
  84. data/lib/milk_tea/core/parser/attributes.rb +0 -2
  85. data/lib/milk_tea/core/parser/blocks.rb +0 -2
  86. data/lib/milk_tea/core/parser/declarations.rb +7 -9
  87. data/lib/milk_tea/core/parser/expressions.rb +15 -10
  88. data/lib/milk_tea/core/parser/recovery.rb +0 -2
  89. data/lib/milk_tea/core/parser/statements.rb +8 -2
  90. data/lib/milk_tea/core/parser/types.rb +12 -14
  91. data/lib/milk_tea/core/parser.rb +0 -2
  92. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +31 -33
  93. data/lib/milk_tea/core/pretty_printer/base_formatter.rb +0 -2
  94. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +0 -2
  95. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +0 -2
  96. data/lib/milk_tea/core/semantic_analyzer/attributes.rb +14 -16
  97. data/lib/milk_tea/core/semantic_analyzer/calls.rb +0 -2
  98. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -14
  99. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +18 -21
  100. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +0 -3
  101. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +14 -17
  102. data/lib/milk_tea/core/semantic_analyzer/generics.rb +57 -59
  103. data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +0 -2
  104. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +5 -9
  105. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +0 -3
  106. data/lib/milk_tea/core/semantic_analyzer/statements.rb +35 -40
  107. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +10 -12
  108. data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -6
  109. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +106 -109
  110. data/lib/milk_tea/core/semantic_analyzer.rb +17 -8
  111. data/lib/milk_tea/core/types/layout.rb +21 -22
  112. data/lib/milk_tea/core/types/predicates.rb +0 -2
  113. data/lib/milk_tea/core/types/registry.rb +16 -18
  114. data/lib/milk_tea/core/types/visitor.rb +0 -4
  115. data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -2
  116. data/lib/milk_tea/dap/protocol.rb +1 -1
  117. data/lib/milk_tea/dap/server/breakpoints.rb +0 -2
  118. data/lib/milk_tea/dap/server/debug_map.rb +0 -2
  119. data/lib/milk_tea/dap/server/handlers.rb +0 -2
  120. data/lib/milk_tea/dap/server/launch.rb +0 -2
  121. data/lib/milk_tea/dap/server/lldb_backend.rb +8 -10
  122. data/lib/milk_tea/dap/server/pause_diagnostics.rb +14 -16
  123. data/lib/milk_tea/dap/server/utilities.rb +0 -2
  124. data/lib/milk_tea/dap/server/wire.rb +0 -2
  125. data/lib/milk_tea/dap/server.rb +0 -2
  126. data/lib/milk_tea/lsp/diagnostics.rb +16 -16
  127. data/lib/milk_tea/lsp/server/call_hierarchy.rb +11 -12
  128. data/lib/milk_tea/lsp/server/code_actions.rb +355 -357
  129. data/lib/milk_tea/lsp/server/code_lens.rb +23 -25
  130. data/lib/milk_tea/lsp/server/completion.rb +873 -875
  131. data/lib/milk_tea/lsp/server/configuration.rb +129 -131
  132. data/lib/milk_tea/lsp/server/debug_info.rb +0 -2
  133. data/lib/milk_tea/lsp/server/definition.rb +564 -565
  134. data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +191 -193
  135. data/lib/milk_tea/lsp/server/execute_command.rb +0 -2
  136. data/lib/milk_tea/lsp/server/folding_range.rb +0 -4
  137. data/lib/milk_tea/lsp/server/formatting.rb +478 -480
  138. data/lib/milk_tea/lsp/server/hover.rb +1282 -1284
  139. data/lib/milk_tea/lsp/server/inlay_hints.rb +179 -181
  140. data/lib/milk_tea/lsp/server/lifecycle.rb +192 -194
  141. data/lib/milk_tea/lsp/server/linked_editing_range.rb +0 -2
  142. data/lib/milk_tea/lsp/server/on_type_formatting.rb +0 -2
  143. data/lib/milk_tea/lsp/server/progress.rb +0 -2
  144. data/lib/milk_tea/lsp/server/references.rb +316 -318
  145. data/lib/milk_tea/lsp/server/rename.rb +445 -447
  146. data/lib/milk_tea/lsp/server/selection_range.rb +0 -4
  147. data/lib/milk_tea/lsp/server/semantic_tokens.rb +1376 -1314
  148. data/lib/milk_tea/lsp/server/signature_help.rb +146 -148
  149. data/lib/milk_tea/lsp/server/text_documents.rb +99 -101
  150. data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -4
  151. data/lib/milk_tea/lsp/server/utilities.rb +397 -399
  152. data/lib/milk_tea/lsp/server.rb +0 -3
  153. data/lib/milk_tea/lsp/workspace/analysis.rb +40 -42
  154. data/lib/milk_tea/lsp/workspace/dependency_graph.rb +4 -10
  155. data/lib/milk_tea/lsp/workspace/utilities.rb +19 -19
  156. data/lib/milk_tea/packages/atomic_write.rb +4 -5
  157. data/lib/milk_tea/packages/dependency_solver.rb +15 -15
  158. data/lib/milk_tea/packages/lock.rb +4 -4
  159. data/lib/milk_tea/packages/manager_cli.rb +1 -1
  160. data/lib/milk_tea/packages/manifest.rb +3 -3
  161. data/lib/milk_tea/packages/registry_store.rb +4 -6
  162. data/lib/milk_tea/packages/services.rb +16 -16
  163. data/lib/milk_tea/packages/source_cache.rb +4 -6
  164. data/lib/milk_tea/packages/source_resolver.rb +44 -44
  165. data/lib/milk_tea/packages/version.rb +8 -8
  166. data/lib/milk_tea/tooling/build.rb +3 -7
  167. data/lib/milk_tea/tooling/build_cache.rb +0 -2
  168. data/lib/milk_tea/tooling/cli.rb +10 -4
  169. data/lib/milk_tea/tooling/debug_info_formatter.rb +31 -33
  170. data/lib/milk_tea/tooling/debug_map.rb +8 -10
  171. data/lib/milk_tea/tooling/docs_app.rb +0 -2
  172. data/lib/milk_tea/tooling/linter/doc_tags.rb +25 -27
  173. data/lib/milk_tea/tooling/linter/fix_engine.rb +87 -24
  174. data/lib/milk_tea/tooling/linter/flow_rules.rb +44 -46
  175. data/lib/milk_tea/tooling/linter/imports_platform.rb +14 -16
  176. data/lib/milk_tea/tooling/linter/release_rules.rb +3 -5
  177. data/lib/milk_tea/tooling/linter/reserved_names.rb +23 -25
  178. data/lib/milk_tea/tooling/linter/rules.rb +87 -89
  179. data/lib/milk_tea/tooling/linter/source_helpers.rb +40 -42
  180. data/lib/milk_tea/tooling/linter/trailing_comma.rb +17 -19
  181. data/lib/milk_tea/tooling/linter/visitors.rb +112 -54
  182. data/lib/milk_tea/tooling/linter.rb +0 -2
  183. data/lib/milk_tea/tooling/project_scaffold.rb +0 -2
  184. data/lib/milk_tea/tooling/run.rb +0 -2
  185. data/lib/milk_tea/tooling/toolchain_cli.rb +0 -2
  186. data/std/cli.mt +13 -32
  187. data/std/color.mt +28 -28
  188. data/std/encoding.mt +4 -4
  189. data/std/graph.mt +1 -2
  190. data/std/hash.mt +14 -14
  191. data/std/http/server.mt +3 -3
  192. data/std/input.mt +1 -1
  193. data/std/json.mt +1 -1
  194. data/std/linear_algebra.mt +6 -6
  195. data/std/net/mux.mt +1 -1
  196. data/std/noise.mt +23 -23
  197. data/std/parse.mt +2 -2
  198. data/std/process.mt +3 -4
  199. data/std/sparse_set.mt +1 -1
  200. data/std/steering.mt +5 -5
  201. data/std/str.mt +1 -1
  202. data/std/tween.mt +4 -4
  203. data/std/utility.mt +3 -3
  204. metadata +2 -2
@@ -4,1741 +4,1803 @@ module MilkTea
4
4
  module LSP
5
5
  class Server
6
6
  module ServerSemanticTokens
7
- private
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
- def handle_semantic_tokens_full(params)
10
- uri = params.dig('textDocument', 'uri')
11
- return { data: [] } unless uri
24
+ tokens_start = monotonic_time
25
+ tokens = @workspace.get_tokens(uri) || []
26
+ tokens_ms = elapsed_ms(tokens_start)
12
27
 
13
- total_start = monotonic_time
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
- content = @workspace.get_content(uri)
16
- cache_key = content.hash
17
- cached = @semantic_tokens_cache[uri]
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
- tokens_start = monotonic_time
27
- tokens = @workspace.get_tokens(uri) || []
28
- tokens_ms = elapsed_ms(tokens_start)
36
+ encode_start = monotonic_time
37
+ data = encode_semantic_tokens(semantic_entries)
38
+ encode_ms = elapsed_ms(encode_start)
29
39
 
30
- facts_start = monotonic_time
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
- build_start = monotonic_time
35
- semantic_entries = build_semantic_token_entries(tokens, facts)
36
- build_ms = elapsed_ms(build_start)
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
- encode_start = monotonic_time
39
- data = encode_semantic_tokens(semantic_entries)
40
- encode_ms = elapsed_ms(encode_start)
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
- @semantic_tokens_cache[uri] = { content_hash: cache_key, data: data }
54
+ { data: data }
55
+ rescue StandardError => e
56
+ warn "Error in semanticTokens/full handler: #{e.message}"
57
+ { data: [] }
58
+ end
43
59
 
44
- result_id = next_semantic_token_result_id(uri)
45
- @semantic_tokens_delta_cache[uri] = {
46
- result_id: result_id,
47
- content_hash: cache_key,
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
- elapsed = elapsed_ms(total_start)
52
- short_uri = shorten_uri(uri) || uri
53
- log_perf_breakdown('textDocument/semanticTokens/full', elapsed,
54
- "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}")
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
- { data: data }
57
- rescue StandardError => e
58
- warn "Error in semanticTokens/full handler: #{e.message}"
59
- { data: [] }
60
- end
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
- def handle_semantic_tokens_delta(params)
63
- uri = params.dig('textDocument', 'uri')
64
- previous_result_id = params['previousResultId']
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
- cached = @semantic_tokens_delta_cache[uri]
68
- unless cached && cached[:result_id] == previous_result_id
69
- return handle_semantic_tokens_full(params)
70
- end
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
- content = @workspace.get_content(uri)
73
- cache_key = content.hash
74
- if cached[:content_hash] == cache_key
75
- return { resultId: cached[:result_id], edits: [] }
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
- tokens = @workspace.get_tokens(uri) || []
79
- facts = @workspace.get_facts(uri, allow_last_good_fallback: semantic_tokens_allow_last_good_fallback?(uri))
80
- new_entries = build_semantic_token_entries(tokens, facts)
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
- new_result_id = next_semantic_token_result_id(uri)
83
- @semantic_tokens_delta_cache[uri] = {
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
- edits = compute_semantic_tokens_edits(cached[:entries], new_entries)
90
- { resultId: new_result_id, edits: edits }
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
- def handle_semantic_tokens_range(params)
97
- uri = params.dig("textDocument", "uri")
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
- content = @workspace.get_content(uri)
102
- return { data: [] } unless content
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
- tokens = @workspace.get_tokens(uri) || []
105
- return { data: [] } if tokens.empty?
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
- start_line = range.dig("start", "line") + 1
108
- end_line = range.dig("end", "line") + 1
116
+ entries_in_range = semantic_entries.select do |entry|
117
+ entry[:line] >= start_line && entry[:line] <= end_line
118
+ end
109
119
 
110
- range_tokens = tokens.select do |t|
111
- t.line >= start_line && t.line <= end_line &&
112
- ![:newline, :indent, :dedent, :eof].include?(t.type)
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
- facts = @workspace.get_facts(uri, allow_last_good_fallback: semantic_tokens_allow_last_good_fallback?(uri))
116
- semantic_entries = build_semantic_token_entries(range_tokens, facts)
117
-
118
- entries_in_range = semantic_entries.select do |entry|
119
- entry[:line] >= start_line && entry[:line] <= end_line
120
- end
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
- data = encode_semantic_tokens(entries_in_range)
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
- def build_semantic_token_entries(tokens, facts = nil)
130
- # Precompute line non-trivia tokens index so non_trivia_tokens_on_line
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
- entries = []
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
- tokens.each_with_index do |tok, index|
140
- next if [:newline, :indent, :dedent, :eof].include?(tok.type)
146
+ semantic_type, modifiers = classify_semantic_token(tokens, index, facts)
147
+ next unless semantic_type
141
148
 
142
- if tok.type == :fstring
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
- semantic_type, modifiers = classify_semantic_token(tokens, index, facts)
149
- next unless semantic_type
150
-
151
- token_semantic_entries(tok, semantic_type, modifiers).each { |entry| entries << entry }
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
- entries.sort_by { |entry| [entry[:line], entry[:start_char]] }
155
- ensure
156
- @tokens_by_line_cache = nil
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
- def fstring_interpolation_entries(fstring_tok, facts)
161
- parts = fstring_tok.literal
162
- 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)
163
-
164
- result = []
165
- fstr_line = fstring_tok.line - 1 # 0-indexed
166
- fstr_col0 = fstring_tok.column - 1 # 0-indexed start of `f`
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
- # classified entries for format spec (if present), excluding the
213
- # delimiter token so TextMate interpolation punctuation can style it.
214
- if part[:format_spec]
215
- spec_col0 = expr_col0 + source.length
216
- # Format spec content (e.g., ".0", "3", ".5f") as individual token-like entries.
217
- # Treat it as lexable content or just string for simplicity.
218
- spec = part[:format_spec]
219
- unless spec.empty?
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
- spec_tokens = MilkTea::Lexer.new(spec).lex
222
- .reject { |t| [:newline, :indent, :dedent, :eof].include?(t.type) }
223
- spec_tokens.each_with_index do |spec_tok, i|
224
- spec_sem_type, spec_modifiers = classify_semantic_token(spec_tokens, i, facts)
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: fstr_line,
228
- start_char: spec_col0 + 1 + (spec_tok.column - 1),
229
- length: spec_tok.lexeme.length,
230
- type: spec_sem_type,
231
- modifiers: spec_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: treat spec as a number/string token.
199
+ # Fall back to string coloring for malformed expression.
236
200
  result << {
237
201
  line: fstr_line,
238
- start_char: spec_col0 + 1,
239
- length: spec.length,
240
- type: :number,
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
- # :string for tail text + closing `"`
251
- fstr_end_col0 = fstr_col0 + fstring_tok.lexeme.length - 1
252
- tail_len = fstr_end_col0 - cursor + 1
253
- result << { line: fstr_line, start_char: cursor, length: tail_len, type: :string, modifiers: [] } if tail_len > 0
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
- result
256
- end
245
+ cursor = rbrace_col0 + 1
246
+ end
257
247
 
258
- def classify_semantic_token(tokens, index, facts = nil)
259
- tok = tokens[index]
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
- if tok.type == :identifier || namespace_keyword_token?(tokens, index)
262
- return classify_name_semantic(tok.lexeme, tokens, index, facts)
253
+ result
263
254
  end
264
255
 
265
- if [:string, :cstring].include?(tok.type)
266
- return [nil, []] if embedded_heredoc_token?(tok)
256
+ def classify_semantic_token(tokens, index, facts = nil)
257
+ tok = tokens[index]
267
258
 
268
- return [:string, []]
269
- end
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
- if tok.type == :comment
272
- return [:comment, []]
273
- end
263
+ if [:string, :cstring].include?(tok.type)
264
+ return [nil, []] if embedded_heredoc_token?(tok)
274
265
 
275
- if [:integer, :float].include?(tok.type)
276
- return [:number, []]
277
- end
266
+ return [:string, []]
267
+ end
278
268
 
279
- if KEYWORD_TOKEN_TYPES.include?(tok.type)
280
- return [:keyword, []]
281
- end
269
+ if tok.type == :comment
270
+ return [:comment, []]
271
+ end
282
272
 
283
- if OPERATOR_TOKEN_TYPES.include?(tok.type)
284
- return [:operator, []]
285
- end
273
+ if [:integer, :float].include?(tok.type)
274
+ return [:number, []]
275
+ end
286
276
 
287
- [nil, []]
288
- end
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
- def embedded_heredoc_token?(token)
291
- return false unless [:string, :cstring, :fstring].include?(token.type)
287
+ if OPERATOR_TOKEN_TYPES.include?(tok.type)
288
+ return [:operator, []]
289
+ end
292
290
 
293
- tag = token.lexeme[/\A(?:f|c)?<<-([A-Za-z_][A-Za-z0-9_]*)[ \t]*\n/, 1]
294
- return false if tag.nil?
291
+ [nil, []]
292
+ end
295
293
 
296
- %w[GLSL VERT FRAG COMP JSON JSONC SQL HTML MT].include?(tag)
297
- end
294
+ def embedded_heredoc_token?(token)
295
+ return false unless [:string, :cstring, :fstring].include?(token.type)
298
296
 
299
- def token_semantic_entries(token, semantic_type, modifiers)
300
- token.lexeme.split("\n", -1).each_with_index.filter_map do |segment, index|
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
- def classify_name_semantic(name, tokens, index, facts = nil)
314
- tok = tokens[index]
315
- prev_tok = previous_non_trivia_token(tokens, index)
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
- if @attribute_name_semantic_overrides && (override = @attribute_name_semantic_overrides[[tok.line, tok.column]])
321
- return override
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
- if (import_info = import_path_info_at(tokens, index, allow_keywords: true))
325
- modifiers = []
326
- modifiers << 'declaration' if import_info[:role] == :alias
327
- return [:namespace, modifiers]
328
- end
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
- return [:namespace, []] if module_declaration_path_token?(tokens, index, allow_keywords: true)
324
+ if @attribute_name_semantic_overrides && (override = @attribute_name_semantic_overrides[[tok.line, tok.column]])
325
+ return override
326
+ end
331
327
 
332
- if prev_tok && [:function, :fn, :proc].include?(prev_tok.type)
333
- return [:function, ['declaration']]
334
- end
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
- if prev_tok && [:struct, :union, :enum, :flags, :variant, :type, :opaque, :interface].include?(prev_tok.type)
337
- return [:type, ['declaration']]
338
- end
334
+ return [:namespace, []] if module_declaration_path_token?(tokens, index, allow_keywords: true)
339
335
 
340
- return [:variable, []] if name == "_"
336
+ if prev_tok && [:function, :fn, :proc].include?(prev_tok.type)
337
+ return [:function, ['declaration']]
338
+ end
341
339
 
342
- if prev_tok&.type == :event
343
- return struct_event_declaration_token?(tokens, index) ? [:property, ['declaration']] : [:variable, ['declaration']]
344
- end
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
- if prev_tok&.type == :const
347
- return [:variable, ['declaration', 'readonly']]
348
- end
344
+ return [:variable, []] if name == "_"
349
345
 
350
- if prev_tok&.type == :let
351
- return [:variable, ['declaration', 'readonly']] unless next_tok&.type == :lparen
352
- end
346
+ if prev_tok&.type == :event
347
+ return struct_event_declaration_token?(tokens, index) ? [:property, ['declaration']] : [:variable, ['declaration']]
348
+ end
353
349
 
354
- if prev_tok&.type == :var
355
- return [:variable, ['declaration']] unless next_tok&.type == :lparen
356
- end
350
+ if prev_tok&.type == :const
351
+ return [:variable, ['declaration', 'readonly']]
352
+ end
357
353
 
358
- if prev_tok&.type == :for
359
- return [:variable, ['declaration', 'readonly']]
360
- end
354
+ if prev_tok&.type == :let
355
+ return [:variable, ['declaration', 'readonly']] unless next_tok&.type == :lparen
356
+ end
361
357
 
362
- return [:variable, ['declaration', 'readonly']] if match_arm_binding_token?(tokens, index)
363
- return [:parameter, ['declaration']] if callable_parameter_declaration_token?(tokens, index)
364
- return [:property, ['declaration']] if variant_payload_field_declaration_token?(tokens, index)
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
- if destructure_let_binding?(tokens, index)
368
- return [:variable, ['declaration', 'readonly']]
369
- end
362
+ if prev_tok&.type == :for
363
+ return [:variable, ['declaration', 'readonly']]
364
+ end
370
365
 
371
- if facts
372
- return [:typeParameter, ['declaration']] if type_parameter_declaration_token?(facts, tokens, index)
373
- return [:typeParameter, []] if type_parameter_reference_token?(facts, tokens, index)
374
- end
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
- return [:property, []] if named_argument_label_token?(tokens, index) && named_argument_label_in_type_constructor?(tokens, index, facts)
377
- return [:parameter, []] if named_argument_label_token?(tokens, index)
371
+ if destructure_let_binding?(tokens, index)
372
+ return [:variable, ['declaration', 'readonly']]
373
+ end
378
374
 
379
- if facts && prev_tok&.type != :dot && (generic_binding = generic_function_lexical_binding_semantic(facts, tok))
380
- return generic_binding
381
- end
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
- if next_tok&.type == :dot && facts
384
- return [:type, []] if known_type_name?(facts, name)
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 (binding = local_semantic_value_binding(facts, tok, allow_same_line_future: parameter_declaration))
389
- return semantic_value_binding_entry(binding, declaration: binding.kind == :param && parameter_declaration)
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 (binding = facts.values[name])
393
- return semantic_value_binding_entry(binding)
394
- end
395
- end
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
- if facts && (known_type_name?(facts, name) || facts.interfaces.key?(name)) && identifier_in_type_argument_position?(tokens, index)
398
- return [:type, []]
399
- end
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
- return [:enumMember, ['declaration']] if variant_enum_member_declaration?(tokens, index)
396
+ if (binding = facts.values[name])
397
+ return semantic_value_binding_entry(binding)
398
+ end
399
+ end
402
400
 
403
- if prev_tok&.type == :dot
404
- if facts
405
- module_binding = imported_module_binding_for_member(tokens, index, facts)
406
- if module_binding
407
- if module_binding.functions.key?(name)
408
- return [:function, []] if next_tok&.type == :lparen || specialized_call_with_type_args?(tokens, index)
409
- return [:function, []] if next_tok&.type == :lbracket
410
- return [:function, []] if imported_module_function_value_member_access_site?(facts, tokens, index)
411
- return [:property, []]
412
- end
413
- return [:type, []] if module_binding.types.key?(name)
414
- return [:type, []] if module_binding.interfaces.key?(name)
415
- if (value_binding = module_binding.values[name])
416
- modifiers = []
417
- modifiers << 'readonly' if value_binding.respond_to?(:mutable) && value_binding.mutable == false
418
- return [:variable, modifiers]
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
- return [:namespace, []] if facts.imports.key?(name)
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 [:type, []] if dot_nested_type_member?(tokens, index, facts)
424
- return [:property, []] if callable_field_member_access?(name, tokens, index, facts)
425
- return [:method, []] if static_type_member_access?(tokens, index, facts)
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
- return [:enumMember, []] if type_name_member_access?(tokens, index, facts)
429
- return [:method, []] if next_tok&.type == :lparen || specialized_call_with_type_args?(tokens, index)
430
- return [:property, []]
431
- end
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
- if next_tok&.type == :lparen || specialized_call_with_type_args?(tokens, index)
434
- if facts && (resolved = resolved_call_callee_semantic(name, tok, parameter_declaration, facts))
435
- return resolved
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
- modifiers = []
441
- modifiers << 'defaultLibrary' if BUILTIN_FUNCTION_NAMES.include?(name)
442
- if BUILTIN_ASSOCIATED_HOOK_NAMES.include?(name) && specialized_call_with_type_args?(tokens, index) && !user_defined_function
443
- modifiers << 'defaultLibrary'
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
- return [:function, []] if next_tok&.type == :lbracket && user_defined_function
467
+ if facts
449
468
 
450
- if facts && identifier_in_type_reference_position?(tokens, index)
451
- if known_type_name?(facts, name)
452
- modifiers = []
453
- modifiers << 'defaultLibrary' if DEFAULT_LIBRARY_TYPE_NAMES.include?(name)
454
- return [:type, modifiers]
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
- if facts
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
- if (binding = local_semantic_value_binding(facts, tok, allow_same_line_future: parameter_declaration))
466
- return semantic_value_binding_entry(binding, declaration: binding.kind == :param && parameter_declaration)
467
- end
504
+ def named_argument_label_in_type_constructor?(tokens, index, facts)
505
+ return false unless facts
468
506
 
469
- if known_type_name?(facts, name)
470
- modifiers = []
471
- modifiers << 'defaultLibrary' if DEFAULT_LIBRARY_TYPE_NAMES.include?(name)
472
- return [:type, modifiers]
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 [:namespace, []] if facts.imports.key?(name)
519
+ return false unless callee_index && tokens[callee_index].type == :identifier
477
520
 
478
- if (binding = facts.values[name])
479
- return semantic_value_binding_entry(binding)
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 [:function, []] if bare_function_value_identifier_site?(facts, tok)
483
- end
536
+ return false unless receiver_index && tokens[receiver_index].type == :identifier
484
537
 
485
- if DEFAULT_LIBRARY_TYPE_NAMES.include?(name)
486
- return [:type, ['defaultLibrary']]
538
+ receiver_name = tokens[receiver_index].lexeme
539
+ facts.types.key?(receiver_name) || facts.interfaces.key?(receiver_name)
487
540
  end
488
541
 
489
- return [:function, ['defaultLibrary']] if bare_builtin_specialization?(name, tokens, index)
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
- [:variable, []]
492
- end
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
- def named_argument_label_token?(tokens, index)
495
- prev_tok = previous_non_trivia_token(tokens, index)
496
- next_tok = next_non_trivia_token(tokens, index + 1)
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
- def named_argument_label_in_type_constructor?(tokens, index, facts)
501
- return false unless facts
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
- opener_index = parameter_list_opener_index(tokens, index)
504
- return false unless opener_index
563
+ next_tok = next_non_trivia_token(tokens, index + 1)
564
+ next_tok&.type == :colon
565
+ end
505
566
 
506
- callee_index = previous_non_trivia_token_index(tokens, opener_index)
507
- return false unless callee_index
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
- if tokens[callee_index].type == :rbracket
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
- return false unless callee_index && tokens[callee_index].type == :identifier
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
- callee_name = tokens[callee_index].lexeme
518
- return true if facts.types.key?(callee_name) || facts.interfaces.key?(callee_name)
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
- dot_index = previous_non_trivia_token_index(tokens, callee_index)
521
- return false unless dot_index && tokens[dot_index].type == :dot
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
- receiver_index = previous_non_trivia_token_index(tokens, dot_index)
524
- return false unless receiver_index
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
- if tokens[receiver_index].type == :rbracket
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
- return false unless receiver_index && tokens[receiver_index].type == :identifier
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
- receiver_name = tokens[receiver_index].lexeme
535
- facts.types.key?(receiver_name) || facts.interfaces.key?(receiver_name)
536
- end
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
- def match_arm_binding_token?(tokens, index)
539
- prev_tok = previous_non_trivia_token(tokens, index)
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
- def field_declaration_token?(tokens, index)
545
- tok = tokens[index]
546
- return false unless tok&.type == :identifier
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
- next_tok = next_non_trivia_token(tokens, index + 1)
552
- next_tok&.type == :colon
553
- end
621
+ line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
622
+ return false unless line_tokens.length >= 3
554
623
 
555
- def destructure_let_binding?(tokens, index)
556
- tok = tokens[index]
557
- return false unless tok&.type == :identifier
624
+ first = line_tokens[0]
625
+ return false unless [:let, :var].include?(first.type)
558
626
 
559
- line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
560
- return false unless line_tokens.length >= 3
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
- first = line_tokens[0]
563
- return false unless [:let, :var].include?(first.type)
631
+ return false if eq_idx && lparen_idx >= eq_idx
564
632
 
565
- eq_idx = line_tokens.index { |t| t.type == :equal }
566
- lparen_idx = line_tokens.index { |t| t.type == :lparen }
567
- return false unless lparen_idx
633
+ # let (a, b) = ...
634
+ if line_tokens[1]&.type == :lparen
635
+ return first.type == :let
636
+ end
568
637
 
569
- return false if eq_idx && lparen_idx >= eq_idx
638
+ # let Vec2(x, y) = ... identifier then lparen adjacency
639
+ return false unless line_tokens[1]&.type == :identifier && lparen_idx == 2
570
640
 
571
- # let (a, b) = ...
572
- if line_tokens[1]&.type == :lparen
573
- return first.type == :let
641
+ first.type == :let
574
642
  end
575
643
 
576
- # let Vec2(x, y) = ... — identifier then lparen adjacency
577
- return false unless line_tokens[1]&.type == :identifier && lparen_idx == 2
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
- def struct_event_declaration_token?(tokens, index)
583
- tok = tokens[index]
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
- prev_tok = previous_non_trivia_token(tokens, index)
587
- return false unless prev_tok&.type == :event
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
- line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
590
- line_start = line_tokens.first
591
- return false unless line_start && line_start.column > 1
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
- i = index - 1
594
- while i >= 0
595
- current = tokens[i]
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
- header_line_toks = non_trivia_tokens_on_line(tokens, current.line)
602
- return header_line_toks.first&.type == :struct
667
+ false
603
668
  end
604
669
 
605
- false
606
- end
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
- opener_index = parameter_list_opener_index(tokens, index)
612
- return false unless opener_index
673
+ opener_index = parameter_list_opener_index(tokens, index)
674
+ return false unless opener_index
613
675
 
614
- head_index = previous_non_trivia_token_index(tokens, opener_index)
615
- return false unless head_index
676
+ head_index = previous_non_trivia_token_index(tokens, opener_index)
677
+ return false unless head_index
616
678
 
617
- variant_enum_member_declaration?(tokens, head_index)
618
- end
679
+ variant_enum_member_declaration?(tokens, head_index)
680
+ end
619
681
 
620
- FOREIGN_PARAM_MODE_TOKENS = [:out, :in, :inout, :consuming].freeze
621
- private_constant :FOREIGN_PARAM_MODE_TOKENS
682
+ FOREIGN_PARAM_MODE_TOKENS = [:out, :in, :inout, :consuming].freeze
683
+ private_constant :FOREIGN_PARAM_MODE_TOKENS
622
684
 
623
- def parameter_declaration_token?(tokens, index)
624
- prev_tok = previous_non_trivia_token(tokens, index)
625
- next_tok = next_non_trivia_token(tokens, index + 1)
626
- next_tok&.type == :colon && prev_tok && (
627
- [:lparen, :comma].include?(prev_tok.type) ||
628
- FOREIGN_PARAM_MODE_TOKENS.include?(prev_tok.type)
629
- )
630
- end
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
- def callable_parameter_declaration_token?(tokens, index)
633
- return false unless parameter_declaration_token?(tokens, index)
694
+ def callable_parameter_declaration_token?(tokens, index)
695
+ return false unless parameter_declaration_token?(tokens, index)
634
696
 
635
- opener_index = parameter_list_opener_index(tokens, index)
636
- return false unless opener_index
697
+ opener_index = parameter_list_opener_index(tokens, index)
698
+ return false unless opener_index
637
699
 
638
- head_index = previous_non_trivia_token_index(tokens, opener_index)
639
- return false unless head_index
700
+ head_index = previous_non_trivia_token_index(tokens, opener_index)
701
+ return false unless head_index
640
702
 
641
- head = tokens[head_index]
642
- return true if [:fn, :proc].include?(head.type)
703
+ head = tokens[head_index]
704
+ return true if [:fn, :proc].include?(head.type)
643
705
 
644
- if head.type == :rbracket
645
- lbracket_index = matching_opener_index(tokens, head_index)
646
- return false unless lbracket_index
706
+ if head.type == :rbracket
707
+ lbracket_index = matching_opener_index(tokens, head_index)
708
+ return false unless lbracket_index
647
709
 
648
- head_index = previous_non_trivia_token_index(tokens, lbracket_index)
649
- return false unless head_index
710
+ head_index = previous_non_trivia_token_index(tokens, lbracket_index)
711
+ return false unless head_index
650
712
 
651
- head = tokens[head_index]
652
- end
713
+ head = tokens[head_index]
714
+ end
653
715
 
654
- return false unless head.type == :identifier
716
+ return false unless head.type == :identifier
655
717
 
656
- previous_non_trivia_token(tokens, head_index)&.type == :function
657
- end
718
+ previous_non_trivia_token(tokens, head_index)&.type == :function
719
+ end
658
720
 
659
- def parameter_list_opener_index(tokens, index)
660
- depth = 0
661
- i = index - 1
662
- while i >= 0
663
- tok = tokens[i]
664
- if tok.type == :rparen
665
- depth += 1
666
- elsif tok.type == :lparen
667
- return i if depth.zero?
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
- depth -= 1
731
+ depth -= 1
732
+ end
733
+ i -= 1
670
734
  end
671
- i -= 1
735
+
736
+ nil
672
737
  end
673
738
 
674
- nil
675
- end
739
+ def lexically_declared_free_function_name?(tokens, name)
740
+ lexically_declared_free_function_names(tokens).include?(name)
741
+ end
676
742
 
677
- def lexically_declared_free_function_name?(tokens, name)
678
- lexically_declared_free_function_names(tokens).include?(name)
679
- end
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
- def lexically_declared_free_function_names(tokens)
682
- cache = @lexically_declared_free_function_name_cache ||= {}
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
- cache[tokens.object_id] = tokens.each_with_index.each_with_object(Set.new) do |(token, index), names|
687
- next unless token.type == :identifier
751
+ prev_index = previous_non_trivia_token_index(tokens, index)
752
+ next unless prev_index
688
753
 
689
- prev_index = previous_non_trivia_token_index(tokens, index)
690
- next unless prev_index
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
- prev_tok = tokens[prev_index]
693
- next unless [:function, :fn, :proc].include?(prev_tok.type)
694
- next unless first_non_trivia_token_on_line?(tokens, prev_index)
758
+ names << token.lexeme
759
+ end
760
+ end
695
761
 
696
- names << token.lexeme
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
- def generic_function_lexical_binding_semantic(facts, token)
701
- kind = generic_function_lexical_binding_kind_at(facts, token.line, token.column, token.lexeme)
702
- case kind
703
- when :param
704
- [:parameter, []]
705
- when :variable
706
- [:variable, []]
707
- else
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
- def generic_function_lexical_binding_kind_at(facts, line, column, name)
713
- generic_function_lexical_binding_scopes(facts).reverse_each do |scope|
714
- next if line < scope[:start_line] || line > scope[:end_line]
715
- next if line == scope[:start_line] && column < scope[:start_column]
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
- kind = scope[:bindings][name]
718
- return kind if kind
800
+ cached
719
801
  end
720
802
 
721
- nil
722
- end
723
-
724
- def generic_function_lexical_binding_scopes(facts)
725
- scopes = @generic_function_lexical_binding_scope_cache ||= {}
726
- cached = scopes[facts.object_id]
727
- unless cached
728
- decls = Array(facts.ast&.declarations)
729
- cached = decls.each_with_index.flat_map do |decl, index|
730
- generic_function_lexical_scopes_for_declaration(
731
- decl,
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
- scopes[facts.object_id] = cached
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
- cached
739
- end
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
- def generic_function_lexical_scopes_for_declaration(decl, end_line: Float::INFINITY)
742
- if decl.is_a?(AST::ExtendingBlock)
743
- receiver_type_params = generic_type_parameter_names_for_extending_block(decl)
744
- methods = Array(decl.methods)
745
- return methods.each_with_index.flat_map do |method, index|
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
- return [] unless generic_function_declaration?(decl)
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
- generic_callable_lexical_scopes(decl, end_line: generic_statement_list_end_line(decl.body, decl.line))
757
- end
839
+ current_bindings[param.name] = :param
840
+ end
758
841
 
759
- def generic_method_lexical_scopes(method, receiver_type_params:, end_line:)
760
- return [] unless method.respond_to?(:body) && !method.body.nil?
761
- return [] if receiver_type_params.empty? && Array(method.type_params).empty?
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
- generic_callable_lexical_scopes(
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
- def generic_callable_lexical_scopes(decl, end_line:, include_receiver: false)
771
- scopes = []
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
- current_bindings[param.name] = :param
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
- unless current_bindings.empty?
781
- scopes << {
782
- start_line: decl.line,
783
- start_column: 0,
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: current_bindings.dup,
916
+ bindings: bindings.dup,
786
917
  }
787
918
  end
788
919
 
789
- collect_generic_function_local_scopes(Array(decl.body), current_bindings, end_line, scopes)
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
- scopes
792
- end
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).each do |branch|
811
- branch_body = Array(branch.body)
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).each do |arm|
823
- arm_bindings = active_bindings.dup
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
- when AST::UnsafeStmt, AST::WhileStmt, AST::DeferStmt
833
- body = Array(statement.body)
834
- body_end_line = generic_statement_list_end_line(body, statement.line)
835
- collect_generic_function_local_scopes(body, active_bindings, body_end_line, scopes)
836
- when AST::ForStmt
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
- def generic_binding_scope(node, bindings, end_line)
850
- {
851
- start_line: node.respond_to?(:line) && node.line ? node.line : 0,
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
- def generic_statement_end_line(statement)
865
- return 0 unless statement
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
- import_path_info_at(tokens, index, allow_keywords: true) ||
891
- module_declaration_path_token?(tokens, index, allow_keywords: true)
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
- end
963
+ snapshot = latest_completion_snapshot(frame, line, char)
964
+ binding = snapshot&.bindings&.dig(token.lexeme)
965
+ return binding if binding
894
966
 
895
- def local_semantic_value_binding(facts, token, allow_same_line_future: false)
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
- snapshot = latest_completion_snapshot(frame, line, char)
902
- binding = snapshot&.bindings&.dig(token.lexeme)
903
- return binding if binding
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
- next unless allow_same_line_future
974
+ nil
975
+ end
906
976
 
907
- future_snapshot = same_line_future_completion_snapshot(frame, line, char)
908
- binding = future_snapshot&.bindings&.dig(token.lexeme)
909
- return binding if binding
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
- nil
913
- end
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 << 'declaration' if declaration
926
- [:variable, modifiers]
927
- end
928
- end
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
- def resolved_call_callee_semantic(name, token, parameter_declaration, facts)
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
- if (binding = facts.values[name])
936
- return semantic_value_binding_entry(binding)
937
- end
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
- modifiers = []
940
- modifiers << 'defaultLibrary' if BUILTIN_FUNCTION_NAMES.include?(name)
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
- nil
946
- end
1017
+ receiver_index = previous_non_trivia_token_index(tokens, dot_index)
1018
+ return false unless receiver_index
947
1019
 
948
- def callable_field_member_access?(name, tokens, index, facts)
949
- next_tok = next_non_trivia_token(tokens, index + 1)
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
- dot_index = previous_non_trivia_token_index(tokens, index)
953
- return false unless dot_index && tokens[dot_index].type == :dot
1023
+ resolve_receiver_value_type(facts, receiver_tok).then do |receiver_type|
1024
+ next false unless receiver_type
954
1025
 
955
- receiver_index = previous_non_trivia_token_index(tokens, dot_index)
956
- return false unless receiver_index
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
- receiver_tok = tokens[receiver_index]
959
- return false unless receiver_tok.type == :identifier
1029
+ callable_semantic_type?(field_receiver_type.field(name))
1030
+ end
1031
+ end
960
1032
 
961
- resolve_receiver_value_type(facts, receiver_tok).then do |receiver_type|
962
- next false unless receiver_type
1033
+ def resolve_receiver_value_type(facts, token)
1034
+ char = token.column
963
1035
 
964
- field_receiver_type = project_field_receiver_type_for_completion(receiver_type, facts)
965
- next false unless field_receiver_type.respond_to?(:field)
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
- callable_semantic_type?(field_receiver_type.field(name))
1041
+ nil
968
1042
  end
969
- end
970
1043
 
971
- def resolve_receiver_value_type(facts, token)
972
- char = token.column
1044
+ def callable_semantic_type?(type)
1045
+ type.is_a?(Types::Function) || type.is_a?(Types::Proc)
1046
+ end
973
1047
 
974
- [token.line - 1, token.line].uniq.each do |line|
975
- receiver_type = resolve_dot_receiver_value_type(facts, token.lexeme, line, char)
976
- return receiver_type if receiver_type
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
- nil
980
- end
1057
+ def dot_nested_type_member?(tokens, index, facts)
1058
+ return false unless facts
981
1059
 
982
- def callable_semantic_type?(type)
983
- type.is_a?(Types::Function) || type.is_a?(Types::Proc)
984
- end
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
- def known_type_name?(facts, name)
987
- return false unless facts
988
- return true if facts.types.key?(name)
989
- facts.types.each_value do |type|
990
- return true if type.respond_to?(:nested_types) && type.nested_types.key?(name)
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
- def dot_nested_type_member?(tokens, index, facts)
996
- return false unless facts
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
- dot_index = index - 1
999
- return false unless dot_index >= 0 && tokens[dot_index].type == :dot
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
- receiver_index = previous_non_trivia_token_index(tokens, dot_index)
1002
- return false unless receiver_index && tokens[receiver_index].type == :identifier
1089
+ def bare_builtin_specialization?(name, tokens, index)
1090
+ return false unless name == 'zero' || name == 'default'
1003
1091
 
1004
- receiver_name = tokens[receiver_index].lexeme
1005
- type = resolve_struct_type_name(facts, receiver_name)
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
- member_name = tokens[index].lexeme
1009
- type.nested_types.key?(member_name)
1010
- end
1095
+ rbracket_index = matching_closer_index(tokens, next_index, :lbracket, :rbracket)
1096
+ return false unless rbracket_index
1011
1097
 
1012
- def resolve_struct_type_name(facts, name)
1013
- type = facts.types[name]
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
- def constructible_semantic_type?(type)
1024
- 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)
1025
- end
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
- def bare_builtin_specialization?(name, tokens, index)
1028
- return false unless name == 'zero' || name == 'default'
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
- next_index = next_non_trivia_token_index(tokens, index + 1)
1031
- return false unless next_index && tokens[next_index].type == :lbracket
1111
+ receiver_index = previous_non_trivia_token_index(tokens, dot_index)
1112
+ return false unless receiver_index
1032
1113
 
1033
- rbracket_index = matching_closer_index(tokens, next_index, :lbracket, :rbracket)
1034
- return false unless rbracket_index
1114
+ receiver = tokens[receiver_index]
1115
+ return false unless receiver.type == :identifier
1035
1116
 
1036
- after_bracket_index = next_non_trivia_token_index(tokens, rbracket_index + 1)
1037
- after_bracket_index.nil? || tokens[after_bracket_index].type != :lparen
1038
- end
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
- def bare_function_value_identifier_site?(facts, token)
1041
- facts.functions.key?(token.lexeme) &&
1042
- facts.callable_value_identifier_sites.fetch([token.line, token.column], false)
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
- def imported_module_function_value_member_access_site?(facts, tokens, index)
1046
- dot_index = previous_non_trivia_token_index(tokens, index)
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
- receiver_index = previous_non_trivia_token_index(tokens, dot_index)
1050
- return false unless receiver_index
1130
+ receiver = tokens[receiver_index]
1131
+ return nil unless receiver.type == :identifier
1051
1132
 
1052
- receiver = tokens[receiver_index]
1053
- return false unless receiver.type == :identifier
1133
+ facts.imports[receiver.lexeme]
1134
+ end
1054
1135
 
1055
- facts.callable_value_member_access_sites.fetch(
1056
- [receiver.lexeme, receiver.line, receiver.column, tokens[index].lexeme],
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
- def imported_module_binding_for_member(tokens, index, facts)
1062
- dot_index = previous_non_trivia_token_index(tokens, index)
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
- receiver_index = previous_non_trivia_token_index(tokens, dot_index)
1066
- return nil unless receiver_index
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
- receiver = tokens[receiver_index]
1069
- return nil unless receiver.type == :identifier
1147
+ receiver_index = previous_non_trivia_token_index(tokens, dot_index)
1148
+ return nil unless receiver_index
1070
1149
 
1071
- facts.imports[receiver.lexeme]
1072
- end
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
- def static_type_member_access?(tokens, index, facts)
1075
- receiver_info = dot_type_receiver_info(tokens, index, facts)
1076
- return false unless receiver_info
1154
+ receiver_index = previous_non_trivia_token_index(tokens, lbracket_index)
1155
+ return nil unless receiver_index
1156
+ end
1077
1157
 
1078
- !static_method_binding_for_receiver(facts, receiver_info[:type], tokens[index].lexeme).nil?
1079
- end
1158
+ receiver = tokens[receiver_index]
1159
+ return nil unless receiver.type == :identifier
1080
1160
 
1081
- def dot_type_receiver_info(tokens, index, facts)
1082
- dot_index = previous_non_trivia_token_index(tokens, index)
1083
- return nil unless dot_index && tokens[dot_index].type == :dot
1161
+ receiver_name = receiver.lexeme
1162
+ receiver_path = receiver_name
1084
1163
 
1085
- receiver_index = previous_non_trivia_token_index(tokens, dot_index)
1086
- return nil unless receiver_index
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
- if tokens[receiver_index].type == :rbracket
1089
- lbracket_index = matching_opener_index(tokens, receiver_index)
1090
- return nil unless lbracket_index
1169
+ receiver_path = "#{tokens[module_index].lexeme}.#{receiver_name}"
1170
+ end
1091
1171
 
1092
- receiver_index = previous_non_trivia_token_index(tokens, lbracket_index)
1093
- return nil unless receiver_index
1172
+ resolve_type_receiver_info(facts, receiver_name, receiver_path)
1094
1173
  end
1095
1174
 
1096
- receiver = tokens[receiver_index]
1097
- return nil unless receiver.type == :identifier
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
- module_dot_index = previous_non_trivia_token_index(tokens, receiver_index)
1103
- if module_dot_index && tokens[module_dot_index].type == :dot
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
- receiver_path = "#{tokens[module_index].lexeme}.#{receiver_name}"
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
- resolve_type_receiver_info(facts, receiver_name, receiver_path)
1111
- end
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
- def specialized_call_with_type_args?(tokens, index)
1114
- next_index = next_non_trivia_token_index(tokens, index + 1)
1115
- return false unless next_index && tokens[next_index].type == :lbracket
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
- rbracket_index = matching_closer_index(tokens, next_index, :lbracket, :rbracket)
1118
- return false unless rbracket_index
1204
+ depth -= 1
1205
+ end
1206
+ i -= 1
1207
+ end
1208
+ end
1119
1209
 
1120
- after_bracket_index = next_non_trivia_token_index(tokens, rbracket_index + 1)
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
- def identifier_in_type_argument_position?(tokens, index)
1125
- lbracket_index = previous_non_trivia_token_index(tokens, index)
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
- if tokens[lbracket_index].type == :comma
1129
- depth = 0
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
- depth -= 1
1143
- end
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
- return false unless lbracket_index && tokens[lbracket_index].type == :lbracket
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
- rbracket_index = matching_closer_index(tokens, lbracket_index, :lbracket, :rbracket)
1151
- return false unless rbracket_index
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
- next_index = next_non_trivia_token_index(tokens, index + 1)
1154
- return false unless next_index
1232
+ identifier_in_type_parameter_reference_position?(tokens, index)
1233
+ end
1155
1234
 
1156
- # Type argument entries should stay inside the current [] pair.
1157
- next_index <= rbracket_index
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
- def type_parameter_declaration_token?(facts, tokens, index)
1161
- info = type_parameter_declaration_info_on_line(tokens, tokens[index].line)
1162
- info && info[:tokens].any? { |token| token.equal?(tokens[index]) }
1163
- end
1238
+ prev_tok = previous_non_trivia_token(tokens, index)
1239
+ [:colon, :arrow].include?(prev_tok&.type)
1240
+ end
1164
1241
 
1165
- def type_parameter_reference_token?(facts, tokens, index)
1166
- tok = tokens[index]
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
- identifier_in_type_parameter_reference_position?(tokens, index)
1171
- end
1245
+ prev_tok = previous_non_trivia_token(tokens, index)
1246
+ return true if [:colon, :arrow, :as].include?(prev_tok&.type)
1172
1247
 
1173
- def identifier_in_type_parameter_reference_position?(tokens, index)
1174
- return true if identifier_in_type_argument_position?(tokens, index)
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
- prev_tok = previous_non_trivia_token(tokens, index)
1177
- [:colon, :arrow].include?(prev_tok&.type)
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
- def identifier_in_type_reference_position?(tokens, index)
1181
- return true if identifier_in_type_argument_position?(tokens, index)
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
- prev_tok = previous_non_trivia_token(tokens, index)
1184
- return true if [:colon, :arrow, :as].include?(prev_tok&.type)
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
- line_tokens = non_trivia_tokens_on_line(tokens, tokens[index].line)
1187
- return true if prev_tok&.type == :equal && line_tokens.first&.type == :type
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
- next_index = next_non_trivia_token_index(tokens, index + 1)
1190
- return false unless next_index && tokens[next_index].type == :less
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
- minus_index = next_non_trivia_token_index(tokens, next_index + 1)
1193
- return false unless minus_index && tokens[minus_index].type == :minus
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
- tokens[next_index].line == tokens[index].line &&
1196
- tokens[next_index].column == (tokens[index].column + tokens[index].lexeme.length) &&
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
- def type_parameter_declaration_info_on_line(tokens, line)
1202
- line_tokens = non_trivia_tokens_on_line(tokens, line)
1203
- return nil if line_tokens.empty?
1204
-
1205
- header_index = line_tokens.index { |line_tok| generic_type_parameter_header_token?(line_tok.type) }
1206
- return nil unless header_index
1207
-
1208
- name_index = ((header_index + 1)...line_tokens.length).find { |i| line_tokens[i].type == :identifier }
1209
- return nil unless name_index
1210
-
1211
- lbracket_index = name_index + 1
1212
- return nil unless line_tokens[lbracket_index]&.type == :lbracket
1213
-
1214
- depth = 0
1215
- type_param_tokens = []
1216
- expect_name = false
1217
- i = lbracket_index
1218
- while i < line_tokens.length
1219
- tok = line_tokens[i]
1220
- case tok.type
1221
- when :lbracket
1222
- depth += 1
1223
- expect_name = true if depth == 1
1224
- when :rbracket
1225
- depth -= 1
1226
- return {
1227
- names: type_param_tokens.map(&:lexeme),
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
- i += 1
1306
+
1307
+ nil
1243
1308
  end
1244
1309
 
1245
- nil
1246
- end
1310
+ def generic_type_parameter_header_token?(type)
1311
+ [:function, :struct, :union, :enum, :flags, :variant, :type, :extending].include?(type)
1312
+ end
1247
1313
 
1248
- def generic_type_parameter_header_token?(type)
1249
- [:function, :struct, :union, :enum, :flags, :variant, :type, :extending].include?(type)
1250
- end
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
- def type_parameter_names_in_scope(facts, line)
1253
- scopes = @type_parameter_scope_cache ||= {}
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
- cached.reverse_each do |scope|
1267
- return scope[:names] if line >= scope[:start_line] && line <= scope[:end_line]
1332
+ []
1268
1333
  end
1269
1334
 
1270
- []
1271
- end
1272
-
1273
- def type_parameter_scopes_for_declaration(decl, end_line: Float::INFINITY)
1274
- if decl.is_a?(AST::ExtendingBlock)
1275
- receiver_names = generic_type_parameter_names_for_extending_block(decl)
1276
- methods = Array(decl.methods)
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
- start_line: method.line,
1283
- end_line: nested_declaration_scope_end_line(methods, index, fallback_end_line: end_line),
1284
- names: names.uniq,
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
- names = generic_type_parameter_names_for_declaration(decl)
1290
- return [] if names.empty? || decl.line.nil?
1351
+ names = generic_type_parameter_names_for_declaration(decl)
1352
+ return [] if names.empty? || decl.line.nil?
1291
1353
 
1292
- [{
1293
- start_line: decl.line,
1294
- end_line: end_line,
1295
- names: names,
1296
- }]
1297
- end
1354
+ [{
1355
+ start_line: decl.line,
1356
+ end_line: end_line,
1357
+ names: names,
1358
+ }]
1359
+ end
1298
1360
 
1299
- def generic_type_parameter_names_for_declaration(decl)
1300
- return [] unless decl.respond_to?(:type_params)
1361
+ def generic_type_parameter_names_for_declaration(decl)
1362
+ return [] unless decl.respond_to?(:type_params)
1301
1363
 
1302
- Array(decl.type_params).filter_map { |type_param| type_param.respond_to?(:name) ? type_param.name : nil }
1303
- end
1364
+ Array(decl.type_params).filter_map { |type_param| type_param.respond_to?(:name) ? type_param.name : nil }
1365
+ end
1304
1366
 
1305
- def generic_type_parameter_names_for_extending_block(decl)
1306
- return [] unless decl.respond_to?(:type_name)
1367
+ def generic_type_parameter_names_for_extending_block(decl)
1368
+ return [] unless decl.respond_to?(:type_name)
1307
1369
 
1308
- type_ref = decl.type_name
1309
- return [] unless type_ref.is_a?(AST::TypeRef)
1370
+ type_ref = decl.type_name
1371
+ return [] unless type_ref.is_a?(AST::TypeRef)
1310
1372
 
1311
- Array(type_ref.arguments).filter_map do |argument|
1312
- simple_type_parameter_name_from_type_argument(argument)
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
- def simple_type_parameter_name_from_type_argument(argument)
1317
- value = argument.respond_to?(:value) ? argument.value : nil
1318
- return nil unless value.is_a?(AST::TypeRef)
1319
- return nil unless value.arguments.empty? && !value.nullable && value.name.parts.length == 1
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
- value.name.parts.first
1322
- end
1383
+ value.name.parts.first
1384
+ end
1323
1385
 
1324
- def declaration_scope_end_line(decls, index)
1325
- nested_declaration_scope_end_line(decls, index, fallback_end_line: Float::INFINITY)
1326
- end
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
- def nested_declaration_scope_end_line(decls, index, fallback_end_line:)
1329
- next_decl = decls[(index + 1)..]&.find { |candidate| candidate.respond_to?(:line) && !candidate.line.nil? }
1330
- next_decl ? next_decl.line - 1 : fallback_end_line
1331
- end
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
- def matching_closer_index(tokens, opener_index, opener_type, closer_type)
1334
- depth = 0
1335
- i = opener_index
1336
- while i < tokens.length
1337
- tok = tokens[i]
1338
- if tok.type == opener_type
1339
- depth += 1
1340
- elsif tok.type == closer_type
1341
- depth -= 1
1342
- return i if depth.zero?
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
- i += 1
1408
+ nil
1345
1409
  end
1346
- nil
1347
- end
1348
1410
 
1349
- def import_path_info_at(tokens, index, allow_keywords: false)
1350
- tok = tokens[index]
1351
- return nil unless tok
1352
- return nil unless tok.type == :identifier || (allow_keywords && Token::KEYWORDS.value?(tok.type))
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
- line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
1355
- return nil if line_tokens.empty? || line_tokens.first.type != :import
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
- as_index = line_tokens.index { |line_tok| line_tok.type == :as }
1358
- module_tokens = line_tokens[1...(as_index || line_tokens.length)] || []
1359
- alias_token = as_index ? line_tokens[as_index + 1] : nil
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
- module_identifiers = module_tokens.select do |line_tok|
1362
- line_tok.type == :identifier || (allow_keywords && Token::KEYWORDS.value?(line_tok.type))
1363
- end
1364
- return nil if module_identifiers.empty?
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
- module_name = module_identifiers.map(&:lexeme).join('.')
1367
- return { module_name: module_name, role: :module_path } if module_identifiers.include?(tok)
1368
- return { module_name: module_name, role: :alias } if alias_token == tok
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
- nil
1371
- end
1432
+ nil
1433
+ end
1372
1434
 
1373
- def variant_enum_member_declaration?(tokens, index)
1374
- tok = tokens[index]
1375
- line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
1376
- return false unless line_tokens.first.equal?(tok) && tok.column > 1
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
- i = index - 1
1379
- while i >= 0
1380
- t = tokens[i]
1381
- i -= 1
1382
- next if [:newline, :indent, :dedent, :eof].include?(t.type)
1383
- next if t.line == tok.line
1384
- next if t.column >= tok.column
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
- header_line_toks = non_trivia_tokens_on_line(tokens, t.line)
1387
- header_kind = header_line_toks.find { |header_tok| [:variant, :enum, :flags].include?(header_tok.type) }
1388
- return !header_kind.nil?
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
- def type_name_member_access?(tokens, index, facts = nil)
1394
- dot_index = previous_non_trivia_token_index(tokens, index)
1395
- return false unless dot_index && tokens[dot_index].type == :dot
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
- receiver_index = previous_non_trivia_token_index(tokens, dot_index)
1398
- return false unless receiver_index
1459
+ receiver_index = previous_non_trivia_token_index(tokens, dot_index)
1460
+ return false unless receiver_index
1399
1461
 
1400
- type_name_receiver_token?(tokens, receiver_index, facts)
1401
- end
1462
+ type_name_receiver_token?(tokens, receiver_index, facts)
1463
+ end
1402
1464
 
1403
- def type_name_receiver_token?(tokens, index, facts = nil)
1404
- receiver = tokens[index]
1465
+ def type_name_receiver_token?(tokens, index, facts = nil)
1466
+ receiver = tokens[index]
1405
1467
 
1406
- if receiver.type == :identifier
1407
- return true if receiver.lexeme.match?(/\A[A-Z]/)
1408
- return true if facts && facts.types.key?(receiver.lexeme)
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
- if facts
1411
- module_binding = imported_module_binding_for_member(tokens, index, facts)
1412
- return true if module_binding && module_binding.types.key?(receiver.lexeme)
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
- return false
1416
- end
1480
+ if receiver.type == :rbracket
1481
+ lbracket_i = matching_opener_index(tokens, index)
1482
+ return false unless lbracket_i
1417
1483
 
1418
- if receiver.type == :rbracket
1419
- lbracket_i = matching_opener_index(tokens, index)
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
- base_index = previous_non_trivia_token_index(tokens, lbracket_i)
1423
- return false unless base_index
1487
+ return type_name_receiver_token?(tokens, base_index, facts)
1488
+ end
1424
1489
 
1425
- return type_name_receiver_token?(tokens, base_index, facts)
1490
+ false
1426
1491
  end
1427
1492
 
1428
- false
1429
- end
1493
+ def matching_opener_index(tokens, closer_index)
1494
+ closer = tokens[closer_index]
1495
+ return nil unless closer
1430
1496
 
1431
- def matching_opener_index(tokens, closer_index)
1432
- closer = tokens[closer_index]
1433
- return nil unless closer
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
- opener_type, closer_type = case closer.type
1436
- when :rbracket then [:lbracket, :rbracket]
1437
- when :rparen then [:lparen, :rparen]
1438
- else return nil
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
- depth = 0
1442
- i = closer_index
1443
- while i >= 0
1444
- t = tokens[i]
1445
- if t.type == closer_type
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
- def non_trivia_tokens_on_line(tokens, line)
1457
- return @tokens_by_line_cache[line] if @tokens_by_line_cache
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
- tokens.select do |tok|
1460
- tok.line == line && ![:newline, :indent, :dedent, :eof].include?(tok.type)
1560
+ overrides
1461
1561
  end
1462
- end
1463
1562
 
1464
- def build_attribute_name_semantic_overrides(tokens, facts)
1465
- return {} unless facts&.respond_to?(:ast) && facts.ast
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
- token_indices_by_position = tokens.each_with_index.each_with_object({}) do |(token, index), positions|
1468
- positions[[token.line, token.column]] = index
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
- walk_ast_nodes(facts.ast) do |node|
1473
- case node
1474
- when AST::AttributeDecl
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
- [node.name],
1480
- line: node.line,
1481
- column: node.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::AttributeApplication
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
- node.name.parts,
1490
- line: node.line,
1491
- column: node.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
- end
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
- def mark_attribute_reflection_name_overrides(overrides, token_indices_by_position, tokens, call_expression)
1516
- callee = call_expression.callee
1517
- return unless callee.is_a?(AST::Identifier)
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
- def mark_attribute_name_override(overrides, token_indices_by_position, tokens, parts, line:, column:, declaration: false)
1548
- current_index = token_indices_by_position[[line, column]]
1549
- return unless current_index
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
- parts.each_with_index do |part, part_index|
1552
- token = tokens[current_index]
1553
- return unless token&.lexeme == part
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
- if part_index == parts.length - 1
1556
- modifiers = []
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
- overrides[[token.line, token.column]] = [:namespace, []]
1563
- dot_index = next_non_trivia_token_index(tokens, current_index + 1)
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
- def module_declaration_path_token?(tokens, index, allow_keywords: false)
1572
- !module_declaration_info_at(tokens, index, allow_keywords:).nil?
1573
- end
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
- def module_declaration_info_at(tokens, index, allow_keywords: false)
1576
- tok = tokens[index]
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
- line_tokens = non_trivia_tokens_on_line(tokens, tok.line)
1580
- return nil if line_tokens.empty? || line_tokens.first.type != :module
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
- path_tokens = line_tokens[1..].to_a.select do |line_tok|
1583
- line_tok.type == :identifier || (allow_keywords && Token::KEYWORDS.value?(line_tok.type))
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
- module_name: path_tokens.map(&:lexeme).join('.'),
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
- def previous_non_trivia_token(tokens, index)
1593
- prev_index = previous_non_trivia_token_index(tokens, index)
1594
- return nil unless prev_index
1658
+ tokens[prev_index]
1659
+ end
1595
1660
 
1596
- tokens[prev_index]
1597
- end
1661
+ def first_non_trivia_token_on_line?(tokens, index)
1662
+ token = tokens[index]
1663
+ return false unless token
1598
1664
 
1599
- def first_non_trivia_token_on_line?(tokens, index)
1600
- token = tokens[index]
1601
- return false unless token
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
- i = index - 1
1604
- while i >= 0
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
- i -= 1
1674
+ true
1610
1675
  end
1611
1676
 
1612
- true
1613
- end
1614
-
1615
- def previous_non_trivia_token_index(tokens, index)
1616
- i = index - 1
1617
- while i >= 0
1618
- tok = tokens[i]
1619
- return i unless [:newline, :indent, :dedent].include?(tok.type)
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
- def next_non_trivia_token_index(tokens, index)
1626
- i = index
1627
- while i < tokens.length
1628
- tok = tokens[i]
1629
- return i unless [:newline, :indent, :dedent].include?(tok.type)
1630
- i += 1
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
- def encode_semantic_tokens(entries)
1636
- data = []
1637
- prev_line = 0
1638
- prev_char = 0
1697
+ def encode_semantic_tokens(entries)
1698
+ data = []
1699
+ prev_line = 0
1700
+ prev_char = 0
1639
1701
 
1640
- entries.each do |entry|
1641
- delta_line = entry[:line] - prev_line
1642
- delta_start = delta_line.zero? ? entry[:start_char] - prev_char : entry[:start_char]
1643
- type_index = SEMANTIC_TOKEN_TYPES.index(entry[:type].to_s) || 0
1644
- modifiers_bitset = semantic_modifiers_bitset(entry[:modifiers])
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
- data << delta_line
1647
- data << delta_start
1648
- data << entry[:length]
1649
- data << type_index
1650
- data << modifiers_bitset
1708
+ data << delta_line
1709
+ data << delta_start
1710
+ data << entry[:length]
1711
+ data << type_index
1712
+ data << modifiers_bitset
1651
1713
 
1652
- prev_line = entry[:line]
1653
- prev_char = entry[:start_char]
1654
- end
1655
-
1656
- data
1657
- end
1714
+ prev_line = entry[:line]
1715
+ prev_char = entry[:start_char]
1716
+ end
1658
1717
 
1659
- def next_semantic_token_result_id(uri)
1660
- @semantic_token_result_counter ||= 0
1661
- @semantic_token_result_counter += 1
1662
- "#{uri}:#{@semantic_token_result_counter}"
1663
- end
1718
+ data
1719
+ end
1664
1720
 
1665
- def compute_semantic_tokens_edits(old_entries, new_entries)
1666
- return [] if old_entries == new_entries
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
- prefix = find_semantic_token_common_prefix(old_entries, new_entries)
1669
- suffix = find_semantic_token_common_suffix(old_entries, new_entries, prefix)
1727
+ def compute_semantic_tokens_edits(old_entries, new_entries)
1728
+ return [] if old_entries == new_entries
1670
1729
 
1671
- old_mid = old_entries.length - prefix - suffix
1672
- new_mid = new_entries.length - prefix - suffix
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
- if old_mid.zero? && new_mid.zero?
1675
- return []
1676
- end
1733
+ old_mid = old_entries.length - prefix - suffix
1734
+ new_mid = new_entries.length - prefix - suffix
1677
1735
 
1678
- start_offset = prefix * 5
1679
- delete_count = old_mid * 5
1680
- insert_tokens = encode_semantic_tokens(new_entries[prefix...(new_entries.length - suffix)])
1736
+ if old_mid.zero? && new_mid.zero?
1737
+ return []
1738
+ end
1681
1739
 
1682
- [{ start: start_offset, deleteCount: delete_count, data: insert_tokens }]
1683
- end
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
- def find_semantic_token_common_prefix(old_entries, new_entries)
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
- def find_semantic_token_common_suffix(old_entries, new_entries, prefix)
1695
- old_limit = old_entries.length - prefix
1696
- new_limit = new_entries.length - prefix
1697
- limit = [old_limit, new_limit].min
1698
- suffix = 0
1699
- while suffix < limit &&
1700
- semantic_token_entry_equal?(old_entries[old_entries.length - 1 - suffix],
1701
- new_entries[new_entries.length - 1 - suffix])
1702
- suffix += 1
1703
- end
1704
- suffix
1705
- end
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
- def semantic_token_entry_equal?(a, b)
1708
- a[:line] == b[:line] &&
1709
- a[:start_char] == b[:start_char] &&
1710
- a[:length] == b[:length] &&
1711
- a[:type] == b[:type] &&
1712
- a[:modifiers] == b[:modifiers]
1713
- end
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
- def semantic_modifiers_bitset(modifiers)
1716
- bits = 0
1717
- Array(modifiers).each do |modifier|
1718
- idx = SEMANTIC_TOKEN_MODIFIERS.index(modifier.to_s)
1719
- next unless idx
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
- bits |= (1 << idx)
1783
+ bits |= (1 << idx)
1784
+ end
1785
+ bits
1722
1786
  end
1723
- bits
1724
- end
1725
1787
 
1726
- def generic_function_binding_for_line(facts, line)
1727
- generic_function_bindings(facts).filter_map do |binding|
1728
- next unless binding.ast.respond_to?(:body) && binding.ast.respond_to?(:line)
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
- start_line = binding.ast.line
1731
- end_line = generic_statement_list_end_line(Array(binding.ast.body), start_line)
1732
- next unless start_line <= line && line <= end_line
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
- [end_line - start_line, -start_line, binding]
1735
- end.min_by { |span, start_line, _binding| [span, start_line] }&.last
1736
- end
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
- def generic_function_bindings(facts)
1739
- facts.functions.each_value.select { |binding| binding.type_params.any? } +
1740
- facts.methods.each_value.flat_map(&:values).select { |binding| binding.type_params.any? }
1741
- end
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