Skip to content

Commit bd59db6

Browse files
committed
AST: Refactor missing import diagnostic into standalone utility.
NFC.
1 parent ee4a542 commit bd59db6

File tree

6 files changed

+50
-37
lines changed

6 files changed

+50
-37
lines changed

include/swift/AST/Decl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2788,7 +2788,7 @@ class ValueDecl : public Decl {
27882788
public:
27892789
/// Find the import that makes the given declaration available.
27902790
std::optional<AttributedImport<ImportedModule>>
2791-
findImport(const DeclContext *fromDC);
2791+
findImport(const DeclContext *fromDC) const;
27922792

27932793
/// Return true if this protocol member is a protocol requirement.
27942794
///

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ ERROR(init_candidate_inaccessible,none,
167167

168168
ERROR(candidate_from_missing_import,none,
169169
"%0 %1 is not available due to missing import of defining module %2",
170-
(DescriptiveDeclKind, DeclName, DeclName))
170+
(DescriptiveDeclKind, DeclName, ModuleDecl *))
171171
NOTE(candidate_add_import,none,
172-
"add import of module %0", (DeclName))
172+
"add import of module %0", (ModuleDecl *))
173173

174174
ERROR(cannot_pass_rvalue_mutating_subelement,none,
175175
"cannot use mutating member on immutable value: %0",

include/swift/AST/Module.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,11 @@ void collectParsedExportedImports(const ModuleDecl *M,
12691269
llvm::SmallDenseMap<ModuleDecl *, SmallPtrSet<Decl *, 4>, 4> &QualifiedImports,
12701270
llvm::function_ref<bool(AttributedImport<ImportedModule>)> includeImport = nullptr);
12711271

1272+
/// If the import that would make the given declaration visibile is absent,
1273+
/// emit a diagnostic and a fix-it suggesting adding the missing import.
1274+
bool diagnoseMissingImportForMember(const ValueDecl *decl,
1275+
const DeclContext *dc, SourceLoc loc);
1276+
12721277
} // end namespace swift
12731278

12741279
#endif

lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3865,7 +3865,7 @@ ValueDecl::getSatisfiedProtocolRequirements(bool Sorted) const {
38653865
}
38663866

38673867
std::optional<AttributedImport<ImportedModule>>
3868-
ValueDecl::findImport(const DeclContext *fromDC) {
3868+
ValueDecl::findImport(const DeclContext *fromDC) const {
38693869
// If the type is from the current module, there's no import.
38703870
auto module = getModuleContext();
38713871
if (module == fromDC->getParentModule())

lib/AST/Module.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4001,3 +4001,40 @@ version::Version ModuleDecl::getLanguageVersionBuiltWith() const {
40014001

40024002
return version::Version();
40034003
}
4004+
4005+
bool swift::diagnoseMissingImportForMember(const ValueDecl *decl,
4006+
const DeclContext *dc,
4007+
SourceLoc loc) {
4008+
if (decl->findImport(dc))
4009+
return false;
4010+
4011+
auto &ctx = dc->getASTContext();
4012+
auto definingModule = decl->getModuleContext();
4013+
ctx.Diags.diagnose(loc, diag::candidate_from_missing_import,
4014+
decl->getDescriptiveKind(), decl->getName(),
4015+
definingModule);
4016+
4017+
SourceLoc bestLoc =
4018+
ctx.Diags.getBestAddImportFixItLoc(decl, dc->getParentSourceFile());
4019+
if (bestLoc.isValid()) {
4020+
llvm::SmallString<64> importText;
4021+
4022+
// @_spi imports.
4023+
if (decl->isSPI()) {
4024+
auto spiGroups = decl->getSPIGroups();
4025+
if (!spiGroups.empty()) {
4026+
importText += "@_spi(";
4027+
importText += spiGroups[0].str();
4028+
importText += ") ";
4029+
}
4030+
}
4031+
4032+
importText += "import ";
4033+
importText += definingModule->getName().str();
4034+
importText += "\n";
4035+
ctx.Diags.diagnose(bestLoc, diag::candidate_add_import, definingModule)
4036+
.fixItInsert(bestLoc, importText);
4037+
}
4038+
4039+
return true;
4040+
}

lib/Sema/CSDiagnostics.cpp

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6187,39 +6187,11 @@ bool InaccessibleMemberFailure::diagnoseAsError() {
61876187

61886188
auto loc = nameLoc.isValid() ? nameLoc.getStartLoc() : ::getLoc(anchor);
61896189
auto accessLevel = Member->getFormalAccessScope().accessLevelForDiagnostics();
6190-
bool suppressDeclHereNote = false;
61916190
if (accessLevel == AccessLevel::Public &&
6192-
!Member->findImport(getDC())) {
6193-
auto definingModule = Member->getDeclContext()->getParentModule();
6194-
emitDiagnosticAt(loc, diag::candidate_from_missing_import,
6195-
Member->getDescriptiveKind(), Member->getName(),
6196-
definingModule->getName());
6197-
6198-
SourceLoc bestLoc =
6199-
getBestAddImportFixItLocation(Member, getDC()->getParentSourceFile());
6200-
if (bestLoc.isValid()) {
6201-
llvm::SmallString<64> importText;
6202-
6203-
// @_spi imports.
6204-
if (Member->isSPI()) {
6205-
auto spiGroups = Member->getSPIGroups();
6206-
if (!spiGroups.empty()) {
6207-
importText += "@_spi(";
6208-
importText += spiGroups[0].str();
6209-
importText += ") ";
6210-
}
6211-
}
6212-
6213-
importText += "import ";
6214-
importText += definingModule->getName().str();
6215-
importText += "\n";
6216-
emitDiagnosticAt(bestLoc, diag::candidate_add_import,
6217-
definingModule->getName())
6218-
.fixItInsert(bestLoc, importText);
6219-
}
6191+
diagnoseMissingImportForMember(Member, getDC(), loc))
6192+
return true;
62206193

6221-
suppressDeclHereNote = true;
6222-
} else if (auto *CD = dyn_cast<ConstructorDecl>(Member)) {
6194+
if (auto *CD = dyn_cast<ConstructorDecl>(Member)) {
62236195
emitDiagnosticAt(loc, diag::init_candidate_inaccessible,
62246196
CD->getResultInterfaceType(), accessLevel)
62256197
.highlight(nameLoc.getSourceRange());
@@ -6229,8 +6201,7 @@ bool InaccessibleMemberFailure::diagnoseAsError() {
62296201
.highlight(nameLoc.getSourceRange());
62306202
}
62316203

6232-
if (!suppressDeclHereNote)
6233-
emitDiagnosticAt(Member, diag::decl_declared_here, Member);
6204+
emitDiagnosticAt(Member, diag::decl_declared_here, Member);
62346205
return true;
62356206
}
62366207

0 commit comments

Comments
 (0)