@@ -385,6 +385,55 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
385
385
}
386
386
}
387
387
388
+ // Retrieve the location of the start of the inheritance clause.
389
+ auto getStartLocOfInheritanceClause = [&] {
390
+ if (auto genericTypeDecl = dyn_cast<GenericTypeDecl>(decl)) {
391
+ if (auto genericParams = genericTypeDecl->getGenericParams ())
392
+ return genericParams->getSourceRange ().End ;
393
+
394
+ return genericTypeDecl->getNameLoc ();
395
+ }
396
+
397
+ if (auto typeDecl = dyn_cast<TypeDecl>(decl))
398
+ return typeDecl->getNameLoc ();
399
+
400
+ if (auto ext = dyn_cast<ExtensionDecl>(decl))
401
+ return ext->getSourceRange ().End ;
402
+
403
+ return SourceLoc ();
404
+ };
405
+
406
+ // Compute the source range to be used when removing something from an
407
+ // inheritance clause.
408
+ auto getRemovalRange = [&](unsigned i) {
409
+ // If there is just one entry, remove the entire inheritance clause.
410
+ if (inheritedClause.size () == 1 ) {
411
+ SourceLoc start = getStartLocOfInheritanceClause ();
412
+ SourceLoc end = inheritedClause[i].getSourceRange ().End ;
413
+ return SourceRange (Lexer::getLocForEndOfToken (Context.SourceMgr , start),
414
+ Lexer::getLocForEndOfToken (Context.SourceMgr , end));
415
+ }
416
+
417
+ // If we're at the first entry, remove from the start of this entry to the
418
+ // start of the next entry.
419
+ if (i == 0 ) {
420
+ return SourceRange (inheritedClause[i].getSourceRange ().Start ,
421
+ inheritedClause[i+1 ].getSourceRange ().Start );
422
+ }
423
+
424
+ // Otherwise, remove from the end of the previous entry to the end of this
425
+ // entry.
426
+ SourceLoc afterPriorLoc =
427
+ Lexer::getLocForEndOfToken (Context.SourceMgr ,
428
+ inheritedClause[i-1 ].getSourceRange ().End );
429
+
430
+ SourceLoc afterMyEndLoc =
431
+ Lexer::getLocForEndOfToken (Context.SourceMgr ,
432
+ inheritedClause[i].getSourceRange ().End );
433
+
434
+ return SourceRange (afterPriorLoc, afterMyEndLoc);
435
+ };
436
+
388
437
// Check all of the types listed in the inheritance clause.
389
438
Type superclassTy;
390
439
SourceRange superclassRange;
@@ -424,16 +473,10 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
424
473
CanType inheritedCanTy = inheritedTy->getCanonicalType ();
425
474
auto knownType = inheritedTypes.find (inheritedCanTy);
426
475
if (knownType != inheritedTypes.end ()) {
427
- SourceLoc afterPriorLoc
428
- = Lexer::getLocForEndOfToken (Context.SourceMgr ,
429
- inheritedClause[i-1 ].getSourceRange ().End );
430
- SourceLoc afterMyEndLoc
431
- = Lexer::getLocForEndOfToken (Context.SourceMgr ,
432
- inherited.getSourceRange ().Start );
433
-
476
+ auto removeRange = getRemovalRange (i);
434
477
diagnose (inherited.getSourceRange ().Start ,
435
478
diag::duplicate_inheritance, inheritedTy)
436
- .fixItRemoveChars (afterPriorLoc, afterMyEndLoc )
479
+ .fixItRemoveChars (removeRange. Start , removeRange. End )
437
480
.highlight (knownType->second );
438
481
inherited.setInvalidType (Context);
439
482
continue ;
@@ -457,6 +500,18 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
457
500
}
458
501
continue ;
459
502
}
503
+
504
+ // Swift 3 compatibility:
505
+ if (Context.LangOpts .isSwiftVersion3 () && isa<ClassDecl>(decl) &&
506
+ inheritedTy->isAnyObject ()) {
507
+ auto classDecl = cast<ClassDecl>(decl);
508
+ auto removeRange = getRemovalRange (i);
509
+ diagnose (inherited.getSourceRange ().Start ,
510
+ diag::class_inherits_anyobject,
511
+ classDecl->getDeclaredInterfaceType ())
512
+ .fixItRemoveChars (removeRange.Start , removeRange.End );
513
+ continue ;
514
+ }
460
515
}
461
516
462
517
// If this is an enum inheritance clause, check for a raw type.
@@ -472,17 +527,11 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
472
527
473
528
// If this is not the first entry in the inheritance clause, complain.
474
529
if (i > 0 ) {
475
- SourceLoc afterPriorLoc
476
- = Lexer::getLocForEndOfToken (
477
- Context.SourceMgr ,
478
- inheritedClause[i-1 ].getSourceRange ().End );
479
- SourceLoc afterMyEndLoc
480
- = Lexer::getLocForEndOfToken (Context.SourceMgr ,
481
- inherited.getSourceRange ().End );
530
+ auto removeRange = getRemovalRange (i);
482
531
483
532
diagnose (inherited.getSourceRange ().Start ,
484
533
diag::raw_type_not_first, inheritedTy)
485
- .fixItRemoveChars (afterPriorLoc, afterMyEndLoc )
534
+ .fixItRemoveChars (removeRange. Start , removeRange. End )
486
535
.fixItInsert (inheritedClause[0 ].getSourceRange ().Start ,
487
536
inheritedTy.getString () + " , " );
488
537
@@ -532,17 +581,10 @@ void TypeChecker::checkInheritanceClause(Decl *decl,
532
581
533
582
// If this is not the first entry in the inheritance clause, complain.
534
583
if (i > 0 ) {
535
- SourceLoc afterPriorLoc
536
- = Lexer::getLocForEndOfToken (
537
- Context.SourceMgr ,
538
- inheritedClause[i-1 ].getSourceRange ().End );
539
- SourceLoc afterMyEndLoc
540
- = Lexer::getLocForEndOfToken (Context.SourceMgr ,
541
- inherited.getSourceRange ().End );
542
-
584
+ auto removeRange = getRemovalRange (i);
543
585
diagnose (inherited.getSourceRange ().Start ,
544
586
diag::superclass_not_first, inheritedTy)
545
- .fixItRemoveChars (afterPriorLoc, afterMyEndLoc )
587
+ .fixItRemoveChars (removeRange. Start , removeRange. End )
546
588
.fixItInsert (inheritedClause[0 ].getSourceRange ().Start ,
547
589
inheritedTy.getString () + " , " );
548
590
0 commit comments