Merge remote-tracking branch 'origin/main' into rebranch

This commit is contained in:
swift-ci
2021-08-20 09:13:20 -07:00
5 changed files with 328 additions and 315 deletions

View File

@@ -76,16 +76,6 @@ struct MatchedNodeListener {
virtual ~MatchedNodeListener() = default;
};
template<typename T>
bool contains(std::vector<T*> &container, T *instance) {
return std::find(container.begin(), container.end(), instance) != container.end();
}
template<typename T>
bool contains(ArrayRef<T> container, T instance) {
return std::find(container.begin(), container.end(), instance) != container.end();
}
static
void singleMatch(SDKNode* Left, SDKNode *Right, MatchedNodeListener &Listener) {
@@ -184,7 +174,7 @@ class RemovedAddedNodeMatcher : public NodeMatcher, public MatchedNodeListener {
void handleUnmatch(NodeVector &Matched, NodeVector &All, bool Left) {
for (auto A : All) {
if (contains(Matched, A))
if (llvm::is_contained(Matched, A))
continue;
if (Left)
Listener.foundMatch(A, nullptr, NodeMatchReason::Removed);
@@ -383,12 +373,12 @@ public:
NodeVector RenameRight;
for (auto Remain : Removed) {
if (!contains(RemovedMatched, Remain))
if (!llvm::is_contained(RemovedMatched, Remain))
RenameLeft.push_back(Remain);
}
for (auto Remain : Added) {
if (!contains(AddedMatched, Remain))
if (!llvm::is_contained(AddedMatched, Remain))
RenameRight.push_back(Remain);
}
@@ -490,7 +480,7 @@ void SameNameNodeMatcher::match() {
for (auto *RN : Right) {
// If RN has matched before, ignore it.
if (contains(MatchedRight, RN))
if (llvm::is_contained(MatchedRight, RN))
continue;
// If LN and RN have the same name for some reason, keep track of RN.
@@ -509,7 +499,7 @@ void SameNameNodeMatcher::match() {
}
}
for (auto &R : Right) {
if (!contains(MatchedRight, R)) {
if (!llvm::is_contained(MatchedRight, R)) {
Added.push_back(R);
}
}
@@ -552,306 +542,8 @@ public:
virtual void pass(NodePtr Left, NodePtr Right) = 0;
virtual ~SDKTreeDiffPass() {}
};
static void detectRename(SDKNode *L, SDKNode *R) {
if (L->getKind() == R->getKind() && isa<SDKNodeDecl>(L) &&
L->getPrintedName() != R->getPrintedName()) {
L->annotate(NodeAnnotation::Rename);
L->annotate(NodeAnnotation::RenameOldName, L->getPrintedName());
L->annotate(NodeAnnotation::RenameNewName, R->getPrintedName());
}
}
static bool isOwnershipEquivalent(ReferenceOwnership Left,
ReferenceOwnership Right) {
if (Left == Right)
return true;
if (Left == ReferenceOwnership::Unowned && Right == ReferenceOwnership::Weak)
return true;
if (Left == ReferenceOwnership::Weak && Right == ReferenceOwnership::Unowned)
return true;
return false;
}
}// End of anonymous namespace
void swift::ide::api::SDKNodeDeclType::diagnose(SDKNode *Right) {
SDKNodeDecl::diagnose(Right);
auto *R = dyn_cast<SDKNodeDeclType>(Right);
if (!R)
return;
auto Loc = R->getLoc();
if (getDeclKind() != R->getDeclKind()) {
emitDiag(Loc, diag::decl_kind_changed, getDeclKindStr(R->getDeclKind(),
getSDKContext().getOpts().CompilerStyle));
return;
}
assert(getDeclKind() == R->getDeclKind());
auto DKind = getDeclKind();
switch (DKind) {
case DeclKind::Class: {
auto LSuperClass = getSuperClassName();
auto RSuperClass = R->getSuperClassName();
if (!LSuperClass.empty() && LSuperClass != RSuperClass) {
if (RSuperClass.empty()) {
emitDiag(Loc, diag::super_class_removed, LSuperClass);
} else if (!contains(R->getClassInheritanceChain(), LSuperClass)) {
emitDiag(Loc, diag::super_class_changed, LSuperClass, RSuperClass);
}
}
// Check for @_hasMissingDesignatedInitializers and
// @_inheritsConvenienceInitializers changes.
if (isOpen() && R->isOpen()) {
// It's not safe to add new, invisible designated inits to open
// classes.
if (!hasMissingDesignatedInitializers() &&
R->hasMissingDesignatedInitializers())
R->emitDiag(R->getLoc(), diag::added_invisible_designated_init);
}
// It's not safe to stop inheriting convenience inits, it changes
// the set of initializers that are available.
if (!Ctx.checkingABI() &&
inheritsConvenienceInitializers() &&
!R->inheritsConvenienceInitializers())
R->emitDiag(R->getLoc(), diag::not_inheriting_convenience_inits);
break;
}
default:
break;
}
}
void swift::ide::api::SDKNodeDeclAbstractFunc::diagnose(SDKNode *Right) {
SDKNodeDecl::diagnose(Right);
auto *R = dyn_cast<SDKNodeDeclAbstractFunc>(Right);
if (!R)
return;
auto Loc = R->getLoc();
if (!isThrowing() && R->isThrowing()) {
emitDiag(Loc, diag::decl_new_attr, Ctx.buffer("throwing"));
}
if (Ctx.checkingABI()) {
if (reqNewWitnessTableEntry() != R->reqNewWitnessTableEntry()) {
emitDiag(Loc, diag::decl_new_witness_table_entry, reqNewWitnessTableEntry());
}
}
}
void swift::ide::api::SDKNodeDeclFunction::diagnose(SDKNode *Right) {
SDKNodeDeclAbstractFunc::diagnose(Right);
auto *R = dyn_cast<SDKNodeDeclFunction>(Right);
if (!R)
return;
auto Loc = R->getLoc();
if (getSelfAccessKind() != R->getSelfAccessKind()) {
emitDiag(Loc, diag::func_self_access_change, getSelfAccessKind(),
R->getSelfAccessKind());
}
if (Ctx.checkingABI()) {
if (hasFixedBinaryOrder() != R->hasFixedBinaryOrder()) {
emitDiag(Loc, diag::func_has_fixed_order_change, hasFixedBinaryOrder());
}
}
}
static StringRef getAttrName(DeclAttrKind Kind) {
switch (Kind) {
#define DECL_ATTR(NAME, CLASS, ...) \
case DAK_##CLASS: \
return DeclAttribute::isDeclModifier(DAK_##CLASS) ? #NAME : "@"#NAME;
#include "swift/AST/Attr.def"
case DAK_Count:
llvm_unreachable("unrecognized attribute kind.");
}
llvm_unreachable("covered switch");
}
static bool shouldDiagnoseAddingAttribute(SDKNodeDecl *D, DeclAttrKind Kind) {
return true;
}
static bool shouldDiagnoseRemovingAttribute(SDKNodeDecl *D, DeclAttrKind Kind) {
return true;
}
void swift::ide::api::SDKNodeDecl::diagnose(SDKNode *Right) {
SDKNode::diagnose(Right);
auto *RD = dyn_cast<SDKNodeDecl>(Right);
if (!RD)
return;
detectRename(this, RD);
auto Loc = RD->getLoc();
if (isOpen() && !RD->isOpen()) {
emitDiag(Loc, diag::no_longer_open);
}
// Diagnose static attribute change.
if (isStatic() ^ RD->isStatic()) {
emitDiag(Loc, diag::decl_new_attr, Ctx.buffer(isStatic() ? "not static" :
"static"));
}
// Diagnose ownership change.
if (!isOwnershipEquivalent(getReferenceOwnership(),
RD->getReferenceOwnership())) {
auto getOwnershipDescription = [&](swift::ReferenceOwnership O) {
if (O == ReferenceOwnership::Strong)
return Ctx.buffer("strong");
return keywordOf(O);
};
emitDiag(Loc, diag::decl_attr_change,
getOwnershipDescription(getReferenceOwnership()),
getOwnershipDescription(RD->getReferenceOwnership()));
}
// Diagnose generic signature change
if (getGenericSignature() != RD->getGenericSignature()) {
// Prefer sugared signature in diagnostics to be more user-friendly.
if (Ctx.commonVersionAtLeast(2) &&
getSugaredGenericSignature() != RD->getSugaredGenericSignature()) {
emitDiag(Loc, diag::generic_sig_change,
getSugaredGenericSignature(), RD->getSugaredGenericSignature());
} else {
emitDiag(Loc, diag::generic_sig_change,
getGenericSignature(), RD->getGenericSignature());
}
}
// ObjC name changes are considered breakage
if (getObjCName() != RD->getObjCName()) {
if (Ctx.commonVersionAtLeast(4)) {
emitDiag(Loc, diag::objc_name_change, getObjCName(), RD->getObjCName());
}
}
if (isOptional() != RD->isOptional()) {
if (Ctx.checkingABI()) {
// Both adding/removing optional is ABI-breaking.
emitDiag(Loc, diag::optional_req_changed, isOptional());
} else if (isOptional()) {
// Removing optional is source-breaking.
emitDiag(Loc, diag::optional_req_changed, isOptional());
}
}
// Diagnose removing attributes.
for (auto Kind: getDeclAttributes()) {
if (!RD->hasDeclAttribute(Kind)) {
if ((Ctx.checkingABI() ? DeclAttribute::isRemovingBreakingABI(Kind) :
DeclAttribute::isRemovingBreakingAPI(Kind)) &&
shouldDiagnoseRemovingAttribute(this, Kind)) {
emitDiag(Loc, diag::decl_new_attr,
Ctx.buffer((llvm::Twine("without ") + getAttrName(Kind)).str()));
}
}
}
// Diagnose adding attributes.
for (auto Kind: RD->getDeclAttributes()) {
if (!hasDeclAttribute(Kind)) {
if ((Ctx.checkingABI() ? DeclAttribute::isAddingBreakingABI(Kind) :
DeclAttribute::isAddingBreakingAPI(Kind)) &&
shouldDiagnoseAddingAttribute(this, Kind)) {
emitDiag(Loc, diag::decl_new_attr,
Ctx.buffer((llvm::Twine("with ") + getAttrName(Kind)).str()));
}
}
}
if (Ctx.checkingABI()) {
if (hasFixedBinaryOrder() && RD->hasFixedBinaryOrder() &&
getFixedBinaryOrder() != RD->getFixedBinaryOrder()) {
emitDiag(Loc, diag::decl_reorder, getFixedBinaryOrder(),
RD->getFixedBinaryOrder());
}
}
}
void swift::ide::api::SDKNodeDeclOperator::diagnose(SDKNode *Right) {
SDKNodeDecl::diagnose(Right);
auto *RO = dyn_cast<SDKNodeDeclOperator>(Right);
if (!RO)
return;
auto Loc = RO->getLoc();
if (getDeclKind() != RO->getDeclKind()) {
emitDiag(Loc, diag::decl_kind_changed, getDeclKindStr(RO->getDeclKind(),
getSDKContext().getOpts().CompilerStyle));
}
}
void swift::ide::api::SDKNodeDeclVar::diagnose(SDKNode *Right) {
SDKNodeDecl::diagnose(Right);
auto *RV = dyn_cast<SDKNodeDeclVar>(Right);
if (!RV)
return;
auto Loc = RV->getLoc();
if (Ctx.checkingABI()) {
if (hasFixedBinaryOrder() != RV->hasFixedBinaryOrder()) {
emitDiag(Loc, diag::var_has_fixed_order_change, hasFixedBinaryOrder());
}
}
}
static bool shouldDiagnoseType(SDKNodeType *T) {
return T->isTopLevelType();
}
void swift::ide::api::SDKNodeType::diagnose(SDKNode *Right) {
SDKNode::diagnose(Right);
auto *RT = dyn_cast<SDKNodeType>(Right);
if (!RT || !shouldDiagnoseType(this))
return;
assert(isTopLevelType());
// Diagnose type witness changes when diagnosing ABI breakages.
if (auto *Wit = dyn_cast<SDKNodeTypeWitness>(getParent())) {
auto *Conform = Wit->getParent()->getAs<SDKNodeConformance>();
if (Ctx.checkingABI() && getPrintedName() != RT->getPrintedName()) {
auto *LD = Conform->getNominalTypeDecl();
LD->emitDiag(SourceLoc(), diag::type_witness_change,
Wit->getWitnessedTypeName(),
getPrintedName(), RT->getPrintedName());
}
return;
}
StringRef Descriptor = getTypeRoleDescription();
assert(isa<SDKNodeDecl>(getParent()));
auto LParent = cast<SDKNodeDecl>(getParent());
assert(LParent->getKind() == RT->getParent()->getAs<SDKNodeDecl>()->getKind());
auto Loc = RT->getParent()->getAs<SDKNodeDecl>()->getLoc();
if (getPrintedName() != RT->getPrintedName()) {
LParent->emitDiag(Loc, diag::decl_type_change,
Descriptor, getPrintedName(), RT->getPrintedName());
}
if (hasDefaultArgument() && !RT->hasDefaultArgument()) {
LParent->emitDiag(Loc, diag::default_arg_removed, Descriptor);
}
if (getParamValueOwnership() != RT->getParamValueOwnership()) {
LParent->emitDiag(Loc, diag::param_ownership_change,
getTypeRoleDescription(),
getParamValueOwnership(),
RT->getParamValueOwnership());
}
}
void swift::ide::api::SDKNodeTypeFunc::diagnose(SDKNode *Right) {
SDKNodeType::diagnose(Right);
auto *RT = dyn_cast<SDKNodeTypeFunc>(Right);
if (!RT || !shouldDiagnoseType(this))
return;
assert(isTopLevelType());
auto Loc = RT->getParent()->getAs<SDKNodeDecl>()->getLoc();
if (Ctx.checkingABI() && isEscaping() != RT->isEscaping()) {
getParent()->getAs<SDKNodeDecl>()->emitDiag(Loc,
diag::func_type_escaping_changed,
getTypeRoleDescription(),
isEscaping());
}
}
namespace {
static void diagnoseRemovedDecl(const SDKNodeDecl *D) {
if (D->getSDKContext().checkingABI()) {
@@ -2048,7 +1740,7 @@ public:
void foundMatch(NodePtr Left, NodePtr Right, NodeMatchReason Reason) override {
if (!Left || !Right)
return;
detectRename(Left, Right);
swift::ide::api::detectRename(Left, Right);
LeftDetector.detect(Left, Right);
RightDetector.detect(Right, Left);
}