5
5
#include " Luau/Type.h"
6
6
#include " Luau/TypePack.h"
7
7
#include " Luau/Unifiable.h"
8
+ #include " Luau/VisitType.h"
8
9
9
10
LUAU_FASTFLAG (LuauSolverV2)
10
11
LUAU_FASTFLAG(LuauFreezeIgnorePersistent)
@@ -28,6 +29,8 @@ const T* get(const Kind& kind)
28
29
29
30
class TypeCloner
30
31
{
32
+
33
+ protected:
31
34
NotNull<TypeArena> arena;
32
35
NotNull<BuiltinTypes> builtinTypes;
33
36
@@ -62,6 +65,8 @@ class TypeCloner
62
65
{
63
66
}
64
67
68
+ virtual ~TypeCloner () = default ;
69
+
65
70
TypeId clone (TypeId ty)
66
71
{
67
72
shallowClone (ty);
@@ -120,6 +125,7 @@ class TypeCloner
120
125
}
121
126
}
122
127
128
+ protected:
123
129
std::optional<TypeId> find (TypeId ty) const
124
130
{
125
131
ty = follow (ty, FollowOption::DisableLazyTypeThunks);
@@ -154,7 +160,7 @@ class TypeCloner
154
160
}
155
161
156
162
public:
157
- TypeId shallowClone (TypeId ty)
163
+ virtual TypeId shallowClone (TypeId ty)
158
164
{
159
165
// We want to [`Luau::follow`] but without forcing the expansion of [`LazyType`]s.
160
166
ty = follow (ty, FollowOption::DisableLazyTypeThunks);
@@ -181,7 +187,7 @@ class TypeCloner
181
187
return target;
182
188
}
183
189
184
- TypePackId shallowClone (TypePackId tp)
190
+ virtual TypePackId shallowClone (TypePackId tp)
185
191
{
186
192
tp = follow (tp);
187
193
@@ -469,6 +475,78 @@ class TypeCloner
469
475
}
470
476
};
471
477
478
+ class FragmentAutocompleteTypeCloner final : public TypeCloner
479
+ {
480
+ Scope* freeTypeReplacementScope = nullptr ;
481
+
482
+ public:
483
+ FragmentAutocompleteTypeCloner (
484
+ NotNull<TypeArena> arena,
485
+ NotNull<BuiltinTypes> builtinTypes,
486
+ NotNull<SeenTypes> types,
487
+ NotNull<SeenTypePacks> packs,
488
+ TypeId forceTy,
489
+ TypePackId forceTp,
490
+ Scope* freeTypeReplacementScope
491
+ )
492
+ : TypeCloner(arena, builtinTypes, types, packs, forceTy, forceTp)
493
+ , freeTypeReplacementScope(freeTypeReplacementScope)
494
+ {
495
+ LUAU_ASSERT (freeTypeReplacementScope);
496
+ }
497
+
498
+ TypeId shallowClone (TypeId ty) override
499
+ {
500
+ // We want to [`Luau::follow`] but without forcing the expansion of [`LazyType`]s.
501
+ ty = follow (ty, FollowOption::DisableLazyTypeThunks);
502
+
503
+ if (auto clone = find (ty))
504
+ return *clone;
505
+ else if (ty->persistent && (!FFlag::LuauFreezeIgnorePersistent || ty != forceTy))
506
+ return ty;
507
+
508
+ TypeId target = arena->addType (ty->ty );
509
+ asMutable (target)->documentationSymbol = ty->documentationSymbol ;
510
+
511
+ if (auto generic = getMutable<GenericType>(target))
512
+ generic->scope = nullptr ;
513
+ else if (auto free = getMutable<FreeType>(target))
514
+ {
515
+ free->scope = freeTypeReplacementScope;
516
+ }
517
+ else if (auto fn = getMutable<FunctionType>(target))
518
+ fn->scope = nullptr ;
519
+ else if (auto table = getMutable<TableType>(target))
520
+ table->scope = nullptr ;
521
+
522
+ (*types)[ty] = target;
523
+ queue.emplace_back (target);
524
+ return target;
525
+ }
526
+
527
+ TypePackId shallowClone (TypePackId tp) override
528
+ {
529
+ tp = follow (tp);
530
+
531
+ if (auto clone = find (tp))
532
+ return *clone;
533
+ else if (tp->persistent && (!FFlag::LuauFreezeIgnorePersistent || tp != forceTp))
534
+ return tp;
535
+
536
+ TypePackId target = arena->addTypePack (tp->ty );
537
+
538
+ if (auto generic = getMutable<GenericTypePack>(target))
539
+ generic->scope = nullptr ;
540
+ else if (auto free = getMutable<FreeTypePack>(target))
541
+ free->scope = freeTypeReplacementScope;
542
+
543
+ (*packs)[tp] = target;
544
+ queue.emplace_back (target);
545
+ return target;
546
+ }
547
+ };
548
+
549
+
472
550
} // namespace
473
551
474
552
TypePackId shallowClone (TypePackId tp, TypeArena& dest, CloneState& cloneState, bool ignorePersistent)
@@ -564,4 +642,96 @@ Binding clone(const Binding& binding, TypeArena& dest, CloneState& cloneState)
564
642
return b;
565
643
}
566
644
645
+ TypePackId cloneIncremental (TypePackId tp, TypeArena& dest, CloneState& cloneState, Scope* freshScopeForFreeTypes)
646
+ {
647
+ if (tp->persistent )
648
+ return tp;
649
+
650
+ FragmentAutocompleteTypeCloner cloner{
651
+ NotNull{&dest},
652
+ cloneState.builtinTypes ,
653
+ NotNull{&cloneState.seenTypes },
654
+ NotNull{&cloneState.seenTypePacks },
655
+ nullptr ,
656
+ nullptr ,
657
+ freshScopeForFreeTypes
658
+ };
659
+ return cloner.clone (tp);
660
+ }
661
+
662
+ TypeId cloneIncremental (TypeId typeId, TypeArena& dest, CloneState& cloneState, Scope* freshScopeForFreeTypes)
663
+ {
664
+ if (typeId->persistent )
665
+ return typeId;
666
+
667
+ FragmentAutocompleteTypeCloner cloner{
668
+ NotNull{&dest},
669
+ cloneState.builtinTypes ,
670
+ NotNull{&cloneState.seenTypes },
671
+ NotNull{&cloneState.seenTypePacks },
672
+ nullptr ,
673
+ nullptr ,
674
+ freshScopeForFreeTypes
675
+ };
676
+ return cloner.clone (typeId);
677
+ }
678
+
679
+ TypeFun cloneIncremental (const TypeFun& typeFun, TypeArena& dest, CloneState& cloneState, Scope* freshScopeForFreeTypes)
680
+ {
681
+ FragmentAutocompleteTypeCloner cloner{
682
+ NotNull{&dest},
683
+ cloneState.builtinTypes ,
684
+ NotNull{&cloneState.seenTypes },
685
+ NotNull{&cloneState.seenTypePacks },
686
+ nullptr ,
687
+ nullptr ,
688
+ freshScopeForFreeTypes
689
+ };
690
+
691
+ TypeFun copy = typeFun;
692
+
693
+ for (auto & param : copy.typeParams )
694
+ {
695
+ param.ty = cloner.clone (param.ty );
696
+
697
+ if (param.defaultValue )
698
+ param.defaultValue = cloner.clone (*param.defaultValue );
699
+ }
700
+
701
+ for (auto & param : copy.typePackParams )
702
+ {
703
+ param.tp = cloner.clone (param.tp );
704
+
705
+ if (param.defaultValue )
706
+ param.defaultValue = cloner.clone (*param.defaultValue );
707
+ }
708
+
709
+ copy.type = cloner.clone (copy.type );
710
+
711
+ return copy;
712
+ }
713
+
714
+ Binding cloneIncremental (const Binding& binding, TypeArena& dest, CloneState& cloneState, Scope* freshScopeForFreeTypes)
715
+ {
716
+ FragmentAutocompleteTypeCloner cloner{
717
+ NotNull{&dest},
718
+ cloneState.builtinTypes ,
719
+ NotNull{&cloneState.seenTypes },
720
+ NotNull{&cloneState.seenTypePacks },
721
+ nullptr ,
722
+ nullptr ,
723
+ freshScopeForFreeTypes
724
+ };
725
+
726
+ Binding b;
727
+ b.deprecated = binding.deprecated ;
728
+ b.deprecatedSuggestion = binding.deprecatedSuggestion ;
729
+ b.documentationSymbol = binding.documentationSymbol ;
730
+ b.location = binding.location ;
731
+ b.typeId = cloner.clone (binding.typeId );
732
+
733
+ return b;
734
+ }
735
+
736
+
567
737
} // namespace Luau
0 commit comments