@@ -1264,6 +1264,57 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
1264
1264
// / to the \c Consumer.
1265
1265
bool DeliveredResults = false ;
1266
1266
1267
+ std::pair<Type, ConcreteDeclRef> getReferencedDecl (Expr *expr) {
1268
+ auto exprTy = ParsedExpr->getType ();
1269
+
1270
+ // Look through unbound instance member accesses.
1271
+ if (auto *dotSyntaxExpr = dyn_cast<DotSyntaxBaseIgnoredExpr>(expr))
1272
+ expr = dotSyntaxExpr->getRHS ();
1273
+
1274
+ // Look through the 'self' application.
1275
+ if (auto *selfApplyExpr = dyn_cast<SelfApplyExpr>(expr))
1276
+ expr = selfApplyExpr->getFn ();
1277
+
1278
+ // Look through curry thunks.
1279
+ if (auto *closure = dyn_cast<AutoClosureExpr>(expr)) {
1280
+ if (closure->isThunk ()) {
1281
+ auto *body = closure->getSingleExpressionBody ();
1282
+ if (isa<AutoClosureExpr>(body) &&
1283
+ closure->getParameters ()->size () == 1 )
1284
+ expr = closure->getSingleExpressionBody ();
1285
+ }
1286
+ }
1287
+
1288
+ if (auto *closure = dyn_cast<AutoClosureExpr>(expr)) {
1289
+ if (closure->isThunk ()) {
1290
+ auto *body = closure->getSingleExpressionBody ();
1291
+ body = body->getSemanticsProvidingExpr ();
1292
+ if (auto *outerCall = dyn_cast<ApplyExpr>(body)) {
1293
+ if (auto *innerCall = dyn_cast<ApplyExpr>(outerCall->getFn ())) {
1294
+ if (auto *declRef = dyn_cast<DeclRefExpr>(innerCall->getFn ())) {
1295
+ expr = declRef;
1296
+ }
1297
+ }
1298
+ }
1299
+ }
1300
+ }
1301
+
1302
+ // If this is an IUO result, unwrap the optional type.
1303
+ auto refDecl = expr->getReferencedDecl ();
1304
+ if (!refDecl) {
1305
+ if (auto *applyExpr = dyn_cast<ApplyExpr>(expr)) {
1306
+ auto fnDecl = applyExpr->getFn ()->getReferencedDecl ();
1307
+ if (auto *func = fnDecl.getDecl ()) {
1308
+ if (func->isImplicitlyUnwrappedOptional ()) {
1309
+ if (auto objectTy = exprTy->getOptionalObjectType ())
1310
+ exprTy = objectTy;
1311
+ }
1312
+ }
1313
+ }
1314
+ }
1315
+
1316
+ return std::make_pair (exprTy, refDecl);
1317
+ }
1267
1318
1268
1319
Optional<std::pair<Type, ConcreteDeclRef>> typeCheckParsedExpr () {
1269
1320
assert (ParsedExpr && " should have an expression" );
@@ -1279,24 +1330,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
1279
1330
// typecheck again. rdar://21466394
1280
1331
if (CheckKind == CompletionTypeCheckKind::Normal &&
1281
1332
ParsedExpr->getType () && !ParsedExpr->getType ()->is <ErrorType>()) {
1282
- auto refDecl = ParsedExpr->getReferencedDecl ();
1283
- auto exprTy = ParsedExpr->getType ();
1284
- if (!refDecl) {
1285
- // FIXME: do this in the not-already-type-checked branch too?
1286
- if (auto *apply = dyn_cast<SelfApplyExpr>(ParsedExpr)) {
1287
- refDecl = apply->getFn ()->getReferencedDecl ();
1288
- } else if (auto *apply = dyn_cast<ApplyExpr>(ParsedExpr)) {
1289
- // If this is an IUO, use the underlying non-optional type instead
1290
- auto fnDecl = apply->getFn ()->getReferencedDecl ();
1291
- if (auto FD = fnDecl.getDecl ()) {
1292
- if (FD->isImplicitlyUnwrappedOptional ()) {
1293
- if (auto OT = exprTy->getOptionalObjectType ())
1294
- exprTy = OT;
1295
- }
1296
- }
1297
- }
1298
- }
1299
- return std::make_pair (exprTy, refDecl);
1333
+ return getReferencedDecl (ParsedExpr);
1300
1334
}
1301
1335
1302
1336
ConcreteDeclRef ReferencedDecl = nullptr ;
0 commit comments