mt-lang 0.2.11 → 0.2.13
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 34c858250b3d56b9c9e2184e4cf3a29d180b176e49d77be5bffd52063a458718
|
|
4
|
+
data.tar.gz: 8ad1e294bd42fc71273ee495ff91b632b788a835c1f4d96203f298d6e2b6db6b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ebd5cae94ad9eaa939d265bbc31d57a1b29ecb53b2abf8e3437b6264d0ce635ca21a64bbaeb930b4526c34a633fd5f8742ed579c3b7aa1ad63e4c953e98d3651
|
|
7
|
+
data.tar.gz: 977bea5a674e4a5a0b7eade459a18a7c7aaf1eb157c7e09bd7c13f4baf2665461e480943e8c8a509f21f399e5e9315c1c9b70d75d500bad20b7d9301af29aed6
|
data/lib/milk_tea/base.rb
CHANGED
|
@@ -472,20 +472,13 @@ module MilkTea
|
|
|
472
472
|
|
|
473
473
|
members = []
|
|
474
474
|
skip_newlines
|
|
475
|
-
auto_value = 0
|
|
476
475
|
until check(:dedent) || eof?
|
|
477
476
|
member_token = consume_name("expected member name")
|
|
478
477
|
member_name = member_token.lexeme
|
|
479
478
|
if match(:equal)
|
|
480
479
|
value = parse_expression
|
|
481
|
-
if value.is_a?(AST::IntegerLiteral)
|
|
482
|
-
auto_value = value.value + 1
|
|
483
|
-
elsif value.is_a?(AST::UnaryOp) && value.operator == "-" && value.operand.is_a?(AST::IntegerLiteral)
|
|
484
|
-
auto_value = -value.operand.value + 1
|
|
485
|
-
end
|
|
486
480
|
else
|
|
487
|
-
value =
|
|
488
|
-
auto_value += 1
|
|
481
|
+
value = nil
|
|
489
482
|
end
|
|
490
483
|
consume_end_of_statement
|
|
491
484
|
members << AST::EnumMember.new(name: member_name, value:, line: member_token.line, column: member_token.column)
|
|
@@ -581,8 +581,13 @@ module MilkTea
|
|
|
581
581
|
|
|
582
582
|
decl.members.each do |member|
|
|
583
583
|
begin
|
|
584
|
-
|
|
585
|
-
|
|
584
|
+
if member.value
|
|
585
|
+
actual_type = infer_expression(member.value, scopes: [], expected_type: backing_type)
|
|
586
|
+
const_value = evaluate_enum_member_const_value(member.value, enum_type:, member_values:)
|
|
587
|
+
else
|
|
588
|
+
const_value = (member_values.values.last&.succ || 0)
|
|
589
|
+
actual_type = backing_type
|
|
590
|
+
end
|
|
586
591
|
|
|
587
592
|
compatible = types_compatible?(actual_type, backing_type, expression: member.value, scopes: [])
|
|
588
593
|
compatible ||= actual_type.is_a?(Types::EnumBase) && types_compatible?(actual_type.backing_type, backing_type, expression: member.value, scopes: [])
|
|
@@ -272,6 +272,34 @@ module MilkTea
|
|
|
272
272
|
'Subscription' => 'Opaque handle returned by `event.subscribe`. Pass to `event.unsubscribe` to remove a listener.',
|
|
273
273
|
}.freeze
|
|
274
274
|
|
|
275
|
+
BUILTIN_TYPE_METHOD_SIGNATURES = {
|
|
276
|
+
'atomic' => {
|
|
277
|
+
'load' => 'function load() -> T',
|
|
278
|
+
'store' => 'static function store(value: T) -> void',
|
|
279
|
+
'add' => 'static function add(value: T) -> T',
|
|
280
|
+
'sub' => 'static function sub(value: T) -> T',
|
|
281
|
+
'exchange' => 'static function exchange(value: T) -> T',
|
|
282
|
+
'compare_exchange' => 'static function compare_exchange(expected: T, desired: T) -> bool',
|
|
283
|
+
},
|
|
284
|
+
'event' => {
|
|
285
|
+
'subscribe' => 'function subscribe(listener) -> Result[Subscription, EventError]',
|
|
286
|
+
'subscribe_once' => 'function subscribe_once(listener) -> Result[Subscription, EventError]',
|
|
287
|
+
'unsubscribe' => 'function unsubscribe(subscription) -> bool',
|
|
288
|
+
'wait' => 'function wait() -> Task[Result[T, EventError]]',
|
|
289
|
+
},
|
|
290
|
+
'str_buffer' => {
|
|
291
|
+
'assign' => 'static function assign(value: str) -> void',
|
|
292
|
+
'append' => 'static function append(value: str) -> void',
|
|
293
|
+
'assign_format' => 'static function assign_format(fmt: str) -> void',
|
|
294
|
+
'append_format' => 'static function append_format(fmt: str) -> void',
|
|
295
|
+
'clear' => 'static function clear() -> void',
|
|
296
|
+
'len' => 'static function len() -> ptr_uint',
|
|
297
|
+
'capacity' => 'static function capacity() -> ptr_uint',
|
|
298
|
+
'as_str' => 'static function as_str() -> str',
|
|
299
|
+
'as_cstr' => 'static function as_cstr() -> cstr',
|
|
300
|
+
},
|
|
301
|
+
}.freeze
|
|
302
|
+
|
|
275
303
|
def handle_hover(params)
|
|
276
304
|
stages = new_perf_stages
|
|
277
305
|
total_start = stages ? monotonic_time : nil
|
|
@@ -285,7 +313,8 @@ module MilkTea
|
|
|
285
313
|
token = context&.fetch(:token, nil)
|
|
286
314
|
token_kind = token&.type || :none
|
|
287
315
|
unless token&.type == :identifier
|
|
288
|
-
info = builtin_keyword_hover_info(token)
|
|
316
|
+
info = builtin_keyword_hover_info(token) ||
|
|
317
|
+
BUILTIN_CALL_HOVER_INFO[token.lexeme]&.slice(:signature, :docs)
|
|
289
318
|
if info
|
|
290
319
|
result_state = 'hit'
|
|
291
320
|
return {
|
|
@@ -390,6 +419,7 @@ module MilkTea
|
|
|
390
419
|
signature = nil
|
|
391
420
|
docs = nil
|
|
392
421
|
source_location = nil
|
|
422
|
+
resolved_via_type_member = false
|
|
393
423
|
|
|
394
424
|
if (binding = method_binding_at_token(facts, token))
|
|
395
425
|
signature = method_signature(binding)
|
|
@@ -427,11 +457,26 @@ module MilkTea
|
|
|
427
457
|
type = facts.types[name]
|
|
428
458
|
signature = type_hover_signature(name, type)
|
|
429
459
|
docs ||= BUILTIN_TYPE_DOCS[name]
|
|
460
|
+
elsif !name.include?(".") && (nested = find_nested_type_by_short_name(facts, name))
|
|
461
|
+
signature = type_hover_signature(name, nested)
|
|
462
|
+
docs ||= BUILTIN_TYPE_DOCS[name]
|
|
430
463
|
elsif (binding = facts.values[name])
|
|
431
464
|
signature = value_hover_signature(binding)
|
|
465
|
+
elsif (member_info = find_member_in_types(facts, name))
|
|
466
|
+
type, member, value = member_info
|
|
467
|
+
signature = value ? "#{type.name}.#{member} = #{value}" : "#{type.name}.#{member}"
|
|
468
|
+
resolved_via_type_member = true
|
|
469
|
+
elsif (arm_sig = find_variant_arm_in_types(facts, name))
|
|
470
|
+
signature = arm_sig
|
|
471
|
+
resolved_via_type_member = true
|
|
432
472
|
elsif (import_binding = facts.imports[name])
|
|
433
473
|
signature = "module #{import_binding.name}"
|
|
434
474
|
source_location = module_definition_location(uri, import_binding.name)
|
|
475
|
+
elsif (attr_binding = facts.attributes[name])
|
|
476
|
+
targets = attr_binding.targets.map(&:to_s).join(", ")
|
|
477
|
+
params_str = attr_binding.params.map { |p| "#{p.name}: #{p.type}" }.join(", ")
|
|
478
|
+
signature = "attribute [#{targets}] #{name}(#{params_str})"
|
|
479
|
+
source_location ||= module_definition_location(uri, facts.module_name)
|
|
435
480
|
else
|
|
436
481
|
dot_receiver = @workspace.find_dot_receiver(uri, lsp_line, lsp_char)
|
|
437
482
|
dot_receiver_path = @workspace.find_dot_receiver_path(uri, lsp_line, lsp_char)
|
|
@@ -465,6 +510,27 @@ module MilkTea
|
|
|
465
510
|
end
|
|
466
511
|
end
|
|
467
512
|
|
|
513
|
+
unless signature
|
|
514
|
+
if dot_receiver
|
|
515
|
+
receiver_name = dot_receiver
|
|
516
|
+
receiver_binding = resolve_local_hover_binding(facts, receiver_name, lsp_line + 1, lsp_char + 1) ||
|
|
517
|
+
facts.values[receiver_name] ||
|
|
518
|
+
facts.functions[receiver_name]
|
|
519
|
+
if receiver_binding && receiver_binding.type
|
|
520
|
+
receiver_type = receiver_binding.respond_to?(:storage_type) ? receiver_binding.storage_type : receiver_binding.type
|
|
521
|
+
methods = methods_for_receiver_type(facts, receiver_type)
|
|
522
|
+
if (method_binding = methods[name])
|
|
523
|
+
signature = method_signature(method_binding)
|
|
524
|
+
else
|
|
525
|
+
type_base = receiver_type.to_s[/^([a-z_]+)/, 1]
|
|
526
|
+
if type_base && (method_sigs = BUILTIN_TYPE_METHOD_SIGNATURES[type_base])
|
|
527
|
+
signature = method_sigs[name]
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
end
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
|
|
468
534
|
unless signature
|
|
469
535
|
if token_index && (builtin_info = builtin_hover_info(name, tokens, token_index))
|
|
470
536
|
signature = builtin_info[:signature]
|
|
@@ -473,14 +539,28 @@ module MilkTea
|
|
|
473
539
|
end
|
|
474
540
|
|
|
475
541
|
unless signature
|
|
476
|
-
|
|
477
|
-
name,
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
if
|
|
483
|
-
signature =
|
|
542
|
+
if token_index && tokens && parameter_declaration_token?(tokens, token_index)
|
|
543
|
+
signature = resolve_lexical_local_hover_signature(uri, name, tokens[token_index])
|
|
544
|
+
end
|
|
545
|
+
end
|
|
546
|
+
|
|
547
|
+
unless signature
|
|
548
|
+
if token_index && tokens && attribute_target_token?(tokens, token_index)
|
|
549
|
+
signature = "attribute target #{name}"
|
|
550
|
+
end
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
unless signature
|
|
554
|
+
unless token_index && tokens && (tokens[previous_non_trivia_token_index(tokens, token_index)]&.type == :dot || call_argument_token?(tokens, token_index))
|
|
555
|
+
local_def = @workspace.find_definition_token_global(
|
|
556
|
+
name,
|
|
557
|
+
preferred_uri: uri,
|
|
558
|
+
before_line: lsp_line + 1,
|
|
559
|
+
before_char: lsp_char + 1,
|
|
560
|
+
)
|
|
561
|
+
if local_def
|
|
562
|
+
signature = resolve_lexical_local_hover_signature(local_def[:uri], name, local_def[:token])
|
|
563
|
+
end
|
|
484
564
|
end
|
|
485
565
|
end
|
|
486
566
|
end
|
|
@@ -490,6 +570,8 @@ module MilkTea
|
|
|
490
570
|
|
|
491
571
|
definition_entry = if source_location
|
|
492
572
|
measure_perf_stage(stages, 'definition_entry') { hover_definition_entry_from_location(source_location) }
|
|
573
|
+
elsif resolved_via_type_member
|
|
574
|
+
nil
|
|
493
575
|
else
|
|
494
576
|
measure_perf_stage(stages, 'global_definition') do
|
|
495
577
|
@workspace.find_definition_token_global(
|
|
@@ -1341,6 +1423,43 @@ module MilkTea
|
|
|
1341
1423
|
"field #{name}: #{type}"
|
|
1342
1424
|
end
|
|
1343
1425
|
|
|
1426
|
+
def find_nested_type_by_short_name(facts, short_name)
|
|
1427
|
+
matches = facts.types.keys.select { |k| k.to_s.end_with?(".#{short_name}") }
|
|
1428
|
+
return nil unless matches.length == 1
|
|
1429
|
+
|
|
1430
|
+
facts.types[matches.first]
|
|
1431
|
+
end
|
|
1432
|
+
|
|
1433
|
+
def find_member_in_types(facts, name)
|
|
1434
|
+
facts.types.reverse_each do |_key, type|
|
|
1435
|
+
next unless type.respond_to?(:members)
|
|
1436
|
+
|
|
1437
|
+
member = type.members.find { |m| m == name }
|
|
1438
|
+
if member
|
|
1439
|
+
value = type.respond_to?(:member_value) ? type.member_value(name) : nil
|
|
1440
|
+
return [type, member, value]
|
|
1441
|
+
end
|
|
1442
|
+
end
|
|
1443
|
+
nil
|
|
1444
|
+
end
|
|
1445
|
+
|
|
1446
|
+
def find_variant_arm_in_types(facts, name)
|
|
1447
|
+
facts.types.reverse_each do |_key, type|
|
|
1448
|
+
arm = nil
|
|
1449
|
+
if type.respond_to?(:arms)
|
|
1450
|
+
arm = type.arms[name]
|
|
1451
|
+
elsif type.respond_to?(:arm_names) && type.arm_names.include?(name)
|
|
1452
|
+
arm = type.arm(name)
|
|
1453
|
+
end
|
|
1454
|
+
next unless arm
|
|
1455
|
+
|
|
1456
|
+
fields = arm.map { |fname, ftype| "#{fname}: #{ftype}" }.join(", ")
|
|
1457
|
+
field_str = fields.empty? ? "" : "(#{fields})"
|
|
1458
|
+
return "#{type.name}.#{name}#{field_str}"
|
|
1459
|
+
end
|
|
1460
|
+
nil
|
|
1461
|
+
end
|
|
1462
|
+
|
|
1344
1463
|
def builtin_hover_info(name, tokens, token_index)
|
|
1345
1464
|
specialization_info = builtin_value_specialization_info(name, tokens, token_index)
|
|
1346
1465
|
return specialization_info if specialization_info
|
|
@@ -1354,6 +1473,39 @@ module MilkTea
|
|
|
1354
1473
|
builtin_call_hover_info(name, tokens, token_index)
|
|
1355
1474
|
end
|
|
1356
1475
|
|
|
1476
|
+
def parameter_declaration_token?(tokens, index)
|
|
1477
|
+
return false unless index && tokens[index]&.type == :identifier
|
|
1478
|
+
|
|
1479
|
+
prev = previous_non_trivia_token_index(tokens, index)
|
|
1480
|
+
return false unless prev
|
|
1481
|
+
return false unless [:lparen, :comma].include?(tokens[prev].type)
|
|
1482
|
+
|
|
1483
|
+
nxt = next_non_trivia_token_index(tokens, index + 1)
|
|
1484
|
+
nxt && tokens[nxt].type == :colon
|
|
1485
|
+
end
|
|
1486
|
+
|
|
1487
|
+
def attribute_target_token?(tokens, index)
|
|
1488
|
+
return false unless index && tokens[index]&.type == :identifier
|
|
1489
|
+
|
|
1490
|
+
prev = previous_non_trivia_token_index(tokens, index)
|
|
1491
|
+
return false unless prev && [:lbracket, :comma].include?(tokens[prev].type)
|
|
1492
|
+
|
|
1493
|
+
after = next_non_trivia_token_index(tokens, index + 1)
|
|
1494
|
+
return false unless after && [:rbracket, :comma].include?(tokens[after].type)
|
|
1495
|
+
|
|
1496
|
+
true
|
|
1497
|
+
end
|
|
1498
|
+
|
|
1499
|
+
def call_argument_token?(tokens, index)
|
|
1500
|
+
return false unless index && tokens[index]&.type == :identifier
|
|
1501
|
+
|
|
1502
|
+
prev = previous_non_trivia_token_index(tokens, index)
|
|
1503
|
+
return false unless prev && [:lparen, :comma].include?(tokens[prev].type)
|
|
1504
|
+
|
|
1505
|
+
nxt = next_non_trivia_token_index(tokens, index + 1)
|
|
1506
|
+
!nxt || ![:colon, :rbracket, :comma].include?(tokens[nxt].type)
|
|
1507
|
+
end
|
|
1508
|
+
|
|
1357
1509
|
def builtin_in_member_access_context?(tokens, token_index)
|
|
1358
1510
|
prev_index = previous_non_trivia_token_index(tokens, token_index)
|
|
1359
1511
|
prev_index && tokens[prev_index].type == :dot
|
|
@@ -1394,7 +1546,7 @@ module MilkTea
|
|
|
1394
1546
|
end
|
|
1395
1547
|
|
|
1396
1548
|
def builtin_type_constructor_hover_info(name, tokens, token_index)
|
|
1397
|
-
return nil unless %w[array span Option Result SoA str_buffer].include?(name)
|
|
1549
|
+
return nil unless %w[array span Option Result SoA str_buffer ref ptr const_ptr own Task atomic].include?(name)
|
|
1398
1550
|
|
|
1399
1551
|
lbracket_index = next_non_trivia_token_index(tokens, token_index + 1)
|
|
1400
1552
|
return nil unless lbracket_index && tokens[lbracket_index].type == :lbracket
|
|
@@ -1449,6 +1601,18 @@ module MilkTea
|
|
|
1449
1601
|
'`Result[T, E]` is the built-in success/failure type with `success(value = ...)` and `failure(error = ...)` arms.'
|
|
1450
1602
|
when 'str_buffer'
|
|
1451
1603
|
'`str_buffer[N]` is a fixed-capacity mutable UTF-8 text buffer. Methods: `assign`, `append`, `assign_format`, `append_format`, `clear`, `len`, `as_str`, `as_cstr`.'
|
|
1604
|
+
when 'ref'
|
|
1605
|
+
'`ref[T]` is a non-null borrow reference. Auto-dereferences for member access and method calls. Cannot be stored in module-level variables, constants, or nested containers.'
|
|
1606
|
+
when 'ptr'
|
|
1607
|
+
'`ptr[T]` is a raw mutable pointer. Indexing, dereference, and arithmetic require `unsafe`. Nullable via `ptr[T]?`.'
|
|
1608
|
+
when 'const_ptr'
|
|
1609
|
+
'`const_ptr[T]` is a read-only pointer. Does not require `unsafe` for dereference.'
|
|
1610
|
+
when 'own'
|
|
1611
|
+
'`own[T]` is an owning heap pointer. Auto-dereferences like `ref`. Storable, returnable, and nullable. Allocated via `heap.must_alloc[T](count)`.'
|
|
1612
|
+
when 'Task'
|
|
1613
|
+
'`Task[T]` is an async task future. Returned by `async function`. Use `await` to unwrap, or `aio.wait`/`aio.run` to drive.'
|
|
1614
|
+
when 'atomic'
|
|
1615
|
+
'`atomic[T]` is an atomic value for lock-free concurrent access. `T` must be a primitive integer or `bool`. Methods: `load`, `store`, `add`, `sub`, `exchange`.'
|
|
1452
1616
|
end
|
|
1453
1617
|
|
|
1454
1618
|
{
|
|
@@ -1689,6 +1853,14 @@ module MilkTea
|
|
|
1689
1853
|
when "let" then kind = :let
|
|
1690
1854
|
when "var" then kind = :var
|
|
1691
1855
|
when "const" then kind = :const
|
|
1856
|
+
when "struct" then kind = :struct_type
|
|
1857
|
+
when "function", "async", "external", "foreign" then kind = :function
|
|
1858
|
+
when "enum" then kind = :enum_type
|
|
1859
|
+
when "flags" then kind = :flags_type
|
|
1860
|
+
when "union" then kind = :union_type
|
|
1861
|
+
when "variant" then kind = :variant_type
|
|
1862
|
+
when "(" then kind = :param
|
|
1863
|
+
when "," then kind = :param
|
|
1692
1864
|
end
|
|
1693
1865
|
end
|
|
1694
1866
|
|
|
@@ -1715,9 +1887,15 @@ module MilkTea
|
|
|
1715
1887
|
end
|
|
1716
1888
|
|
|
1717
1889
|
kind ||= :let
|
|
1890
|
+
unless %i[let var const param].include?(kind)
|
|
1891
|
+
kind = kind.to_s.sub(/_type$/, "")
|
|
1892
|
+
return "#{kind} #{name}"
|
|
1893
|
+
end
|
|
1894
|
+
|
|
1895
|
+
display_kind = kind == :param ? "parameter" : kind.to_s
|
|
1718
1896
|
mutability = kind == :var ? "mutable" : "immutable"
|
|
1719
1897
|
if type_str && !type_str.empty?
|
|
1720
|
-
"#{
|
|
1898
|
+
"#{display_kind} #{name}: #{type_str} (#{mutability})"
|
|
1721
1899
|
else
|
|
1722
1900
|
"#{kind} #{name} (#{mutability})"
|
|
1723
1901
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mt-lang
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.13
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Long (Teefan) Tran
|
|
@@ -583,7 +583,7 @@ metadata:
|
|
|
583
583
|
homepage_uri: https://teefan.github.io/mt-lang/
|
|
584
584
|
source_code_uri: https://github.com/teefan/mt-lang
|
|
585
585
|
post_install_message: |
|
|
586
|
-
Milk Tea 0.2.
|
|
586
|
+
Milk Tea 0.2.13 installed!
|
|
587
587
|
|
|
588
588
|
System requirements:
|
|
589
589
|
- A C compiler (gcc or clang) must be available on PATH
|