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:
Xi Ge
2019-03-27 14:18:09 -07:00
parent 72ea2426c1
commit 350ed65def
2 changed files with 70 additions and 86 deletions

View File

@@ -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;