mt-lang 0.3.8 → 0.3.10

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