mt-lang 0.3.39 → 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/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/server/code_actions.rb +0 -4
- 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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3a57605301758f1ff1307cfb5aa7300bb73876be082b9736f853bf14dce18352
|
|
4
|
+
data.tar.gz: 8d540b3326a74c0a8370d5799b19eadb78f8d579899ffdfed263847bbfa0c367
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c7ff36f0b7a609a7c4dbd69264c70ee7dca22201d520753e254609a3009844c23572c578cbdb5802afdd04897559b578f1e539b5c9c6c2a97c64f16f5e286062
|
|
7
|
+
data.tar.gz: 1987f20a6c919b3c8341a339c6473292bf31866a07ffe1805707153b077a282284686366dd299eeb02e91de23a83eec1b8aaa837fc901eadefe58acf54df07a9
|
data/lib/milk_tea/base.rb
CHANGED
data/lib/milk_tea/core/ast.rb
CHANGED
|
@@ -111,8 +111,8 @@ module MilkTea
|
|
|
111
111
|
InterfaceDecl = Data.define(:name, :type_params, :methods, :visibility, :line, :column) do
|
|
112
112
|
def initialize(name:, type_params: [], methods:, visibility:, line: nil, column: nil) = super
|
|
113
113
|
end
|
|
114
|
-
ExtendingBlock = Data.define(:type_name, :methods, :line, :column) do
|
|
115
|
-
def initialize(type_name:, methods:, line: nil, column: nil) = super
|
|
114
|
+
ExtendingBlock = Data.define(:type_name, :methods, :line, :column, :inline) do
|
|
115
|
+
def initialize(type_name:, methods:, line: nil, column: nil, inline: false) = super
|
|
116
116
|
end
|
|
117
117
|
InterfaceMethodDecl = Data.define(:name, :params, :return_type, :kind, :async, :attributes, :line, :column) do
|
|
118
118
|
def initialize(name:, params:, return_type:, kind:, async:, attributes: [], line: nil, column: nil) = super
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module MilkTea
|
|
4
4
|
module Bindings
|
|
5
|
-
AttributeBinding = Data.define(:name, :targets, :params, :module_name, :builtin
|
|
5
|
+
AttributeBinding = Data.define(:name, :targets, :params, :module_name, :builtin)
|
|
6
6
|
BUILTIN_ATTRIBUTE_NAMES = %w[packed align deprecated test expect_fatal].freeze
|
|
7
7
|
|
|
8
8
|
def self.builtin_attribute_binding(name, types)
|
|
@@ -14,7 +14,6 @@ module MilkTea
|
|
|
14
14
|
params: [].freeze,
|
|
15
15
|
module_name: nil,
|
|
16
16
|
builtin: true,
|
|
17
|
-
ast: nil,
|
|
18
17
|
)
|
|
19
18
|
when "align"
|
|
20
19
|
AttributeBinding.new(
|
|
@@ -23,7 +22,6 @@ module MilkTea
|
|
|
23
22
|
params: [Types::Registry.parameter("bytes", types.fetch("ptr_uint"))].freeze,
|
|
24
23
|
module_name: nil,
|
|
25
24
|
builtin: true,
|
|
26
|
-
ast: nil,
|
|
27
25
|
)
|
|
28
26
|
when "deprecated"
|
|
29
27
|
AttributeBinding.new(
|
|
@@ -32,7 +30,6 @@ module MilkTea
|
|
|
32
30
|
params: [Types::Registry.parameter("message", types.fetch("str"))].freeze,
|
|
33
31
|
module_name: nil,
|
|
34
32
|
builtin: true,
|
|
35
|
-
ast: nil,
|
|
36
33
|
)
|
|
37
34
|
when "test"
|
|
38
35
|
AttributeBinding.new(
|
|
@@ -41,7 +38,6 @@ module MilkTea
|
|
|
41
38
|
params: [].freeze,
|
|
42
39
|
module_name: nil,
|
|
43
40
|
builtin: true,
|
|
44
|
-
ast: nil,
|
|
45
41
|
)
|
|
46
42
|
when "expect_fatal"
|
|
47
43
|
AttributeBinding.new(
|
|
@@ -50,7 +46,6 @@ module MilkTea
|
|
|
50
46
|
params: [].freeze,
|
|
51
47
|
module_name: nil,
|
|
52
48
|
builtin: true,
|
|
53
|
-
ast: nil,
|
|
54
49
|
)
|
|
55
50
|
end
|
|
56
51
|
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module MilkTea
|
|
4
4
|
module Bindings
|
|
5
|
-
ModuleBinding = Data.define(:name, :types, :type_declarations, :interfaces, :attributes, :attribute_applications, :values, :functions, :methods, :implemented_interfaces, :imports, :private_types, :private_interfaces, :private_attributes, :private_values, :private_functions, :private_methods
|
|
5
|
+
ModuleBinding = Data.define(:name, :types, :type_declarations, :interfaces, :attributes, :attribute_applications, :values, :functions, :methods, :implemented_interfaces, :imports, :private_types, :private_interfaces, :private_attributes, :private_values, :private_functions, :private_methods) do
|
|
6
6
|
def private_type?(name)
|
|
7
7
|
private_types.key?(name)
|
|
8
8
|
end
|
|
@@ -84,5 +84,27 @@ module MilkTea
|
|
|
84
84
|
def string_literal_cstr_compatibility?(expression, expected_type)
|
|
85
85
|
expression.is_a?(AST::StringLiteral) && !expression.cstring && expected_type == BUILTIN_CSTR
|
|
86
86
|
end
|
|
87
|
+
|
|
88
|
+
def current_nested_types
|
|
89
|
+
@current_nested_types
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Resolves the receiver type's short name (self-reference) and its own
|
|
93
|
+
# nested types as a bare-name scope for method bodies and signatures.
|
|
94
|
+
def method_receiver_nested_scope(receiver_type)
|
|
95
|
+
return nil unless receiver_type.respond_to?(:name)
|
|
96
|
+
|
|
97
|
+
nested = receiver_type.respond_to?(:nested_types) ? receiver_type.nested_types : nil
|
|
98
|
+
scope = { receiver_type.name => receiver_type }
|
|
99
|
+
scope = scope.merge(nested) if nested && !nested.empty?
|
|
100
|
+
scope
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Looks up a bare type name, consulting the active method-receiver nested
|
|
104
|
+
# scope before the module type namespace so nested types self-reference
|
|
105
|
+
# by their short name inside their own methods.
|
|
106
|
+
def lookup_named_type(name)
|
|
107
|
+
(@current_nested_types && @current_nested_types[name]) || @ctx.types[name]
|
|
108
|
+
end
|
|
87
109
|
end
|
|
88
|
-
end
|
|
110
|
+
end
|
|
@@ -118,8 +118,10 @@ module MilkTea
|
|
|
118
118
|
parameter_setup = []
|
|
119
119
|
previous_type_substitutions = @ctx.current_type_substitutions
|
|
120
120
|
previous_value_type_params = @ctx.current_value_type_params
|
|
121
|
+
previous_nested_types = @current_nested_types
|
|
121
122
|
@ctx.current_type_substitutions = binding.type_substitutions
|
|
122
123
|
@ctx.current_value_type_params = resolve_value_type_params(decl.type_params)
|
|
124
|
+
@current_nested_types = method_receiver_nested_scope(binding.declared_receiver_type)
|
|
123
125
|
|
|
124
126
|
return lower_async_function_decl(binding, receiver_type:) if binding.async
|
|
125
127
|
|
|
@@ -179,6 +181,7 @@ module MilkTea
|
|
|
179
181
|
ensure
|
|
180
182
|
@ctx.current_type_substitutions = previous_type_substitutions
|
|
181
183
|
@ctx.current_value_type_params = previous_value_type_params
|
|
184
|
+
@current_nested_types = previous_nested_types
|
|
182
185
|
end
|
|
183
186
|
|
|
184
187
|
def resolve_value_type_params(type_params)
|
|
@@ -444,7 +444,7 @@ module MilkTea
|
|
|
444
444
|
return [:compile_time_builtin, callee.name, nil, compile_time_builtin_function_type(callee.name, arguments, env)]
|
|
445
445
|
end
|
|
446
446
|
|
|
447
|
-
type =
|
|
447
|
+
type = lookup_named_type(callee.name)
|
|
448
448
|
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)
|
|
449
449
|
return [:struct_literal, nil, nil, type]
|
|
450
450
|
end
|
|
@@ -606,7 +606,6 @@ module MilkTea
|
|
|
606
606
|
return [:array_as_span, nil, callee.receiver, Types::Registry.span(array_element_type(field_receiver_type))]
|
|
607
607
|
end
|
|
608
608
|
|
|
609
|
-
member_type = field_receiver_type.respond_to?(:field) ? field_receiver_type.field(callee.member) : nil
|
|
610
609
|
member_type = field_receiver_type.respond_to?(:field) ? field_receiver_type.field(callee.member) : nil
|
|
611
610
|
return [:callable_value, nil, nil, member_type, nil] if callable_type?(member_type)
|
|
612
611
|
|
|
@@ -1055,7 +1054,7 @@ module MilkTea
|
|
|
1055
1054
|
end
|
|
1056
1055
|
end
|
|
1057
1056
|
|
|
1058
|
-
def type_contains_array_storage?(type
|
|
1057
|
+
def type_contains_array_storage?(type)
|
|
1059
1058
|
visitor = Types::ContainsArrayStorageVisitor.new
|
|
1060
1059
|
visitor.visit(type)
|
|
1061
1060
|
visitor.found?
|
|
@@ -1118,62 +1117,6 @@ module MilkTea
|
|
|
1118
1117
|
expected_type || null_type
|
|
1119
1118
|
end
|
|
1120
1119
|
|
|
1121
|
-
def common_numeric_type(left_type, right_type)
|
|
1122
|
-
left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
|
|
1123
|
-
right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
|
|
1124
|
-
return left_type if left_type == right_type
|
|
1125
|
-
return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
|
|
1126
|
-
return unless left_type.numeric? && right_type.numeric?
|
|
1127
|
-
|
|
1128
|
-
return common_integer_type(left_type, right_type) if left_type.integer? && right_type.integer?
|
|
1129
|
-
return wider_float_type(left_type, right_type) if left_type.float? && right_type.float?
|
|
1130
|
-
|
|
1131
|
-
float_type, integer_type = left_type.float? ? [left_type, right_type] : [right_type, left_type]
|
|
1132
|
-
return unless integer_type.integer? && integer_type.fixed_width_integer?
|
|
1133
|
-
|
|
1134
|
-
float_type
|
|
1135
|
-
end
|
|
1136
|
-
|
|
1137
|
-
def common_integer_type(left_type, right_type)
|
|
1138
|
-
left_type = left_type.backing_type if left_type.is_a?(Types::EnumBase)
|
|
1139
|
-
right_type = right_type.backing_type if right_type.is_a?(Types::EnumBase)
|
|
1140
|
-
return left_type if left_type == right_type
|
|
1141
|
-
return unless left_type.is_a?(Types::Primitive) && right_type.is_a?(Types::Primitive)
|
|
1142
|
-
return unless left_type.integer? && right_type.integer?
|
|
1143
|
-
return unless left_type.fixed_width_integer? && right_type.fixed_width_integer?
|
|
1144
|
-
|
|
1145
|
-
# Mirrors the semantic analyzer's rule: same signedness picks the wider
|
|
1146
|
-
# type; mixed signed/unsigned promotes to the narrowest signed type that
|
|
1147
|
-
# holds both operands' full ranges (a strictly-wider signed type covers
|
|
1148
|
-
# an unsigned operand, otherwise widen to the next signed width). Mixing
|
|
1149
|
-
# with a 64-bit unsigned type has no safe signed common type.
|
|
1150
|
-
if left_type.signed_integer? == right_type.signed_integer?
|
|
1151
|
-
return left_type.integer_width >= right_type.integer_width ? left_type : right_type
|
|
1152
|
-
end
|
|
1153
|
-
|
|
1154
|
-
signed_type, unsigned_type = if left_type.signed_integer?
|
|
1155
|
-
[left_type, right_type]
|
|
1156
|
-
else
|
|
1157
|
-
[right_type, left_type]
|
|
1158
|
-
end
|
|
1159
|
-
|
|
1160
|
-
return signed_type if signed_type.integer_width > unsigned_type.integer_width
|
|
1161
|
-
|
|
1162
|
-
signed_type_above_width(unsigned_type.integer_width)
|
|
1163
|
-
end
|
|
1164
|
-
|
|
1165
|
-
def signed_type_above_width(width)
|
|
1166
|
-
case width
|
|
1167
|
-
when 8 then @ctx.types.fetch("short")
|
|
1168
|
-
when 16 then @ctx.types.fetch("int")
|
|
1169
|
-
when 32 then @ctx.types.fetch("long")
|
|
1170
|
-
end
|
|
1171
|
-
end
|
|
1172
|
-
|
|
1173
|
-
def wider_float_type(left_type, right_type)
|
|
1174
|
-
left_type.float_width >= right_type.float_width ? left_type : right_type
|
|
1175
|
-
end
|
|
1176
|
-
|
|
1177
1120
|
def aggregate_arithmetic_result_type(operator, left_type, right_type)
|
|
1178
1121
|
if left_type.is_a?(Types::Vector) && right_type.is_a?(Types::Vector) && left_type.name == right_type.name
|
|
1179
1122
|
return left_type
|
|
@@ -1217,7 +1160,7 @@ module MilkTea
|
|
|
1217
1160
|
when AST::Identifier
|
|
1218
1161
|
return current_type_params[expression.name] if current_type_params.key?(expression.name)
|
|
1219
1162
|
|
|
1220
|
-
|
|
1163
|
+
lookup_named_type(expression.name)
|
|
1221
1164
|
when AST::MemberAccess
|
|
1222
1165
|
return nil unless expression.receiver.is_a?(AST::Identifier)
|
|
1223
1166
|
|
|
@@ -1870,10 +1813,6 @@ module MilkTea
|
|
|
1870
1813
|
def top_level_function(name)
|
|
1871
1814
|
@lowerer.instance_variable_get(:@ctx).functions&.[](name)
|
|
1872
1815
|
end
|
|
1873
|
-
|
|
1874
|
-
def raise_sema_error(message)
|
|
1875
|
-
raise CompileTime::Error, message
|
|
1876
|
-
end
|
|
1877
1816
|
end
|
|
1878
1817
|
|
|
1879
1818
|
def evaluate_reflection_target_argument(expression, env:)
|
|
@@ -2532,7 +2471,7 @@ module MilkTea
|
|
|
2532
2471
|
elsif parts.length == 1 && type_params.key?(parts.first)
|
|
2533
2472
|
type_params.fetch(parts.first)
|
|
2534
2473
|
elsif parts.length == 1
|
|
2535
|
-
type =
|
|
2474
|
+
type = lookup_named_type(parts.first)
|
|
2536
2475
|
raise LoweringError.new("unknown type #{parts.first}", line: 0, column: 0, path: @ctx.current_analysis_path) unless type
|
|
2537
2476
|
raise LoweringError.new("generic type #{parts.first} requires type arguments", line: 0, column: 0, path: @ctx.current_analysis_path) if type.is_a?(Types::GenericStructDefinition) || type.is_a?(Types::GenericVariantDefinition)
|
|
2538
2477
|
|
|
@@ -155,18 +155,6 @@ module MilkTea
|
|
|
155
155
|
receiver_type
|
|
156
156
|
end
|
|
157
157
|
|
|
158
|
-
def collection_loop_type(type)
|
|
159
|
-
super
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def collection_loop_binding_type(iterable_type, element_type)
|
|
163
|
-
super
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
def collection_loop_ref_element_type?(type)
|
|
167
|
-
super
|
|
168
|
-
end
|
|
169
|
-
|
|
170
158
|
def collection_loop_item_value(iterable_ref, iterable_type, index_ref, element_type)
|
|
171
159
|
if array_type?(iterable_type)
|
|
172
160
|
IR::Index.new(receiver: iterable_ref, index: index_ref, type: element_type)
|
|
@@ -248,11 +236,6 @@ module MilkTea
|
|
|
248
236
|
raise LoweringError.new("cannot index #{receiver_type}", line: 0, column: 0, path: @ctx.current_analysis_path)
|
|
249
237
|
end
|
|
250
238
|
|
|
251
|
-
def contains_type_var?(type)
|
|
252
|
-
super
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
|
|
256
239
|
def stored_ref_supported_type?(type, visited = {})
|
|
257
240
|
return true unless type
|
|
258
241
|
|
|
@@ -100,7 +100,6 @@ module MilkTea
|
|
|
100
100
|
include Intrinsics
|
|
101
101
|
|
|
102
102
|
attr_accessor :bypass_sema_type_cache
|
|
103
|
-
attr_reader :recorded_expr_types
|
|
104
103
|
|
|
105
104
|
include Lowering::Scans
|
|
106
105
|
include Lowering::Declarations
|
|
@@ -122,6 +121,7 @@ module MilkTea
|
|
|
122
121
|
@program = program
|
|
123
122
|
@ctx = LoweringContext.new
|
|
124
123
|
@artifacts = Artifacts.new
|
|
124
|
+
@error_type = Types::Error.new
|
|
125
125
|
@synthetic_proc_counter = 0
|
|
126
126
|
@parallel_for_counter = 0
|
|
127
127
|
@async_binding_counter = 0
|
|
@@ -130,7 +130,6 @@ module MilkTea
|
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
def lower
|
|
133
|
-
@recorded_expr_types = {} if @bypass_sema_type_cache
|
|
134
133
|
ir_program, _modules, _synths = lower_and_assemble
|
|
135
134
|
ir_program
|
|
136
135
|
end
|
|
@@ -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
|
|
@@ -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
|
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
|
|
@@ -443,10 +443,6 @@ module MilkTea
|
|
|
443
443
|
{ items: [] }
|
|
444
444
|
end
|
|
445
445
|
|
|
446
|
-
def refresh_workspace_diagnostics
|
|
447
|
-
@protocol.write_notification('workspace/diagnostic/refresh', nil)
|
|
448
|
-
end
|
|
449
|
-
|
|
450
446
|
def find_match_end_line(lines, match_start_idx)
|
|
451
447
|
return nil if match_start_idx >= lines.length
|
|
452
448
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "../core"
|
|
4
|
-
require_relative "cst_formatter"
|
|
5
4
|
|
|
6
5
|
module MilkTea
|
|
7
6
|
class FormatterError < StandardError; end
|
|
@@ -49,12 +48,12 @@ module MilkTea
|
|
|
49
48
|
|
|
50
49
|
def self.preserve_format(source, path:, profile: nil)
|
|
51
50
|
cst = profile_phase(profile, "format.cst") { build_cst(source, path:) }
|
|
52
|
-
profile_phase(profile, "format.cst_fmt") {
|
|
51
|
+
profile_phase(profile, "format.cst_fmt") { cst.reconstruct }
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
def self.tidy_format(source, path:, max_line_length: DEFAULT_MAX_LINE_LENGTH, profile: nil)
|
|
56
55
|
cst = profile_phase(profile, "format.cst") { build_cst(source, path:) }
|
|
57
|
-
normalized = profile_phase(profile, "format.normalize") {
|
|
56
|
+
normalized = profile_phase(profile, "format.normalize") { cst.reconstruct_normalized }
|
|
58
57
|
wrapped = profile_phase(profile, "format.wrap") { wrap_long_argument_lists(normalized, max_line_length:, path:) }
|
|
59
58
|
profile_phase(profile, "format.blank_lines") { normalize_blank_lines(wrapped, path:) }
|
|
60
59
|
end
|
|
@@ -17,6 +17,7 @@ module MilkTea
|
|
|
17
17
|
when "redundant-else" then redundant_else_edits(lines, warning)
|
|
18
18
|
when "redundant-return" then redundant_return_edits(lines, warning)
|
|
19
19
|
when "redundant-type-annotation" then redundant_type_annotation_edits(lines, warning)
|
|
20
|
+
when "prefer-inline-methods" then prefer_inline_methods_edits(lines, warning)
|
|
20
21
|
when "unused-import" then unused_import_edits(lines, warning)
|
|
21
22
|
when "trailing-list-comma" then trailing_list_comma_edits(lines, warning)
|
|
22
23
|
else []
|
|
@@ -152,6 +153,51 @@ module MilkTea
|
|
|
152
153
|
[FixEdit.new(start_line: line_idx, start_char: 0, end_line: line_idx + 1, end_char: 0, new_text: "")]
|
|
153
154
|
end
|
|
154
155
|
|
|
156
|
+
# Moves the methods of an `extending X:` block inline into the matching
|
|
157
|
+
# `struct X:` declaration. Only rewrites when the struct immediately
|
|
158
|
+
# precedes the extending block (blank lines allowed between them); other
|
|
159
|
+
# layouts are left alone since the move would be non-local.
|
|
160
|
+
def self.prefer_inline_methods_edits(lines, warning)
|
|
161
|
+
name = warning.symbol_name
|
|
162
|
+
return [] unless name && warning.line
|
|
163
|
+
|
|
164
|
+
struct_idx = lines.index { |l| l.match?(/\A\s*struct\s+#{Regexp.escape(name)}\b/) }
|
|
165
|
+
return [] unless struct_idx
|
|
166
|
+
|
|
167
|
+
last_member_idx = nil
|
|
168
|
+
((struct_idx + 1)...lines.length).each do |i|
|
|
169
|
+
l = lines[i]
|
|
170
|
+
break if !l.chomp.empty? && !l.start_with?(" ", "\t")
|
|
171
|
+
|
|
172
|
+
last_member_idx = i unless l.chomp.empty?
|
|
173
|
+
end
|
|
174
|
+
return [] unless last_member_idx
|
|
175
|
+
|
|
176
|
+
ext_start_idx = warning.line - 1
|
|
177
|
+
return [] unless last_member_idx < ext_start_idx
|
|
178
|
+
|
|
179
|
+
ext_end_idx = ext_start_idx
|
|
180
|
+
((ext_start_idx + 1)...lines.length).each do |i|
|
|
181
|
+
l = lines[i]
|
|
182
|
+
break if !l.chomp.empty? && !l.start_with?(" ", "\t")
|
|
183
|
+
|
|
184
|
+
ext_end_idx = i unless l.chomp.empty?
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
method_lines = lines[(ext_start_idx + 1)..ext_end_idx].to_a
|
|
188
|
+
method_lines.shift while method_lines.first && method_lines.first.chomp.empty?
|
|
189
|
+
method_lines.pop while method_lines.last && method_lines.last.chomp.empty?
|
|
190
|
+
return [] if method_lines.empty?
|
|
191
|
+
|
|
192
|
+
between = lines[(last_member_idx + 1)...ext_start_idx]
|
|
193
|
+
return [] unless between.all? { |l| l.chomp.empty? }
|
|
194
|
+
|
|
195
|
+
method_text = method_lines.join
|
|
196
|
+
new_text = "#{lines[last_member_idx].chomp}\n\n#{method_text}"
|
|
197
|
+
|
|
198
|
+
[FixEdit.new(start_line: last_member_idx, start_char: 0, end_line: ext_end_idx + 1, end_char: 0, new_text: new_text)]
|
|
199
|
+
end
|
|
200
|
+
|
|
155
201
|
def self.unused_import_edits(lines, warning)
|
|
156
202
|
return [] unless warning.line
|
|
157
203
|
|
|
@@ -586,6 +586,38 @@ module MilkTea
|
|
|
586
586
|
def lvalue_expression?(expression)
|
|
587
587
|
expression.is_a?(AST::Identifier) || expression.is_a?(AST::MemberAccess) || expression.is_a?(AST::IndexAccess)
|
|
588
588
|
end
|
|
589
|
+
# ── prefer-inline-methods ──────────────────────────────────────────────
|
|
590
|
+
# Flag `extending X:` blocks whose receiver struct is declared in the same
|
|
591
|
+
# file, suggesting the methods be written inline inside the struct body
|
|
592
|
+
# (which desugars to the identical `extending` block).
|
|
593
|
+
|
|
594
|
+
def emit_prefer_inline_methods_warnings(source_file)
|
|
595
|
+
struct_names = source_file.declarations.filter_map { |decl| decl.name if decl.is_a?(AST::StructDecl) }.to_set
|
|
596
|
+
return if struct_names.empty?
|
|
597
|
+
|
|
598
|
+
source_file.declarations.each do |declaration|
|
|
599
|
+
next unless declaration.is_a?(AST::ExtendingBlock)
|
|
600
|
+
next if declaration.inline
|
|
601
|
+
|
|
602
|
+
parts = declaration.type_name.name.parts
|
|
603
|
+
next unless parts.length == 1
|
|
604
|
+
next if declaration.type_name.arguments.any?
|
|
605
|
+
|
|
606
|
+
name = parts.first
|
|
607
|
+
next unless struct_names.include?(name)
|
|
608
|
+
|
|
609
|
+
@warnings << Warning.new(
|
|
610
|
+
path: @path,
|
|
611
|
+
line: declaration.line,
|
|
612
|
+
column: declaration.column,
|
|
613
|
+
length: name.length,
|
|
614
|
+
code: "prefer-inline-methods",
|
|
615
|
+
message: "methods on '#{name}' can be written inline inside the struct declaration",
|
|
616
|
+
severity: :hint,
|
|
617
|
+
symbol_name: name,
|
|
618
|
+
)
|
|
619
|
+
end
|
|
620
|
+
end
|
|
589
621
|
end
|
|
590
622
|
end
|
|
591
623
|
end
|
|
@@ -35,6 +35,7 @@ module MilkTea
|
|
|
35
35
|
owning-release-double
|
|
36
36
|
prefer-conditional-expression
|
|
37
37
|
prefer-inline-if
|
|
38
|
+
prefer-inline-methods
|
|
38
39
|
prefer-is-variant
|
|
39
40
|
prefer-let
|
|
40
41
|
prefer-let-else
|
|
@@ -69,6 +70,7 @@ module MilkTea
|
|
|
69
70
|
redundant-ignored-match-binding
|
|
70
71
|
prefer-let-else
|
|
71
72
|
prefer-var-else
|
|
73
|
+
prefer-inline-methods
|
|
72
74
|
redundant-bool-compare
|
|
73
75
|
redundant-cast
|
|
74
76
|
redundant-else
|
|
@@ -95,6 +97,7 @@ module MilkTea
|
|
|
95
97
|
"redundant-type-annotation" => "Remove redundant type annotation",
|
|
96
98
|
"prefer-let-else" => "Rewrite as let-else",
|
|
97
99
|
"prefer-var-else" => "Rewrite as var-else",
|
|
100
|
+
"prefer-inline-methods" => "Inline methods into struct",
|
|
98
101
|
"trailing-list-comma" => "Remove trailing list comma",
|
|
99
102
|
}.freeze
|
|
100
103
|
EVENT_STACK_SNAPSHOT_WARNING_THRESHOLD = 128
|
|
@@ -771,6 +774,7 @@ module MilkTea
|
|
|
771
774
|
profile_phase("rule.doc_tag") { emit_doc_tag_warnings(ast) } if full_tier?
|
|
772
775
|
profile_phase("rule.event_capacity") { emit_event_capacity_warnings(ast) }
|
|
773
776
|
profile_phase("rule.trailing_list_comma") { emit_trailing_list_comma_warnings(ast) }
|
|
777
|
+
profile_phase("rule.prefer_inline_methods") { emit_prefer_inline_methods_warnings(ast) }
|
|
774
778
|
profile_phase("rule.line_too_long") { emit_line_too_long_warnings }
|
|
775
779
|
@warnings
|
|
776
780
|
end
|
data/lib/milk_tea/tooling.rb
CHANGED
|
@@ -11,7 +11,6 @@ require_relative "tooling/sexpr_dumper"
|
|
|
11
11
|
require_relative "tooling/sexpr_parser"
|
|
12
12
|
require_relative "tooling/build"
|
|
13
13
|
require_relative "tooling/run"
|
|
14
|
-
require_relative "tooling/cst_formatter"
|
|
15
14
|
require_relative "tooling/error_formatter"
|
|
16
15
|
require_relative "tooling/formatter"
|
|
17
16
|
require_relative "tooling/linter"
|
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.3.
|
|
4
|
+
version: 0.3.40
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Long (Teefan) Tran
|
|
@@ -385,7 +385,6 @@ files:
|
|
|
385
385
|
- lib/milk_tea/tooling/cli/commands/snapshot.rb
|
|
386
386
|
- lib/milk_tea/tooling/cli/commands/test.rb
|
|
387
387
|
- lib/milk_tea/tooling/cli/commands/toolchain.rb
|
|
388
|
-
- lib/milk_tea/tooling/cst_formatter.rb
|
|
389
388
|
- lib/milk_tea/tooling/debug_info_formatter.rb
|
|
390
389
|
- lib/milk_tea/tooling/debug_map.rb
|
|
391
390
|
- lib/milk_tea/tooling/docs_app.rb
|
|
@@ -626,7 +625,7 @@ metadata:
|
|
|
626
625
|
homepage_uri: https://teefan.github.io/mt-lang/
|
|
627
626
|
source_code_uri: https://github.com/teefan/mt-lang
|
|
628
627
|
post_install_message: |
|
|
629
|
-
Milk Tea 0.3.
|
|
628
|
+
Milk Tea 0.3.40 installed!
|
|
630
629
|
|
|
631
630
|
System requirements:
|
|
632
631
|
- A C compiler (gcc or clang) must be available on PATH
|