1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
|
//===--- Type.swift -------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 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
//
//===----------------------------------------------------------------------===//
import Basic
import ASTBridging
/// A Swift type.
/// It is not necessarily canoncial, e.g. typealiases are not resolved.
public struct Type: TypeProperties, CustomStringConvertible, NoReflectionChildren {
public enum TraitResult {
case isNot
case canBe
case `is`
}
public enum MetatypeRepresentation {
case thin
case thick
case objC
};
public let bridged: BridgedASTType
// Needed to conform to TypeProperties
public var rawType: Type { self }
public init?(bridgedOrNil: BridgedASTType) {
if bridgedOrNil.type == nil {
return nil
}
self.bridged = bridgedOrNil
}
public init(bridged: BridgedASTType) {
self.bridged = bridged
}
public var canonical: CanonicalType { CanonicalType(bridged: bridged.getCanonicalType()) }
public var instanceTypeOfMetatype: Type { Type(bridged: bridged.getInstanceTypeOfMetatype()) }
public var staticTypeOfDynamicSelf: Type { Type(bridged: bridged.getStaticTypeOfDynamicSelf()) }
public var interfaceTypeOfArchetype: Type { Type(bridged: bridged.getInterfaceTypeOfArchetype()) }
public var superClassType: Type? {
precondition(isClass)
let bridgedSuperClassTy = bridged.getSuperClassType()
if bridgedSuperClassTy.type != nil {
return Type(bridged: bridgedSuperClassTy)
}
return nil
}
public var builtinVectorElementType: Type { Type(bridged: bridged.getBuiltinVectorElementType()) }
public func subst(with substitutionMap: SubstitutionMap) -> Type {
return Type(bridged: bridged.subst(substitutionMap.bridged))
}
public func subst(type: Type, with targetType: Type) -> Type {
return Type(bridged: bridged.subst(type.bridged, targetType.bridged))
}
}
/// A Type that is statically known to be canonical.
/// For example, typealiases are resolved.
public struct CanonicalType: TypeProperties, CustomStringConvertible, NoReflectionChildren {
public let bridged: BridgedCanType
public init(bridged: BridgedCanType) { self.bridged = bridged }
public var rawType: Type { Type(bridged: bridged.getRawType()) }
public var instanceTypeOfMetatype: CanonicalType { rawType.instanceTypeOfMetatype.canonical }
public var superClassType: CanonicalType? { rawType.superClassType?.canonical }
public var builtinVectorElementType: CanonicalType { rawType.builtinVectorElementType.canonical }
public func subst(with substitutionMap: SubstitutionMap) -> CanonicalType {
return rawType.subst(with: substitutionMap).canonical
}
public func subst(type: CanonicalType, with targetType: CanonicalType) -> CanonicalType {
return self.rawType.subst(type: type.rawType, with: targetType.rawType).canonical
}
}
/// Implements the common members of `AST.Type`, `AST.CanonicalType` and `SIL.Type`.
public protocol TypeProperties {
var rawType: Type { get }
}
extension TypeProperties {
public var description: String { String(taking: rawType.bridged.getDebugDescription()) }
//===--------------------------------------------------------------------===//
// Checks for different kinds of types
//===--------------------------------------------------------------------===//
public var isBuiltinInteger: Bool { rawType.bridged.isBuiltinInteger() }
public func isBuiltinInteger(withFixedWidth width: Int) -> Bool {
rawType.bridged.isBuiltinFixedWidthInteger(width)
}
public var isBuiltinFloat: Bool { rawType.bridged.isBuiltinFloat() }
public var isBuiltinVector: Bool { rawType.bridged.isBuiltinVector() }
public var isClass: Bool {
if let nominal = nominal, nominal is ClassDecl {
return true
}
return false
}
public var isStruct: Bool {
if let nominal = nominal, nominal is StructDecl {
return true
}
return false
}
public var isEnum: Bool {
if let nominal = nominal, nominal is EnumDecl {
return true
}
return false
}
public var isTuple: Bool { rawType.bridged.isTuple() }
public var isFunction: Bool { rawType.bridged.isFunction() }
public var isArchetype: Bool { rawType.bridged.isArchetype() }
public var isExistentialArchetype: Bool { rawType.bridged.isExistentialArchetype() }
public var isExistentialArchetypeWithError: Bool { rawType.bridged.isExistentialArchetypeWithError() }
public var isRootArchetype: Bool { rawType.interfaceTypeOfArchetype.isGenericTypeParameter }
public var isRootExistentialArchetype: Bool { isExistentialArchetype && isRootArchetype }
public var isExistential: Bool { rawType.bridged.isExistential() }
public var isClassExistential: Bool { rawType.bridged.isClassExistential() }
public var isGenericTypeParameter: Bool { rawType.bridged.isGenericTypeParam() }
public var isUnownedStorageType: Bool { return rawType.bridged.isUnownedStorageType() }
public var isMetatype: Bool { rawType.bridged.isMetatypeType() }
public var isExistentialMetatype: Bool { rawType.bridged.isExistentialMetatypeType() }
public var isDynamicSelf: Bool { rawType.bridged.isDynamicSelf()}
/// True if this is the type which represents an integer literal used in a type position.
/// For example `N` in `struct T<let N: Int> {}`
public var isInteger: Bool { rawType.bridged.isInteger() }
public var canBeClass: Type.TraitResult { rawType.bridged.canBeClass().result }
/// True if this the nominal type `Swift.Optional`.
public var isOptional: Bool { rawType.bridged.isOptional() }
/// True if this type is a value type (struct/enum) that defines a `deinit`.
public var isValueTypeWithDeinit: Bool {
if let nominal = nominal, nominal.valueTypeDestructor != nil {
return true
}
return false
}
//===--------------------------------------------------------------------===//
// Properties of lowered `SILFunctionType`s
//===--------------------------------------------------------------------===//
public var isLoweredFunction: Bool { rawType.bridged.isLoweredFunction() }
public var isNoEscapeFunction: Bool { rawType.bridged.isNoEscapeFunction() }
public var isCalleeConsumedFunction: Bool { rawType.bridged.isCalleeConsumedFunction() }
public var isThickFunction: Bool { rawType.bridged.isThickFunction() }
public var isAsyncFunction: Bool { rawType.bridged.isAsyncFunction() }
public var invocationGenericSignatureOfFunction: GenericSignature {
GenericSignature(bridged: rawType.bridged.getInvocationGenericSignatureOfFunctionType())
}
//===--------------------------------------------------------------------===//
// Type properties
//===--------------------------------------------------------------------===//
public var isLegalFormalType: Bool { rawType.bridged.isLegalFormalType() }
public var hasArchetype: Bool { rawType.bridged.hasArchetype() }
public var hasTypeParameter: Bool { rawType.bridged.hasTypeParameter() }
public var hasLocalArchetype: Bool { rawType.bridged.hasLocalArchetype() }
public var isEscapable: Bool { rawType.bridged.isEscapable() }
public var isNoEscape: Bool { rawType.bridged.isNoEscape() }
public var isBuiltinType: Bool { rawType.bridged.isBuiltinType() }
public var archetypeRequiresClass: Bool { rawType.bridged.archetypeRequiresClass() }
public var representationOfMetatype: AST.`Type`.MetatypeRepresentation {
rawType.bridged.getRepresentationOfMetatype().representation
}
/// Assumes this is a nominal type. Returns a substitution map that sends each
/// generic parameter of the declaration's generic signature to the corresponding
/// generic argument of this nominal type.
///
/// Eg: Array<Int> ---> { Element := Int }
public var contextSubstitutionMap: SubstitutionMap {
SubstitutionMap(bridged: rawType.bridged.getContextSubstitutionMap())
}
// True if this type has generic parameters or it is in a context (e.g. an outer type) which has generic parameters.
public var isGenericAtAnyLevel: Bool { rawType.bridged.isGenericAtAnyLevel() }
public var nominal: NominalTypeDecl? {
rawType.bridged.getNominalOrBoundGenericNominal().getAs(NominalTypeDecl.self)
}
/// Performas a global conformance lookup for this type for `protocol`.
/// It checks conditional requirements.
///
/// This type must be a contextualized type. It must not contain type parameters.
///
/// The resulting conformance reference does not include "missing" conformances, which are synthesized for
/// some protocols as an error recovery mechanism.
///
/// Returns an invalid conformance if the search failed, otherwise an
/// abstract, concrete or pack conformance, depending on the lookup type.
public func checkConformance(to protocol: ProtocolDecl) -> Conformance {
return Conformance(bridged: rawType.bridged.checkConformance(`protocol`.bridged))
}
}
public struct TypeArray : RandomAccessCollection, CustomReflectable {
public let bridged: BridgedASTTypeArray
public var startIndex: Int { return 0 }
public var endIndex: Int { return bridged.getCount() }
public init(bridged: BridgedASTTypeArray) {
self.bridged = bridged
}
public subscript(_ index: Int) -> Type {
Type(bridged: bridged.getAt(index))
}
public var customMirror: Mirror {
let c: [Mirror.Child] = map { (label: nil, value: $0) }
return Mirror(self, children: c)
}
}
extension BridgedASTType.TraitResult {
var result: Type.TraitResult {
switch self {
case .IsNot: return .isNot
case .CanBe: return .canBe
case .Is: return .is
default:
fatalError("wrong type TraitResult enum case")
}
}
}
extension BridgedASTType.MetatypeRepresentation {
var representation: Type.MetatypeRepresentation {
switch self {
case .Thin: return .thin
case .Thick: return .thick
case .ObjC: return .objC
default:
fatalError("wrong type MetatypeRepresentation enum case")
}
}
}
extension Type: Equatable {
public static func ==(lhs: Type, rhs: Type) -> Bool {
lhs.bridged.type == rhs.bridged.type
}
}
extension CanonicalType: Equatable {
public static func ==(lhs: CanonicalType, rhs: CanonicalType) -> Bool {
lhs.rawType == rhs.rawType
}
}
|