@@ -4,78 +4,112 @@ import Block from '../../Block';
4
4
import TemplateScope from '../../../nodes/shared/TemplateScope' ;
5
5
import { BinaryExpression } from 'estree' ;
6
6
7
- export function get_slot_definition ( block : Block , scope : TemplateScope , lets : Let [ ] ) {
8
- if ( lets . length === 0 ) return { block, scope } ;
9
-
10
- const input = {
11
- type : 'ObjectPattern' ,
12
- properties : lets . map ( l => ( {
13
- type : 'Property' ,
14
- kind : 'init' ,
15
- key : l . name ,
16
- value : l . value || l . name
17
- } ) )
18
- } ;
19
-
20
- const names : Set < string > = new Set ( ) ;
21
- lets . forEach ( l => {
22
- l . names . forEach ( name => {
23
- names . add ( name ) ;
24
- } ) ;
25
- } ) ;
26
-
27
- const context = {
28
- type : 'ObjectExpression' ,
29
- properties : Array . from ( names ) . map ( name => p `${ block . renderer . context_lookup . get ( name ) . index } : ${ name } ` )
30
- } ;
31
-
32
- const { context_lookup } = block . renderer ;
33
-
34
- // i am well aware that this code is gross
35
- // TODO make it less gross
36
- const changes = {
37
- type : 'ParenthesizedExpression' ,
38
- get expression ( ) {
39
- if ( block . renderer . context_overflow ) {
40
- const grouped = [ ] ;
41
-
42
- Array . from ( names ) . forEach ( name => {
43
- const i = context_lookup . get ( name ) . index . value as number ;
44
- const g = Math . floor ( i / 31 ) ;
45
-
46
- if ( ! grouped [ g ] ) grouped [ g ] = [ ] ;
47
- grouped [ g ] . push ( { name, n : i % 31 } ) ;
48
- } ) ;
49
-
50
- const elements = [ ] ;
51
-
52
- for ( let g = 0 ; g < grouped . length ; g += 1 ) {
53
- elements [ g ] = grouped [ g ]
54
- ? grouped [ g ]
55
- . map ( ( { name, n } ) => x `${ name } ? ${ 1 << n } : 0` )
56
- . reduce ( ( lhs , rhs ) => x `${ lhs } | ${ rhs } ` )
57
- : x `0` ;
58
- }
7
+ export function get_slot_definition (
8
+ block : Block ,
9
+ scope : TemplateScope ,
10
+ lets : Let [ ]
11
+ ) {
12
+ return new SlotDefinition ( block , scope , lets ) ;
13
+ }
14
+
15
+ export class SlotDefinition {
16
+ block : Block ;
17
+ scope : TemplateScope ;
18
+ lets : Let [ ] ;
19
+ lets_set : Set < string > ;
59
20
60
- return {
61
- type : 'ArrayExpression' ,
62
- elements
63
- } ;
21
+ constructor ( block : Block , scope : TemplateScope , lets : Let [ ] ) {
22
+ this . block = block ;
23
+ this . scope = scope ;
24
+ this . lets = lets ;
25
+ this . lets_set = new Set ( this . lets . map ( l => l . name . name ) ) ;
26
+ }
27
+
28
+ add_let_binding ( lets : Let [ ] ) {
29
+ for ( const l of lets ) {
30
+ if ( ! this . lets_set . has ( l . name . name ) ) {
31
+ this . lets_set . add ( l . name . name ) ;
32
+ this . lets . push ( l ) ;
64
33
}
34
+ }
35
+ }
65
36
66
- return Array . from ( names )
67
- . map ( name => {
68
- const i = context_lookup . get ( name ) . index . value as number ;
69
- return x `${ name } ? ${ 1 << i } : 0` ;
70
- } )
71
- . reduce ( ( lhs , rhs ) => x `${ lhs } | ${ rhs } ` ) as BinaryExpression ;
37
+ render ( ) {
38
+ if ( this . lets . length === 0 ) {
39
+ return x `[${ this . block . name } , null, null]` ;
72
40
}
73
- } ;
74
-
75
- return {
76
- block,
77
- scope,
78
- get_context : x `${ input } => ${ context } ` ,
79
- get_changes : x `${ input } => ${ changes } `
80
- } ;
81
- }
41
+
42
+ const input = {
43
+ type : 'ObjectPattern' ,
44
+ properties : this . lets . map ( l => ( {
45
+ type : 'Property' ,
46
+ kind : 'init' ,
47
+ key : l . name ,
48
+ value : l . value || l . name ,
49
+ } ) ) ,
50
+ } ;
51
+
52
+ const names : Set < string > = new Set ( ) ;
53
+ this . lets . forEach ( l => {
54
+ l . names . forEach ( name => {
55
+ names . add ( name ) ;
56
+ } ) ;
57
+ } ) ;
58
+
59
+ const context = {
60
+ type : 'ObjectExpression' ,
61
+ properties : Array . from ( names ) . map (
62
+ name =>
63
+ p `${ this . block . renderer . context_lookup . get ( name ) . index } : ${ name } `
64
+ ) ,
65
+ } ;
66
+
67
+ const { context_lookup } = this . block . renderer ;
68
+ const { renderer } = this . block ;
69
+
70
+ // i am well aware that this code is gross
71
+ // TODO make it less gross
72
+ const changes = {
73
+ type : 'ParenthesizedExpression' ,
74
+ get expression ( ) {
75
+ if ( renderer . context_overflow ) {
76
+ const grouped = [ ] ;
77
+ Array . from ( names ) . forEach ( name => {
78
+ const i = context_lookup . get ( name ) . index . value as number ;
79
+ const g = Math . floor ( i / 31 ) ;
80
+
81
+ if ( ! grouped [ g ] ) grouped [ g ] = [ ] ;
82
+ grouped [ g ] . push ( { name, n : i % 31 } ) ;
83
+ } ) ;
84
+
85
+ const elements = [ ] ;
86
+
87
+ for ( let g = 0 ; g < grouped . length ; g += 1 ) {
88
+ elements [ g ] = grouped [ g ]
89
+ ? grouped [ g ]
90
+ . map ( ( { name, n } ) => x `${ name } ? ${ 1 << n } : 0` )
91
+ . reduce ( ( lhs , rhs ) => x `${ lhs } | ${ rhs } ` )
92
+ : x `0` ;
93
+ }
94
+
95
+ return {
96
+ type : 'ArrayExpression' ,
97
+ elements,
98
+ } ;
99
+ }
100
+
101
+ return Array . from ( names )
102
+ . map ( name => {
103
+ const i = context_lookup . get ( name ) . index . value as number ;
104
+ return x `${ name } ? ${ 1 << i } : 0` ;
105
+ } )
106
+ . reduce ( ( lhs , rhs ) => x `${ lhs } | ${ rhs } ` ) as BinaryExpression ;
107
+ } ,
108
+ } ;
109
+
110
+ const get_context = x `${ input } => ${ context } ` ;
111
+ const get_changes = x `${ input } => ${ changes } ` ;
112
+
113
+ return x `[${ this . block . name } , ${ get_context } , ${ get_changes } ]` ;
114
+ }
115
+ }
0 commit comments