Enums
Classifies the semantic shape of a reflected type.
Module std.reflection
import std.reflection;Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.
TypeKind
pub enum TypeKindClassifies the semantic shape of a reflected type.
Example
module example.reflection;
from std.reflection import Argument, CopySlot, DestroySlot, Erase,
EraseForeign, EraseForeignMut, FindType, FindTypeByStableId,
InvocationFrame, Invoke, MemberQuery, MethodSignature, ParameterMode,
ParameterSignature, PrivateAccess, ReadField, ReadProperty, RegisteredTypeAt,
RegisteredTypeCount, ReturnMode, SlotFromStorage, TakeSlot, TypeInfo,
TypeKind, TypeOf, WriteBorrow, WriteField, WriteProperty;
pub struct Sample {
pub Value: i32;
pub Total: i32 { get; set; }
pub readonly fn Add(Amount: i32) -> i32 {
return Value + Amount;
}
pub fn Reset() -> void {
Value = 0;
}
}
pub struct StaticSample { pub static Value: i32; }
fn SameType(Left: TypeInfo, Right: TypeInfo) -> bool {
let LeftId = Left.StableId;
let RightId = Right.StableId;
return LeftId.High == RightId.High && LeftId.Low == RightId.Low;
}
fn Main() -> i32 {
let Type = TypeOf<Sample>();
if Type.Kind != .Struct || Type.Name != "Sample" ||
Type.ModulePath != "example.reflection" || Type.ByteSize == 0 ||
Type.Alignment == 0 || Type.IsOpaque {
return 1;
}
if Type.BaseCount() != 0 || Type.InterfaceCount() != 0 ||
Type.GenericArgumentCount() != 0 || Type.AttributeCount() != 0 {
return 2;
}
if Type.BaseAt(0) is .Some { Value = _ } {
return 3;
}
if Type.InterfaceAt(0) is .Some { Value = _ } {
return 4;
}
if Type.GenericArgumentAt(0) is .Some { Value = _ } {
return 5;
}
if Type.AttributeAt(0) is .Some { Value = _ } {
return 6;
}
let StableId = Type.StableId;
let StableMatch = switch FindTypeByStableId(StableId) {
case .Ok { Value = Found } => break Found;
case .Err { Error = _ } => return 7;
};
if StableMatch.StableId.High != StableId.High ||
StableMatch.StableId.Low != StableId.Low {
return 8;
}
let NamedMatch = switch FindType(Type.ModulePath, Type.QualifiedName) {
case .Ok { Value = Found } => break Found;
case .Err { Error = _ } => return 9;
};
if !SameType(NamedMatch, Type) || RegisteredTypeCount() == 0 {
return 10;
}
if RegisteredTypeAt(RegisteredTypeCount()) is .Some { Value = _ } {
return 11;
}
if Type.FieldCount(.Declared) != 1 ||
Type.FieldAt(.Declared, 1) is .Some { Value = _ } {
return 12;
}
let Field = switch Type.FindField("Value", .Declared) {
case .Ok { Value = Found } => break Found;
case .Err { Error = _ } => return 13;
};
if Field.Name != "Value" || !SameType(Field.DeclaringType, Type) ||
Field.ValueType.Kind != .Integer || Field.Visibility != .Pub ||
Field.IsStatic || !Field.IsMutable || Field.IsCompilerGenerated ||
Field.AttributeCount != 0 ||
Field.AttributeAt(0) is .Some { Value = _ } {
return 14;
}
if Field.AutoProperty is .Some { Value = _ } {
return 15;
}
if Type.PropertyCount(.Declared) != 1 ||
Type.PropertyAt(.Declared, 1) is .Some { Value = _ } {
return 16;
}
let Property = switch Type.FindProperty("Total", .Declared) {
case .Ok { Value = Found } => break Found;
case .Err { Error = _ } => return 17;
};
if Property.Name != "Total" ||
!SameType(Property.DeclaringType, Type) ||
Property.ValueType.Kind != .Integer ||
Property.Visibility != .Pub || Property.Getter.IsStatic ||
Property.IsVirtual || Property.IsOverride ||
Property.IsSealedOverride || Property.AttributeCount != 0 ||
Property.AttributeAt(0) is .Some { Value = _ } {
return 18;
}
if (Property.Setter is .None) {
return 19;
}
let BackingField = switch Property.BackingField {
case .Some { Value = Found } => break Found;
case .None => return 20;
};
if !BackingField.IsCompilerGenerated ||
BackingField.AutoProperty is .None {
return 21;
}
let ParameterTypes: ParameterSignature[1] = [
ParameterSignature.Create(TypeOf<i32>(), .Value)
];
let Signature = MethodSignature.Create(
false,
ParameterTypes,
TypeOf<i32>(),
.Value
);
if Signature.IsStatic || Signature.Parameters.Length != 1 ||
Signature.Parameters[0].Mode != ParameterMode.Value ||
!SameType(Signature.Parameters[0].Type, TypeOf<i32>()) ||
!SameType(Signature.ResultType, TypeOf<i32>()) ||
Signature.ResultMode != ReturnMode.Value {
return 22;
}
let Method = switch Type.FindMethod("Add", Signature, .Declared) {
case .Ok { Value = Found } => break Found;
case .Err { Error = _ } => return 23;
};
if Method.Name != "Add" || !SameType(Method.DeclaringType, Type) ||
Method.Visibility != .Pub || Method.IsStatic || Method.IsVirtual ||
Method.IsOverride || Method.ParameterCount != 1 ||
Method.AttributeCount != 0 || Method.ResultMode != .Value ||
!SameType(Method.ResultType, TypeOf<i32>()) ||
Method.AttributeAt(0) is .Some { Value = _ } {
return 24;
}
let Parameter = switch Method.ParameterAt(0) {
case .Some { Value = Found } => break Found;
case .None => return 25;
};
if Parameter.Name != "Amount" || Parameter.Position != 0 ||
Parameter.Mode != .Value ||
!SameType(Parameter.Type, TypeOf<i32>()) ||
Parameter.AttributeCount != 0 ||
Parameter.AttributeAt(0) is .Some { Value = _ } {
return 26;
}
if Method.ParameterAt(1) is .Some { Value = _ } ||
Type.MethodCount(MemberQuery.Declared) < 2 ||
Type.MethodAt(.Declared, Type.MethodCount(.Declared))
is .Some { Value = _ } {
return 27;
}
var Instance: Sample = .{ Value = 7 };
let InstanceRef = Erase(Instance);
if InstanceRef.Address == null || InstanceRef.Access != .Write ||
!SameType(InstanceRef.Type, Type) {
return 28;
}
let SafeRead = switch Field.Read<i32>(Instance) {
case .Ok { Value = Copied } => break Copied;
case .Err { Error = _ } => return 53;
};
if SafeRead != 7 { return 54; }
switch Field.Borrow<i32>(Instance) {
case .Ok { Value = View } => { if View.Get() != 7 { return 201; } }
case .Err { Error = _ } => return 202;
}
var Writable = Field.BorrowMut<i32>(Instance);
switch Writable {
case .Ok { Value = View: mut WriteBorrow<i32>& } => { View.Get() = 7; }
case .Err { Error = _ } => return 203;
}
var ResultStorage: i32 = 0;
var ResultSlot = unsafe {
// Safety: ResultStorage is live, exact i32 storage for this scope.
break SlotFromStorage(
(&ResultStorage) as! mut void*,
TypeOf<i32>(),
TypeOf<i32>().ByteSize,
TypeOf<i32>().Alignment,
.Live
);
};
if ResultSlot.Address == null || ResultSlot.Capacity == 0 ||
ResultSlot.Alignment == 0 || ResultSlot.State != .Live ||
!SameType(ResultSlot.Type, TypeOf<i32>()) {
DestroySlot(ResultSlot);
return 29;
}
if DestroySlot(ResultSlot) != .Success ||
ResultSlot.State != .Empty {
return 29;
}
if ReadField(Field, InstanceRef, ResultSlot, .Deny) != .Success {
return 30;
}
let ReadValue = switch CopySlot<i32>(ResultSlot) {
case .Ok { Value = Value } => break Value;
case .Err { Error = _ } => {
DestroySlot(ResultSlot);
return 31;
}
};
if ReadValue != 7 || ResultSlot.State != .Live {
DestroySlot(ResultSlot);
return 32;
}
if DestroySlot(ResultSlot) != .Success ||
ResultSlot.State != .Empty {
return 32;
}
let Replacement: i32 = 11;
let WriteArgument = Argument.CopyValue(Erase(Replacement));
if WriteArgument.Mode != .CopyValue ||
WriteField(Field, InstanceRef, WriteArgument, .Deny) != .Success ||
Instance.Value != 11 {
return 33;
}
let PublicAccess: PrivateAccess = .Deny;
switch Field.Write<i32>(Instance, Replacement) {
case .Ok => {}
case .Err { Error = _ } => return 55;
}
switch Field.Write<i32>(Instance, Replacement, PublicAccess) {
case .Ok => {}
case .Err { Error = _ } => return 56;
}
if Instance.Value != 11 || Replacement != 11 { return 57; }
let StaticType = TypeOf<StaticSample>();
let StaticField = switch StaticType.FindField("Value", .Declared) {
case .Ok { Value = Found } => break Found;
case .Err { Error = _ } => return 58;
};
switch StaticField.WriteStatic<i32>(Replacement) {
case .Ok => {}
case .Err { Error = _ } => return 59;
}
switch StaticField.WriteStatic<i32>(Replacement, PublicAccess) {
case .Ok => {}
case .Err { Error = _ } => return 60;
}
if StaticSample.Value != 11 { return 61; }
let PropertyValue: i32 = 23;
let PropertyArgument = Argument.CopyValue(Erase(PropertyValue));
if WriteProperty(Property, InstanceRef, PropertyArgument, .Deny) !=
.Success || Instance.Total != 23 {
return 34;
}
if ReadProperty(Property, InstanceRef, ResultSlot, .Deny) != .Success {
return 35;
}
let ReflectedProperty = switch TakeSlot<i32>(ResultSlot) {
case .Ok { Value = Value } => break Value;
case .Err { Error = _ } => {
DestroySlot(ResultSlot);
return 36;
}
};
if ReflectedProperty != 23 || ResultSlot.State != .Empty {
return 37;
}
let Amount: i32 = 5;
let Arguments: Argument[1] = [Argument.CopyValue(Erase(Amount))];
var Frame = InvocationFrame.WithResult(
InstanceRef,
Arguments,
ResultSlot,
.Deny
);
if !Frame.HasResult || Frame.Arguments.Length != 1 ||
Frame.Access != .Deny || Frame.Instance is .None ||
Invoke(Method, Frame) != .Success {
return 38;
}
let InvokedValue = switch CopySlot<i32>(ResultSlot) {
case .Ok { Value = Value } => break Value;
case .Err { Error = _ } => {
DestroySlot(ResultSlot);
return 39;
}
};
if InvokedValue != 16 || ResultSlot.State != .Live {
DestroySlot(ResultSlot);
return 40;
}
if DestroySlot(ResultSlot) != .Success ||
ResultSlot.State != .Empty {
return 40;
}
let NoParameters: ParameterSignature[0] = [];
let ResetSignature = MethodSignature.Create(
false,
NoParameters,
TypeOf<void>(),
.Void
);
let ResetMethod = switch Type.FindMethod(
"Reset",
ResetSignature,
.Declared
) {
case .Ok { Value = Found } => break Found;
case .Err { Error = _ } => return 41;
};
let NoArguments: Argument[0] = [];
var ResetFrame = InvocationFrame.WithoutResult(
InstanceRef,
NoArguments,
.Deny
);
if ResetFrame.HasResult || Invoke(ResetMethod, ResetFrame) != .Success ||
Instance.Value != 0 {
return 42;
}
var DelayedSource: i32 = 9;
let MoveArgument = Argument.MoveValue(Erase(DelayedSource));
let ReadArgument = Argument.RefRead(Erase(Amount));
let WriteReference = Argument.RefWrite(Erase(DelayedSource));
let RValueArgument = Argument.RValue(Erase(DelayedSource));
let OutArgument = Argument.Out(ResultSlot);
if DelayedSource != 9 || MoveArgument.Mode != .MoveValue ||
ReadArgument.Mode != .RefRead ||
WriteReference.Mode != .RefWrite ||
RValueArgument.Mode != .RValue || OutArgument.Mode != .Out {
return 43;
}
let ForeignRead = unsafe {
// Safety: Amount is an exact live i32 for the complete view use.
break EraseForeign((&Amount) as! void*, TypeOf<i32>());
};
var ForeignValue: i32 = 3;
let ForeignWrite = unsafe {
// Safety: ForeignValue is writable exact i32 storage for this scope.
break EraseForeignMut(
(&ForeignValue) as! mut void*,
TypeOf<i32>()
);
};
if ForeignRead.Access != .Read || ForeignWrite.Access != .Write ||
ForeignRead.Address == null || ForeignWrite.Address == null {
return 44;
}
if !SameType(TypeOf(Instance), Type) {
return 45;
}
let Pointer: readonly Sample* = unsafe {
// Safety: Instance remains live throughout the pointer query.
break (&Instance) as! readonly Sample*;
};
let Pointee = unsafe { break TypeOf(Pointer); };
switch Pointee {
case .Some { Value = Actual } => {
if !SameType(Actual, Type) { return 46; }
}
case .None => return 47;
}
return 0;
}TypeKind.Void
Void;No stored value/result.
TypeKind.Bool
Bool;Boolean primitive.
TypeKind.Integer
Integer;Any fixed-width integer primitive.
TypeKind.Float
Float;Any accepted floating primitive.
TypeKind.RawPointer
RawPointer;Nullable raw pointer.
TypeKind.Reference
Reference;Nonnull borrowed reference.
TypeKind.Array
Array;Inline fixed array.
TypeKind.Slice
Slice;Nonowning contiguous slice.
TypeKind.Optional
Optional;Structural optional.
TypeKind.Tuple
Tuple;Heterogeneous structural tuple.
TypeKind.Unique
Unique;Canonical unique ownership wrapper.
TypeKind.Shared
Shared;Canonical shared ownership wrapper.
TypeKind.Weak
Weak;Canonical weak ownership wrapper.
TypeKind.Function
Function;Callable function type.
TypeKind.Struct
Struct;Nominal concrete struct.
TypeKind.Enum
Enum;Closed/open/tagged enum.
TypeKind.Union
Union;Visibly unsafe raw union.
TypeKind.Interface
Interface;Runtime interface view/type.
TypeKind.Class
Class;Native inline object with class construction and optional inheritance.
Visibility
pub enum VisibilityReports authored member visibility.
Visibility.Priv
Priv;Declaring-type-only access.
Visibility.Prot
Prot;Declaring type and descendants.
Visibility.Internal
Internal;Declaring package access.
Visibility.Pub
Pub;Ordinary public access.
MemberQuery
pub enum MemberQuerySelects declared/inherited and compiler-generated member enumeration.
MemberQuery.Declared
Declared;Authored members declared directly on the type.
MemberQuery.DeclaredIncludingCompilerGenerated
DeclaredIncludingCompilerGenerated;Direct authored and compiler-generated members.
MemberQuery.IncludeInherited
IncludeInherited;Authored members including inherited members.
MemberQuery.IncludeInheritedAndCompilerGenerated
IncludeInheritedAndCompilerGenerated;Authored/compiler-generated members including inherited members.
LookupError
pub enum LookupErrorClassifies exact descriptor lookup failure.
LookupError.NotFound
NotFound;No exact candidate exists.
LookupError.Ambiguous
Ambiguous;More than one exact candidate remains.
AccessMode
pub enum AccessModeRecords erased-place read/write authority.
AccessMode.Read
Read;Read-only access.
AccessMode.Write
Write;Writable access.
ParameterMode
pub enum ParameterModeRecords one declared parameter passing mode.
ParameterMode.Value
Value;By-value parameter.
ParameterMode.RefRead
RefRead;Read-only reference parameter.
ParameterMode.RefWrite
RefWrite;Writable reference parameter.
ParameterMode.RValue
RValue;Direct rvalue-reference parameter.
ParameterMode.Out
Out;Caller-owned output slot parameter.
ReturnMode
pub enum ReturnModeRecords one reflected callable result mode.
ReturnMode.Void
Void;No result slot is accepted.
ReturnMode.Value
Value;Result initializes caller-owned value storage.
ReturnMode.RefRead
RefRead;Result is a read-only reference.
ReturnMode.RefWrite
RefWrite;Result is a writable reference.
ValueSlotState
pub enum ValueSlotStateTracks caller-owned reflected result/output storage lifetime.
ValueSlotState.Empty
Empty;Storage contains no live value.
ValueSlotState.Live
Live;Storage contains one live exact-type value.
ArgumentMode
pub enum ArgumentModeSelects the delayed operation performed for one invocation argument.
ArgumentMode.CopyValue
CopyValue;Copy one Copyable value at invocation.
ArgumentMode.MoveValue
MoveValue;Select the move operation for one writable source; it stays live.
ArgumentMode.RefRead
RefRead;Pass a read-only reference.
ArgumentMode.RefWrite
RefWrite;Pass a writable reference.
ArgumentMode.RValue
RValue;Pass direct rvalue-reference access.
ArgumentMode.Out
Out;Initialize one caller-owned Empty slot.
PrivateAccess
pub enum PrivateAccessSelects explicit private-member operation authority.
PrivateAccess.Deny
Deny;Deny non-public operations.
PrivateAccess.Allow
Allow;Authorize one checked non-public operation.
InvocationStatus
pub enum InvocationStatusReports one complete checked reflection operation outcome.
InvocationStatus.Success
Success;Validation completed and the operation returned normally.
InvocationStatus.InvalidDescriptor
InvalidDescriptor;Descriptor handle is malformed or stale.
InvocationStatus.NotReflected
NotReflected;Owning module/type did not publish required metadata.
InvocationStatus.NotFound
NotFound;Requested exact member/entry does not exist.
InvocationStatus.Ambiguous
Ambiguous;Requested exact lookup has multiple results.
InvocationStatus.AccessDenied
AccessDenied;Private/protected/internal authority is insufficient.
InvocationStatus.InvalidInstance
InvalidInstance;Instance presence/type/access is invalid.
InvocationStatus.ArityMismatch
ArityMismatch;Argument count differs from the descriptor.
InvocationStatus.TypeMismatch
TypeMismatch;Exact semantic value type does not match.
InvocationStatus.AccessMismatch
AccessMismatch;Writable/read-only access is insufficient or unexpected.
InvocationStatus.PassModeMismatch
PassModeMismatch;Argument operation differs from declared pass mode.
InvocationStatus.OutputRequired
OutputRequired;Nonvoid operation lacks a result slot.
InvocationStatus.OutputUnexpected
OutputUnexpected;Void operation received a result slot.
InvocationStatus.OutputLive
OutputLive;Result/output slot already contains a live value.
InvocationStatus.BadStorage
BadStorage;Capacity, alignment, address, or slot state is invalid.
InvocationStatus.IllegalOverlap
IllegalOverlap;Frame violates disjoint move/output/result storage rules.
InvocationStatus.UnmaterializedGeneric
UnmaterializedGeneric;Requested generic declaration has no published closed instance.