@@ -1450,71 +1450,114 @@ void CodeCompletionCallbacksImpl::completeExpr() {
1450
1450
deliverCompletionResults ();
1451
1451
}
1452
1452
1453
+ struct ArchetypeTransformer ::Implementation {
1454
+ DeclContext *DC;
1455
+ Type BaseTy;
1456
+ std::function<Type(Type)> TheFunc;
1457
+ TypeSubstitutionMap Map;
1458
+
1459
+ Implementation (DeclContext *DC, Type Ty) : DC(DC),
1460
+ BaseTy (Ty->getRValueType ()),
1461
+ TheFunc(nullptr ) {
1462
+ auto D = BaseTy->getNominalOrBoundGenericNominal ();
1463
+ if (!D)
1464
+ return ;
1465
+ SmallVector<Type, 3 > Scrach;
1466
+ auto Params = D->getInnermostGenericParamTypes ();
1467
+ auto Args = BaseTy->getAllGenericArgs (Scrach);
1468
+ assert (Params.size () == Args.size ());
1469
+ for (unsigned I = 0 , N = Params.size (); I < N; I++) {
1470
+ Map[Params[I]->getCanonicalType ()->castTo <GenericTypeParamType>()] = Args[I];
1471
+ }
1472
+ }
1473
+
1474
+ Type mapGenericTypeParam (Type Ty) {
1475
+ if (auto GTP = Ty->getAs <GenericTypeParamType>()) {
1476
+ for (auto It : Map) {
1477
+ auto Known = It.getFirst ()->getAs <GenericTypeParamType>();
1478
+ if (GTP->getIndex () == Known->getIndex () &&
1479
+ GTP->getDepth () == Known->getDepth ()) {
1480
+ return It.getSecond ();
1481
+ }
1482
+ }
1483
+ }
1484
+ return Type ();
1485
+ }
1486
+ };
1487
+
1453
1488
ArchetypeTransformer::ArchetypeTransformer (DeclContext *DC, Type Ty) :
1454
- DC(DC), BaseTy(Ty->getRValueType ()){
1455
- auto D = BaseTy->getNominalOrBoundGenericNominal ();
1456
- if (!D)
1457
- return ;
1458
- SmallVector<Type, 3 > Scrach;
1459
- auto Params = D->getInnermostGenericParamTypes ();
1460
- auto Args = BaseTy->getAllGenericArgs (Scrach);
1461
- assert (Params.size () == Args.size ());
1462
- for (unsigned I = 0 , N = Params.size (); I < N; I++) {
1463
- Map[Params[I]->getCanonicalType ()->castTo <GenericTypeParamType>()] = Args[I];
1489
+ Impl(*new Implementation(DC, Ty)){}
1490
+
1491
+ ArchetypeTransformer::~ArchetypeTransformer () { delete &Impl; }
1492
+
1493
+ static Type
1494
+ resolveAssociatedType (DeclContext *DC, Type BaseTy, SubstitutableType *SubTy) {
1495
+ llvm::SmallVector<Identifier, 1 > Names;
1496
+ for (auto *AT = SubTy; AT; AT = AT->getParent ()) {
1497
+ if (AT->getName ().str () != " Self" )
1498
+ Names.insert (Names.begin (), AT->getName ());
1499
+ }
1500
+ if (auto MT = checkMemberType (*DC, BaseTy, Names)) {
1501
+ if (auto NAT = dyn_cast<NameAliasType>(MT.getPointer ()))
1502
+ return Type (NAT->getSinglyDesugaredType ());
1503
+ else
1504
+ return MT;
1505
+ }
1506
+ return Type ();
1507
+ }
1508
+
1509
+ static Type
1510
+ getConformedProtocols (DeclContext *DC, ArchetypeType *ATT) {
1511
+ auto Conformances = ATT->getConformsTo ();
1512
+ if (Conformances.size () == 1 ) {
1513
+ return Conformances[0 ]->getDeclaredType ();
1514
+ } else if (!Conformances.empty ()) {
1515
+ llvm::SmallVector<Type, 3 > ConformedTypes;
1516
+ for (auto PD : Conformances) {
1517
+ ConformedTypes.push_back (PD->getDeclaredType ());
1518
+ }
1519
+ return ProtocolCompositionType::get (DC->getASTContext (), ConformedTypes);
1464
1520
}
1521
+ return Type ();
1465
1522
}
1466
1523
1467
- llvm::function_ref<Type(Type)> ArchetypeTransformer::getTransformerFunc() {
1468
- if (TheFunc)
1469
- return TheFunc;
1470
- TheFunc = [&](Type Ty) {
1471
- if (Ty->getKind () != TypeKind::Archetype)
1524
+ llvm::function_ref<Type(Type)>
1525
+ ArchetypeTransformer::getTransformerFunc() {
1526
+ if (Impl.TheFunc )
1527
+ return Impl.TheFunc ;
1528
+ Impl.TheFunc = [&](Type Ty) {
1529
+ if (!Ty->is <SubstitutableType>())
1472
1530
return Ty;
1473
- if (Cache.count (Ty.getPointer ()) > 0 ) {
1474
- return Cache[Ty.getPointer ()];
1475
- }
1476
- Type Result = Ty;
1477
- auto *RootArc = cast<ArchetypeType>(Result.getPointer ());
1478
- llvm::SmallVector<Identifier, 1 > Names;
1479
- bool SelfDerived = false ;
1480
- for (auto *AT = RootArc; AT; AT = AT->getParent ()) {
1481
- if (!AT->getSelfProtocol ())
1482
- Names.insert (Names.begin (), AT->getName ());
1483
- else
1484
- SelfDerived = true ;
1485
- }
1486
- if (SelfDerived) {
1487
- if (auto MT = checkMemberType (*DC, BaseTy, Names)) {
1488
- if (auto NAT = dyn_cast<NameAliasType>(MT.getPointer ())) {
1489
- Result = NAT->getSinglyDesugaredType ();
1490
- } else {
1491
- Result = MT;
1531
+ auto OriginalTy = Ty;
1532
+ Ty = Ty->getCanonicalType ();
1533
+
1534
+ // Try to resolve generic type params.
1535
+ if (Type Result = Impl.mapGenericTypeParam (Ty))
1536
+ return Result;
1537
+
1538
+ // Try to translate associated type with the concrete base type.
1539
+ if (Type Result = resolveAssociatedType (Impl.DC , Impl.BaseTy ,
1540
+ Ty->getAs <SubstitutableType>())) {
1541
+ return Result.transform ([&](Type Input) {
1542
+ if (auto *ATT = Input->getAs <ArchetypeType>()) {
1543
+ if (auto Conform = getConformedProtocols (Impl.DC , ATT))
1544
+ return Conform;
1492
1545
}
1493
- }
1494
- } else {
1495
- Result = Ty.subst (DC->getParentModule (), Map, SubstFlags::IgnoreMissing);
1496
- }
1497
-
1498
- auto ATT = dyn_cast<ArchetypeType>(Result.getPointer ());
1499
- if (ATT && !ATT->getParent ()) {
1500
- auto Conformances = ATT->getConformsTo ();
1501
- if (Conformances.size () == 1 ) {
1502
- Result = Conformances[0 ]->getDeclaredType ();
1503
- } else if (!Conformances.empty ()) {
1504
- llvm::SmallVector<Type, 3 > ConformedTypes;
1505
- for (auto PD : Conformances) {
1506
- ConformedTypes.push_back (PD->getDeclaredType ());
1507
- }
1508
- Result = ProtocolCompositionType::get (DC->getASTContext (),
1509
- ConformedTypes);
1546
+ return Input;
1547
+ });
1548
+ }
1549
+
1550
+ // For those archetypes that cannot be translated, use the conformances to
1551
+ // provide users' some insight.
1552
+ if (auto *ATT = Ty->getAs <ArchetypeType>()) {
1553
+ if (Type Result = getConformedProtocols (Impl.DC , ATT)) {
1554
+ return Result;
1510
1555
}
1511
1556
}
1512
- if (Result->getKind () != TypeKind::Archetype)
1513
- Result = Result.transform (getTransformerFunc ());
1514
- Cache[Ty.getPointer ()] = Result;
1515
- return Result;
1557
+
1558
+ return OriginalTy;
1516
1559
};
1517
- return TheFunc;
1560
+ return Impl. TheFunc ;
1518
1561
}
1519
1562
1520
1563
namespace {
0 commit comments