Struct CilType

pub struct CilType {
Show 20 fields pub token: Token, pub namespace: String, pub name: String, pub external: Option<CilTypeReference>, pub flags: u32, pub fields: FieldList, pub methods: MethodRefList, pub properties: PropertyList, pub events: EventList, pub interfaces: CilTypeRefList, pub overwrites: Arc<Vec<CilTypeReference>>, pub nested_types: CilTypeRefList, pub generic_params: GenericParamList, pub generic_args: MethodSpecList, pub custom_attributes: CustomAttributeValueList, pub packing_size: OnceLock<u16>, pub class_size: OnceLock<u32>, pub spec: OnceLock<CilFlavor>, pub modifiers: Arc<Vec<CilModifier>>, pub security: OnceLock<Security>, /* private fields */
}
Expand description

Represents a unified type definition combining information from TypeDef, TypeRef, and TypeSpec tables.

CilType provides a complete representation of a .NET type, merging metadata from multiple tables into a single coherent structure. This eliminates the need to navigate between different metadata tables during type analysis and provides a more convenient API.

The token field indicates the source table:

  • TypeDef tokens for types defined in the current assembly
  • TypeRef tokens for types referenced from other assemblies
  • TypeSpec tokens for generic instantiations and complex type signatures
  • Artificial tokens for runtime primitive types

§Thread Safety

CilType is designed for concurrent access with interior mutability using OnceLock for lazily computed fields. Most fields are immutable after construction, while computed properties like flavor and base are thread-safely cached.

§Examples

Basic type information access is available through the type registry. Complex iteration patterns may require understanding the current iterator implementation.

Fields§

§token: Token

Metadata token identifying this type (TypeDef, TypeRef, TypeSpec, or artificial)

§namespace: String

Type namespace (empty for global types and some special cases like <Module>)

§name: String

Type name (class name, interface name, etc.)

§external: Option<CilTypeReference>

External type reference for imported types (from AssemblyRef, File, ModuleRef)

§flags: u32

Type attributes flags - 4-byte bitmask from TypeAttributes (ECMA-335 §II.23.1.15)

§fields: FieldList

All fields defined in this type

§methods: MethodRefList

All methods defined in this type (constructors, instance methods, static methods)

§properties: PropertyList

All properties defined in this type

§events: EventList

All events defined in this type

§interfaces: CilTypeRefList

All interfaces this type implements (from InterfaceImpl table)

§overwrites: Arc<Vec<CilTypeReference>>

All method overwrites this type implements (explicit interface implementations)

§nested_types: CilTypeRefList

Nested types contained within this type (inner classes, delegates, etc.)

§generic_params: GenericParamList

Generic parameters for this type definition (e.g., T, U in Class<T, U>)

§generic_args: MethodSpecList

Generic arguments for instantiated generic types (actual types substituted for parameters)

§custom_attributes: CustomAttributeValueList

Custom attributes applied to this type (annotations, decorators)

§packing_size: OnceLock<u16>

Field layout packing size - alignment of fields in memory (from ClassLayout table)

§class_size: OnceLock<u32>

Total size of the class in bytes (from ClassLayout table)

§spec: OnceLock<CilFlavor>

TypeSpec specifiers providing additional type information for complex types

§modifiers: Arc<Vec<CilModifier>>

Type modifiers from TypeSpec (required/optional modifiers, pinned types, etc.)

§security: OnceLock<Security>

Security declarations and permissions associated with this type

Implementations§

§

impl CilType

pub fn new( token: Token, namespace: String, name: String, external: Option<CilTypeReference>, base: Option<CilTypeRef>, flags: u32, fields: FieldList, methods: MethodRefList, flavor: Option<CilFlavor>, ) -> Self

Create a new instance of a CilType.

Creates a new type representation with the provided metadata. Some fields like properties, events, interfaces, etc. are initialized as empty collections and can be populated later during metadata loading.

