mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #79614 from DougGregor/conformance-attributes
Factor conformance attributes into their own separate structure.
This commit is contained in:
46
include/swift/AST/ConformanceAttributes.h
Normal file
46
include/swift/AST/ConformanceAttributes.h
Normal file
@@ -0,0 +1,46 @@
|
||||
//===--- ConformanceLookup.h - Global conformance lookup --------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2024 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_AST_CONFORMANCEATTRIBUTES_H
|
||||
#define SWIFT_AST_CONFORMANCEATTRIBUTES_H
|
||||
|
||||
#include "swift/Basic/SourceLoc.h"
|
||||
|
||||
namespace swift {
|
||||
|
||||
/// Describes all of the attributes that can occur on a conformance.
|
||||
struct ConformanceAttributes {
|
||||
/// The location of the "unchecked" attribute, if present.
|
||||
SourceLoc uncheckedLoc;
|
||||
|
||||
/// The location of the "preconcurrency" attribute if present.
|
||||
SourceLoc preconcurrencyLoc;
|
||||
|
||||
/// The location of the "unsafe" attribute if present.
|
||||
SourceLoc unsafeLoc;
|
||||
|
||||
/// Merge other conformance attributes into this set.
|
||||
ConformanceAttributes &
|
||||
operator |=(const ConformanceAttributes &other) {
|
||||
if (other.uncheckedLoc.isValid())
|
||||
uncheckedLoc = other.uncheckedLoc;
|
||||
if (other.preconcurrencyLoc.isValid())
|
||||
preconcurrencyLoc = other.preconcurrencyLoc;
|
||||
if (other.unsafeLoc.isValid())
|
||||
unsafeLoc = other.unsafeLoc;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "swift/AST/ASTVisitor.h"
|
||||
#include "swift/AST/CatchNode.h"
|
||||
#include "swift/AST/ConformanceAttributes.h"
|
||||
#include "swift/AST/GenericSignature.h"
|
||||
#include "swift/AST/Identifier.h"
|
||||
#include "swift/AST/Module.h"
|
||||
@@ -603,14 +604,7 @@ void forEachPotentialAttachedMacro(
|
||||
|
||||
/// Describes an inherited nominal entry.
|
||||
struct InheritedNominalEntry : Located<NominalTypeDecl *> {
|
||||
/// The location of the "unchecked" attribute, if present.
|
||||
SourceLoc uncheckedLoc;
|
||||
|
||||
/// The location of the "preconcurrency" attribute if present.
|
||||
SourceLoc preconcurrencyLoc;
|
||||
|
||||
/// The location of the "unsafe" attribute if present.
|
||||
SourceLoc unsafeLoc;
|
||||
ConformanceAttributes attributes;
|
||||
|
||||
/// Whether this inherited entry was suppressed via "~".
|
||||
bool isSuppressed;
|
||||
@@ -618,10 +612,9 @@ struct InheritedNominalEntry : Located<NominalTypeDecl *> {
|
||||
InheritedNominalEntry() { }
|
||||
|
||||
InheritedNominalEntry(NominalTypeDecl *item, SourceLoc loc,
|
||||
SourceLoc uncheckedLoc, SourceLoc preconcurrencyLoc,
|
||||
SourceLoc unsafeLoc, bool isSuppressed)
|
||||
: Located(item, loc), uncheckedLoc(uncheckedLoc),
|
||||
preconcurrencyLoc(preconcurrencyLoc), unsafeLoc(unsafeLoc),
|
||||
ConformanceAttributes attributes,
|
||||
bool isSuppressed)
|
||||
: Located(item, loc), attributes(attributes),
|
||||
isSuppressed(isSuppressed) {}
|
||||
};
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "ConformanceLookupTable.h"
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/ConformanceAttributes.h"
|
||||
#include "swift/AST/ConformanceLookup.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/ExistentialLayout.h"
|
||||
@@ -148,23 +149,13 @@ void ConformanceLookupTable::destroy() {
|
||||
|
||||
namespace {
|
||||
struct ConformanceConstructionInfo : public Located<ProtocolDecl *> {
|
||||
/// The location of the "unchecked" attribute, if present.
|
||||
const SourceLoc uncheckedLoc;
|
||||
|
||||
/// The location of the "preconcurrency" attribute if present.
|
||||
const SourceLoc preconcurrencyLoc;
|
||||
|
||||
/// The location of the "unsafe" attribute if present.
|
||||
const SourceLoc unsafeLoc;
|
||||
ConformanceAttributes attributes;
|
||||
|
||||
ConformanceConstructionInfo() { }
|
||||
|
||||
ConformanceConstructionInfo(ProtocolDecl *item, SourceLoc loc,
|
||||
SourceLoc uncheckedLoc,
|
||||
SourceLoc preconcurrencyLoc,
|
||||
SourceLoc unsafeLoc)
|
||||
: Located(item, loc), uncheckedLoc(uncheckedLoc),
|
||||
preconcurrencyLoc(preconcurrencyLoc), unsafeLoc(unsafeLoc) {}
|
||||
ConformanceAttributes attributes)
|
||||
: Located(item, loc), attributes(attributes) {}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -220,7 +211,7 @@ void ConformanceLookupTable::forEachInStage(ConformanceStage stage,
|
||||
registerProtocolConformances(next, conformances);
|
||||
for (auto conf : conformances) {
|
||||
protocols.push_back(
|
||||
{conf->getProtocol(), SourceLoc(), SourceLoc(), SourceLoc(), SourceLoc()});
|
||||
{conf->getProtocol(), SourceLoc(), ConformanceAttributes()});
|
||||
}
|
||||
} else if (next->getParentSourceFile() ||
|
||||
next->getParentModule()->isBuiltinModule()) {
|
||||
@@ -229,9 +220,7 @@ void ConformanceLookupTable::forEachInStage(ConformanceStage stage,
|
||||
for (const auto &found :
|
||||
getDirectlyInheritedNominalTypeDecls(next, inverses, anyObject)) {
|
||||
if (auto proto = dyn_cast<ProtocolDecl>(found.Item))
|
||||
protocols.push_back(
|
||||
{proto, found.Loc, found.uncheckedLoc,
|
||||
found.preconcurrencyLoc, found.unsafeLoc});
|
||||
protocols.push_back({proto, found.Loc, found.attributes});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,10 +307,8 @@ void ConformanceLookupTable::updateLookupTable(NominalTypeDecl *nominal,
|
||||
kp.has_value() &&
|
||||
"suppressed conformance for non-known protocol!?");
|
||||
if (!found.isSuppressed) {
|
||||
addProtocol(proto, found.Loc,
|
||||
source.withUncheckedLoc(found.uncheckedLoc)
|
||||
.withPreconcurrencyLoc(found.preconcurrencyLoc)
|
||||
.withUnsafeLoc(found.unsafeLoc));
|
||||
addProtocol(
|
||||
proto, found.Loc, source.withAttributes(found.attributes));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,9 +322,7 @@ void ConformanceLookupTable::updateLookupTable(NominalTypeDecl *nominal,
|
||||
for (auto locAndProto : protos)
|
||||
addProtocol(
|
||||
locAndProto.Item, locAndProto.Loc,
|
||||
source.withUncheckedLoc(locAndProto.uncheckedLoc)
|
||||
.withPreconcurrencyLoc(locAndProto.preconcurrencyLoc)
|
||||
.withUnsafeLoc(locAndProto.unsafeLoc));
|
||||
source.withAttributes(locAndProto.attributes));
|
||||
});
|
||||
break;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define SWIFT_AST_CONFORMANCE_LOOKUP_TABLE_H
|
||||
|
||||
#include "swift/AST/DeclContext.h"
|
||||
#include "swift/AST/ConformanceAttributes.h"
|
||||
#include "swift/AST/ProtocolConformanceOptions.h"
|
||||
#include "swift/Basic/Debug.h"
|
||||
#include "swift/Basic/LLVM.h"
|
||||
@@ -89,14 +90,7 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
|
||||
|
||||
ConformanceEntryKind Kind;
|
||||
|
||||
/// The location of the "unchecked" attribute, if there is one.
|
||||
SourceLoc uncheckedLoc;
|
||||
|
||||
/// The location of the "preconcurrency" attribute, if there is one.
|
||||
SourceLoc preconcurrencyLoc;
|
||||
|
||||
/// The location of the "unsafe" attribute, if there is one.
|
||||
SourceLoc unsafeLoc;
|
||||
ConformanceAttributes attributes;
|
||||
|
||||
ConformanceSource(void *ptr, ConformanceEntryKind kind)
|
||||
: Storage(ptr), Kind(kind) { }
|
||||
@@ -140,29 +134,16 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
|
||||
return ConformanceSource(dc, ConformanceEntryKind::PreMacroExpansion);
|
||||
}
|
||||
|
||||
/// Return a new conformance source with the given location of "@unchecked".
|
||||
ConformanceSource withUncheckedLoc(SourceLoc uncheckedLoc) {
|
||||
/// Return a new conformance source with the given conformance
|
||||
/// attributes.
|
||||
ConformanceSource withAttributes(ConformanceAttributes attributes) {
|
||||
ConformanceSource result(*this);
|
||||
if (uncheckedLoc.isValid())
|
||||
result.uncheckedLoc = uncheckedLoc;
|
||||
result.attributes |= attributes;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Return a new conformance source with the given location of
|
||||
/// "@preconcurrency".
|
||||
ConformanceSource withPreconcurrencyLoc(SourceLoc preconcurrencyLoc) {
|
||||
ConformanceSource result(*this);
|
||||
if (preconcurrencyLoc.isValid())
|
||||
result.preconcurrencyLoc = preconcurrencyLoc;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Return a new conformance source with the given location of "@unsafe".
|
||||
ConformanceSource withUnsafeLoc(SourceLoc unsafeLoc) {
|
||||
ConformanceSource result(*this);
|
||||
if (unsafeLoc.isValid())
|
||||
result.unsafeLoc = unsafeLoc;
|
||||
return result;
|
||||
ConformanceAttributes getAttributes() const {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
ProtocolConformanceOptions getOptions() const {
|
||||
@@ -216,16 +197,16 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
|
||||
|
||||
/// The location of the @unchecked attribute, if any.
|
||||
SourceLoc getUncheckedLoc() const {
|
||||
return uncheckedLoc;
|
||||
return attributes.uncheckedLoc;
|
||||
}
|
||||
|
||||
SourceLoc getPreconcurrencyLoc() const {
|
||||
return preconcurrencyLoc;
|
||||
return attributes.preconcurrencyLoc;
|
||||
}
|
||||
|
||||
/// The location of the @unsafe attribute, if any.
|
||||
SourceLoc getUnsafeLoc() const {
|
||||
return unsafeLoc;
|
||||
return attributes.unsafeLoc;
|
||||
}
|
||||
|
||||
/// For an inherited conformance, retrieve the class declaration
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "swift/AST/ASTVisitor.h"
|
||||
#include "swift/AST/ASTWalker.h"
|
||||
#include "swift/AST/ClangModuleLoader.h"
|
||||
#include "swift/AST/ConformanceAttributes.h"
|
||||
#include "swift/AST/DebuggerClient.h"
|
||||
#include "swift/AST/ExistentialLayout.h"
|
||||
#include "swift/AST/GenericParamList.h"
|
||||
@@ -3962,23 +3963,19 @@ void swift::getDirectlyInheritedNominalTypeDecls(
|
||||
// FIXME: This is a hack. We need cooperation from
|
||||
// InheritedDeclsReferencedRequest to make this work.
|
||||
SourceLoc loc;
|
||||
SourceLoc uncheckedLoc;
|
||||
SourceLoc preconcurrencyLoc;
|
||||
SourceLoc unsafeLoc;
|
||||
ConformanceAttributes attributes;
|
||||
auto inheritedTypes = InheritedTypes(decl);
|
||||
bool isSuppressed = inheritedTypes.getEntry(i).isSuppressed();
|
||||
if (TypeRepr *typeRepr = inheritedTypes.getTypeRepr(i)) {
|
||||
loc = typeRepr->getLoc();
|
||||
uncheckedLoc = typeRepr->findAttrLoc(TypeAttrKind::Unchecked);
|
||||
preconcurrencyLoc = typeRepr->findAttrLoc(TypeAttrKind::Preconcurrency);
|
||||
unsafeLoc = typeRepr->findAttrLoc(TypeAttrKind::Unsafe);
|
||||
attributes.uncheckedLoc = typeRepr->findAttrLoc(TypeAttrKind::Unchecked);
|
||||
attributes.preconcurrencyLoc = typeRepr->findAttrLoc(TypeAttrKind::Preconcurrency);
|
||||
attributes.unsafeLoc = typeRepr->findAttrLoc(TypeAttrKind::Unsafe);
|
||||
}
|
||||
|
||||
// Form the result.
|
||||
for (auto nominal : nominalTypes) {
|
||||
result.push_back(
|
||||
{nominal, loc, uncheckedLoc, preconcurrencyLoc, unsafeLoc,
|
||||
isSuppressed});
|
||||
result.push_back({nominal, loc, attributes, isSuppressed});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4008,10 +4005,11 @@ swift::getDirectlyInheritedNominalTypeDecls(
|
||||
for (auto attr :
|
||||
protoDecl->getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
|
||||
auto loc = attr->getLocation();
|
||||
ConformanceAttributes attributes;
|
||||
if (attr->isUnchecked())
|
||||
attributes.uncheckedLoc = loc;
|
||||
result.push_back(
|
||||
{attr->getProtocol(), loc, attr->isUnchecked() ? loc : SourceLoc(),
|
||||
/*preconcurrencyLoc=*/SourceLoc(), SourceLoc(),
|
||||
/*isSuppressed=*/false});
|
||||
{attr->getProtocol(), loc, attributes, /*isSuppressed=*/false});
|
||||
}
|
||||
|
||||
// Else we have access to this information on the where clause.
|
||||
@@ -4022,8 +4020,8 @@ swift::getDirectlyInheritedNominalTypeDecls(
|
||||
// FIXME: Refactor SelfBoundsFromWhereClauseRequest to dig out
|
||||
// the source location.
|
||||
for (auto inheritedNominal : selfBounds.decls)
|
||||
result.emplace_back(inheritedNominal, SourceLoc(), SourceLoc(),
|
||||
SourceLoc(), SourceLoc(), /*isSuppressed=*/false);
|
||||
result.emplace_back(inheritedNominal, SourceLoc(), ConformanceAttributes(),
|
||||
/*isSuppressed=*/false);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user