1 /*
<lambda>null2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 @file:OptIn(InternalComposeApi::class)
18 
19 package androidx.compose.runtime.internal
20 
21 import androidx.compose.runtime.Composable
22 import androidx.compose.runtime.ComposeCompilerApi
23 import androidx.compose.runtime.Composer
24 import androidx.compose.runtime.InternalComposeApi
25 import androidx.compose.runtime.RecomposeScope
26 import androidx.compose.runtime.RecomposeScopeImpl
27 import androidx.compose.runtime.Stable
28 import androidx.compose.runtime.remember
29 import androidx.compose.runtime.rol
30 import androidx.compose.runtime.updateChangedFlags
31 
32 internal const val SLOTS_PER_INT = 10
33 private const val BITS_PER_SLOT = 3
34 
35 internal fun bitsForSlot(bits: Int, slot: Int): Int {
36     val realSlot = slot.rem(SLOTS_PER_INT)
37     return bits shl (realSlot * BITS_PER_SLOT + 1)
38 }
39 
sameBitsnull40 internal fun sameBits(slot: Int): Int = bitsForSlot(0b01, slot)
41 
42 internal fun differentBits(slot: Int): Int = bitsForSlot(0b10, slot)
43 
44 /**
45  * A Restart is created to hold composable lambdas to track when they are invoked allowing the
46  * invocations to be invalidated when a new composable lambda is created during composition.
47  *
48  * This allows much of the call-graph to be skipped when a composable function is passed through
49  * multiple levels of composable functions.
50  */
51 @Suppress("NAME_SHADOWING", "UNCHECKED_CAST")
52 @Stable
53 internal class ComposableLambdaImpl(val key: Int, private val tracked: Boolean, block: Any?) :
54     ComposableLambda {
55     private var _block: Any? = block
56     private var scope: RecomposeScope? = null
57     private var scopes: MutableList<RecomposeScope>? = null
58 
59     private fun trackWrite() {
60         if (tracked) {
61             val scope = this.scope
62             if (scope != null) {
63                 scope.invalidate()
64                 this.scope = null
65             }
66             val scopes = this.scopes
67             if (scopes != null) {
68                 for (index in 0 until scopes.size) {
69                     val item = scopes[index]
70                     item.invalidate()
71                 }
72                 scopes.clear()
73             }
74         }
75     }
76 
77     private fun trackRead(composer: Composer) {
78         if (tracked) {
79             val scope = composer.recomposeScope
80             if (scope != null) {
81                 // Find the first invalid scope and replace it or record it if no scopes are invalid
82                 composer.recordUsed(scope)
83                 val lastScope = this.scope
84                 if (lastScope.replacableWith(scope)) {
85                     this.scope = scope
86                 } else {
87                     val lastScopes = scopes
88                     if (lastScopes == null) {
89                         val newScopes = mutableListOf<RecomposeScope>()
90                         scopes = newScopes
91                         newScopes.add(scope)
92                     } else {
93                         for (index in 0 until lastScopes.size) {
94                             val scopeAtIndex = lastScopes[index]
95                             if (scopeAtIndex.replacableWith(scope)) {
96                                 lastScopes[index] = scope
97                                 return
98                             }
99                         }
100                         lastScopes.add(scope)
101                     }
102                 }
103             }
104         }
105     }
106 
107     fun update(block: Any) {
108         if (_block != block) {
109             val oldBlockNull = _block == null
110             _block = block
111             if (!oldBlockNull) {
112                 trackWrite()
113             }
114         }
115     }
116 
117     override operator fun invoke(c: Composer, changed: Int): Any? {
118         val c = c.startRestartGroup(key)
119         trackRead(c)
120         val dirty = changed or if (c.changed(this)) differentBits(0) else sameBits(0)
121         val result = (_block as (c: Composer, changed: Int) -> Any?)(c, dirty)
122         c.endRestartGroup()?.updateScope(this::invoke)
123         return result
124     }
125 
126     override operator fun invoke(p1: Any?, c: Composer, changed: Int): Any? {
127         val c = c.startRestartGroup(key)
128         trackRead(c)
129         val dirty = changed or if (c.changed(this)) differentBits(1) else sameBits(1)
130         val result = (_block as (p1: Any?, c: Composer, changed: Int) -> Any?)(p1, c, dirty)
131         c.endRestartGroup()?.updateScope { nc, _ ->
132             this(p1, nc, updateChangedFlags(changed) or 0b1)
133         }
134         return result
135     }
136 
137     override operator fun invoke(p1: Any?, p2: Any?, c: Composer, changed: Int): Any? {
138         val c = c.startRestartGroup(key)
139         trackRead(c)
140         val dirty = changed or if (c.changed(this)) differentBits(2) else sameBits(2)
141         val result =
142             (_block as (p1: Any?, p2: Any?, c: Composer, changed: Int) -> Any?)(p1, p2, c, dirty)
143         c.endRestartGroup()?.updateScope { nc, _ ->
144             this(p1, p2, nc, updateChangedFlags(changed) or 0b1)
145         }
146         return result
147     }
148 
149     override operator fun invoke(p1: Any?, p2: Any?, p3: Any?, c: Composer, changed: Int): Any? {
150         val c = c.startRestartGroup(key)
151         trackRead(c)
152         val dirty = changed or if (c.changed(this)) differentBits(3) else sameBits(3)
153         val result =
154             (_block as (p1: Any?, p2: Any?, p3: Any?, c: Composer, changed: Int) -> Any?)(
155                 p1,
156                 p2,
157                 p3,
158                 c,
159                 dirty
160             )
161         c.endRestartGroup()?.updateScope { nc, _ ->
162             this(p1, p2, p3, nc, updateChangedFlags(changed) or 0b1)
163         }
164         return result
165     }
166 
167     override operator fun invoke(
168         p1: Any?,
169         p2: Any?,
170         p3: Any?,
171         p4: Any?,
172         c: Composer,
173         changed: Int
174     ): Any? {
175         val c = c.startRestartGroup(key)
176         trackRead(c)
177         val dirty = changed or if (c.changed(this)) differentBits(4) else sameBits(4)
178         val result =
179             (_block as (p1: Any?, p2: Any?, p3: Any?, p4: Any?, c: Composer, changed: Int) -> Any?)(
180                 p1,
181                 p2,
182                 p3,
183                 p4,
184                 c,
185                 dirty
186             )
187         c.endRestartGroup()?.updateScope { nc, _ ->
188             this(p1, p2, p3, p4, nc, updateChangedFlags(changed) or 0b1)
189         }
190         return result
191     }
192 
193     override operator fun invoke(
194         p1: Any?,
195         p2: Any?,
196         p3: Any?,
197         p4: Any?,
198         p5: Any?,
199         c: Composer,
200         changed: Int
201     ): Any? {
202         val c = c.startRestartGroup(key)
203         trackRead(c)
204         val dirty = changed or if (c.changed(this)) differentBits(5) else sameBits(5)
205         val result =
206             (_block
207                 as
208                 (
209                     p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, c: Composer, changed: Int
210                 ) -> Any?)(p1, p2, p3, p4, p5, c, dirty)
211         c.endRestartGroup()?.updateScope { nc, _ ->
212             this(p1, p2, p3, p4, p5, nc, updateChangedFlags(changed) or 0b1)
213         }
214         return result
215     }
216 
217     override operator fun invoke(
218         p1: Any?,
219         p2: Any?,
220         p3: Any?,
221         p4: Any?,
222         p5: Any?,
223         p6: Any?,
224         c: Composer,
225         changed: Int
226     ): Any? {
227         val c = c.startRestartGroup(key)
228         trackRead(c)
229         val dirty = changed or if (c.changed(this)) differentBits(6) else sameBits(6)
230         val result =
231             (_block
232                 as
233                 (
234                     p1: Any?,
235                     p2: Any?,
236                     p3: Any?,
237                     p4: Any?,
238                     p5: Any?,
239                     p6: Any?,
240                     c: Composer,
241                     changed: Int
242                 ) -> Any?)(p1, p2, p3, p4, p5, p6, c, dirty)
243         c.endRestartGroup()?.updateScope { nc, _ ->
244             this(p1, p2, p3, p4, p5, p6, nc, updateChangedFlags(changed) or 0b1)
245         }
246         return result
247     }
248 
249     override operator fun invoke(
250         p1: Any?,
251         p2: Any?,
252         p3: Any?,
253         p4: Any?,
254         p5: Any?,
255         p6: Any?,
256         p7: Any?,
257         c: Composer,
258         changed: Int
259     ): Any? {
260         val c = c.startRestartGroup(key)
261         trackRead(c)
262         val dirty = changed or if (c.changed(this)) differentBits(7) else sameBits(7)
263         val result =
264             (_block
265                 as
266                 (
267                     p1: Any?,
268                     p2: Any?,
269                     p3: Any?,
270                     p4: Any?,
271                     p5: Any?,
272                     p6: Any?,
273                     p7: Any?,
274                     c: Composer,
275                     changed: Int
276                 ) -> Any?)(p1, p2, p3, p4, p5, p6, p7, c, dirty)
277         c.endRestartGroup()?.updateScope { nc, _ ->
278             this(p1, p2, p3, p4, p5, p6, p7, nc, updateChangedFlags(changed) or 0b1)
279         }
280         return result
281     }
282 
283     override operator fun invoke(
284         p1: Any?,
285         p2: Any?,
286         p3: Any?,
287         p4: Any?,
288         p5: Any?,
289         p6: Any?,
290         p7: Any?,
291         p8: Any?,
292         c: Composer,
293         changed: Int
294     ): Any? {
295         val c = c.startRestartGroup(key)
296         trackRead(c)
297         val dirty = changed or if (c.changed(this)) differentBits(8) else sameBits(8)
298         val result =
299             (_block
300                 as
301                 (
302                     p1: Any?,
303                     p2: Any?,
304                     p3: Any?,
305                     p4: Any?,
306                     p5: Any?,
307                     p6: Any?,
308                     p7: Any?,
309                     p8: Any?,
310                     c: Composer,
311                     changed: Int
312                 ) -> Any?)(p1, p2, p3, p4, p5, p6, p7, p8, c, dirty)
313         c.endRestartGroup()?.updateScope { nc, _ ->
314             this(p1, p2, p3, p4, p5, p6, p7, p8, nc, updateChangedFlags(changed) or 0b1)
315         }
316         return result
317     }
318 
319     override operator fun invoke(
320         p1: Any?,
321         p2: Any?,
322         p3: Any?,
323         p4: Any?,
324         p5: Any?,
325         p6: Any?,
326         p7: Any?,
327         p8: Any?,
328         p9: Any?,
329         c: Composer,
330         changed: Int
331     ): Any? {
332         val c = c.startRestartGroup(key)
333         trackRead(c)
334         val dirty = changed or if (c.changed(this)) differentBits(9) else sameBits(9)
335         val result =
336             (_block
337                 as
338                 (
339                     p1: Any?,
340                     p2: Any?,
341                     p3: Any?,
342                     p4: Any?,
343                     p5: Any?,
344                     p6: Any?,
345                     p7: Any?,
346                     p8: Any?,
347                     p9: Any?,
348                     c: Composer,
349                     changed: Int
350                 ) -> Any?)(p1, p2, p3, p4, p5, p6, p7, p8, p9, c, dirty)
351         c.endRestartGroup()?.updateScope { nc, _ ->
352             this(p1, p2, p3, p4, p5, p6, p7, p8, p9, nc, updateChangedFlags(changed) or 0b1)
353         }
354         return result
355     }
356 
357     override operator fun invoke(
358         p1: Any?,
359         p2: Any?,
360         p3: Any?,
361         p4: Any?,
362         p5: Any?,
363         p6: Any?,
364         p7: Any?,
365         p8: Any?,
366         p9: Any?,
367         p10: Any?,
368         c: Composer,
369         changed: Int,
370         changed1: Int
371     ): Any? {
372         val c = c.startRestartGroup(key)
373         trackRead(c)
374         val dirty = changed1 or if (c.changed(this)) differentBits(10) else sameBits(10)
375         val result =
376             (_block
377                 as
378                 (
379                     p1: Any?,
380                     p2: Any?,
381                     p3: Any?,
382                     p4: Any?,
383                     p5: Any?,
384                     p6: Any?,
385                     p7: Any?,
386                     p8: Any?,
387                     p9: Any?,
388                     p10: Any?,
389                     c: Composer,
390                     changed: Int,
391                     changed1: Int
392                 ) -> Any?)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, c, changed, dirty)
393         c.endRestartGroup()?.updateScope { nc, _ ->
394             this(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, nc, changed or 0b1, changed)
395         }
396         return result
397     }
398 
399     override operator fun invoke(
400         p1: Any?,
401         p2: Any?,
402         p3: Any?,
403         p4: Any?,
404         p5: Any?,
405         p6: Any?,
406         p7: Any?,
407         p8: Any?,
408         p9: Any?,
409         p10: Any?,
410         p11: Any?,
411         c: Composer,
412         changed: Int,
413         changed1: Int
414     ): Any? {
415         val c = c.startRestartGroup(key)
416         trackRead(c)
417         val dirty = changed1 or if (c.changed(this)) differentBits(11) else sameBits(11)
418         val result =
419             (_block
420                 as
421                 (
422                     p1: Any?,
423                     p2: Any?,
424                     p3: Any?,
425                     p4: Any?,
426                     p5: Any?,
427                     p6: Any?,
428                     p7: Any?,
429                     p8: Any?,
430                     p9: Any?,
431                     p10: Any?,
432                     p11: Any?,
433                     c: Composer,
434                     changed: Int,
435                     changed1: Int
436                 ) -> Any?)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, c, changed, dirty)
437         c.endRestartGroup()?.updateScope { nc, _ ->
438             this(
439                 p1,
440                 p2,
441                 p3,
442                 p4,
443                 p5,
444                 p6,
445                 p7,
446                 p8,
447                 p9,
448                 p10,
449                 p11,
450                 nc,
451                 updateChangedFlags(changed) or 0b1,
452                 updateChangedFlags(changed1)
453             )
454         }
455         return result
456     }
457 
458     override operator fun invoke(
459         p1: Any?,
460         p2: Any?,
461         p3: Any?,
462         p4: Any?,
463         p5: Any?,
464         p6: Any?,
465         p7: Any?,
466         p8: Any?,
467         p9: Any?,
468         p10: Any?,
469         p11: Any?,
470         p12: Any?,
471         c: Composer,
472         changed: Int,
473         changed1: Int
474     ): Any? {
475         val c = c.startRestartGroup(key)
476         trackRead(c)
477         val dirty = changed1 or if (c.changed(this)) differentBits(12) else sameBits(12)
478         val result =
479             (_block
480                 as
481                 (
482                     p1: Any?,
483                     p2: Any?,
484                     p3: Any?,
485                     p4: Any?,
486                     p5: Any?,
487                     p6: Any?,
488                     p7: Any?,
489                     p8: Any?,
490                     p9: Any?,
491                     p10: Any?,
492                     p11: Any?,
493                     p12: Any?,
494                     c: Composer,
495                     changed: Int,
496                     changed1: Int
497                 ) -> Any?)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, c, changed, dirty)
498         c.endRestartGroup()?.updateScope { nc, _ ->
499             this(
500                 p1,
501                 p2,
502                 p3,
503                 p4,
504                 p5,
505                 p6,
506                 p7,
507                 p8,
508                 p9,
509                 p10,
510                 p11,
511                 p12,
512                 nc,
513                 updateChangedFlags(changed) or 0b1,
514                 updateChangedFlags(changed1)
515             )
516         }
517         return result
518     }
519 
520     override operator fun invoke(
521         p1: Any?,
522         p2: Any?,
523         p3: Any?,
524         p4: Any?,
525         p5: Any?,
526         p6: Any?,
527         p7: Any?,
528         p8: Any?,
529         p9: Any?,
530         p10: Any?,
531         p11: Any?,
532         p12: Any?,
533         p13: Any?,
534         c: Composer,
535         changed: Int,
536         changed1: Int
537     ): Any? {
538         val c = c.startRestartGroup(key)
539         trackRead(c)
540         val dirty = changed1 or if (c.changed(this)) differentBits(13) else sameBits(13)
541         val result =
542             (_block
543                 as
544                 (
545                     p1: Any?,
546                     p2: Any?,
547                     p3: Any?,
548                     p4: Any?,
549                     p5: Any?,
550                     p6: Any?,
551                     p7: Any?,
552                     p8: Any?,
553                     p9: Any?,
554                     p10: Any?,
555                     p11: Any?,
556                     p12: Any?,
557                     p13: Any?,
558                     c: Composer,
559                     changed: Int,
560                     changed1: Int
561                 ) -> Any?)(
562                 p1,
563                 p2,
564                 p3,
565                 p4,
566                 p5,
567                 p6,
568                 p7,
569                 p8,
570                 p9,
571                 p10,
572                 p11,
573                 p12,
574                 p13,
575                 c,
576                 changed,
577                 dirty
578             )
579         c.endRestartGroup()?.updateScope { nc, _ ->
580             this(
581                 p1,
582                 p2,
583                 p3,
584                 p4,
585                 p5,
586                 p6,
587                 p7,
588                 p8,
589                 p9,
590                 p10,
591                 p11,
592                 p12,
593                 p13,
594                 nc,
595                 updateChangedFlags(changed) or 0b1,
596                 updateChangedFlags(changed1)
597             )
598         }
599         return result
600     }
601 
602     override operator fun invoke(
603         p1: Any?,
604         p2: Any?,
605         p3: Any?,
606         p4: Any?,
607         p5: Any?,
608         p6: Any?,
609         p7: Any?,
610         p8: Any?,
611         p9: Any?,
612         p10: Any?,
613         p11: Any?,
614         p12: Any?,
615         p13: Any?,
616         p14: Any?,
617         c: Composer,
618         changed: Int,
619         changed1: Int
620     ): Any? {
621         val c = c.startRestartGroup(key)
622         trackRead(c)
623         val dirty = changed1 or if (c.changed(this)) differentBits(14) else sameBits(14)
624         val result =
625             (_block
626                 as
627                 (
628                     p1: Any?,
629                     p2: Any?,
630                     p3: Any?,
631                     p4: Any?,
632                     p5: Any?,
633                     p6: Any?,
634                     p7: Any?,
635                     p8: Any?,
636                     p9: Any?,
637                     p10: Any?,
638                     p11: Any?,
639                     p12: Any?,
640                     p13: Any?,
641                     p14: Any?,
642                     c: Composer,
643                     changed: Int,
644                     changed1: Int
645                 ) -> Any?)(
646                 p1,
647                 p2,
648                 p3,
649                 p4,
650                 p5,
651                 p6,
652                 p7,
653                 p8,
654                 p9,
655                 p10,
656                 p11,
657                 p12,
658                 p13,
659                 p14,
660                 c,
661                 changed,
662                 dirty
663             )
664         c.endRestartGroup()?.updateScope { nc, _ ->
665             this(
666                 p1,
667                 p2,
668                 p3,
669                 p4,
670                 p5,
671                 p6,
672                 p7,
673                 p8,
674                 p9,
675                 p10,
676                 p11,
677                 p12,
678                 p13,
679                 p14,
680                 nc,
681                 updateChangedFlags(changed) or 0b1,
682                 updateChangedFlags(changed1)
683             )
684         }
685         return result
686     }
687 
688     override operator fun invoke(
689         p1: Any?,
690         p2: Any?,
691         p3: Any?,
692         p4: Any?,
693         p5: Any?,
694         p6: Any?,
695         p7: Any?,
696         p8: Any?,
697         p9: Any?,
698         p10: Any?,
699         p11: Any?,
700         p12: Any?,
701         p13: Any?,
702         p14: Any?,
703         p15: Any?,
704         c: Composer,
705         changed: Int,
706         changed1: Int
707     ): Any? {
708         val c = c.startRestartGroup(key)
709         trackRead(c)
710         val dirty = changed1 or if (c.changed(this)) differentBits(15) else sameBits(15)
711         val result =
712             (_block
713                 as
714                 (
715                     p1: Any?,
716                     p2: Any?,
717                     p3: Any?,
718                     p4: Any?,
719                     p5: Any?,
720                     p6: Any?,
721                     p7: Any?,
722                     p8: Any?,
723                     p9: Any?,
724                     p10: Any?,
725                     p11: Any?,
726                     p12: Any?,
727                     p13: Any?,
728                     p14: Any?,
729                     p15: Any?,
730                     c: Composer,
731                     changed: Int,
732                     changed1: Int
733                 ) -> Any?)(
734                 p1,
735                 p2,
736                 p3,
737                 p4,
738                 p5,
739                 p6,
740                 p7,
741                 p8,
742                 p9,
743                 p10,
744                 p11,
745                 p12,
746                 p13,
747                 p14,
748                 p15,
749                 c,
750                 changed,
751                 dirty
752             )
753         c.endRestartGroup()?.updateScope { nc, _ ->
754             this(
755                 p1,
756                 p2,
757                 p3,
758                 p4,
759                 p5,
760                 p6,
761                 p7,
762                 p8,
763                 p9,
764                 p10,
765                 p11,
766                 p12,
767                 p13,
768                 p14,
769                 p15,
770                 nc,
771                 updateChangedFlags(changed) or 0b1,
772                 updateChangedFlags(changed1)
773             )
774         }
775         return result
776     }
777 
778     override operator fun invoke(
779         p1: Any?,
780         p2: Any?,
781         p3: Any?,
782         p4: Any?,
783         p5: Any?,
784         p6: Any?,
785         p7: Any?,
786         p8: Any?,
787         p9: Any?,
788         p10: Any?,
789         p11: Any?,
790         p12: Any?,
791         p13: Any?,
792         p14: Any?,
793         p15: Any?,
794         p16: Any?,
795         c: Composer,
796         changed: Int,
797         changed1: Int
798     ): Any? {
799         val c = c.startRestartGroup(key)
800         trackRead(c)
801         val dirty = changed1 or if (c.changed(this)) differentBits(16) else sameBits(16)
802         val result =
803             (_block
804                 as
805                 (
806                     p1: Any?,
807                     p2: Any?,
808                     p3: Any?,
809                     p4: Any?,
810                     p5: Any?,
811                     p6: Any?,
812                     p7: Any?,
813                     p8: Any?,
814                     p9: Any?,
815                     p10: Any?,
816                     p11: Any?,
817                     p12: Any?,
818                     p13: Any?,
819                     p14: Any?,
820                     p15: Any?,
821                     p16: Any?,
822                     c: Composer,
823                     changed: Int,
824                     changed1: Int
825                 ) -> Any?)(
826                 p1,
827                 p2,
828                 p3,
829                 p4,
830                 p5,
831                 p6,
832                 p7,
833                 p8,
834                 p9,
835                 p10,
836                 p11,
837                 p12,
838                 p13,
839                 p14,
840                 p15,
841                 p16,
842                 c,
843                 changed,
844                 dirty
845             )
846         c.endRestartGroup()?.updateScope { nc, _ ->
847             this(
848                 p1,
849                 p2,
850                 p3,
851                 p4,
852                 p5,
853                 p6,
854                 p7,
855                 p8,
856                 p9,
857                 p10,
858                 p11,
859                 p12,
860                 p13,
861                 p14,
862                 p15,
863                 p16,
864                 nc,
865                 updateChangedFlags(changed) or 0b1,
866                 updateChangedFlags(changed1)
867             )
868         }
869         return result
870     }
871 
872     override operator fun invoke(
873         p1: Any?,
874         p2: Any?,
875         p3: Any?,
876         p4: Any?,
877         p5: Any?,
878         p6: Any?,
879         p7: Any?,
880         p8: Any?,
881         p9: Any?,
882         p10: Any?,
883         p11: Any?,
884         p12: Any?,
885         p13: Any?,
886         p14: Any?,
887         p15: Any?,
888         p16: Any?,
889         p17: Any?,
890         c: Composer,
891         changed: Int,
892         changed1: Int
893     ): Any? {
894         val c = c.startRestartGroup(key)
895         trackRead(c)
896         val dirty = changed1 or if (c.changed(this)) differentBits(17) else sameBits(17)
897         val result =
898             (_block
899                 as
900                 (
901                     p1: Any?,
902                     p2: Any?,
903                     p3: Any?,
904                     p4: Any?,
905                     p5: Any?,
906                     p6: Any?,
907                     p7: Any?,
908                     p8: Any?,
909                     p9: Any?,
910                     p10: Any?,
911                     p11: Any?,
912                     p12: Any?,
913                     p13: Any?,
914                     p14: Any?,
915                     p15: Any?,
916                     p16: Any?,
917                     p17: Any?,
918                     c: Composer,
919                     changed: Int,
920                     changed1: Int
921                 ) -> Any?)(
922                 p1,
923                 p2,
924                 p3,
925                 p4,
926                 p5,
927                 p6,
928                 p7,
929                 p8,
930                 p9,
931                 p10,
932                 p11,
933                 p12,
934                 p13,
935                 p14,
936                 p15,
937                 p16,
938                 p17,
939                 c,
940                 changed,
941                 dirty
942             )
943         c.endRestartGroup()?.updateScope { nc, _ ->
944             this(
945                 p1,
946                 p2,
947                 p3,
948                 p4,
949                 p5,
950                 p6,
951                 p7,
952                 p8,
953                 p9,
954                 p10,
955                 p11,
956                 p12,
957                 p13,
958                 p14,
959                 p15,
960                 p16,
961                 p17,
962                 nc,
963                 updateChangedFlags(changed) or 0b1,
964                 updateChangedFlags(changed1)
965             )
966         }
967         return result
968     }
969 
970     override operator fun invoke(
971         p1: Any?,
972         p2: Any?,
973         p3: Any?,
974         p4: Any?,
975         p5: Any?,
976         p6: Any?,
977         p7: Any?,
978         p8: Any?,
979         p9: Any?,
980         p10: Any?,
981         p11: Any?,
982         p12: Any?,
983         p13: Any?,
984         p14: Any?,
985         p15: Any?,
986         p16: Any?,
987         p17: Any?,
988         p18: Any?,
989         c: Composer,
990         changed: Int,
991         changed1: Int
992     ): Any? {
993         val c = c.startRestartGroup(key)
994         trackRead(c)
995         val dirty = changed1 or if (c.changed(this)) differentBits(18) else sameBits(18)
996         val result =
997             (_block
998                 as
999                 (
1000                     p1: Any?,
1001                     p2: Any?,
1002                     p3: Any?,
1003                     p4: Any?,
1004                     p5: Any?,
1005                     p6: Any?,
1006                     p7: Any?,
1007                     p8: Any?,
1008                     p9: Any?,
1009                     p10: Any?,
1010                     p11: Any?,
1011                     p12: Any?,
1012                     p13: Any?,
1013                     p14: Any?,
1014                     p15: Any?,
1015                     p16: Any?,
1016                     p17: Any?,
1017                     p18: Any?,
1018                     c: Composer,
1019                     changed: Int,
1020                     changed1: Int
1021                 ) -> Any?)(
1022                 p1,
1023                 p2,
1024                 p3,
1025                 p4,
1026                 p5,
1027                 p6,
1028                 p7,
1029                 p8,
1030                 p9,
1031                 p10,
1032                 p11,
1033                 p12,
1034                 p13,
1035                 p14,
1036                 p15,
1037                 p16,
1038                 p17,
1039                 p18,
1040                 c,
1041                 changed,
1042                 dirty
1043             )
1044         c.endRestartGroup()?.updateScope { nc, _ ->
1045             this(
1046                 p1,
1047                 p2,
1048                 p3,
1049                 p4,
1050                 p5,
1051                 p6,
1052                 p7,
1053                 p8,
1054                 p9,
1055                 p10,
1056                 p11,
1057                 p12,
1058                 p13,
1059                 p14,
1060                 p15,
1061                 p16,
1062                 p17,
1063                 p18,
1064                 nc,
1065                 updateChangedFlags(changed) or 0b1,
1066                 updateChangedFlags(changed1)
1067             )
1068         }
1069         return result
1070     }
1071 }
1072 
replacableWithnull1073 internal fun RecomposeScope?.replacableWith(other: RecomposeScope) =
1074     this == null ||
1075         (this is RecomposeScopeImpl &&
1076             other is RecomposeScopeImpl &&
1077             (!this.valid || this == other || this.anchor == other.anchor))
1078 
1079 @ComposeCompilerApi
1080 @Stable
1081 expect interface ComposableLambda {
1082     operator fun invoke(c: Composer, changed: Int): Any?
1083 
1084     operator fun invoke(p1: Any?, c: Composer, changed: Int): Any?
1085 
1086     operator fun invoke(p1: Any?, p2: Any?, c: Composer, changed: Int): Any?
1087 
1088     operator fun invoke(p1: Any?, p2: Any?, p3: Any?, c: Composer, changed: Int): Any?
1089 
1090     operator fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, c: Composer, changed: Int): Any?
1091 
1092     operator fun invoke(
1093         p1: Any?,
1094         p2: Any?,
1095         p3: Any?,
1096         p4: Any?,
1097         p5: Any?,
1098         c: Composer,
1099         changed: Int
1100     ): Any?
1101 
1102     operator fun invoke(
1103         p1: Any?,
1104         p2: Any?,
1105         p3: Any?,
1106         p4: Any?,
1107         p5: Any?,
1108         p6: Any?,
1109         c: Composer,
1110         changed: Int
1111     ): Any?
1112 
1113     operator fun invoke(
1114         p1: Any?,
1115         p2: Any?,
1116         p3: Any?,
1117         p4: Any?,
1118         p5: Any?,
1119         p6: Any?,
1120         p7: Any?,
1121         c: Composer,
1122         changed: Int
1123     ): Any?
1124 
1125     operator fun invoke(
1126         p1: Any?,
1127         p2: Any?,
1128         p3: Any?,
1129         p4: Any?,
1130         p5: Any?,
1131         p6: Any?,
1132         p7: Any?,
1133         p8: Any?,
1134         c: Composer,
1135         changed: Int
1136     ): Any?
1137 
1138     operator fun invoke(
1139         p1: Any?,
1140         p2: Any?,
1141         p3: Any?,
1142         p4: Any?,
1143         p5: Any?,
1144         p6: Any?,
1145         p7: Any?,
1146         p8: Any?,
1147         p9: Any?,
1148         c: Composer,
1149         changed: Int
1150     ): Any?
1151 
1152     operator fun invoke(
1153         p1: Any?,
1154         p2: Any?,
1155         p3: Any?,
1156         p4: Any?,
1157         p5: Any?,
1158         p6: Any?,
1159         p7: Any?,
1160         p8: Any?,
1161         p9: Any?,
1162         p10: Any?,
1163         c: Composer,
1164         changed: Int,
1165         changed1: Int
1166     ): Any?
1167 
1168     operator fun invoke(
1169         p1: Any?,
1170         p2: Any?,
1171         p3: Any?,
1172         p4: Any?,
1173         p5: Any?,
1174         p6: Any?,
1175         p7: Any?,
1176         p8: Any?,
1177         p9: Any?,
1178         p10: Any?,
1179         p11: Any?,
1180         c: Composer,
1181         changed: Int,
1182         changed1: Int
1183     ): Any?
1184 
1185     operator fun invoke(
1186         p1: Any?,
1187         p2: Any?,
1188         p3: Any?,
1189         p4: Any?,
1190         p5: Any?,
1191         p6: Any?,
1192         p7: Any?,
1193         p8: Any?,
1194         p9: Any?,
1195         p10: Any?,
1196         p11: Any?,
1197         p12: Any?,
1198         c: Composer,
1199         changed: Int,
1200         changed1: Int
1201     ): Any?
1202 
1203     operator fun invoke(
1204         p1: Any?,
1205         p2: Any?,
1206         p3: Any?,
1207         p4: Any?,
1208         p5: Any?,
1209         p6: Any?,
1210         p7: Any?,
1211         p8: Any?,
1212         p9: Any?,
1213         p10: Any?,
1214         p11: Any?,
1215         p12: Any?,
1216         p13: Any?,
1217         c: Composer,
1218         changed: Int,
1219         changed1: Int
1220     ): Any?
1221 
1222     operator fun invoke(
1223         p1: Any?,
1224         p2: Any?,
1225         p3: Any?,
1226         p4: Any?,
1227         p5: Any?,
1228         p6: Any?,
1229         p7: Any?,
1230         p8: Any?,
1231         p9: Any?,
1232         p10: Any?,
1233         p11: Any?,
1234         p12: Any?,
1235         p13: Any?,
1236         p14: Any?,
1237         c: Composer,
1238         changed: Int,
1239         changed1: Int
1240     ): Any?
1241 
1242     operator fun invoke(
1243         p1: Any?,
1244         p2: Any?,
1245         p3: Any?,
1246         p4: Any?,
1247         p5: Any?,
1248         p6: Any?,
1249         p7: Any?,
1250         p8: Any?,
1251         p9: Any?,
1252         p10: Any?,
1253         p11: Any?,
1254         p12: Any?,
1255         p13: Any?,
1256         p14: Any?,
1257         p15: Any?,
1258         c: Composer,
1259         changed: Int,
1260         changed1: Int
1261     ): Any?
1262 
1263     operator fun invoke(
1264         p1: Any?,
1265         p2: Any?,
1266         p3: Any?,
1267         p4: Any?,
1268         p5: Any?,
1269         p6: Any?,
1270         p7: Any?,
1271         p8: Any?,
1272         p9: Any?,
1273         p10: Any?,
1274         p11: Any?,
1275         p12: Any?,
1276         p13: Any?,
1277         p14: Any?,
1278         p15: Any?,
1279         p16: Any?,
1280         c: Composer,
1281         changed: Int,
1282         changed1: Int
1283     ): Any?
1284 
1285     operator fun invoke(
1286         p1: Any?,
1287         p2: Any?,
1288         p3: Any?,
1289         p4: Any?,
1290         p5: Any?,
1291         p6: Any?,
1292         p7: Any?,
1293         p8: Any?,
1294         p9: Any?,
1295         p10: Any?,
1296         p11: Any?,
1297         p12: Any?,
1298         p13: Any?,
1299         p14: Any?,
1300         p15: Any?,
1301         p16: Any?,
1302         p17: Any?,
1303         c: Composer,
1304         changed: Int,
1305         changed1: Int
1306     ): Any?
1307 
1308     operator fun invoke(
1309         p1: Any?,
1310         p2: Any?,
1311         p3: Any?,
1312         p4: Any?,
1313         p5: Any?,
1314         p6: Any?,
1315         p7: Any?,
1316         p8: Any?,
1317         p9: Any?,
1318         p10: Any?,
1319         p11: Any?,
1320         p12: Any?,
1321         p13: Any?,
1322         p14: Any?,
1323         p15: Any?,
1324         p16: Any?,
1325         p17: Any?,
1326         p18: Any?,
1327         c: Composer,
1328         changed: Int,
1329         changed1: Int
1330     ): Any?
1331 }
1332 
1333 @Suppress("unused")
1334 @ComposeCompilerApi
composableLambdanull1335 fun composableLambda(composer: Composer, key: Int, tracked: Boolean, block: Any): ComposableLambda {
1336     // Use a rolled version of the key to avoid the key being a duplicate of the function's
1337     // key. This is particularly important for live edit scenarios where the groups will be
1338     // invalidated by the key number. This ensures that invalidating the function will not
1339     // also invalidate its lambda.
1340     composer.startMovableGroup(key.rol(1), lambdaKey)
1341     val slot = composer.rememberedValue()
1342     val result =
1343         if (slot === Composer.Empty) {
1344             val value = ComposableLambdaImpl(key, tracked, block)
1345             composer.updateRememberedValue(value)
1346             value
1347         } else {
1348             slot as ComposableLambdaImpl
1349             slot.update(block)
1350             slot
1351         }
1352     composer.endMovableGroup()
1353     return result
1354 }
1355 
1356 private val lambdaKey = Any()
1357 
1358 @Suppress("unused")
1359 @ComposeCompilerApi
composableLambdaInstancenull1360 fun composableLambdaInstance(key: Int, tracked: Boolean, block: Any): ComposableLambda =
1361     ComposableLambdaImpl(key, tracked, block)
1362 
1363 @Suppress("unused")
1364 @Composable
1365 @ComposeCompilerApi
1366 fun rememberComposableLambda(key: Int, tracked: Boolean, block: Any): ComposableLambda =
1367     remember { ComposableLambdaImpl(key, tracked, block) }.also { it.update(block) }
1368