§Arguments
  • token - The metadata token for this type
  • namespace - The namespace of the type (can be empty for global types)
  • name - The name of the type
  • external - External type reference if this is an imported type
  • base - Base type reference if this type inherits from another (optional)
  • flags - Type attributes flags from TypeAttributes
  • fields - Fields belonging to this type
  • methods - Methods belonging to this type
  • flavor - Optional explicit flavor. If None, flavor will be computed lazily
§Thread Safety

The returned CilType is safe for concurrent access. Lazily computed fields like flavor and base use OnceLock for thread-safe initialization.

§Examples
use dotscope::metadata::{
    typesystem::{CilType, CilFlavor},
    token::Token,
};
use std::sync::Arc;

let cil_type = CilType::new(
    Token::new(0x02000001), // TypeDef token
    "MyNamespace".to_string(),
    "MyClass".to_string(),
    None, // Not an external type
    None, // No base type specified yet
    0x00100001, // TypeAttributes flags
    Arc::new(boxcar::Vec::new()), // Empty fields list
    Arc::new(boxcar::Vec::new()), // Empty methods list
    Some(CilFlavor::Class), // Explicit class flavor
);

pub fn set_base(&self, base_type: CilTypeRef) -> Result<(), CilTypeRef>

Set the base type of this type for inheritance relationships.

This method allows setting the base type after the CilType has been created, which is useful during metadata loading when type references may not be fully resolved at construction time.

§Arguments
  • base_type - The base type this type inherits from
§Returns
  • Ok(()) if the base type was set successfully
  • Err(base_type) if a base type was already set for this type
§Thread Safety

This method is thread-safe and can be called concurrently. Only the first call will succeed in setting the base type.

§Examples
use dotscope::metadata::typesystem::{CilType, CilTypeRef};
use std::sync::{Arc, Weak};

let base_ref = CilTypeRef::new(&base_type);
match cil_type.set_base(base_ref) {
    Ok(()) => println!("Base type set successfully"),
    Err(_) => println!("Base type was already set"),
}

pub fn base(&self) -> Option<CilTypeRc>

Access the base type of this type, if it exists.

Returns the base type that this type inherits from, if one has been set. For classes, this is typically another class or System.Object. For value types, this is usually System.ValueType or System.Enum.

§Returns
  • Some(CilTypeRc) - The base type if one is set and the reference is still valid
  • None - If no base type is set or the reference has been dropped
§Thread Safety

This method is thread-safe and can be called concurrently.

§Examples
if let Some(base) = cil_type.base() {
    println!("Base type: {}.{}", base.namespace, base.name);
} else {
    println!("No base type (likely System.Object or interface)");
}

pub fn flavor(&self) -> &CilFlavor

Get the computed type flavor - determined lazily from context.

The flavor represents the fundamental nature of the type (class, interface, value type, etc.) and is computed from type attributes, inheritance relationships, and naming patterns. The result is cached for performance.

§Returns

A reference to the computed CilFlavor for this type

§Thread Safety

This method is thread-safe. The flavor is computed once and cached using OnceLock for subsequent calls.

§Examples
use dotscope::metadata::typesystem::{CilType, CilFlavor};

match cil_type.flavor() {
    CilFlavor::Class => println!("Reference type class"),
    CilFlavor::ValueType => println!("Value type (struct/enum)"),
    CilFlavor::Interface => println!("Interface definition"),
    _ => println!("Other type flavor"),
}

pub fn fullname(&self) -> String

Returns the full name (Namespace.Name) of the type.

Combines the namespace and name to create a fully qualified type name, which is useful for type lookup and identification.

§Returns

A string containing the full name in the format “Namespace.Name”

pub fn is_compatible_with(&self, target: &CilType) -> bool

Check if this type is compatible with (assignable to) another type

This implements .NET type compatibility rules including:

  • Exact type matching
  • Inheritance compatibility
  • Interface implementation
  • Primitive type widening
  • Reference type to System.Object
§Arguments
  • target - The target type to check compatibility against
§Returns

true if this type can be assigned to the target type

pub fn accepts_constant(&self, constant: &CilPrimitive) -> bool

Check if a constant value is compatible with this type

§Arguments
  • constant - The constant primitive value to check
§Returns

true if the constant can be assigned to this type

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.