@@ -20,22 +20,26 @@ defmodule Module.Types.Descr do
2020 @ bit_pid 1 <<< 4
2121 @ bit_port 1 <<< 5
2222 @ bit_reference 1 <<< 6
23-
2423 @ bit_fun 1 <<< 7
2524 @ bit_top ( 1 <<< 8 ) - 1
26-
2725 @ bit_number @ bit_integer ||| @ bit_float
28- @ bit_optional 1 <<< 8
2926
3027 @ atom_top { :negation , :sets . new ( version: 2 ) }
31- @ tuple_top [ { :open , [ ] , [ ] } ]
3228 @ map_top [ { :open , % { } , [ ] } ]
29+ @ non_empty_list_top [ { :term , :term , [ ] } ]
30+ @ tuple_top [ { :open , [ ] , [ ] } ]
3331 @ map_empty [ { :closed , % { } , [ ] } ]
32+
3433 @ none % { }
3534 @ empty_list % { bitmap: @ bit_empty_list }
36- # A definition of non empty list that does not use negation. Includes empty list.
3735 @ not_non_empty_list % { bitmap: @ bit_top , atom: @ atom_top , tuple: @ tuple_top , map: @ map_top }
38- @ non_empty_list_top [ { :term , @ not_non_empty_list , [ ] } ]
36+ @ term % {
37+ bitmap: @ bit_top ,
38+ atom: @ atom_top ,
39+ tuple: @ tuple_top ,
40+ map: @ map_top ,
41+ list: @ non_empty_list_top
42+ }
3943
4044 # Type definitions
4145
@@ -47,15 +51,7 @@ defmodule Module.Types.Descr do
4751
4852 defp unfold ( :term ) , do: unfolded_term ( )
4953 defp unfold ( other ) , do: other
50-
51- defp unfolded_term ,
52- do: % {
53- bitmap: @ bit_top ,
54- atom: @ atom_top ,
55- tuple: @ tuple_top ,
56- map: @ map_top ,
57- list: @ non_empty_list_top
58- }
54+ defp unfolded_term , do: @ term
5955
6056 def atom ( as ) , do: % { atom: atom_new ( as ) }
6157 def atom ( ) , do: % { atom: @ atom_top }
@@ -92,30 +88,23 @@ defmodule Module.Types.Descr do
9288 #
9389 # `not_set()` has no meaning outside of map types.
9490
95- @ not_set % { bitmap: @ bit_optional }
96- @ term_or_optional % {
97- bitmap: @ bit_top ||| @ bit_optional ,
98- atom: @ atom_top ,
99- tuple: @ tuple_top ,
100- map: @ map_top ,
101- list: @ non_empty_list_top
102- }
91+ @ not_set % { optional: 1 }
92+ @ term_or_optional Map . put ( @ term , :optional , 1 )
10393
10494 def not_set ( ) , do: @ not_set
10595 defp term_or_optional ( ) , do: @ term_or_optional
10696
10797 def if_set ( :term ) , do: term_or_optional ( )
108- def if_set ( type ) , do: Map . update ( type , :bitmap , @ bit_optional , & ( & 1 ||| @ bit_optional ) )
98+ def if_set ( type ) , do: Map . put ( type , :optional , 1 )
10999
110100 defguardp is_optional ( map )
111101 when is_map ( map ) and
112- ( ( is_map_key ( map , :bitmap ) and ( map . bitmap &&& @ bit_optional ) != 0 ) or
102+ ( is_map_key ( map , :optional ) or
113103 ( is_map_key ( map , :dynamic ) and is_map ( map . dynamic ) and
114- is_map_key ( map . dynamic , :bitmap ) and
115- ( map . dynamic . bitmap &&& @ bit_optional ) != 0 ) )
104+ is_map_key ( map . dynamic , :optional ) ) )
116105
117106 defguardp is_optional_static ( map )
118- when is_map ( map ) and is_map_key ( map , :bitmap ) and ( map . bitmap &&& @ bit_optional ) != 0
107+ when is_map ( map ) and is_map_key ( map , :optional )
119108
120109 defp descr_key? ( :term , _key ) , do: true
121110 defp descr_key? ( descr , key ) , do: is_map_key ( descr , key )
@@ -125,8 +114,6 @@ defmodule Module.Types.Descr do
125114 def term_type? ( :term ) , do: true
126115 def term_type? ( descr ) , do: subtype_static? ( unfolded_term ( ) , Map . delete ( descr , :dynamic ) )
127116
128- def dynamic_term_type? ( descr ) , do: descr == % { dynamic: :term }
129-
130117 def gradual? ( :term ) , do: false
131118 def gradual? ( descr ) , do: is_map_key ( descr , :dynamic )
132119
@@ -171,12 +158,13 @@ defmodule Module.Types.Descr do
171158 end
172159
173160 @ compile { :inline , union: 3 }
174- defp union ( :bitmap , v1 , v2 ) , do: bitmap_union ( v1 , v2 )
175161 defp union ( :atom , v1 , v2 ) , do: atom_union ( v1 , v2 )
162+ defp union ( :bitmap , v1 , v2 ) , do: v1 ||| v2
176163 defp union ( :dynamic , v1 , v2 ) , do: dynamic_union ( v1 , v2 )
164+ defp union ( :list , v1 , v2 ) , do: list_union ( v1 , v2 )
177165 defp union ( :map , v1 , v2 ) , do: map_union ( v1 , v2 )
166+ defp union ( :optional , 1 , 1 ) , do: 1
178167 defp union ( :tuple , v1 , v2 ) , do: tuple_union ( v1 , v2 )
179- defp union ( :list , v1 , v2 ) , do: list_union ( v1 , v2 )
180168
181169 @ doc """
182170 Computes the intersection of two descrs.
@@ -208,12 +196,13 @@ defmodule Module.Types.Descr do
208196
209197 # Returning 0 from the callback is taken as none() for that subtype.
210198 @ compile { :inline , intersection: 3 }
211- defp intersection ( :bitmap , v1 , v2 ) , do: bitmap_intersection ( v1 , v2 )
212199 defp intersection ( :atom , v1 , v2 ) , do: atom_intersection ( v1 , v2 )
200+ defp intersection ( :bitmap , v1 , v2 ) , do: v1 &&& v2
213201 defp intersection ( :dynamic , v1 , v2 ) , do: dynamic_intersection ( v1 , v2 )
202+ defp intersection ( :list , v1 , v2 ) , do: list_intersection ( v1 , v2 )
214203 defp intersection ( :map , v1 , v2 ) , do: map_intersection ( v1 , v2 )
204+ defp intersection ( :optional , 1 , 1 ) , do: 1
215205 defp intersection ( :tuple , v1 , v2 ) , do: tuple_intersection ( v1 , v2 )
216- defp intersection ( :list , v1 , v2 ) , do: list_intersection ( v1 , v2 )
217206
218207 @ doc """
219208 Computes the difference between two types.
@@ -265,12 +254,13 @@ defmodule Module.Types.Descr do
265254
266255 # Returning 0 from the callback is taken as none() for that subtype.
267256 @ compile { :inline , difference: 3 }
268- defp difference ( :bitmap , v1 , v2 ) , do: bitmap_difference ( v1 , v2 )
269257 defp difference ( :atom , v1 , v2 ) , do: atom_difference ( v1 , v2 )
258+ defp difference ( :bitmap , v1 , v2 ) , do: v1 - ( v1 &&& v2 )
270259 defp difference ( :dynamic , v1 , v2 ) , do: dynamic_difference ( v1 , v2 )
260+ defp difference ( :list , v1 , v2 ) , do: list_difference ( v1 , v2 )
271261 defp difference ( :map , v1 , v2 ) , do: map_difference ( v1 , v2 )
262+ defp difference ( :optional , 1 , 1 ) , do: 0
272263 defp difference ( :tuple , v1 , v2 ) , do: tuple_difference ( v1 , v2 )
273- defp difference ( :list , v1 , v2 ) , do: list_difference ( v1 , v2 )
274264
275265 @ doc """
276266 Compute the negation of a type.
@@ -297,10 +287,12 @@ defmodule Module.Types.Descr do
297287 true
298288
299289 descr ->
300- not Map . has_key? ( descr , :bitmap ) and not Map . has_key? ( descr , :atom ) and
301- ( not Map . has_key? ( descr , :tuple ) or tuple_empty? ( descr . tuple ) ) and
290+ not Map . has_key? ( descr , :atom ) and
291+ not Map . has_key? ( descr , :bitmap ) and
292+ not Map . has_key? ( descr , :optional ) and
302293 ( not Map . has_key? ( descr , :map ) or map_empty? ( descr . map ) ) and
303- ( not Map . has_key? ( descr , :list ) or list_empty? ( descr . list ) )
294+ ( not Map . has_key? ( descr , :list ) or list_empty? ( descr . list ) ) and
295+ ( not Map . has_key? ( descr , :tuple ) or tuple_empty? ( descr . tuple ) )
304296 end
305297 end
306298
@@ -319,12 +311,12 @@ defmodule Module.Types.Descr do
319311 end
320312
321313 @ compile { :inline , to_quoted: 2 }
322- defp to_quoted ( :bitmap , val ) , do: bitmap_to_quoted ( val )
323314 defp to_quoted ( :atom , val ) , do: atom_to_quoted ( val )
315+ defp to_quoted ( :bitmap , val ) , do: bitmap_to_quoted ( val )
324316 defp to_quoted ( :dynamic , descr ) , do: dynamic_to_quoted ( descr )
325317 defp to_quoted ( :map , dnf ) , do: map_to_quoted ( dnf )
326- defp to_quoted ( :tuple , dnf ) , do: tuple_to_quoted ( dnf )
327318 defp to_quoted ( :list , dnf ) , do: list_to_quoted ( dnf )
319+ defp to_quoted ( :tuple , dnf ) , do: tuple_to_quoted ( dnf )
328320
329321 @ doc """
330322 Converts a descr to its quoted string representation.
@@ -454,8 +446,6 @@ defmodule Module.Types.Descr do
454446 end
455447 end
456448
457- ## Bitmaps
458-
459449 @ doc """
460450 Optimized version of `not empty?(intersection(empty_list(), type))`.
461451 """
@@ -513,9 +503,7 @@ defmodule Module.Types.Descr do
513503 def list_type? ( % { list: _ } ) , do: true
514504 def list_type? ( _ ) , do: false
515505
516- defp bitmap_union ( v1 , v2 ) , do: v1 ||| v2
517- defp bitmap_intersection ( v1 , v2 ) , do: v1 &&& v2
518- defp bitmap_difference ( v1 , v2 ) , do: v1 - ( v1 &&& v2 )
506+ ## Bitmaps
519507
520508 defp bitmap_to_quoted ( val ) do
521509 pairs =
@@ -1218,16 +1206,12 @@ defmodule Module.Types.Descr do
12181206 end
12191207 end
12201208
1221- defp pop_optional_static ( type ) do
1222- case type do
1223- % { bitmap: @ bit_optional } ->
1224- { true , Map . delete ( type , :bitmap ) }
1225-
1226- % { bitmap: bitmap } when ( bitmap &&& @ bit_optional ) != 0 ->
1227- { true , % { type | bitmap: bitmap - @ bit_optional } }
1209+ defp pop_optional_static ( :term ) , do: { false , :term }
12281210
1229- _ ->
1230- { false , type }
1211+ defp pop_optional_static ( type ) do
1212+ case :maps . take ( :optional , type ) do
1213+ :error -> { false , type }
1214+ { 1 , type } -> { true , type }
12311215 end
12321216 end
12331217
@@ -1587,8 +1571,10 @@ defmodule Module.Types.Descr do
15871571 literal_to_quoted ( key )
15881572 end
15891573
1574+ { optional? , type } = pop_optional_static ( type )
1575+
15901576 cond do
1591- not is_optional_static ( type ) -> { key , to_quoted ( type ) }
1577+ not optional? -> { key , to_quoted ( type ) }
15921578 empty? ( type ) -> { key , { :not_set , [ ] , [ ] } }
15931579 true -> { key , { :if_set , [ ] , [ to_quoted ( type ) ] } }
15941580 end
0 commit comments