mt-lang 0.3.39 → 0.3.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/milk_tea/base.rb +1 -1
- data/lib/milk_tea/core/ast.rb +2 -2
- data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -6
- data/lib/milk_tea/core/bindings/module_binding.rb +1 -1
- data/lib/milk_tea/core/intrinsics.rb +23 -1
- data/lib/milk_tea/core/lowering/functions.rb +3 -0
- data/lib/milk_tea/core/lowering/resolve.rb +4 -65
- data/lib/milk_tea/core/lowering/utils.rb +0 -17
- data/lib/milk_tea/core/lowering.rb +1 -2
- data/lib/milk_tea/core/module_binder.rb +4 -15
- data/lib/milk_tea/core/module_loader.rb +41 -8
- data/lib/milk_tea/core/parser/declarations.rb +24 -17
- data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +2 -111
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -2
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +26 -17
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +26 -42
- data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -59
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +0 -2
- data/lib/milk_tea/core/types/predicates.rb +57 -0
- data/lib/milk_tea/core/types/registry.rb +14 -2
- data/lib/milk_tea/core/types.rb +0 -4
- data/lib/milk_tea/lsp/server/code_actions.rb +13 -7
- data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +56 -12
- data/lib/milk_tea/lsp/server/text_documents.rb +18 -2
- data/lib/milk_tea/lsp/workspace/caches.rb +28 -1
- data/lib/milk_tea/lsp/workspace/dependency_graph.rb +31 -0
- data/lib/milk_tea/lsp/workspace/store.rb +7 -1
- data/lib/milk_tea/lsp/workspace.rb +6 -0
- data/lib/milk_tea/tooling/formatter.rb +2 -3
- data/lib/milk_tea/tooling/linter/fix_engine.rb +46 -0
- data/lib/milk_tea/tooling/linter/rules.rb +32 -0
- data/lib/milk_tea/tooling/linter.rb +4 -0
- data/lib/milk_tea/tooling.rb +0 -1
- metadata +2 -3
- data/lib/milk_tea/tooling/cst_formatter.rb +0 -13
|
@@ -129,53 +129,23 @@ module MilkTea
|
|
|
129
129
|
def validate_async_statement!(statement)
|
|
130
130
|
case statement
|
|
131
131
|
when AST::ErrorBlockStmt
|
|
132
|
-
if statement.header_expression
|
|
133
|
-
context = case statement.header_type
|
|
134
|
-
when :if then "if conditions"
|
|
135
|
-
when :while then "while conditions"
|
|
136
|
-
end
|
|
137
|
-
validate_async_expression_support!(statement.header_expression, context:) if context
|
|
138
|
-
end
|
|
139
|
-
if statement.header_type == :for
|
|
140
|
-
Array(statement.header_iterables).each do |iterable|
|
|
141
|
-
validate_async_expression_support!(iterable, context: "for iterables")
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
132
|
statement.body.each { |s| validate_async_statement!(s) }
|
|
145
133
|
when AST::ErrorStmt
|
|
146
134
|
nil
|
|
147
135
|
when AST::LocalDecl
|
|
148
|
-
validate_async_expression_support!(statement.value, context: "local initializer") if statement.value
|
|
149
136
|
statement.else_body&.each { |s| validate_async_statement!(s) }
|
|
150
|
-
when AST::Assignment
|
|
151
|
-
|
|
152
|
-
validate_async_expression_support!(statement.value, context: "assignment")
|
|
153
|
-
when AST::ExpressionStmt
|
|
154
|
-
validate_async_expression_support!(statement.expression, context: "expression statement")
|
|
155
|
-
when AST::ReturnStmt
|
|
156
|
-
return unless statement.value
|
|
157
|
-
|
|
158
|
-
validate_async_expression_support!(statement.value, context: "return statement")
|
|
137
|
+
when AST::Assignment, AST::ExpressionStmt, AST::ReturnStmt
|
|
138
|
+
nil
|
|
159
139
|
when AST::IfStmt
|
|
160
140
|
statement.branches.each do |branch|
|
|
161
|
-
validate_async_expression_support!(branch.condition, context: "if conditions")
|
|
162
|
-
|
|
163
141
|
branch.body.each { |s| validate_async_statement!(s) }
|
|
164
142
|
end
|
|
165
143
|
statement.else_body&.each { |s| validate_async_statement!(s) }
|
|
166
144
|
when AST::WhileStmt
|
|
167
|
-
validate_async_expression_support!(statement.condition, context: "while conditions")
|
|
168
|
-
|
|
169
145
|
statement.body.each { |s| validate_async_statement!(s) }
|
|
170
146
|
when AST::ForStmt
|
|
171
|
-
statement.iterables.each do |iterable|
|
|
172
|
-
validate_async_expression_support!(iterable, context: "for iterables")
|
|
173
|
-
end
|
|
174
|
-
|
|
175
147
|
statement.body.each { |s| validate_async_statement!(s) }
|
|
176
148
|
when AST::MatchStmt
|
|
177
|
-
validate_async_expression_support!(statement.expression, context: "match discriminants")
|
|
178
|
-
|
|
179
149
|
statement.arms.each { |arm| arm.body.each { |s| validate_async_statement!(s) } }
|
|
180
150
|
when AST::UnsafeStmt
|
|
181
151
|
statement.body.each { |s| validate_async_statement!(s) }
|
|
@@ -191,85 +161,6 @@ module MilkTea
|
|
|
191
161
|
end
|
|
192
162
|
end
|
|
193
163
|
|
|
194
|
-
def validate_async_expression_support!(expression, context:)
|
|
195
|
-
unsupported_context = unsupported_await_position(expression)
|
|
196
|
-
return unless unsupported_context
|
|
197
|
-
|
|
198
|
-
raise_sema_error("await in async functions is not supported inside #{unsupported_context} yet")
|
|
199
|
-
end
|
|
200
|
-
|
|
201
|
-
def unsupported_await_position(expression)
|
|
202
|
-
nil
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
def statement_contains_await?(statement)
|
|
206
|
-
case statement
|
|
207
|
-
when AST::ErrorBlockStmt
|
|
208
|
-
(statement.header_expression && expression_contains_await?(statement.header_expression)) ||
|
|
209
|
-
Array(statement.header_iterables).any? { |iterable| expression_contains_await?(iterable) } ||
|
|
210
|
-
statements_contain_await?(statement.body)
|
|
211
|
-
when AST::LocalDecl
|
|
212
|
-
(statement.value && expression_contains_await?(statement.value)) ||
|
|
213
|
-
(statement.else_body && statements_contain_await?(statement.else_body))
|
|
214
|
-
when AST::Assignment
|
|
215
|
-
expression_contains_await?(statement.target) || expression_contains_await?(statement.value)
|
|
216
|
-
when AST::IfStmt
|
|
217
|
-
statement.branches.any? { |branch| expression_contains_await?(branch.condition) || statements_contain_await?(branch.body) } ||
|
|
218
|
-
(statement.else_body && statements_contain_await?(statement.else_body))
|
|
219
|
-
when AST::MatchStmt
|
|
220
|
-
expression_contains_await?(statement.expression) || statement.arms.any? { |arm| expression_contains_await?(arm.pattern) || statements_contain_await?(arm.body) }
|
|
221
|
-
when AST::UnsafeStmt
|
|
222
|
-
statements_contain_await?(statement.body)
|
|
223
|
-
when AST::StaticAssert
|
|
224
|
-
expression_contains_await?(statement.condition) || expression_contains_await?(statement.message)
|
|
225
|
-
when AST::ForStmt
|
|
226
|
-
statement.iterables.any? { |iterable| expression_contains_await?(iterable) } || statements_contain_await?(statement.body)
|
|
227
|
-
when AST::WhileStmt
|
|
228
|
-
expression_contains_await?(statement.condition) || statements_contain_await?(statement.body)
|
|
229
|
-
when AST::ReturnStmt
|
|
230
|
-
statement.value && expression_contains_await?(statement.value)
|
|
231
|
-
when AST::DeferStmt
|
|
232
|
-
statements_contain_await?(statement.body)
|
|
233
|
-
when AST::ExpressionStmt
|
|
234
|
-
expression_contains_await?(statement.expression)
|
|
235
|
-
else
|
|
236
|
-
false
|
|
237
|
-
end
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
def statements_contain_await?(statements)
|
|
241
|
-
statements.any? { |statement| statement_contains_await?(statement) }
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def expression_contains_await?(expression)
|
|
245
|
-
case expression
|
|
246
|
-
when AST::AwaitExpr
|
|
247
|
-
true
|
|
248
|
-
when AST::Call, AST::Specialization
|
|
249
|
-
expression_contains_await?(expression.callee) || expression.arguments.any? { |argument| expression_contains_await?(argument.value) }
|
|
250
|
-
when AST::UnaryOp
|
|
251
|
-
expression_contains_await?(expression.operand)
|
|
252
|
-
when AST::BinaryOp
|
|
253
|
-
expression_contains_await?(expression.left) || expression_contains_await?(expression.right)
|
|
254
|
-
when AST::IfExpr
|
|
255
|
-
expression_contains_await?(expression.condition) || expression_contains_await?(expression.then_expression) || expression_contains_await?(expression.else_expression)
|
|
256
|
-
when AST::MatchExpr
|
|
257
|
-
expression_contains_await?(expression.expression) || expression.arms.any? { |arm| expression_contains_await?(arm.pattern) || expression_contains_await?(arm.value) }
|
|
258
|
-
when AST::UnsafeExpr
|
|
259
|
-
expression_contains_await?(expression.expression)
|
|
260
|
-
when AST::PrefixCast
|
|
261
|
-
expression_contains_await?(expression.expression)
|
|
262
|
-
when AST::MemberAccess
|
|
263
|
-
expression_contains_await?(expression.receiver)
|
|
264
|
-
when AST::IndexAccess
|
|
265
|
-
expression_contains_await?(expression.receiver) || expression_contains_await?(expression.index)
|
|
266
|
-
when AST::FormatString
|
|
267
|
-
expression.parts.any? { |part| part.is_a?(AST::FormatExprPart) && expression_contains_await?(part.expression) }
|
|
268
|
-
else
|
|
269
|
-
false
|
|
270
|
-
end
|
|
271
|
-
end
|
|
272
|
-
|
|
273
164
|
def suggest_name(wrong, candidates, max_distance: 2)
|
|
274
165
|
return nil if wrong.nil? || wrong.to_s.empty? || candidates.nil? || candidates.empty?
|
|
275
166
|
|
|
@@ -1309,7 +1309,7 @@ module MilkTea
|
|
|
1309
1309
|
return [:has_attribute, nil, nil] if callee.name == "has_attribute"
|
|
1310
1310
|
return [:get, nil, nil] if callee.name == "get"
|
|
1311
1311
|
|
|
1312
|
-
type =
|
|
1312
|
+
type = lookup_named_type(callee.name)
|
|
1313
1313
|
return [:struct, type, nil] if type.is_a?(Types::Struct) || type.is_a?(Types::StringView) || task_type?(type) || type.is_a?(Types::Vector) || type.is_a?(Types::Matrix) || type.is_a?(Types::Quaternion)
|
|
1314
1314
|
if type.is_a?(Types::GenericStructDefinition) || type.is_a?(Types::GenericVariantDefinition)
|
|
1315
1315
|
raise_sema_error("generic type #{callee.name} requires type arguments")
|
|
@@ -1396,7 +1396,6 @@ module MilkTea
|
|
|
1396
1396
|
return [:array_as_span, field_receiver_type, callee.receiver]
|
|
1397
1397
|
end
|
|
1398
1398
|
|
|
1399
|
-
return [:callable_value, field_receiver_type.field(callee.member), nil] if aggregate_type?(field_receiver_type) && callable_type?(field_receiver_type.field(callee.member))
|
|
1400
1399
|
return [:callable_value, field_receiver_type.field(callee.member), nil] if aggregate_type?(field_receiver_type) && callable_type?(field_receiver_type.field(callee.member))
|
|
1401
1400
|
|
|
1402
1401
|
if (imported_module = imported_module_with_private_method(method_receiver_type, callee.member))
|
|
@@ -22,25 +22,31 @@ module MilkTea
|
|
|
22
22
|
when AST::ExtendingBlock
|
|
23
23
|
dispatch_receiver_type, receiver_type, receiver_type_param_names, receiver_type_param_constraints = resolve_methods_receiver_target(decl.type_name)
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
previous_nested_types = @current_nested_types
|
|
26
|
+
@current_nested_types = method_receiver_nested_scope(receiver_type)
|
|
27
|
+
begin
|
|
28
|
+
decl.methods.each do |method|
|
|
29
|
+
begin
|
|
30
|
+
binding = with_error_node(method) do
|
|
31
|
+
declare_function_binding(
|
|
32
|
+
method,
|
|
33
|
+
receiver_type:,
|
|
34
|
+
declared_receiver_type: receiver_type,
|
|
35
|
+
receiver_type_param_names:,
|
|
36
|
+
receiver_type_param_constraints:,
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
instance_method = receiver_type && method.kind != :static
|
|
40
|
+
method_key = instance_method ? binding.name : "static:#{binding.name}"
|
|
41
|
+
raise_sema_error("duplicate method #{decl.type_name}.#{binding.name}") if @ctx.methods[dispatch_receiver_type].key?(method_key)
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
@ctx.methods[dispatch_receiver_type][method_key] = binding
|
|
44
|
+
rescue SemanticError => e
|
|
45
|
+
collect_structural_error(e)
|
|
46
|
+
end
|
|
43
47
|
end
|
|
48
|
+
ensure
|
|
49
|
+
@current_nested_types = previous_nested_types
|
|
44
50
|
end
|
|
45
51
|
end
|
|
46
52
|
end
|
|
@@ -604,6 +610,7 @@ module MilkTea
|
|
|
604
610
|
previous_type_substitutions = @current_type_substitutions
|
|
605
611
|
previous_specialization_owner = @current_specialization_owner
|
|
606
612
|
previous_value_type_params = @current_value_type_params
|
|
613
|
+
previous_nested_types = @current_nested_types
|
|
607
614
|
started_check = false
|
|
608
615
|
return if binding.external
|
|
609
616
|
return if @checked_function_bindings[binding.object_id]
|
|
@@ -614,6 +621,7 @@ module MilkTea
|
|
|
614
621
|
@current_type_substitutions = binding.type_substitutions
|
|
615
622
|
@current_specialization_owner = binding.specialization_owner
|
|
616
623
|
@current_value_type_params = resolve_value_type_params(binding.ast.type_params)
|
|
624
|
+
@current_nested_types = method_receiver_nested_scope(binding.declared_receiver_type)
|
|
617
625
|
with_error_node(binding.ast) do
|
|
618
626
|
with_scope(binding.body_params) do |scopes|
|
|
619
627
|
start_local_completion_frame(binding, scopes)
|
|
@@ -669,6 +677,7 @@ module MilkTea
|
|
|
669
677
|
@current_type_substitutions = previous_type_substitutions
|
|
670
678
|
@current_specialization_owner = previous_specialization_owner
|
|
671
679
|
@current_value_type_params = previous_value_type_params
|
|
680
|
+
@current_nested_types = previous_nested_types
|
|
672
681
|
@checking_function_bindings.delete(binding.object_id)
|
|
673
682
|
end
|
|
674
683
|
|
|
@@ -236,7 +236,7 @@ module MilkTea
|
|
|
236
236
|
end
|
|
237
237
|
end
|
|
238
238
|
|
|
239
|
-
def resolve_type_ref(type_ref, type_params: current_type_params, type_param_constraints: current_type_param_constraints, nested_types:
|
|
239
|
+
def resolve_type_ref(type_ref, type_params: current_type_params, type_param_constraints: current_type_param_constraints, nested_types: current_nested_types)
|
|
240
240
|
base = resolve_non_nullable_type(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
241
241
|
return base if type_ref.is_a?(AST::FunctionType) || type_ref.is_a?(AST::ProcType) || type_ref.is_a?(AST::TupleType)
|
|
242
242
|
|
|
@@ -247,11 +247,11 @@ module MilkTea
|
|
|
247
247
|
|
|
248
248
|
def resolve_non_nullable_type(type_ref, type_params: {}, type_param_constraints: {}, nested_types: nil)
|
|
249
249
|
if type_ref.is_a?(AST::FunctionType)
|
|
250
|
-
return resolve_function_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
250
|
+
return resolve_function_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
251
251
|
end
|
|
252
252
|
|
|
253
253
|
if type_ref.is_a?(AST::ProcType)
|
|
254
|
-
return resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
254
|
+
return resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
255
255
|
end
|
|
256
256
|
|
|
257
257
|
if type_ref.is_a?(AST::DynType)
|
|
@@ -259,13 +259,13 @@ module MilkTea
|
|
|
259
259
|
end
|
|
260
260
|
|
|
261
261
|
if type_ref.is_a?(AST::TupleType)
|
|
262
|
-
return resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
262
|
+
return resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
263
263
|
end
|
|
264
264
|
|
|
265
265
|
parts = type_ref.name.parts
|
|
266
266
|
|
|
267
267
|
if type_ref.arguments.any?
|
|
268
|
-
return resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:)
|
|
268
|
+
return resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:, nested_types:)
|
|
269
269
|
end
|
|
270
270
|
|
|
271
271
|
if parts.length == 1 && type_ref.lifetime
|
|
@@ -279,18 +279,18 @@ module MilkTea
|
|
|
279
279
|
resolve_multi_part_type_ref(type_ref, parts)
|
|
280
280
|
end
|
|
281
281
|
|
|
282
|
-
def resolve_function_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
282
|
+
def resolve_function_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
283
283
|
params = type_ref.params.map do |param|
|
|
284
|
-
Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:))
|
|
284
|
+
Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:, nested_types:))
|
|
285
285
|
end
|
|
286
|
-
Types::Registry.function(nil, params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:))
|
|
286
|
+
Types::Registry.function(nil, params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:, nested_types:))
|
|
287
287
|
end
|
|
288
288
|
|
|
289
|
-
def resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
289
|
+
def resolve_proc_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
290
290
|
params = type_ref.params.map do |param|
|
|
291
|
-
Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:))
|
|
291
|
+
Types::Registry.parameter(param.name, resolve_type_ref(param.type, type_params:, type_param_constraints:, nested_types:))
|
|
292
292
|
end
|
|
293
|
-
Types::Registry.proc(params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:))
|
|
293
|
+
Types::Registry.proc(params:, return_type: resolve_type_ref(type_ref.return_type, type_params:, type_param_constraints:, nested_types:))
|
|
294
294
|
end
|
|
295
295
|
|
|
296
296
|
def resolve_dyn_type_ref(type_ref)
|
|
@@ -302,25 +302,25 @@ module MilkTea
|
|
|
302
302
|
type
|
|
303
303
|
end
|
|
304
304
|
|
|
305
|
-
def resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
305
|
+
def resolve_tuple_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
306
306
|
names = []
|
|
307
307
|
element_types = []
|
|
308
308
|
type_ref.element_types.each do |et|
|
|
309
309
|
if et.is_a?(AST::Argument)
|
|
310
310
|
names << et.name
|
|
311
|
-
element_types << resolve_type_ref(et.value, type_params:, type_param_constraints:)
|
|
311
|
+
element_types << resolve_type_ref(et.value, type_params:, type_param_constraints:, nested_types:)
|
|
312
312
|
else
|
|
313
313
|
names << nil
|
|
314
|
-
element_types << resolve_type_ref(et, type_params:, type_param_constraints:)
|
|
314
|
+
element_types << resolve_type_ref(et, type_params:, type_param_constraints:, nested_types:)
|
|
315
315
|
end
|
|
316
316
|
end
|
|
317
317
|
has_named = names.any?
|
|
318
318
|
Types::Registry.tuple(element_types, field_names: has_named ? names : nil)
|
|
319
319
|
end
|
|
320
320
|
|
|
321
|
-
def resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:)
|
|
321
|
+
def resolve_generic_instance_type_ref(type_ref, parts, type_params:, type_param_constraints:, nested_types:)
|
|
322
322
|
name = parts.join(".")
|
|
323
|
-
arguments = type_ref.arguments.map { |argument| resolve_type_argument(argument.value, type_params:, type_param_constraints:) }
|
|
323
|
+
arguments = type_ref.arguments.map { |argument| resolve_type_argument(argument.value, type_params:, type_param_constraints:, nested_types:) }
|
|
324
324
|
|
|
325
325
|
if name != "ref" && arguments.any? { |argument| contains_ref_type?(argument) && !stored_ref_supported_type?(argument) }
|
|
326
326
|
raise_sema_error("ref types cannot be nested inside #{name}", type_ref)
|
|
@@ -434,12 +434,12 @@ module MilkTea
|
|
|
434
434
|
value.is_a?(Types::Base) ? value : nil
|
|
435
435
|
end
|
|
436
436
|
|
|
437
|
-
def resolve_type_argument(argument, type_params: current_type_params, type_param_constraints: current_type_param_constraints)
|
|
437
|
+
def resolve_type_argument(argument, type_params: current_type_params, type_param_constraints: current_type_param_constraints, nested_types: current_nested_types)
|
|
438
438
|
case argument
|
|
439
439
|
when AST::TypeRef
|
|
440
|
-
resolve_type_argument_ref(argument, type_params:, type_param_constraints:)
|
|
440
|
+
resolve_type_argument_ref(argument, type_params:, type_param_constraints:, nested_types:)
|
|
441
441
|
when AST::FunctionType, AST::ProcType, AST::TupleType
|
|
442
|
-
resolve_type_ref(argument, type_params:, type_param_constraints:)
|
|
442
|
+
resolve_type_ref(argument, type_params:, type_param_constraints:, nested_types:)
|
|
443
443
|
when AST::IntegerLiteral, AST::FloatLiteral
|
|
444
444
|
Types::LiteralTypeArg.new(argument.value)
|
|
445
445
|
else
|
|
@@ -447,20 +447,20 @@ module MilkTea
|
|
|
447
447
|
end
|
|
448
448
|
end
|
|
449
449
|
|
|
450
|
-
def resolve_type_argument_ref(type_ref, type_params:, type_param_constraints:)
|
|
451
|
-
return resolve_type_ref(type_ref, type_params:, type_param_constraints:) unless literal_type_argument_name_candidate?(type_ref)
|
|
450
|
+
def resolve_type_argument_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
451
|
+
return resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:) unless literal_type_argument_name_candidate?(type_ref)
|
|
452
452
|
|
|
453
|
-
result = try_resolve_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
453
|
+
result = try_resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
454
454
|
return result if result
|
|
455
455
|
|
|
456
456
|
literal_type_argument = resolve_named_literal_type_argument(type_ref)
|
|
457
457
|
return literal_type_argument if literal_type_argument
|
|
458
458
|
|
|
459
|
-
resolve_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
459
|
+
resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
460
460
|
end
|
|
461
461
|
|
|
462
|
-
def try_resolve_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
463
|
-
resolve_type_ref(type_ref, type_params:, type_param_constraints:)
|
|
462
|
+
def try_resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
463
|
+
resolve_type_ref(type_ref, type_params:, type_param_constraints:, nested_types:)
|
|
464
464
|
rescue SemanticError
|
|
465
465
|
nil
|
|
466
466
|
end
|
|
@@ -867,10 +867,6 @@ module MilkTea
|
|
|
867
867
|
Types.pointer_to(type)
|
|
868
868
|
end
|
|
869
869
|
|
|
870
|
-
def contains_type_var?(type)
|
|
871
|
-
super
|
|
872
|
-
end
|
|
873
|
-
|
|
874
870
|
def resolve_nested_type_ref(parts)
|
|
875
871
|
current = @ctx.types[parts.first]
|
|
876
872
|
return nil unless current.is_a?(Types::Struct) || current.is_a?(Types::GenericStructDefinition)
|
|
@@ -975,18 +971,6 @@ module MilkTea
|
|
|
975
971
|
nil
|
|
976
972
|
end
|
|
977
973
|
|
|
978
|
-
def collection_loop_type(type)
|
|
979
|
-
super
|
|
980
|
-
end
|
|
981
|
-
|
|
982
|
-
def collection_loop_binding_type(iterable_type, element_type)
|
|
983
|
-
super
|
|
984
|
-
end
|
|
985
|
-
|
|
986
|
-
def collection_loop_ref_element_type?(type)
|
|
987
|
-
super
|
|
988
|
-
end
|
|
989
|
-
|
|
990
974
|
def iterator_loop_type(type)
|
|
991
975
|
type = referenced_type(type) if ref_type?(type)
|
|
992
976
|
iter_method = lookup_method(type, "iter")
|
|
@@ -1091,7 +1075,7 @@ module MilkTea
|
|
|
1091
1075
|
when AST::Identifier
|
|
1092
1076
|
return current_type_params[expression.name] if current_type_params.key?(expression.name)
|
|
1093
1077
|
|
|
1094
|
-
|
|
1078
|
+
lookup_named_type(expression.name)
|
|
1095
1079
|
when AST::MemberAccess
|
|
1096
1080
|
return nil unless expression.receiver.is_a?(AST::Identifier)
|
|
1097
1081
|
|
|
@@ -164,65 +164,6 @@ module MilkTea
|
|
|
164
164
|
backing_type.integer_width == expected_type.integer_width
|
|
165
165
|
end
|
|
166
166
|
|
|
167
|
-
def common_numeric_type(left_type, right_type)
|
|
168
|
-
left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
|
|
169
|
-
right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
|
|
170
|
-
return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
|
|
171
|
-
return unless left_type.numeric? && right_type.numeric?
|
|
172
|
-
return left_type if left_type == right_type
|
|
173
|
-
|
|
174
|
-
return common_integer_type(left_type, right_type) if left_type.integer? && right_type.integer?
|
|
175
|
-
return wider_float_type(left_type, right_type) if left_type.float? && right_type.float?
|
|
176
|
-
|
|
177
|
-
float_type, integer_type = left_type.float? ? [left_type, right_type] : [right_type, left_type]
|
|
178
|
-
return unless integer_type.integer? && integer_type.fixed_width_integer?
|
|
179
|
-
|
|
180
|
-
float_type
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
def common_integer_type(left_type, right_type)
|
|
184
|
-
left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
|
|
185
|
-
right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
|
|
186
|
-
return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
|
|
187
|
-
return unless left_type.integer? && right_type.integer?
|
|
188
|
-
return left_type if left_type == right_type
|
|
189
|
-
return unless left_type.fixed_width_integer? && right_type.fixed_width_integer?
|
|
190
|
-
|
|
191
|
-
# Same signedness: the wider type wins (both operands are losslessly
|
|
192
|
-
# assignable to it).
|
|
193
|
-
if left_type.signed_integer? == right_type.signed_integer?
|
|
194
|
-
return left_type.integer_width >= right_type.integer_width ? left_type : right_type
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
# Mixed signed/unsigned: promote to the narrowest signed type that holds
|
|
198
|
-
# both operands' full ranges, mirroring the lossless assignment rule. A
|
|
199
|
-
# strictly-wider signed type covers an unsigned operand; equal-width or
|
|
200
|
-
# wider unsigned operands widen to the next signed width. Mixing with a
|
|
201
|
-
# 64-bit unsigned type has no safe signed common type, so callers fall
|
|
202
|
-
# back to requiring an explicit cast.
|
|
203
|
-
signed_type, unsigned_type = if left_type.signed_integer?
|
|
204
|
-
[left_type, right_type]
|
|
205
|
-
else
|
|
206
|
-
[right_type, left_type]
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
return signed_type if signed_type.integer_width > unsigned_type.integer_width
|
|
210
|
-
|
|
211
|
-
signed_type_above_width(unsigned_type.integer_width)
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def signed_type_above_width(width)
|
|
215
|
-
case width
|
|
216
|
-
when 8 then @ctx.types.fetch("short")
|
|
217
|
-
when 16 then @ctx.types.fetch("int")
|
|
218
|
-
when 32 then @ctx.types.fetch("long")
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
def wider_float_type(left_type, right_type)
|
|
223
|
-
left_type.float_width >= right_type.float_width ? left_type : right_type
|
|
224
|
-
end
|
|
225
|
-
|
|
226
167
|
def pointer_arithmetic_result(operator, left_type, right_type)
|
|
227
168
|
if pointer_type?(left_type) && integer_type?(right_type)
|
|
228
169
|
require_unsafe!("pointer arithmetic requires unsafe") unless own_type?(left_type)
|
|
@@ -186,7 +186,6 @@ module MilkTea
|
|
|
186
186
|
implemented_interfaces: {}, imports: {},
|
|
187
187
|
private_types: {}, private_interfaces: {}, private_attributes: {},
|
|
188
188
|
private_values: {}, private_functions: {}, private_methods: {},
|
|
189
|
-
private_implemented_interfaces: {},
|
|
190
189
|
)
|
|
191
190
|
end
|
|
192
191
|
|
|
@@ -342,7 +341,6 @@ module MilkTea
|
|
|
342
341
|
params: params.freeze,
|
|
343
342
|
module_name: @ctx.module_name,
|
|
344
343
|
builtin: false,
|
|
345
|
-
ast: decl,
|
|
346
344
|
)
|
|
347
345
|
end
|
|
348
346
|
end
|
|
@@ -650,6 +650,63 @@ module MilkTea
|
|
|
650
650
|
def array_element_type(type)
|
|
651
651
|
type.arguments.first
|
|
652
652
|
end
|
|
653
|
+
|
|
654
|
+
def common_numeric_type(left_type, right_type)
|
|
655
|
+
left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
|
|
656
|
+
right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
|
|
657
|
+
return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
|
|
658
|
+
return unless left_type.numeric? && right_type.numeric?
|
|
659
|
+
return left_type if left_type == right_type
|
|
660
|
+
|
|
661
|
+
return common_integer_type(left_type, right_type) if left_type.integer? && right_type.integer?
|
|
662
|
+
return wider_float_type(left_type, right_type) if left_type.float? && right_type.float?
|
|
663
|
+
|
|
664
|
+
float_type, integer_type = left_type.float? ? [left_type, right_type] : [right_type, left_type]
|
|
665
|
+
return unless integer_type.integer? && integer_type.fixed_width_integer?
|
|
666
|
+
|
|
667
|
+
float_type
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
def common_integer_type(left_type, right_type)
|
|
671
|
+
left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
|
|
672
|
+
right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
|
|
673
|
+
return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
|
|
674
|
+
return unless left_type.integer? && right_type.integer?
|
|
675
|
+
return left_type if left_type == right_type
|
|
676
|
+
return unless left_type.fixed_width_integer? && right_type.fixed_width_integer?
|
|
677
|
+
|
|
678
|
+
# Same signedness: the wider type wins. Mixed signed/unsigned: promote to
|
|
679
|
+
# the narrowest signed type that holds both operands' full ranges. A
|
|
680
|
+
# strictly-wider signed type covers an unsigned operand; equal-width or
|
|
681
|
+
# wider unsigned operands widen to the next signed width. Mixing with a
|
|
682
|
+
# 64-bit unsigned type has no safe signed common type, so callers fall
|
|
683
|
+
# back to requiring an explicit cast.
|
|
684
|
+
if left_type.signed_integer? == right_type.signed_integer?
|
|
685
|
+
return left_type.integer_width >= right_type.integer_width ? left_type : right_type
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
signed_type, unsigned_type = if left_type.signed_integer?
|
|
689
|
+
[left_type, right_type]
|
|
690
|
+
else
|
|
691
|
+
[right_type, left_type]
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
return signed_type if signed_type.integer_width > unsigned_type.integer_width
|
|
695
|
+
|
|
696
|
+
signed_type_above_width(unsigned_type.integer_width)
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
def signed_type_above_width(width)
|
|
700
|
+
case width
|
|
701
|
+
when 8 then Types::Registry.primitive("short")
|
|
702
|
+
when 16 then Types::Registry.primitive("int")
|
|
703
|
+
when 32 then Types::Registry.primitive("long")
|
|
704
|
+
end
|
|
705
|
+
end
|
|
706
|
+
|
|
707
|
+
def wider_float_type(left_type, right_type)
|
|
708
|
+
left_type.float_width >= right_type.float_width ? left_type : right_type
|
|
709
|
+
end
|
|
653
710
|
end
|
|
654
711
|
end
|
|
655
712
|
end
|
|
@@ -41,16 +41,28 @@ module MilkTea
|
|
|
41
41
|
_intern([:string_view]) { StringView.new }
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
# Param signature for intern keys. Parameter#eql? is name-insensitive
|
|
45
|
+
# (assignability must not depend on parameter names), so arrays of
|
|
46
|
+
# Parameter objects would conflate fn(value: int) with fn(arg0: int) in
|
|
47
|
+
# the intern pool. Embedding names here keeps distinct signatures
|
|
48
|
+
# distinct across independent programs sharing a long-lived pool (the LSP
|
|
49
|
+
# never resets the registry between checks).
|
|
50
|
+
def self.param_signature(params)
|
|
51
|
+
params.map { |p| [p.name, p.type, p.mutable, p.passing_mode, p.boundary_type] }
|
|
52
|
+
end
|
|
53
|
+
|
|
44
54
|
def self.function(name, params:, return_type:, receiver_type: nil, receiver_editable: false, variadic: false, external: false)
|
|
45
55
|
params_frozen = params.freeze
|
|
46
|
-
|
|
56
|
+
param_key = param_signature(params_frozen)
|
|
57
|
+
_intern([:function, name, param_key, return_type, receiver_type, receiver_editable, variadic, external]) {
|
|
47
58
|
Function.new(name, params: params_frozen, return_type: return_type, receiver_type: receiver_type, receiver_editable: receiver_editable, variadic: variadic, external: external)
|
|
48
59
|
}
|
|
49
60
|
end
|
|
50
61
|
|
|
51
62
|
def self.proc(params:, return_type:)
|
|
52
63
|
params_frozen = params.freeze
|
|
53
|
-
|
|
64
|
+
param_key = param_signature(params_frozen)
|
|
65
|
+
_intern([:proc, param_key, return_type]) { Proc.new(params: params_frozen, return_type: return_type) }
|
|
54
66
|
end
|
|
55
67
|
|
|
56
68
|
def self.parameter(name, type, mutable: false, passing_mode: :plain, boundary_type: nil)
|
data/lib/milk_tea/core/types.rb
CHANGED
|
@@ -1712,10 +1712,6 @@ module MilkTea
|
|
|
1712
1712
|
GenericInstance.new("ptr", [type])
|
|
1713
1713
|
end
|
|
1714
1714
|
|
|
1715
|
-
def self.integer_type?(type)
|
|
1716
|
-
type.is_a?(Primitive) && %w[int ptr_uint i8 i16 i32 i64 u8 u16 u32 u64].include?(type.name)
|
|
1717
|
-
end
|
|
1718
|
-
|
|
1719
1715
|
def self.array_type?(type)
|
|
1720
1716
|
type.is_a?(GenericInstance) && type.name == "array" && type.arguments.length == 2
|
|
1721
1717
|
end
|
|
@@ -360,6 +360,8 @@ module MilkTea
|
|
|
360
360
|
end
|
|
361
361
|
|
|
362
362
|
def handle_document_diagnostic(params)
|
|
363
|
+
return { kind: 'full', items: [] } if request_cancelled?(@current_request_id)
|
|
364
|
+
|
|
363
365
|
uri = params.dig('textDocument', 'uri')
|
|
364
366
|
return { kind: 'full', items: [] } unless uri
|
|
365
367
|
|
|
@@ -404,6 +406,8 @@ module MilkTea
|
|
|
404
406
|
end
|
|
405
407
|
|
|
406
408
|
def handle_workspace_diagnostic(params)
|
|
409
|
+
return { items: [] } if request_cancelled?(@current_request_id)
|
|
410
|
+
|
|
407
411
|
progress = nil
|
|
408
412
|
if (work_done_token = params['workDoneToken'])
|
|
409
413
|
progress = create_progress_handle(@protocol, work_done_token)
|
|
@@ -416,7 +420,13 @@ module MilkTea
|
|
|
416
420
|
end
|
|
417
421
|
|
|
418
422
|
all_uris = @workspace.open_document_uris
|
|
419
|
-
items =
|
|
423
|
+
items = []
|
|
424
|
+
all_uris.each do |uri|
|
|
425
|
+
# Coarse cancellation: workspace/diagnostic can iterate many cold
|
|
426
|
+
# documents (~1s each); bail early when the client cancels so we do
|
|
427
|
+
# not sink CPU into results that will be discarded.
|
|
428
|
+
break if request_cancelled?(@current_request_id)
|
|
429
|
+
|
|
420
430
|
content = @workspace.get_content(uri)
|
|
421
431
|
next if content.empty?
|
|
422
432
|
|
|
@@ -426,10 +436,10 @@ module MilkTea
|
|
|
426
436
|
|
|
427
437
|
cached = @workspace_diagnostic_cache[uri]
|
|
428
438
|
if cached && cached[:result_id] == prev_map[uri] && cached[:fingerprint] == fingerprint
|
|
429
|
-
{ uri: uri, kind: 'unchanged', resultId: result_id, items: [], version: nil }
|
|
439
|
+
items << { uri: uri, kind: 'unchanged', resultId: result_id, items: [], version: nil }
|
|
430
440
|
else
|
|
431
441
|
@workspace_diagnostic_cache[uri] = { result_id: result_id, fingerprint: fingerprint }
|
|
432
|
-
{ uri: uri, kind: 'full', resultId: result_id, items: diagnostics, version: nil }
|
|
442
|
+
items << { uri: uri, kind: 'full', resultId: result_id, items: diagnostics, version: nil }
|
|
433
443
|
end
|
|
434
444
|
end
|
|
435
445
|
|
|
@@ -443,10 +453,6 @@ module MilkTea
|
|
|
443
453
|
{ items: [] }
|
|
444
454
|
end
|
|
445
455
|
|
|
446
|
-
def refresh_workspace_diagnostics
|
|
447
|
-
@protocol.write_notification('workspace/diagnostic/refresh', nil)
|
|
448
|
-
end
|
|
449
|
-
|
|
450
456
|
def find_match_end_line(lines, match_start_idx)
|
|
451
457
|
return nil if match_start_idx >= lines.length
|
|
452
458
|
|