|
20 | 20 | #include "swift/AST/ASTContext.h" |
21 | 21 | #include "swift/AST/ASTVisitor.h" |
22 | 22 | #include "swift/AST/Decl.h" // FIXME: Bad dependency |
| 23 | +#include "swift/AST/ExistentialLayout.h" |
23 | 24 | #include "swift/AST/MacroDiscriminatorContext.h" |
24 | 25 | #include "swift/AST/ParameterList.h" |
25 | 26 | #include "swift/AST/Stmt.h" |
@@ -2443,6 +2444,35 @@ llvm::Optional<unsigned> KeyPathExpr::findComponentWithSubscriptArg(Expr *arg) { |
2443 | 2444 | return llvm::None; |
2444 | 2445 | } |
2445 | 2446 |
|
| 2447 | +BoundGenericType *KeyPathExpr::getKeyPathType() const { |
| 2448 | + auto type = getType(); |
| 2449 | + if (!type) |
| 2450 | + return nullptr; |
| 2451 | + |
| 2452 | + if (auto *existentialTy = type->getAs<ExistentialType>()) { |
| 2453 | + auto *sendableTy = |
| 2454 | + existentialTy->getConstraintType()->castTo<ProtocolCompositionType>(); |
| 2455 | + assert(sendableTy->getMembers().size() == 2); |
| 2456 | + type = sendableTy->getExistentialLayout().explicitSuperclass; |
| 2457 | + assert(type->isKeyPath() || type->isWritableKeyPath() || |
| 2458 | + type->isReferenceWritableKeyPath()); |
| 2459 | + } |
| 2460 | + |
| 2461 | + return type->castTo<BoundGenericType>(); |
| 2462 | +} |
| 2463 | + |
| 2464 | +Type KeyPathExpr::getRootType() const { |
| 2465 | + auto keyPathTy = getKeyPathType(); |
| 2466 | + assert(keyPathTy && "key path type has not been set yet"); |
| 2467 | + return keyPathTy->getGenericArgs()[0]; |
| 2468 | +} |
| 2469 | + |
| 2470 | +Type KeyPathExpr::getValueType() const { |
| 2471 | + auto keyPathTy = getKeyPathType(); |
| 2472 | + assert(keyPathTy && "key path type has not been set yet"); |
| 2473 | + return keyPathTy->getGenericArgs()[1]; |
| 2474 | +} |
| 2475 | + |
2446 | 2476 | KeyPathExpr::Component KeyPathExpr::Component::forSubscript( |
2447 | 2477 | ASTContext &ctx, ConcreteDeclRef subscript, ArgumentList *argList, |
2448 | 2478 | Type elementType, ArrayRef<ProtocolConformanceRef> indexHashables) { |
|
0 commit comments