本文整理汇总了C++中TypeChecker::conformsToProtocol方法的典型用法代码示例。如果您正苦于以下问题:C++ TypeChecker::conformsToProtocol方法的具体用法?C++ TypeChecker::conformsToProtocol怎么用?C++ TypeChecker::conformsToProtocol使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TypeChecker
的用法示例。
在下文中一共展示了TypeChecker::conformsToProtocol方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: allAssociatedValuesConformToProtocol
/// Returns true if, for every element of the given enum, it either has no
/// associated values or all of them conform to a protocol.
/// \p theEnum The enum whose elements and associated values should be checked.
/// \p protocol The protocol being requested.
/// \return True if all associated values of all elements of the enum conform.
bool allAssociatedValuesConformToProtocol(TypeChecker &tc, EnumDecl *theEnum,
ProtocolDecl *protocol) {
auto declContext = theEnum->getDeclContext();
for (auto elt : theEnum->getAllElements()) {
if (!elt->getArgumentTypeLoc().getType())
tc.validateDecl(elt);
auto argumentType = elt->getArgumentTypeLoc().getType();
if (!argumentType)
continue;
if (auto tupleType = argumentType->getAs<TupleType>()) {
// One associated value with a label or multiple associated values
// (labeled or unlabeled) are tuple types.
for (auto tupleElementType : tupleType->getElementTypes()) {
if (!tc.conformsToProtocol(tupleElementType, protocol, declContext,
ConformanceCheckFlags::Used)) {
return false;
}
}
} else {
// One associated value with no label is represented as a paren type.
auto actualType = argumentType->getWithoutParens();
if (!tc.conformsToProtocol(actualType, protocol, declContext,
ConformanceCheckFlags::Used)) {
return false;
}
}
}
return true;
}
示例2: hasValidCodingKeysEnum
/// Returns whether the given type has a valid nested \c CodingKeys enum.
///
/// If the type has an invalid \c CodingKeys entity, produces diagnostics to
/// complain about the error. In this case, the error result will be true -- in
/// the case where we don't have a valid CodingKeys enum and have produced
/// diagnostics here, we don't want to then attempt to synthesize a CodingKeys
/// enum.
///
/// \param tc The typechecker to use in validating {En,Decodable} conformance.
///
/// \param target The type decl whose nested \c CodingKeys type to validate.
///
/// \param proto The {En,De}codable protocol to ensure the properties matching
/// the keys conform to.
///
/// \returns A \c CodingKeysValidity value representing the result of the check.
static CodingKeysValidity hasValidCodingKeysEnum(TypeChecker &tc,
NominalTypeDecl *target,
ProtocolDecl *proto) {
auto &C = tc.Context;
auto codingKeysDecls = target->lookupDirect(DeclName(C.Id_CodingKeys));
if (codingKeysDecls.empty())
return CodingKeysValidity(/*hasType=*/false, /*isValid=*/true);
// Only ill-formed code would produce multiple results for this lookup.
// This would get diagnosed later anyway, so we're free to only look at the
// first result here.
auto result = codingKeysDecls.front();
auto *codingKeysTypeDecl = dyn_cast<TypeDecl>(result);
if (!codingKeysTypeDecl) {
tc.diagnose(result->getLoc(),
diag::codable_codingkeys_type_is_not_an_enum_here,
proto->getDeclaredType());
return CodingKeysValidity(/*hasType=*/true, /*isValid=*/false);
}
// CodingKeys may be a typealias. If so, follow the alias to its canonical
// type.
auto codingKeysType = codingKeysTypeDecl->getDeclaredInterfaceType();
if (isa<TypeAliasDecl>(codingKeysTypeDecl)) {
codingKeysTypeDecl = codingKeysType->getAnyNominal();
}
// Ensure that the type we found conforms to the CodingKey protocol.
auto *codingKeyProto = C.getProtocol(KnownProtocolKind::CodingKey);
if (!tc.conformsToProtocol(codingKeysType, codingKeyProto,
target->getDeclContext(),
ConformanceCheckFlags::Used)) {
tc.diagnose(codingKeysTypeDecl->getLoc(),
diag::codable_codingkeys_type_does_not_conform_here,
proto->getDeclaredType());
return CodingKeysValidity(/*hasType=*/true, /*isValid=*/false);
}
// CodingKeys must be an enum for synthesized conformance.
auto *codingKeysEnum = dyn_cast<EnumDecl>(codingKeysTypeDecl);
if (!codingKeysEnum) {
tc.diagnose(codingKeysTypeDecl->getLoc(),
diag::codable_codingkeys_type_is_not_an_enum_here,
proto->getDeclaredType());
return CodingKeysValidity(/*hasType=*/true, /*isValid=*/false);
}
bool valid = validateCodingKeysEnum(tc, codingKeysEnum, target, proto);
return CodingKeysValidity(/*hasType=*/true, /*isValid=*/valid);
}
示例3:
/// Determine the relationship between the self types of the given declaration
/// contexts..
static std::pair<SelfTypeRelationship, Optional<ProtocolConformanceRef>>
computeSelfTypeRelationship(TypeChecker &tc, DeclContext *dc, DeclContext *dc1,
DeclContext *dc2) {
// If at least one of the contexts is a non-type context, the two are
// unrelated.
if (!dc1->isTypeContext() || !dc2->isTypeContext())
return {SelfTypeRelationship::Unrelated, None};
Type type1 = dc1->getDeclaredInterfaceType();
Type type2 = dc2->getDeclaredInterfaceType();
// If the types are equal, the answer is simple.
if (type1->isEqual(type2))
return {SelfTypeRelationship::Equivalent, None};
// If both types can have superclasses, which whether one is a superclass
// of the other. The subclass is the common base type.
if (type1->mayHaveSuperclass() && type2->mayHaveSuperclass()) {
if (isNominallySuperclassOf(type1, type2))
return {SelfTypeRelationship::Superclass, None};
if (isNominallySuperclassOf(type2, type1))
return {SelfTypeRelationship::Subclass, None};
return {SelfTypeRelationship::Unrelated, None};
}
// If neither or both are protocol types, consider the bases unrelated.
bool isProtocol1 = isa<ProtocolDecl>(dc1);
bool isProtocol2 = isa<ProtocolDecl>(dc2);
if (isProtocol1 == isProtocol2)
return {SelfTypeRelationship::Unrelated, None};
// Just one of the two is a protocol. Check whether the other conforms to
// that protocol.
Type protoTy = isProtocol1? type1 : type2;
Type modelTy = isProtocol1? type2 : type1;
auto proto = protoTy->castTo<ProtocolType>()->getDecl();
// If the model type does not conform to the protocol, the bases are
// unrelated.
auto conformance = tc.conformsToProtocol(modelTy, proto, dc,
ConformanceCheckFlags::InExpression);
if (!conformance)
return {SelfTypeRelationship::Unrelated, None};
if (isProtocol1)
return {SelfTypeRelationship::ConformedToBy, conformance};
return {SelfTypeRelationship::ConformsTo, conformance};
}
示例4: compareWitnessAndRequirement
/// Compare two declarations to determine whether one is a witness of the other.
static Comparison compareWitnessAndRequirement(TypeChecker &tc, DeclContext *dc,
ValueDecl *decl1,
ValueDecl *decl2) {
// We only have a witness/requirement pair if exactly one of the declarations
// comes from a protocol.
auto proto1 = dyn_cast<ProtocolDecl>(decl1->getDeclContext());
auto proto2 = dyn_cast<ProtocolDecl>(decl2->getDeclContext());
if ((bool)proto1 == (bool)proto2)
return Comparison::Unordered;
// Figure out the protocol, requirement, and potential witness.
ProtocolDecl *proto;
ValueDecl *req;
ValueDecl *potentialWitness;
if (proto1) {
proto = proto1;
req = decl1;
potentialWitness = decl2;
} else {
proto = proto2;
req = decl2;
potentialWitness = decl1;
}
// Cannot compare type declarations this way.
// FIXME: Use the same type-substitution approach as lookupMemberType.
if (isa<TypeDecl>(req))
return Comparison::Unordered;
if (!potentialWitness->getDeclContext()->isTypeContext())
return Comparison::Unordered;
// Determine whether the type of the witness's context conforms to the
// protocol.
auto owningType
= potentialWitness->getDeclContext()->getDeclaredTypeInContext();
ProtocolConformance *conformance = nullptr;
if (!tc.conformsToProtocol(owningType, proto, dc,
ConformanceCheckFlags::InExpression, &conformance) ||
!conformance)
return Comparison::Unordered;
// If the witness and the potential witness are not the same, there's no
// ordering here.
if (conformance->getWitness(req, &tc).getDecl() != potentialWitness)
return Comparison::Unordered;
// We have a requirement/witness match.
return proto1? Comparison::Worse : Comparison::Better;
}
示例5: canSynthesizeRawRepresentable
static bool canSynthesizeRawRepresentable(TypeChecker &tc, Decl *parentDecl,
EnumDecl *enumDecl) {
// Validate the enum and its raw type.
tc.validateDecl(enumDecl);
// It must have a valid raw type.
Type rawType = enumDecl->getRawType();
if (!rawType)
return false;
auto parentDC = cast<DeclContext>(parentDecl);
rawType = parentDC->mapTypeIntoContext(rawType);
auto inherited = enumDecl->getInherited();
if (!inherited.empty() && inherited.front().wasValidated() &&
inherited.front().isError())
return false;
// The raw type must be Equatable, so that we have a suitable ~= for
// synthesized switch statements.
auto equatableProto = tc.getProtocol(enumDecl->getLoc(),
KnownProtocolKind::Equatable);
if (!equatableProto)
return false;
if (!tc.conformsToProtocol(rawType, equatableProto, enumDecl, None))
return false;
// There must be enum elements.
if (enumDecl->getAllElements().empty())
return false;
// Have the type-checker validate that:
// - the enum elements all have the same type
// - they all match the enum type
for (auto elt : enumDecl->getAllElements()) {
tc.validateDecl(elt);
if (elt->isInvalid()) {
return false;
}
}
// If it meets all of those requirements, we can synthesize RawRepresentable conformance.
return true;
}
示例6: allStoredPropertiesConformToProtocol
/// Returns true if every stored property in the given struct conforms to the
/// protocol (or, vacuously, if it has no stored properties).
/// \p theStruct The struct whose stored properties should be checked.
/// \p protocol The protocol being requested.
/// \return True if all stored properties of the struct conform.
bool allStoredPropertiesConformToProtocol(TypeChecker &tc,
StructDecl *theStruct,
ProtocolDecl *protocol) {
auto declContext = theStruct->getDeclContext();
auto storedProperties =
theStruct->getStoredProperties(/*skipInaccessible=*/true);
for (auto propertyDecl : storedProperties) {
if (!propertyDecl->hasType())
tc.validateDecl(propertyDecl);
if (!propertyDecl->hasType() ||
!tc.conformsToProtocol(propertyDecl->getType(), protocol, declContext,
ConformanceCheckFlags::Used)) {
return false;
}
}
return true;
}
示例7: typeConformsToCodable
/// Returns whether the given type conforms to the given {En,De}codable
/// protocol.
///
/// \param tc The typechecker to use in validating {En,De}codable conformance.
///
/// \param context The \c DeclContext the var declarations belong to.
///
/// \param target The \c Type to validate.
///
/// \param proto The \c ProtocolDecl to check conformance to.
static CodableConformanceType typeConformsToCodable(TypeChecker &tc,
DeclContext *context,
Type target,
ProtocolDecl *proto) {
// Some generic types need to be introspected to get at their "true" Codable
// conformance.
auto canType = target->getCanonicalType();
if (auto genericType = dyn_cast<BoundGenericType>(canType)) {
auto *nominalTypeDecl = genericType->getAnyNominal();
// Implicitly unwrapped optionals need to be unwrapped;
// ImplicitlyUnwrappedOptional does not need to conform to Codable directly
// -- only its inner type does.
if (nominalTypeDecl == tc.Context.getImplicitlyUnwrappedOptionalDecl() ||
// FIXME: Remove the following when conditional conformance lands.
// Some generic types in the stdlib currently conform to Codable even
// when the type they are generic on does not [Optional, Array, Set,
// Dictionary]. For synthesizing conformance, we don't want to
// consider these types as Codable if the nested type is not Codable.
// Look through the generic type parameters of these types recursively
// to avoid synthesizing code that will crash at runtime.
//
// We only want to look through generic params for these types; other
// types may validly conform to Codable even if their generic param
// types do not.
nominalTypeDecl == tc.Context.getOptionalDecl() ||
nominalTypeDecl == tc.Context.getArrayDecl() ||
nominalTypeDecl == tc.Context.getSetDecl() ||
nominalTypeDecl == tc.Context.getDictionaryDecl()) {
for (auto paramType : genericType->getGenericArgs()) {
if (typeConformsToCodable(tc, context, paramType, proto) != Conforms)
return DoesNotConform;
}
return Conforms;
}
}
return tc.conformsToProtocol(target, proto, context,
ConformanceCheckFlags::Used) ? Conforms
: DoesNotConform;
}
示例8: canSynthesizeRawRepresentable
static bool canSynthesizeRawRepresentable(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
// It must have a valid raw type.
Type rawType = enumDecl->getRawType();
if (!rawType)
return false;
auto parentDC = cast<DeclContext>(parentDecl);
rawType = ArchetypeBuilder::mapTypeIntoContext(parentDC, rawType);
if (!enumDecl->getInherited().empty() &&
enumDecl->getInherited().front().isError())
return false;
// The raw type must be Equatable, so that we have a suitable ~= for synthesized switch statements.
auto equatableProto = tc.getProtocol(enumDecl->getLoc(),
KnownProtocolKind::Equatable);
if (!equatableProto)
return false;
if (!tc.conformsToProtocol(rawType, equatableProto, enumDecl, None)) {
SourceLoc loc = enumDecl->getInherited()[0].getSourceRange().Start;
tc.diagnose(loc, diag::enum_raw_type_not_equatable, rawType);
return false;
}
// There must be enum elements.
if (enumDecl->getAllElements().empty())
return false;
// Have the type-checker validate that:
// - the enum elements all have the same type
// - they all match the enum type
for (auto elt : enumDecl->getAllElements()) {
tc.validateDecl(elt);
if (elt->isInvalid()) {
return false;
}
}
// If it meets all of those requirements, we can synthesize RawRepresentable conformance.
return true;
}
示例9: allStoredPropertiesConformToProtocol
/// Returns true if every stored property in the given struct conforms to the
/// protocol (or, vacuously, if it has no stored properties).
/// \p theStruct The struct whose stored properties should be checked.
/// \p protocol The protocol being requested.
/// \return True if all stored properties of the struct conform.
static bool allStoredPropertiesConformToProtocol(TypeChecker &tc,
DeclContext *DC,
StructDecl *theStruct,
ProtocolDecl *protocol) {
auto storedProperties =
theStruct->getStoredProperties(/*skipInaccessible=*/true);
for (auto propertyDecl : storedProperties) {
if (!propertyDecl->hasType())
tc.validateDecl(propertyDecl);
if (!propertyDecl->hasType())
return false;
auto type = propertyDecl->getType()->mapTypeOutOfContext();
if (!tc.conformsToProtocol(DC->mapTypeIntoContext(type), protocol, DC,
ConformanceCheckFlags::Used)) {
return false;
}
}
return true;
}
示例10: allAssociatedValuesConformToProtocol
/// Returns true if, for every element of the given enum, it either has no
/// associated values or all of them conform to a protocol.
/// \p theEnum The enum whose elements and associated values should be checked.
/// \p protocol The protocol being requested.
/// \return True if all associated values of all elements of the enum conform.
bool allAssociatedValuesConformToProtocol(TypeChecker &tc, EnumDecl *theEnum,
ProtocolDecl *protocol) {
auto declContext = theEnum->getDeclContext();
for (auto elt : theEnum->getAllElements()) {
if (!elt->hasInterfaceType())
tc.validateDecl(elt);
auto PL = elt->getParameterList();
if (!PL)
continue;
for (auto param : *PL) {
if (!tc.conformsToProtocol(param->getType(), protocol, declContext,
ConformanceCheckFlags::Used)) {
return false;
}
}
}
return true;
}
示例11: typeConformsToCodable
/// Returns whether the given type conforms to the given {En,De}codable
/// protocol.
///
/// \param tc The typechecker to use in validating {En,De}codable conformance.
///
/// \param context The \c DeclContext the var declarations belong to.
///
/// \param target The \c Type to validate.
///
/// \param proto The \c ProtocolDecl to check conformance to.
static CodableConformanceType typeConformsToCodable(TypeChecker &tc,
DeclContext *context,
Type target, bool isIUO,
ProtocolDecl *proto) {
target = context->mapTypeIntoContext(target->mapTypeOutOfContext());
// Some generic types need to be introspected to get at their "true" Codable
// conformance.
if (auto referenceType = target->getAs<ReferenceStorageType>()) {
// This is a weak/unowned/unmanaged var. Get the inner type before checking
// conformance.
target = referenceType->getReferentType();
}
if (isIUO)
return typeConformsToCodable(tc, context, target->getOptionalObjectType(),
false, proto);
return tc.conformsToProtocol(target, proto, context,
ConformanceCheckFlags::Used) ? Conforms
: DoesNotConform;
}
示例12: allAssociatedValuesConformToProtocol
/// Returns true if, for every element of the given enum, it either has no
/// associated values or all of them conform to a protocol.
/// \p theEnum The enum whose elements and associated values should be checked.
/// \p protocol The protocol being requested.
/// \return True if all associated values of all elements of the enum conform.
static bool allAssociatedValuesConformToProtocol(TypeChecker &tc,
DeclContext *DC,
EnumDecl *theEnum,
ProtocolDecl *protocol) {
for (auto elt : theEnum->getAllElements()) {
if (!elt->hasInterfaceType())
tc.validateDecl(elt);
auto PL = elt->getParameterList();
if (!PL)
continue;
for (auto param : *PL) {
auto type = param->getType()->mapTypeOutOfContext();
if (!tc.conformsToProtocol(DC->mapTypeIntoContext(type), protocol, DC,
ConformanceCheckFlags::Used)) {
return false;
}
}
}
return true;
}