mt-lang 0.3.38 → 0.3.40
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/docs/lsp-performance.md +347 -0
- 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 +0 -2
- 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.rb +0 -4
- data/lib/milk_tea/lsp/diagnostics.rb +15 -5
- data/lib/milk_tea/lsp/server/code_actions.rb +0 -4
- data/lib/milk_tea/lsp/server/completion.rb +100 -77
- data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +4 -6
- data/lib/milk_tea/lsp/server/formatting.rb +13 -3
- data/lib/milk_tea/lsp/server/hover.rb +321 -41
- data/lib/milk_tea/lsp/server/lifecycle.rb +12 -0
- data/lib/milk_tea/lsp/server/references.rb +3 -1
- data/lib/milk_tea/lsp/server/semantic_tokens.rb +55 -16
- data/lib/milk_tea/lsp/server/text_documents.rb +2 -2
- data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -2
- data/lib/milk_tea/lsp/server/utilities.rb +4 -0
- data/lib/milk_tea/lsp/server.rb +9 -0
- data/lib/milk_tea/lsp/workspace/analysis.rb +14 -3
- data/lib/milk_tea/lsp/workspace/caches.rb +17 -1
- data/lib/milk_tea/lsp/workspace/collection.rb +4 -0
- data/lib/milk_tea/lsp/workspace/module_index.rb +134 -0
- data/lib/milk_tea/lsp/workspace/store.rb +9 -4
- data/lib/milk_tea/lsp/workspace.rb +8 -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 +4 -3
- data/lib/milk_tea/tooling/cst_formatter.rb +0 -13
|
@@ -42,7 +42,7 @@ module MilkTea
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
methods, private_methods = exported_methods(analysis, types)
|
|
45
|
-
implemented_interfaces
|
|
45
|
+
implemented_interfaces = exported_interface_implementations(analysis, types, interfaces)
|
|
46
46
|
|
|
47
47
|
Bindings::ModuleBinding.new(
|
|
48
48
|
name: analysis.module_name,
|
|
@@ -62,7 +62,6 @@ module MilkTea
|
|
|
62
62
|
private_values:,
|
|
63
63
|
private_functions:,
|
|
64
64
|
private_methods:,
|
|
65
|
-
private_implemented_interfaces:,
|
|
66
65
|
)
|
|
67
66
|
end
|
|
68
67
|
|
|
@@ -102,28 +101,18 @@ module MilkTea
|
|
|
102
101
|
|
|
103
102
|
def exported_interface_implementations(analysis, exported_types, exported_interfaces)
|
|
104
103
|
implemented_interfaces = {}
|
|
105
|
-
private_implemented_interfaces = {}
|
|
106
104
|
|
|
107
105
|
analysis.implemented_interfaces.each do |receiver_type, interfaces|
|
|
108
|
-
public_interfaces =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
interfaces.each do |interface|
|
|
112
|
-
visible = exported_method_receiver?(receiver_type, analysis, exported_types) &&
|
|
106
|
+
public_interfaces = interfaces.select do |interface|
|
|
107
|
+
exported_method_receiver?(receiver_type, analysis, exported_types) &&
|
|
113
108
|
exported_interface_binding?(interface, analysis, exported_interfaces) &&
|
|
114
109
|
exported_interface_methods?(receiver_type, interface, analysis, exported_types)
|
|
115
|
-
if visible
|
|
116
|
-
public_interfaces << interface
|
|
117
|
-
else
|
|
118
|
-
hidden_interfaces << interface
|
|
119
|
-
end
|
|
120
110
|
end
|
|
121
111
|
|
|
122
112
|
implemented_interfaces[receiver_type] = public_interfaces.freeze unless public_interfaces.empty?
|
|
123
|
-
private_implemented_interfaces[receiver_type] = hidden_interfaces.freeze unless hidden_interfaces.empty?
|
|
124
113
|
end
|
|
125
114
|
|
|
126
|
-
|
|
115
|
+
implemented_interfaces.freeze
|
|
127
116
|
end
|
|
128
117
|
|
|
129
118
|
def exported_interface_methods?(receiver_type, interface, analysis, exported_types)
|
|
@@ -691,7 +691,6 @@ module MilkTea
|
|
|
691
691
|
private_values: full_binding.private_values,
|
|
692
692
|
private_functions: full_binding.private_functions,
|
|
693
693
|
private_methods: full_binding.private_methods,
|
|
694
|
-
private_implemented_interfaces: full_binding.private_implemented_interfaces,
|
|
695
694
|
)
|
|
696
695
|
end
|
|
697
696
|
end
|
|
@@ -728,7 +727,6 @@ module MilkTea
|
|
|
728
727
|
implemented_interfaces: {}, imports: {},
|
|
729
728
|
private_types: {}, private_interfaces: {}, private_attributes: {},
|
|
730
729
|
private_values: {}, private_functions: {}, private_methods: {},
|
|
731
|
-
private_implemented_interfaces: {},
|
|
732
730
|
)
|
|
733
731
|
end
|
|
734
732
|
|
|
@@ -369,10 +369,11 @@ module MilkTea
|
|
|
369
369
|
AST::AttributeDecl.new(name: name_token.lexeme, targets:, params:, visibility:, line:, column: name_token.column)
|
|
370
370
|
end
|
|
371
371
|
|
|
372
|
-
def parse_struct_decl(packed: false, alignment: nil, visibility: :private, attributes: [],
|
|
372
|
+
def parse_struct_decl(packed: false, alignment: nil, visibility: :private, attributes: [], qualified_parts: [])
|
|
373
373
|
line = previous.line
|
|
374
374
|
name_token = consume_name("expected struct name")
|
|
375
375
|
name = name_token.lexeme
|
|
376
|
+
qualified_name = qualified_parts + [name]
|
|
376
377
|
lifetime_params, type_params = parse_struct_decl_params
|
|
377
378
|
implements = parse_implements_clause
|
|
378
379
|
c_name = parse_optional_c_name
|
|
@@ -380,29 +381,33 @@ module MilkTea
|
|
|
380
381
|
receiver_type_param_names = type_params.map(&:name)
|
|
381
382
|
members = with_type_param_names(receiver_type_param_names) do
|
|
382
383
|
parse_recoverable_block do
|
|
383
|
-
parse_struct_member
|
|
384
|
+
parse_struct_member(qualified_name)
|
|
384
385
|
end
|
|
385
386
|
end
|
|
386
387
|
fields = members.filter_map { |kind, member| member if kind == :field }
|
|
387
388
|
events = members.filter_map { |kind, member| member if kind == :event }
|
|
388
389
|
nested_types = members.filter_map { |kind, member| member if kind == :nested_type }
|
|
389
390
|
methods = members.filter_map { |kind, member| member if kind == :method }
|
|
391
|
+
nested_extending_blocks = members.filter_map { |kind, _, blocks| blocks if kind == :nested_type }.flatten(1)
|
|
390
392
|
struct_decl = AST::StructDecl.new(name:, type_params:, implements:, c_name:, fields:, events:, nested_types:, attributes:, packed:, alignment:, visibility:, lifetime_params:, line:, column: name_token.column)
|
|
391
393
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
394
|
+
extending_blocks = []
|
|
395
|
+
extending_blocks << inline_methods_extending_block(qualified_name, type_params, methods, name_token) if methods.any?
|
|
396
|
+
extending_blocks.concat(nested_extending_blocks)
|
|
397
|
+
|
|
398
|
+
extending_blocks.empty? ? struct_decl : [struct_decl, *extending_blocks]
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def inline_methods_extending_block(qualified_name, type_params, methods, name_token)
|
|
402
|
+
type_ref_args = type_params.map do |tp|
|
|
403
|
+
AST::TypeArgument.new(
|
|
404
|
+
value: AST::TypeRef.new(name: AST::QualifiedName.new(parts: [tp.name]), arguments: [], nullable: false, line: tp.line, column: tp.column),
|
|
405
|
+
line: tp.line,
|
|
406
|
+
column: tp.column,
|
|
407
|
+
)
|
|
405
408
|
end
|
|
409
|
+
type_ref = AST::TypeRef.new(name: AST::QualifiedName.new(parts: qualified_name), arguments: type_ref_args, nullable: false, line: name_token.line, column: name_token.column)
|
|
410
|
+
AST::ExtendingBlock.new(type_name: type_ref, methods:, line: name_token.line, column: name_token.column, inline: true)
|
|
406
411
|
end
|
|
407
412
|
|
|
408
413
|
def parse_struct_decl_params
|
|
@@ -459,7 +464,7 @@ module MilkTea
|
|
|
459
464
|
result
|
|
460
465
|
end
|
|
461
466
|
|
|
462
|
-
def parse_struct_member
|
|
467
|
+
def parse_struct_member(qualified_name)
|
|
463
468
|
field_attributes = parse_attribute_applications
|
|
464
469
|
|
|
465
470
|
if check_method_start?
|
|
@@ -475,7 +480,9 @@ module MilkTea
|
|
|
475
480
|
|
|
476
481
|
if check(:struct) && !check_next(:colon)
|
|
477
482
|
advance
|
|
478
|
-
|
|
483
|
+
result = parse_struct_decl(visibility:, attributes: field_attributes, qualified_parts: qualified_name)
|
|
484
|
+
nested_decl, *nested_blocks = result.is_a?(Array) ? result : [result]
|
|
485
|
+
return [:nested_type, nested_decl, nested_blocks]
|
|
479
486
|
end
|
|
480
487
|
|
|
481
488
|
raise error(visibility_token, "public is only allowed on struct events") if visibility == :public
|
|
@@ -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
|