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/ASTVisitor.h"
|
||||||
#include "swift/AST/CatchNode.h"
|
#include "swift/AST/CatchNode.h"
|
||||||
|
#include "swift/AST/ConformanceAttributes.h"
|
||||||
#include "swift/AST/GenericSignature.h"
|
#include "swift/AST/GenericSignature.h"
|
||||||
#include "swift/AST/Identifier.h"
|
#include "swift/AST/Identifier.h"
|
||||||
#include "swift/AST/Module.h"
|
#include "swift/AST/Module.h"
|
||||||
@@ -603,14 +604,7 @@ void forEachPotentialAttachedMacro(
|
|||||||
|
|
||||||
/// Describes an inherited nominal entry.
|
/// Describes an inherited nominal entry.
|
||||||
struct InheritedNominalEntry : Located<NominalTypeDecl *> {
|
struct InheritedNominalEntry : Located<NominalTypeDecl *> {
|
||||||
/// The location of the "unchecked" attribute, if present.
|
ConformanceAttributes attributes;
|
||||||
SourceLoc uncheckedLoc;
|
|
||||||
|
|
||||||
/// The location of the "preconcurrency" attribute if present.
|
|
||||||
SourceLoc preconcurrencyLoc;
|
|
||||||
|
|
||||||
/// The location of the "unsafe" attribute if present.
|
|
||||||
SourceLoc unsafeLoc;
|
|
||||||
|
|
||||||
/// Whether this inherited entry was suppressed via "~".
|
/// Whether this inherited entry was suppressed via "~".
|
||||||
bool isSuppressed;
|
bool isSuppressed;
|
||||||
@@ -618,10 +612,9 @@ struct InheritedNominalEntry : Located<NominalTypeDecl *> {
|
|||||||
InheritedNominalEntry() { }
|
InheritedNominalEntry() { }
|
||||||
|
|
||||||
InheritedNominalEntry(NominalTypeDecl *item, SourceLoc loc,
|
InheritedNominalEntry(NominalTypeDecl *item, SourceLoc loc,
|
||||||
SourceLoc uncheckedLoc, SourceLoc preconcurrencyLoc,
|
ConformanceAttributes attributes,
|
||||||
SourceLoc unsafeLoc, bool isSuppressed)
|
bool isSuppressed)
|
||||||
: Located(item, loc), uncheckedLoc(uncheckedLoc),
|
: Located(item, loc), attributes(attributes),
|
||||||
preconcurrencyLoc(preconcurrencyLoc), unsafeLoc(unsafeLoc),
|
|
||||||
isSuppressed(isSuppressed) {}
|
isSuppressed(isSuppressed) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "ConformanceLookupTable.h"
|
#include "ConformanceLookupTable.h"
|
||||||
#include "swift/AST/ASTContext.h"
|
#include "swift/AST/ASTContext.h"
|
||||||
|
#include "swift/AST/ConformanceAttributes.h"
|
||||||
#include "swift/AST/ConformanceLookup.h"
|
#include "swift/AST/ConformanceLookup.h"
|
||||||
#include "swift/AST/Decl.h"
|
#include "swift/AST/Decl.h"
|
||||||
#include "swift/AST/ExistentialLayout.h"
|
#include "swift/AST/ExistentialLayout.h"
|
||||||
@@ -148,23 +149,13 @@ void ConformanceLookupTable::destroy() {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct ConformanceConstructionInfo : public Located<ProtocolDecl *> {
|
struct ConformanceConstructionInfo : public Located<ProtocolDecl *> {
|
||||||
/// The location of the "unchecked" attribute, if present.
|
ConformanceAttributes attributes;
|
||||||
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;
|
|
||||||
|
|
||||||
ConformanceConstructionInfo() { }
|
ConformanceConstructionInfo() { }
|
||||||
|
|
||||||
ConformanceConstructionInfo(ProtocolDecl *item, SourceLoc loc,
|
ConformanceConstructionInfo(ProtocolDecl *item, SourceLoc loc,
|
||||||
SourceLoc uncheckedLoc,
|
ConformanceAttributes attributes)
|
||||||
SourceLoc preconcurrencyLoc,
|
: Located(item, loc), attributes(attributes) {}
|
||||||
SourceLoc unsafeLoc)
|
|
||||||
: Located(item, loc), uncheckedLoc(uncheckedLoc),
|
|
||||||
preconcurrencyLoc(preconcurrencyLoc), unsafeLoc(unsafeLoc) {}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +211,7 @@ void ConformanceLookupTable::forEachInStage(ConformanceStage stage,
|
|||||||
registerProtocolConformances(next, conformances);
|
registerProtocolConformances(next, conformances);
|
||||||
for (auto conf : conformances) {
|
for (auto conf : conformances) {
|
||||||
protocols.push_back(
|
protocols.push_back(
|
||||||
{conf->getProtocol(), SourceLoc(), SourceLoc(), SourceLoc(), SourceLoc()});
|
{conf->getProtocol(), SourceLoc(), ConformanceAttributes()});
|
||||||
}
|
}
|
||||||
} else if (next->getParentSourceFile() ||
|
} else if (next->getParentSourceFile() ||
|
||||||
next->getParentModule()->isBuiltinModule()) {
|
next->getParentModule()->isBuiltinModule()) {
|
||||||
@@ -229,9 +220,7 @@ void ConformanceLookupTable::forEachInStage(ConformanceStage stage,
|
|||||||
for (const auto &found :
|
for (const auto &found :
|
||||||
getDirectlyInheritedNominalTypeDecls(next, inverses, anyObject)) {
|
getDirectlyInheritedNominalTypeDecls(next, inverses, anyObject)) {
|
||||||
if (auto proto = dyn_cast<ProtocolDecl>(found.Item))
|
if (auto proto = dyn_cast<ProtocolDecl>(found.Item))
|
||||||
protocols.push_back(
|
protocols.push_back({proto, found.Loc, found.attributes});
|
||||||
{proto, found.Loc, found.uncheckedLoc,
|
|
||||||
found.preconcurrencyLoc, found.unsafeLoc});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,10 +307,8 @@ void ConformanceLookupTable::updateLookupTable(NominalTypeDecl *nominal,
|
|||||||
kp.has_value() &&
|
kp.has_value() &&
|
||||||
"suppressed conformance for non-known protocol!?");
|
"suppressed conformance for non-known protocol!?");
|
||||||
if (!found.isSuppressed) {
|
if (!found.isSuppressed) {
|
||||||
addProtocol(proto, found.Loc,
|
addProtocol(
|
||||||
source.withUncheckedLoc(found.uncheckedLoc)
|
proto, found.Loc, source.withAttributes(found.attributes));
|
||||||
.withPreconcurrencyLoc(found.preconcurrencyLoc)
|
|
||||||
.withUnsafeLoc(found.unsafeLoc));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,9 +322,7 @@ void ConformanceLookupTable::updateLookupTable(NominalTypeDecl *nominal,
|
|||||||
for (auto locAndProto : protos)
|
for (auto locAndProto : protos)
|
||||||
addProtocol(
|
addProtocol(
|
||||||
locAndProto.Item, locAndProto.Loc,
|
locAndProto.Item, locAndProto.Loc,
|
||||||
source.withUncheckedLoc(locAndProto.uncheckedLoc)
|
source.withAttributes(locAndProto.attributes));
|
||||||
.withPreconcurrencyLoc(locAndProto.preconcurrencyLoc)
|
|
||||||
.withUnsafeLoc(locAndProto.unsafeLoc));
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#define SWIFT_AST_CONFORMANCE_LOOKUP_TABLE_H
|
#define SWIFT_AST_CONFORMANCE_LOOKUP_TABLE_H
|
||||||
|
|
||||||
#include "swift/AST/DeclContext.h"
|
#include "swift/AST/DeclContext.h"
|
||||||
|
#include "swift/AST/ConformanceAttributes.h"
|
||||||
#include "swift/AST/ProtocolConformanceOptions.h"
|
#include "swift/AST/ProtocolConformanceOptions.h"
|
||||||
#include "swift/Basic/Debug.h"
|
#include "swift/Basic/Debug.h"
|
||||||
#include "swift/Basic/LLVM.h"
|
#include "swift/Basic/LLVM.h"
|
||||||
@@ -89,14 +90,7 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
|
|||||||
|
|
||||||
ConformanceEntryKind Kind;
|
ConformanceEntryKind Kind;
|
||||||
|
|
||||||
/// The location of the "unchecked" attribute, if there is one.
|
ConformanceAttributes attributes;
|
||||||
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;
|
|
||||||
|
|
||||||
ConformanceSource(void *ptr, ConformanceEntryKind kind)
|
ConformanceSource(void *ptr, ConformanceEntryKind kind)
|
||||||
: Storage(ptr), Kind(kind) { }
|
: Storage(ptr), Kind(kind) { }
|
||||||
@@ -140,29 +134,16 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
|
|||||||
return ConformanceSource(dc, ConformanceEntryKind::PreMacroExpansion);
|
return ConformanceSource(dc, ConformanceEntryKind::PreMacroExpansion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a new conformance source with the given location of "@unchecked".
|
/// Return a new conformance source with the given conformance
|
||||||
ConformanceSource withUncheckedLoc(SourceLoc uncheckedLoc) {
|
/// attributes.
|
||||||
|
ConformanceSource withAttributes(ConformanceAttributes attributes) {
|
||||||
ConformanceSource result(*this);
|
ConformanceSource result(*this);
|
||||||
if (uncheckedLoc.isValid())
|
result.attributes |= attributes;
|
||||||
result.uncheckedLoc = uncheckedLoc;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a new conformance source with the given location of
|
ConformanceAttributes getAttributes() const {
|
||||||
/// "@preconcurrency".
|
return attributes;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolConformanceOptions getOptions() const {
|
ProtocolConformanceOptions getOptions() const {
|
||||||
@@ -216,16 +197,16 @@ class ConformanceLookupTable : public ASTAllocated<ConformanceLookupTable> {
|
|||||||
|
|
||||||
/// The location of the @unchecked attribute, if any.
|
/// The location of the @unchecked attribute, if any.
|
||||||
SourceLoc getUncheckedLoc() const {
|
SourceLoc getUncheckedLoc() const {
|
||||||
return uncheckedLoc;
|
return attributes.uncheckedLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLoc getPreconcurrencyLoc() const {
|
SourceLoc getPreconcurrencyLoc() const {
|
||||||
return preconcurrencyLoc;
|
return attributes.preconcurrencyLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The location of the @unsafe attribute, if any.
|
/// The location of the @unsafe attribute, if any.
|
||||||
SourceLoc getUnsafeLoc() const {
|
SourceLoc getUnsafeLoc() const {
|
||||||
return unsafeLoc;
|
return attributes.unsafeLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For an inherited conformance, retrieve the class declaration
|
/// For an inherited conformance, retrieve the class declaration
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "swift/AST/ASTVisitor.h"
|
#include "swift/AST/ASTVisitor.h"
|
||||||
#include "swift/AST/ASTWalker.h"
|
#include "swift/AST/ASTWalker.h"
|
||||||
#include "swift/AST/ClangModuleLoader.h"
|
#include "swift/AST/ClangModuleLoader.h"
|
||||||
|
#include "swift/AST/ConformanceAttributes.h"
|
||||||
#include "swift/AST/DebuggerClient.h"
|
#include "swift/AST/DebuggerClient.h"
|
||||||
#include "swift/AST/ExistentialLayout.h"
|
#include "swift/AST/ExistentialLayout.h"
|
||||||
#include "swift/AST/GenericParamList.h"
|
#include "swift/AST/GenericParamList.h"
|
||||||
@@ -3962,23 +3963,19 @@ void swift::getDirectlyInheritedNominalTypeDecls(
|
|||||||
// FIXME: This is a hack. We need cooperation from
|
// FIXME: This is a hack. We need cooperation from
|
||||||
// InheritedDeclsReferencedRequest to make this work.
|
// InheritedDeclsReferencedRequest to make this work.
|
||||||
SourceLoc loc;
|
SourceLoc loc;
|
||||||
SourceLoc uncheckedLoc;
|
ConformanceAttributes attributes;
|
||||||
SourceLoc preconcurrencyLoc;
|
|
||||||
SourceLoc unsafeLoc;
|
|
||||||
auto inheritedTypes = InheritedTypes(decl);
|
auto inheritedTypes = InheritedTypes(decl);
|
||||||
bool isSuppressed = inheritedTypes.getEntry(i).isSuppressed();
|
bool isSuppressed = inheritedTypes.getEntry(i).isSuppressed();
|
||||||
if (TypeRepr *typeRepr = inheritedTypes.getTypeRepr(i)) {
|
if (TypeRepr *typeRepr = inheritedTypes.getTypeRepr(i)) {
|
||||||
loc = typeRepr->getLoc();
|
loc = typeRepr->getLoc();
|
||||||
uncheckedLoc = typeRepr->findAttrLoc(TypeAttrKind::Unchecked);
|
attributes.uncheckedLoc = typeRepr->findAttrLoc(TypeAttrKind::Unchecked);
|
||||||
preconcurrencyLoc = typeRepr->findAttrLoc(TypeAttrKind::Preconcurrency);
|
attributes.preconcurrencyLoc = typeRepr->findAttrLoc(TypeAttrKind::Preconcurrency);
|
||||||
unsafeLoc = typeRepr->findAttrLoc(TypeAttrKind::Unsafe);
|
attributes.unsafeLoc = typeRepr->findAttrLoc(TypeAttrKind::Unsafe);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Form the result.
|
// Form the result.
|
||||||
for (auto nominal : nominalTypes) {
|
for (auto nominal : nominalTypes) {
|
||||||
result.push_back(
|
result.push_back({nominal, loc, attributes, isSuppressed});
|
||||||
{nominal, loc, uncheckedLoc, preconcurrencyLoc, unsafeLoc,
|
|
||||||
isSuppressed});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4008,10 +4005,11 @@ swift::getDirectlyInheritedNominalTypeDecls(
|
|||||||
for (auto attr :
|
for (auto attr :
|
||||||
protoDecl->getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
|
protoDecl->getAttrs().getAttributes<SynthesizedProtocolAttr>()) {
|
||||||
auto loc = attr->getLocation();
|
auto loc = attr->getLocation();
|
||||||
|
ConformanceAttributes attributes;
|
||||||
|
if (attr->isUnchecked())
|
||||||
|
attributes.uncheckedLoc = loc;
|
||||||
result.push_back(
|
result.push_back(
|
||||||
{attr->getProtocol(), loc, attr->isUnchecked() ? loc : SourceLoc(),
|
{attr->getProtocol(), loc, attributes, /*isSuppressed=*/false});
|
||||||
/*preconcurrencyLoc=*/SourceLoc(), SourceLoc(),
|
|
||||||
/*isSuppressed=*/false});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else we have access to this information on the where clause.
|
// Else we have access to this information on the where clause.
|
||||||
@@ -4022,8 +4020,8 @@ swift::getDirectlyInheritedNominalTypeDecls(
|
|||||||
// FIXME: Refactor SelfBoundsFromWhereClauseRequest to dig out
|
// FIXME: Refactor SelfBoundsFromWhereClauseRequest to dig out
|
||||||
// the source location.
|
// the source location.
|
||||||
for (auto inheritedNominal : selfBounds.decls)
|
for (auto inheritedNominal : selfBounds.decls)
|
||||||
result.emplace_back(inheritedNominal, SourceLoc(), SourceLoc(),
|
result.emplace_back(inheritedNominal, SourceLoc(), ConformanceAttributes(),
|
||||||
SourceLoc(), SourceLoc(), /*isSuppressed=*/false);
|
/*isSuppressed=*/false);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user