mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
swift-api-digester: simplify the API to emit diagnostics. NFC
All diagnostics in the abi/api checker shares empty source location and a screening info string as the first argument. This patch adds a new forwarding function to avoid duplicating these common logics.
This commit is contained in:
@@ -678,11 +678,9 @@ void swift::ide::api::SDKNodeDeclType::diagnose(SDKNode *Right) {
|
||||
auto *R = dyn_cast<SDKNodeDeclType>(Right);
|
||||
if (!R)
|
||||
return;
|
||||
auto &Diags = Ctx.getDiags();
|
||||
|
||||
if (getDeclKind() != R->getDeclKind()) {
|
||||
Diags.diagnose(SourceLoc(), diag::decl_kind_changed, getScreenInfo(),
|
||||
getDeclKindStr(R->getDeclKind()));
|
||||
emitDiag(diag::decl_kind_changed, getDeclKindStr(R->getDeclKind()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -694,11 +692,9 @@ void swift::ide::api::SDKNodeDeclType::diagnose(SDKNode *Right) {
|
||||
auto RSuperClass = R->getSuperClassName();
|
||||
if (!LSuperClass.empty() && LSuperClass != RSuperClass) {
|
||||
if (RSuperClass.empty()) {
|
||||
Diags.diagnose(SourceLoc(), diag::super_class_removed, getScreenInfo(),
|
||||
LSuperClass);
|
||||
emitDiag(diag::super_class_removed, LSuperClass);
|
||||
} else if (!contains(R->getClassInheritanceChain(), LSuperClass)) {
|
||||
Diags.diagnose(SourceLoc(), diag::super_class_changed, getScreenInfo(),
|
||||
LSuperClass, RSuperClass);
|
||||
emitDiag(diag::super_class_changed, LSuperClass, RSuperClass);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -713,11 +709,9 @@ void swift::ide::api::SDKNodeDeclAbstractFunc::diagnose(SDKNode *Right) {
|
||||
auto *R = dyn_cast<SDKNodeDeclAbstractFunc>(Right);
|
||||
if (!R)
|
||||
return;
|
||||
auto &Diags = Ctx.getDiags();
|
||||
|
||||
if (!isThrowing() && R->isThrowing()) {
|
||||
Diags.diagnose(SourceLoc(), diag::decl_new_attr, getScreenInfo(),
|
||||
Ctx.buffer("throwing"));
|
||||
emitDiag(diag::decl_new_attr, Ctx.buffer("throwing"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,15 +720,13 @@ void swift::ide::api::SDKNodeDeclFunction::diagnose(SDKNode *Right) {
|
||||
auto *R = dyn_cast<SDKNodeDeclFunction>(Right);
|
||||
if (!R)
|
||||
return;
|
||||
auto &Diags = Ctx.getDiags();
|
||||
if (getSelfAccessKind() != R->getSelfAccessKind()) {
|
||||
Diags.diagnose(SourceLoc(), diag::func_self_access_change, getScreenInfo(),
|
||||
getSelfAccessKind(), R->getSelfAccessKind());
|
||||
emitDiag(diag::func_self_access_change, getSelfAccessKind(),
|
||||
R->getSelfAccessKind());
|
||||
}
|
||||
if (Ctx.checkingABI()) {
|
||||
if (hasFixedBinaryOrder() != R->hasFixedBinaryOrder()) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::func_has_fixed_order_change,
|
||||
getScreenInfo(), hasFixedBinaryOrder());
|
||||
emitDiag(diag::func_has_fixed_order_change, hasFixedBinaryOrder());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -745,8 +737,7 @@ void swift::ide::api::SDKNodeDeclSubscript::diagnose(SDKNode *Right) {
|
||||
if (!R)
|
||||
return;
|
||||
if (hasSetter() && !R->hasSetter()) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::removed_setter,
|
||||
getScreenInfo());
|
||||
emitDiag(diag::removed_setter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -755,16 +746,15 @@ void swift::ide::api::SDKNodeDecl::diagnose(SDKNode *Right) {
|
||||
auto *RD = dyn_cast<SDKNodeDecl>(Right);
|
||||
if (!RD)
|
||||
return;
|
||||
auto &Diags = Ctx.getDiags();
|
||||
detectRename(this, RD);
|
||||
if (isOpen() && !RD->isOpen()) {
|
||||
Diags.diagnose(SourceLoc(), diag::no_longer_open, getScreenInfo());
|
||||
emitDiag(diag::no_longer_open);
|
||||
}
|
||||
|
||||
// Diagnose static attribute change.
|
||||
if (isStatic() ^ RD->isStatic()) {
|
||||
Diags.diagnose(SourceLoc(), diag::decl_new_attr, getScreenInfo(),
|
||||
Ctx.buffer(isStatic() ? "not static" : "static"));
|
||||
emitDiag(diag::decl_new_attr, Ctx.buffer(isStatic() ? "not static" :
|
||||
"static"));
|
||||
}
|
||||
|
||||
// Diagnose ownership change.
|
||||
@@ -775,24 +765,22 @@ void swift::ide::api::SDKNodeDecl::diagnose(SDKNode *Right) {
|
||||
return Ctx.buffer("strong");
|
||||
return keywordOf(O);
|
||||
};
|
||||
Diags.diagnose(SourceLoc(), diag::decl_attr_change, getScreenInfo(),
|
||||
getOwnershipDescription(getReferenceOwnership()),
|
||||
getOwnershipDescription(RD->getReferenceOwnership()));
|
||||
emitDiag(diag::decl_attr_change,
|
||||
getOwnershipDescription(getReferenceOwnership()),
|
||||
getOwnershipDescription(RD->getReferenceOwnership()));
|
||||
}
|
||||
// Diagnose generic signature change
|
||||
if (getGenericSignature() != RD->getGenericSignature()) {
|
||||
Diags.diagnose(SourceLoc(), diag::generic_sig_change, getScreenInfo(),
|
||||
getGenericSignature(), RD->getGenericSignature());
|
||||
emitDiag(diag::generic_sig_change,
|
||||
getGenericSignature(), RD->getGenericSignature());
|
||||
}
|
||||
if (isOptional() != RD->isOptional()) {
|
||||
if (Ctx.checkingABI()) {
|
||||
// Both adding/removing optional is ABI-breaking.
|
||||
Diags.diagnose(SourceLoc(), diag::optional_req_changed,
|
||||
getScreenInfo(), isOptional());
|
||||
emitDiag(diag::optional_req_changed, isOptional());
|
||||
} else if (isOptional()) {
|
||||
// Removing optional is source-breaking.
|
||||
Diags.diagnose(SourceLoc(), diag::optional_req_changed,
|
||||
getScreenInfo(), isOptional());
|
||||
emitDiag(diag::optional_req_changed, isOptional());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -802,18 +790,15 @@ void swift::ide::api::SDKNodeDecl::diagnose(SDKNode *Right) {
|
||||
auto Desc = hasDeclAttribute(Info.Kind) ?
|
||||
Ctx.buffer((llvm::Twine("without ") + Info.Content).str()):
|
||||
Ctx.buffer((llvm::Twine("with ") + Info.Content).str());
|
||||
Diags.diagnose(SourceLoc(), diag::decl_new_attr, getScreenInfo(),
|
||||
Desc);
|
||||
emitDiag(diag::decl_new_attr, Desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (Ctx.checkingABI()) {
|
||||
if (hasFixedBinaryOrder() && RD->hasFixedBinaryOrder() &&
|
||||
getFixedBinaryOrder() != RD->getFixedBinaryOrder()) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::decl_reorder,
|
||||
getScreenInfo(),
|
||||
getFixedBinaryOrder(),
|
||||
RD->getFixedBinaryOrder());
|
||||
emitDiag(diag::decl_reorder, getFixedBinaryOrder(),
|
||||
RD->getFixedBinaryOrder());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -824,8 +809,7 @@ void swift::ide::api::SDKNodeDeclOperator::diagnose(SDKNode *Right) {
|
||||
if (!RO)
|
||||
return;
|
||||
if (getDeclKind() != RO->getDeclKind()) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::decl_kind_changed, getScreenInfo(),
|
||||
getDeclKindStr(RO->getDeclKind()));
|
||||
emitDiag(diag::decl_kind_changed, getDeclKindStr(RO->getDeclKind()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,18 +819,14 @@ void swift::ide::api::SDKNodeDeclVar::diagnose(SDKNode *Right) {
|
||||
if (!RV)
|
||||
return;
|
||||
if (getSetter() && !RV->getSetter()) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::removed_setter,
|
||||
getScreenInfo());
|
||||
emitDiag(diag::removed_setter);
|
||||
}
|
||||
if (Ctx.checkingABI()) {
|
||||
if (hasFixedBinaryOrder() != RV->hasFixedBinaryOrder()) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::var_has_fixed_order_change,
|
||||
getScreenInfo(), hasFixedBinaryOrder());
|
||||
emitDiag(diag::var_has_fixed_order_change, hasFixedBinaryOrder());
|
||||
}
|
||||
if (isLet() != RV->isLet()) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::var_let_changed,
|
||||
getScreenInfo(),
|
||||
isLet());
|
||||
emitDiag(diag::var_let_changed, isLet());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -857,7 +837,6 @@ static bool shouldDiagnoseType(SDKNodeType *T) {
|
||||
|
||||
void swift::ide::api::SDKNodeType::diagnose(SDKNode *Right) {
|
||||
SDKNode::diagnose(Right);
|
||||
auto &Diags = Ctx.getDiags();
|
||||
auto *RT = dyn_cast<SDKNodeType>(Right);
|
||||
if (!RT || !shouldDiagnoseType(this))
|
||||
return;
|
||||
@@ -867,10 +846,10 @@ void swift::ide::api::SDKNodeType::diagnose(SDKNode *Right) {
|
||||
if (auto *Wit = dyn_cast<SDKNodeTypeWitness>(getParent())) {
|
||||
auto *Conform = Wit->getParent()->getAs<SDKNodeConformance>();
|
||||
if (Ctx.checkingABI() && getPrintedName() != RT->getPrintedName()) {
|
||||
Diags.diagnose(SourceLoc(), diag::type_witness_change,
|
||||
Conform->getNominalTypeDecl()->getScreenInfo(),
|
||||
Wit->getWitnessedTypeName(),
|
||||
getPrintedName(), RT->getPrintedName());
|
||||
Conform->getNominalTypeDecl()->emitDiag(diag::type_witness_change,
|
||||
Wit->getWitnessedTypeName(),
|
||||
getPrintedName(),
|
||||
RT->getPrintedName());
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -881,35 +860,31 @@ void swift::ide::api::SDKNodeType::diagnose(SDKNode *Right) {
|
||||
assert(LParent->getKind() == RT->getParent()->getAs<SDKNodeDecl>()->getKind());
|
||||
|
||||
if (getPrintedName() != RT->getPrintedName()) {
|
||||
Diags.diagnose(SourceLoc(), diag::decl_type_change, LParent->getScreenInfo(),
|
||||
Descriptor, getPrintedName(), RT->getPrintedName());
|
||||
LParent->emitDiag(diag::decl_type_change,
|
||||
Descriptor, getPrintedName(), RT->getPrintedName());
|
||||
}
|
||||
|
||||
if (hasDefaultArgument() && !RT->hasDefaultArgument()) {
|
||||
Diags.diagnose(SourceLoc(), diag::default_arg_removed,
|
||||
LParent->getScreenInfo(), Descriptor);
|
||||
LParent->emitDiag(diag::default_arg_removed, Descriptor);
|
||||
}
|
||||
if (getParamValueOwnership() != RT->getParamValueOwnership()) {
|
||||
Diags.diagnose(SourceLoc(), diag::param_ownership_change,
|
||||
getParent()->getAs<SDKNodeDecl>()->getScreenInfo(),
|
||||
getTypeRoleDescription(),
|
||||
getParamValueOwnership(),
|
||||
RT->getParamValueOwnership());
|
||||
getParent()->getAs<SDKNodeDecl>()->emitDiag(diag::param_ownership_change,
|
||||
getTypeRoleDescription(),
|
||||
getParamValueOwnership(),
|
||||
RT->getParamValueOwnership());
|
||||
}
|
||||
}
|
||||
|
||||
void swift::ide::api::SDKNodeTypeFunc::diagnose(SDKNode *Right) {
|
||||
SDKNode::diagnose(Right);
|
||||
auto &Diags = Ctx.getDiags();
|
||||
auto *RT = dyn_cast<SDKNodeTypeFunc>(Right);
|
||||
if (!RT || !shouldDiagnoseType(this))
|
||||
return;
|
||||
assert(isTopLevelType());
|
||||
if (Ctx.checkingABI() && isEscaping() != RT->isEscaping()) {
|
||||
Diags.diagnose(SourceLoc(), diag::func_type_escaping_changed,
|
||||
getParent()->getAs<SDKNodeDecl>()->getScreenInfo(),
|
||||
getTypeRoleDescription(),
|
||||
isEscaping());
|
||||
getParent()->getAs<SDKNodeDecl>()->emitDiag(diag::func_type_escaping_changed,
|
||||
getTypeRoleDescription(),
|
||||
isEscaping());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -980,8 +955,7 @@ public:
|
||||
// Any order-important decl added to a non-resilient type breaks ABI.
|
||||
if (auto *D = dyn_cast<SDKNodeDecl>(Right)) {
|
||||
if (D->hasFixedBinaryOrder()) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::decl_added,
|
||||
D->getScreenInfo());
|
||||
D->emitDiag(diag::decl_added);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -995,23 +969,21 @@ public:
|
||||
ShouldComplain = false;
|
||||
}
|
||||
if (ShouldComplain &&
|
||||
ProtocolReqWhitelist.count(D->getParent()->getAs<SDKNodeDecl>()->getFullyQualifiedName())) {
|
||||
ProtocolReqWhitelist.count(D->getParent()->getAs<SDKNodeDecl>()->
|
||||
getFullyQualifiedName())) {
|
||||
// Ignore protocol requirement additions if the protocol has been added
|
||||
// to the whitelist.
|
||||
ShouldComplain = false;
|
||||
}
|
||||
if (ShouldComplain)
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::protocol_req_added,
|
||||
D->getScreenInfo());
|
||||
D->emitDiag(diag::protocol_req_added);
|
||||
}
|
||||
}
|
||||
// Diagnose an inherited protocol has been added.
|
||||
if (auto *Conf = dyn_cast<SDKNodeConformance>(Right)) {
|
||||
auto *TD = Conf->getNominalTypeDecl();
|
||||
if (TD->isProtocol()) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::conformance_added,
|
||||
TD->getScreenInfo(),
|
||||
Conf->getName());
|
||||
TD->emitDiag(diag::conformance_added, Conf->getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1021,17 +993,16 @@ public:
|
||||
Left->annotate(NodeAnnotation::Removed);
|
||||
if (auto *LT = dyn_cast<SDKNodeType>(Left)) {
|
||||
if (auto *AT = dyn_cast<SDKNodeDeclAssociatedType>(LT->getParent())) {
|
||||
Ctx.getDiags().diagnose(SourceLoc(),
|
||||
diag::default_associated_type_removed,
|
||||
AT->getScreenInfo(), LT->getPrintedName());
|
||||
AT->emitDiag(diag::default_associated_type_removed,
|
||||
LT->getPrintedName());
|
||||
}
|
||||
}
|
||||
// Diagnose a protocol conformance has been removed.
|
||||
if (auto *Conf = dyn_cast<SDKNodeConformance>(Left)) {
|
||||
auto *TD = Conf->getNominalTypeDecl();
|
||||
Ctx.getDiags().diagnose(SourceLoc(), diag::conformance_removed,
|
||||
TD->getScreenInfo(), Conf->getName(),
|
||||
TD->isProtocol());
|
||||
TD->emitDiag(diag::conformance_removed,
|
||||
Conf->getName(),
|
||||
TD->isProtocol());
|
||||
}
|
||||
return;
|
||||
case NodeMatchReason::FuncToProperty:
|
||||
@@ -1807,11 +1778,10 @@ class DiagnosisEmitter : public SDKNodeVisitor {
|
||||
UpdatedNodesMap &UpdateMap;
|
||||
NodeMap &TypeAliasUpdateMap;
|
||||
TypeMemberDiffVector &MemberChanges;
|
||||
DiagnosticEngine &Diags;
|
||||
DiagnosisEmitter(SDKContext &Ctx):
|
||||
UpdateMap(Ctx.getNodeUpdateMap()),
|
||||
TypeAliasUpdateMap(Ctx.getTypeAliasUpdateMap()),
|
||||
MemberChanges(Ctx.getTypeMemberDiffs()), Diags(Ctx.getDiags()) {}
|
||||
MemberChanges(Ctx.getTypeMemberDiffs()) {}
|
||||
|
||||
public:
|
||||
static void diagnosis(NodePtr LeftRoot, NodePtr RightRoot,
|
||||
@@ -1866,7 +1836,7 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
|
||||
return;
|
||||
if (auto *Added = findAddedDecl(Node)) {
|
||||
if (Node->getDeclKind() != DeclKind::Constructor) {
|
||||
Diags.diagnose(SourceLoc(), diag::moved_decl, Node->getScreenInfo(),
|
||||
Node->emitDiag(diag::moved_decl,
|
||||
Ctx.buffer((Twine(getDeclKindStr(Added->getDeclKind())) + " " +
|
||||
Added->getFullyQualifiedName()).str()));
|
||||
return;
|
||||
@@ -1878,7 +1848,7 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
|
||||
auto It = std::find_if(MemberChanges.begin(), MemberChanges.end(),
|
||||
[&](TypeMemberDiffItem &Item) { return Item.usr == Node->getUsr(); });
|
||||
if (It != MemberChanges.end()) {
|
||||
Diags.diagnose(SourceLoc(), diag::renamed_decl, Node->getScreenInfo(),
|
||||
Node->emitDiag(diag::renamed_decl,
|
||||
Ctx.buffer((Twine(getDeclKindStr(Node->getDeclKind())) + " " +
|
||||
It->newTypeName + "." + It->newPrintedName).str()));
|
||||
return;
|
||||
@@ -1889,7 +1859,7 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
|
||||
// refine diagnostics message instead of showing the type alias has been
|
||||
// removed.
|
||||
if (TypeAliasUpdateMap.find((SDKNode*)Node) != TypeAliasUpdateMap.end()) {
|
||||
Diags.diagnose(SourceLoc(), diag::raw_type_change, Node->getScreenInfo(),
|
||||
Node->emitDiag(diag::raw_type_change,
|
||||
Node->getAs<SDKNodeDeclTypeAlias>()->getUnderlyingType()->getPrintedName(),
|
||||
TypeAliasUpdateMap[(SDKNode*)Node]->getAs<SDKNodeDeclType>()->
|
||||
getRawValueType()->getPrintedName());
|
||||
@@ -1911,13 +1881,12 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
|
||||
}
|
||||
if (FoundInSuperclass)
|
||||
return;
|
||||
Diags.diagnose(SourceLoc(), diag::removed_decl, Node->getScreenInfo(),
|
||||
Node->isDeprecated());
|
||||
Node->emitDiag(diag::removed_decl, Node->isDeprecated());
|
||||
return;
|
||||
}
|
||||
case NodeAnnotation::Rename: {
|
||||
auto *Count = UpdateMap.findUpdateCounterpart(Node)->getAs<SDKNodeDecl>();
|
||||
Diags.diagnose(SourceLoc(), diag::renamed_decl, Node->getScreenInfo(),
|
||||
Node->emitDiag(diag::renamed_decl,
|
||||
Ctx.buffer((Twine(getDeclKindStr(Count->getDeclKind())) + " " +
|
||||
Count->getFullyQualifiedName()).str()));
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user