@@ -814,8 +814,11 @@ namespace {
814
814
// / The type of the declaration, cached here once it has been computed.
815
815
Type cachedDeclType;
816
816
817
+ // / Whether to ignore missing imports when looking for overridden methods.
818
+ bool ignoreMissingImports;
819
+
817
820
public:
818
- OverrideMatcher (ValueDecl *decl);
821
+ OverrideMatcher (ValueDecl *decl, bool ignoreMissingImports );
819
822
820
823
// / Returns true when it's possible to perform any override matching.
821
824
explicit operator bool () const {
@@ -860,8 +863,9 @@ namespace {
860
863
};
861
864
}
862
865
863
- OverrideMatcher::OverrideMatcher (ValueDecl *decl)
864
- : ctx(decl->getASTContext ()), decl(decl) {
866
+ OverrideMatcher::OverrideMatcher (ValueDecl *decl, bool ignoreMissingImports)
867
+ : ctx(decl->getASTContext ()), decl(decl),
868
+ ignoreMissingImports(ignoreMissingImports) {
865
869
// The final step for this constructor is to set up the superclass type,
866
870
// without which we will not perform an matching. Early exits therefore imply
867
871
// that there is no way we can match this declaration.
@@ -916,8 +920,12 @@ SmallVector<OverrideMatch, 2> OverrideMatcher::match(
916
920
for (auto *ctx : superContexts) {
917
921
ctx->synthesizeSemanticMembersIfNeeded (membersName);
918
922
}
919
- dc->lookupQualified (superContexts, DeclNameRef (membersName),
920
- decl->getLoc (), NL_QualifiedDefault, members);
923
+ auto lookupOptions = NL_QualifiedDefault;
924
+ if (ignoreMissingImports)
925
+ lookupOptions |= NL_IgnoreMissingImports;
926
+
927
+ dc->lookupQualified (superContexts, DeclNameRef (membersName), decl->getLoc (),
928
+ lookupOptions, members);
921
929
}
922
930
923
931
// Check each member we found.
@@ -1373,50 +1381,12 @@ TinyPtrVector<ValueDecl *> OverrideMatcher::checkPotentialOverrides(
1373
1381
return overridden;
1374
1382
}
1375
1383
1376
- // / Determine which method or subscript this method or subscript overrides
1377
- // / (if any).
1378
- // /
1379
- // / \returns true if an error occurred.
1380
- bool swift::checkOverrides (ValueDecl *decl) {
1381
- // If there is a @_nonoverride attribute, this does not override anything.
1382
- if (decl->getAttrs ().hasAttribute <NonOverrideAttr>())
1383
- return false ;
1384
-
1385
- // If we already computed overridden declarations and either succeeded
1386
- // or invalidated the attribute, there's nothing more to do.
1387
- if (decl->overriddenDeclsComputed ()) {
1388
- // If we computed an overridden declaration successfully, we're done.
1389
- if (decl->getOverriddenDecl ())
1390
- return false ;
1391
-
1392
- // If we set the override attribute to "invalid", we already diagnosed
1393
- // something here.
1394
- if (decl->getAttrs ().hasAttribute <OverrideAttr>(/* AllowInvalid=*/ true ) &&
1395
- !decl->getAttrs ().hasAttribute <OverrideAttr>())
1396
- return true ;
1397
-
1398
- // Otherwise, we have more checking to do.
1399
- }
1400
-
1401
- // Members of constrained extensions are not considered to be overrides.
1402
- if (auto *ext = dyn_cast<ExtensionDecl>(decl->getDeclContext ()))
1403
- if (ext->isConstrainedExtension ())
1404
- return false ;
1405
-
1406
- // Accessor methods get overrides through their storage declaration, and
1407
- // all checking can be performed via that mechanism.
1408
- if (isa<AccessorDecl>(decl)) {
1409
- (void )decl->getOverriddenDecls ();
1410
- return false ;
1411
- }
1412
-
1413
- // Don't bother checking any further for invalid decls since they won't match
1414
- // anything.
1415
- if (decl->isInvalid ())
1416
- return true ;
1417
-
1384
+ static bool
1385
+ checkPotentialOverrides (ValueDecl *decl,
1386
+ TinyPtrVector<ValueDecl *> &potentialOverrides,
1387
+ bool ignoreMissingImports) {
1418
1388
// Set up matching, but bail out if there's nothing to match.
1419
- OverrideMatcher matcher (decl);
1389
+ OverrideMatcher matcher (decl, ignoreMissingImports );
1420
1390
if (!matcher) return false ;
1421
1391
1422
1392
// Look for members with the same name and matching types as this
@@ -1470,10 +1440,80 @@ bool swift::checkOverrides(ValueDecl *decl) {
1470
1440
1471
1441
// FIXME: Check for missing 'override' keyword here?
1472
1442
1443
+ for (auto match : matcher.checkPotentialOverrides (matches, attempt)) {
1444
+ potentialOverrides.push_back (match);
1445
+ }
1446
+
1447
+ return true ;
1448
+ }
1449
+
1450
+ // / Determine which method or subscript this method or subscript overrides
1451
+ // / (if any).
1452
+ // /
1453
+ // / \returns true if an error occurred.
1454
+ bool swift::checkOverrides (ValueDecl *decl) {
1455
+ // If there is a @_nonoverride attribute, this does not override anything.
1456
+ if (decl->getAttrs ().hasAttribute <NonOverrideAttr>())
1457
+ return false ;
1458
+
1459
+ // If we already computed overridden declarations and either succeeded
1460
+ // or invalidated the attribute, there's nothing more to do.
1461
+ if (decl->overriddenDeclsComputed ()) {
1462
+ // If we computed an overridden declaration successfully, we're done.
1463
+ if (decl->getOverriddenDecl ())
1464
+ return false ;
1465
+
1466
+ // If we set the override attribute to "invalid", we already diagnosed
1467
+ // something here.
1468
+ if (decl->getAttrs ().hasAttribute <OverrideAttr>(/* AllowInvalid=*/ true ) &&
1469
+ !decl->getAttrs ().hasAttribute <OverrideAttr>())
1470
+ return true ;
1471
+
1472
+ // Otherwise, we have more checking to do.
1473
+ }
1474
+
1475
+ // Members of constrained extensions are not considered to be overrides.
1476
+ if (auto *ext = dyn_cast<ExtensionDecl>(decl->getDeclContext ()))
1477
+ if (ext->isConstrainedExtension ())
1478
+ return false ;
1479
+
1480
+ // Accessor methods get overrides through their storage declaration, and
1481
+ // all checking can be performed via that mechanism.
1482
+ if (isa<AccessorDecl>(decl)) {
1483
+ (void )decl->getOverriddenDecls ();
1484
+ return false ;
1485
+ }
1486
+
1487
+ // Don't bother checking any further for invalid decls since they won't match
1488
+ // anything.
1489
+ if (decl->isInvalid ())
1490
+ return true ;
1491
+
1492
+ TinyPtrVector<ValueDecl *> overridden;
1493
+ if (!checkPotentialOverrides (decl, overridden,
1494
+ /* ignoreMissingImports=*/ false ))
1495
+ return false ;
1496
+
1497
+ auto &ctx = decl->getASTContext ();
1498
+ if (overridden.empty () &&
1499
+ ctx.LangOpts .hasFeature (Feature::MemberImportVisibility)) {
1500
+ // If we didn't find anything, try broadening the search by ignoring missing
1501
+ // imports.
1502
+ if (!checkPotentialOverrides (decl, overridden,
1503
+ /* ignoreMissingImports=*/ true ))
1504
+ return false ;
1505
+
1506
+ if (!overridden.empty ()) {
1507
+ auto first = overridden.front ();
1508
+ if (maybeDiagnoseMissingImportForMember (first, decl->getDeclContext (),
1509
+ decl->getLoc ()))
1510
+ return true ;
1511
+ }
1512
+ }
1513
+
1473
1514
// We performed override checking, so record the overrides.
1474
1515
// FIXME: It's weird to be pushing state here, but how do we say that
1475
1516
// this check subsumes the normal 'override' check?
1476
- auto overridden = matcher.checkPotentialOverrides (matches, attempt);
1477
1517
if (overridden.empty ())
1478
1518
invalidateOverrideAttribute (decl);
1479
1519
decl->setOverriddenDecls (overridden);
@@ -2263,8 +2303,8 @@ computeOverriddenAssociatedTypes(AssociatedTypeDecl *assocType) {
2263
2303
return overriddenAssocTypes;
2264
2304
}
2265
2305
2266
- llvm::TinyPtrVector<ValueDecl *>
2267
- OverriddenDeclsRequest::evaluate (Evaluator &evaluator, ValueDecl *decl) const {
2306
+ static llvm::TinyPtrVector<ValueDecl *>
2307
+ computeOverriddenDecls ( ValueDecl *decl, bool ignoreMissingImports) {
2268
2308
// Value to return in error cases
2269
2309
auto noResults = llvm::TinyPtrVector<ValueDecl *>();
2270
2310
@@ -2359,7 +2399,7 @@ OverriddenDeclsRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
2359
2399
return noResults;
2360
2400
2361
2401
// Check the correctness of the overrides.
2362
- OverrideMatcher matcher (accessor);
2402
+ OverrideMatcher matcher (accessor, ignoreMissingImports );
2363
2403
return matcher.checkPotentialOverrides (
2364
2404
matches,
2365
2405
OverrideCheckingAttempt::PerfectMatch);
@@ -2373,7 +2413,7 @@ OverriddenDeclsRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
2373
2413
return noResults;
2374
2414
2375
2415
// Try to match potential overridden declarations.
2376
- OverrideMatcher matcher (decl);
2416
+ OverrideMatcher matcher (decl, ignoreMissingImports );
2377
2417
if (!matcher) {
2378
2418
return noResults;
2379
2419
}
@@ -2398,6 +2438,27 @@ OverriddenDeclsRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
2398
2438
OverrideCheckingAttempt::PerfectMatch);
2399
2439
}
2400
2440
2441
+ llvm::TinyPtrVector<ValueDecl *>
2442
+ OverriddenDeclsRequest::evaluate (Evaluator &evaluator, ValueDecl *decl) const {
2443
+ auto &ctx = decl->getASTContext ();
2444
+ auto overridden = computeOverriddenDecls (decl, false );
2445
+
2446
+ // If we didn't find anything, try broadening the search by ignoring missing
2447
+ // imports.
2448
+ if (overridden.empty () &&
2449
+ ctx.LangOpts .hasFeature (Feature::MemberImportVisibility)) {
2450
+ overridden = computeOverriddenDecls (decl, true );
2451
+ if (!overridden.empty ()) {
2452
+ auto first = overridden.front ();
2453
+ if (maybeDiagnoseMissingImportForMember (first, decl->getDeclContext (),
2454
+ decl->getLoc ()))
2455
+ return {};
2456
+ }
2457
+ }
2458
+
2459
+ return overridden;
2460
+ }
2461
+
2401
2462
bool IsABICompatibleOverrideRequest::evaluate (Evaluator &evaluator,
2402
2463
ValueDecl *decl) const {
2403
2464
auto base = decl->getOverriddenDecl ();
0 commit comments