[Macros] When a macro defines a getter or setter, remove didSet/willSet

As with the initial value of a property that is converted from a stored
property to a computed property by an accessor macro, remove
didSet/willSet. It is the macro's responsibility to incorporate their
code or diagnose them.

Fixes rdar://111101833.
This commit is contained in:
Doug Gregor
2023-07-05 19:37:21 -07:00
parent 82239e9d0a
commit 16bfd783f4
6 changed files with 117 additions and 50 deletions

View File

@@ -6421,6 +6421,38 @@ bool ProtocolDecl::hasCircularInheritedProtocols() const {
ctx.evaluator, HasCircularInheritedProtocolsRequest{mutableThis}, true);
}
/// Returns a descriptive name for the given accessor/addressor kind.
StringRef swift::getAccessorNameForDiagnostic(AccessorKind accessorKind,
bool article) {
switch (accessorKind) {
case AccessorKind::Get:
return article ? "a getter" : "getter";
case AccessorKind::Set:
return article ? "a setter" : "setter";
case AccessorKind::Address:
return article ? "an addressor" : "addressor";
case AccessorKind::MutableAddress:
return article ? "a mutable addressor" : "mutable addressor";
case AccessorKind::Read:
return article ? "a 'read' accessor" : "'read' accessor";
case AccessorKind::Modify:
return article ? "a 'modify' accessor" : "'modify' accessor";
case AccessorKind::WillSet:
return "'willSet'";
case AccessorKind::DidSet:
return "'didSet'";
case AccessorKind::Init:
return article ? "an init accessor" : "init accessor";
}
llvm_unreachable("bad accessor kind");
}
StringRef swift::getAccessorNameForDiagnostic(AccessorDecl *accessor,
bool article) {
return getAccessorNameForDiagnostic(accessor->getAccessorKind(),
article);
}
bool AbstractStorageDecl::hasStorage() const {
ASTContext &ctx = getASTContext();
return evaluateOrDefault(ctx.evaluator,
@@ -6583,6 +6615,27 @@ void AbstractStorageDecl::AccessorRecord::addOpaqueAccessor(AccessorDecl *decl){
(void) isUnique;
}
void AbstractStorageDecl::AccessorRecord::removeAccessor(
AccessorDecl *accessor
) {
// Remove this accessor from the list of accessors.
assert(getAccessor(accessor->getAccessorKind()) == accessor);
std::remove(getAccessorsBuffer().begin(), getAccessorsBuffer().end(),
accessor);
// Clear out the accessor kind -> index mapping.
std::memset(AccessorIndices, 0, sizeof(AccessorIndices));
// Re-add all of the remaining accessors to build up the index mapping.
unsigned numAccessorsLeft = NumAccessors - 1;
NumAccessors = numAccessorsLeft;
auto buffer = getAccessorsBuffer();
NumAccessors = 0;
for (auto index : range(0, numAccessorsLeft)) {
addOpaqueAccessor(buffer[index]);
}
}
/// Register that we have an accessor of the given kind.
bool AbstractStorageDecl::AccessorRecord::registerAccessor(AccessorDecl *decl,
AccessorIndex index){