1+ # -----------------------------------------------------------------------
2+ # This file is part of MoonScript
3+ #
4+ # MoonSript is free software: you can redistribute it and/or modify
5+ # it under the terms of the GNU General Public License as published by
6+ # the Free Software Foundation, either version 3 of the License, or
7+ # (at your option) any later version.
8+ #
9+ # MoonSript is distributed in the hope that it will be useful,
10+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ # GNU General Public License for more details.
13+ #
14+ # You should have received a copy of the GNU General Public License
15+ # along with MoonSript. If not, see <https://www.gnu.org/licenses/>.
16+ #
17+ # Copyright (C) 2025 Krisna Pranav, MoonScript Developers
18+ # -----------------------------------------------------------------------
19+
20+ module MoonScript
21+ class TypeChecker
22+ def check (node : Ast ::Decode ) : Checkable
23+ type =
24+ resolve node.type
25+
26+ error! :decode_complex_type do
27+ snippet " This type cannot be automatically decoded:" , type
28+
29+ snippet(
30+ " Only these types and records containing them cantext be " \
31+ " automatically decoded:" ,
32+ <<-MINT
33+ Map(String, a)
34+ Array(a)
35+ Maybe(a)
36+ String
37+ Number
38+ Object
39+ Time
40+ Bool
41+ MINT
42+ )
43+
44+ snippet " The decode:" , node
45+ end unless check_decode(type )
46+
47+ result_type =
48+ Type .new(" Result" , [OBJECT_ERROR , type ] of Checkable )
49+
50+ if item = node.expression
51+ expression =
52+ resolve item
53+
54+ error! :decode_expected_object do
55+ block do
56+ text " Only the"
57+ bold %( "Object")
58+ text " type:"
59+ end
60+
61+ snippet expression
62+ snippet " The decoded question:" , node
63+ end unless Comparer .compare(expression, OBJECT )
64+
65+ result_type
66+ else
67+ Type .new(" Function" , [OBJECT , result_type] of Checkable )
68+ end
69+ end
70+
71+ def check_decode (type : Checkable )
72+ case type
73+ when Record
74+ type .fields.all? do |_ , value |
75+ check_decode value
76+ end
77+ when Variable
78+ false
79+ else
80+ case type .name
81+ when " String" , " Time" , " Number" , " Bool" , " Object"
82+ true
83+ when " Map"
84+ type .parameters.first.name == " String" &&
85+ type .parameters.first.parameters.size == 0 &&
86+ check_decode(type .parameters.last)
87+ when " Tuple"
88+ type .parameters.all? { |item | check_decode(item) }
89+ when " Array" , " Maybe"
90+ if type .parameters.size == 1
91+ check_decode type .parameters.first
92+ else
93+ false
94+ end
95+ else
96+ false
97+ end
98+ end
99+ end
100+ end
101+ end
0 commit comments