Struct CilType
pub struct CilType {Show 20 fields
pub token: Token,
pub namespace: String,
pub name: String,
pub flags: TypeAttributes,
pub fields: FieldList,
pub methods: MethodRefList,
pub properties: PropertyList,
pub events: EventList,
pub interfaces: InterfaceEntryList,
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>,
pub enclosing_type: OnceLock<CilTypeRef>,
/* 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:
TypeDeftokens for types defined in the current assemblyTypeReftokens for types referenced from other assembliesTypeSpectokens 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: TokenMetadata token identifying this type (TypeDef, TypeRef, TypeSpec, or artificial)
namespace: StringType namespace (empty for global types and some special cases like <Module>)
name: StringType name (class name, interface name, etc.)
flags: TypeAttributesType attributes flags (ECMA-335 §II.23.1.15).
fields: FieldListAll fields defined in this type
methods: MethodRefListAll methods defined in this type (constructors, instance methods, static methods)
properties: PropertyListAll properties defined in this type
events: EventListAll events defined in this type
interfaces: InterfaceEntryListAll interfaces this type implements (from InterfaceImpl table)
overwrites: Arc<Vec<CilTypeReference>>All method overwrites this type implements (explicit interface implementations)
nested_types: CilTypeRefListNested types contained within this type (inner classes, delegates, etc.)
generic_params: GenericParamListGeneric parameters for this type definition (e.g., T, U in Class<T, U>)
generic_args: MethodSpecListGeneric arguments for instantiated generic types (actual types substituted for parameters)
custom_attributes: CustomAttributeValueListCustom 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
enclosing_type: OnceLock<CilTypeRef>Enclosing type for nested types - used for reverse lookup to build hierarchical names
Implementations§
§impl CilType
impl CilType
pub fn new(
token: Token,
namespace: String,
name: String,
external: Option<CilTypeReference>,
base: Option<CilTypeRef>,
flags: TypeAttributes,
fields: FieldList,
methods: MethodRefList,
flavor: Option<CilFlavor>,
) -> Self
pub fn new( token: Token, namespace: String, name: String, external: Option<CilTypeReference>, base: Option<CilTypeRef>, flags: TypeAttributes, 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 typenamespace- The namespace of the type (can be empty for global types)name- The name of the typeexternal- External type reference if this is an imported typebase- Base type reference if this type inherits from another (optional)flags- Type attributes flags fromTypeAttributesfields- Fields belonging to this typemethods- Methods belonging to this typeflavor- 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::{
tables::TypeAttributes,
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
TypeAttributes::new(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<()>
pub fn set_base(&self, base_type: &CilTypeRef) -> Result<()>
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 successfullyErr(base_type)if a base type was already set for this type
§Errors
This function will return an error if a base type was already set for this type. The error contains the base type that was attempted to be set.
§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>
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 validNone- 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 set_enclosing_type(&self, enclosing_type: &CilTypeRef) -> Result<()>
pub fn set_enclosing_type(&self, enclosing_type: &CilTypeRef) -> Result<()>
Set the enclosing type for nested types.
This method allows setting the enclosing type for nested types, establishing the bidirectional relationship between nested and enclosing types. This is used to build proper hierarchical names with “/” separators like the .NET runtime.
§Arguments
enclosing_type- The enclosing type that contains this nested type
§Returns
Ok(())if the enclosing type was set successfully or an equivalent type was already setErr(_)if a different enclosing type was already set for this type
§Errors
Returns an error if an enclosing type was already set with a different value.
§Thread Safety
This method is thread-safe and can be called concurrently. Only the first call will succeed in setting the enclosing type; subsequent calls with the same or equivalent enclosing type will succeed, while calls with a different enclosing type will return an error.
pub fn enclosing_type(&self) -> Option<CilTypeRc>
pub fn enclosing_type(&self) -> Option<CilTypeRc>
Access the enclosing type for nested types, if it exists.
Returns the enclosing type that contains this nested type, if one has been set. This is used to traverse up the type hierarchy for building hierarchical names.
§Returns
Some(CilTypeRc)- The enclosing type if one is set and the reference is still validNone- If this is not a nested type or the reference has been dropped
§Thread Safety
This method is thread-safe and can be called concurrently.
pub fn set_external(&self, external_ref: &CilTypeReference) -> Result<()>
pub fn set_external(&self, external_ref: &CilTypeReference) -> Result<()>
Sets the external type reference for this type.
This method sets the external reference that indicates where this type is defined (e.g., which assembly, module, or file). This is primarily used for TypeRef entries that reference types defined outside the current assembly.
§Arguments
external_ref- The external type reference indicating where this type is defined
§Returns
Ok(())- External reference set successfullyErr(_)- External reference was already set or other error occurred
§Errors
Returns an error if the external reference was already set.
§Thread Safety
This method is thread-safe and can be called concurrently. Only the first call will succeed in setting the external reference.
pub fn external(&self) -> Option<&CilTypeReference>
pub fn external(&self) -> Option<&CilTypeReference>
Gets the external type reference for this type, if it exists.
Returns the external reference that indicates where this type is defined,
or None if this is a type defined in the current assembly or if no
external reference has been set.
§Returns
Returns the external reference if it has been set, or None if it’s still pending resolution.
pub fn flavor(&self) -> &CilFlavor
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 is_internal(&self) -> bool
pub fn is_internal(&self) -> bool
Returns true if this type has internal/assembly-only visibility.
Returns true for:
- Top-level types with
NotPublicvisibility (internal to assembly) - Nested types with
NestedAssemblyvisibility
pub fn is_interface(&self) -> bool
pub fn is_interface(&self) -> bool
Returns true if this type is an interface.
Checks if the type’s flavor is CilFlavor::Interface.
pub fn is_class(&self) -> bool
pub fn is_class(&self) -> bool
Returns true if this type is a class.
Checks if the type’s flavor is CilFlavor::Class.
pub fn is_value_type(&self) -> bool
pub fn is_value_type(&self) -> bool
Returns true if this type is a value type (struct, enum, or primitive value type).
pub fn is_abstract(&self) -> bool
pub fn is_abstract(&self) -> bool
Returns true if this type is abstract (cannot be instantiated directly).
pub fn is_delegate(&self) -> bool
pub fn is_delegate(&self) -> bool
Returns true if this type is a delegate (inherits from System.Delegate or System.MulticastDelegate).
pub fn query_methods(&self) -> MethodQuery<'_>
pub fn query_methods(&self) -> MethodQuery<'_>
Returns a composable query over methods defined in this type.
This handles the weak-ref upgrade boilerplate automatically, replacing the common pattern:
for (_, method_ref) in type_info.methods.iter() {
if let Some(method) = method_ref.upgrade() { ... }
}pub fn query_fields(&self) -> FieldQuery<'_>
pub fn query_fields(&self) -> FieldQuery<'_>
Returns a composable query over fields defined in this type.
This provides a fluent API mirroring query_methods():
let static_fields = type_info.query_fields().static_fields().find_all();
let value_field = type_info.query_fields().instance_fields().name("value__").find_first();pub fn cctor(&self) -> Option<Token>
pub fn cctor(&self) -> Option<Token>
Returns the .cctor (class constructor / type initializer) token, if present.
pub fn ctor(&self) -> Option<Token>
pub fn ctor(&self) -> Option<Token>
Returns the first .ctor (instance constructor) token, if present.
pub fn is_module_type(&self) -> bool
pub fn is_module_type(&self) -> bool
Returns true if this is the global <Module> type.
pub fn methods(&self) -> impl Iterator<Item = MethodRc> + '_
pub fn methods(&self) -> impl Iterator<Item = MethodRc> + '_
Returns an iterator over all methods defined in this type.
Automatically upgrades weak references, skipping any that have been dropped.
pub fn fields(&self) -> impl Iterator<Item = &FieldRc> + '_
pub fn fields(&self) -> impl Iterator<Item = &FieldRc> + '_
Returns an iterator over all fields defined in this type.
Returns references to the field entries in the field list.
pub fn is_nested_internal(&self) -> bool
pub fn is_nested_internal(&self) -> bool
Returns true if this is a nested type with private or internal visibility.
This includes:
NestedPrivate- Only accessible within the declaring typeNestedAssembly- Only accessible within the same assemblyNestedFamANDAssem- Only accessible to derived types within the same assembly
Useful for detecting obfuscation infrastructure types that are intentionally hidden.
pub fn has_public_methods(&self) -> bool
pub fn has_public_methods(&self) -> bool
Returns true if any method in this type has public access.
Iterates through all methods declared by this type and checks if any
have Public accessibility.
pub fn has_public_fields(&self) -> bool
pub fn has_public_fields(&self) -> bool
Returns true if any field in this type has public access.
Iterates through all fields declared by this type and checks if any
have Public accessibility (flag value 0x06).
pub fn find_method(&self, name: &str) -> Option<MethodRc>
pub fn find_method(&self, name: &str) -> Option<MethodRc>
Finds the first method with the given name declared by this type.
Searches through the type’s method list, upgrading weak references
and comparing names. Returns None if no method matches or if
all matching weak references have been dropped.
pub fn find_methods(&self, name: &str) -> Vec<MethodRc> ⓘ
pub fn find_methods(&self, name: &str) -> Vec<MethodRc> ⓘ
Finds all methods with the given name declared by this type.
Returns all matching methods, useful for finding overloaded methods.
pub fn fullname(&self) -> String
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. For nested types, uses “/” separators as per .NET runtime convention.
§Returns
A string containing the full name in the format:
"Namespace.Name"for top-level types"Namespace.Outer/Inner"for nested types
§Caching
The result is cached after first computation for performance.
pub fn is_typeref(&self) -> bool
pub fn is_typeref(&self) -> bool
Checks if this type was created from a TypeRef table entry.
Returns true if this type’s token indicates it originated from a TypeRef table,
meaning it references a type defined in an external assembly. This is essential
for TypeRef to TypeDef resolution during multi-assembly loading.
§Returns
true- If the type’s token has table ID 0x01 (TypeRef)false- If the type came from TypeDef (0x02), TypeSpec (0x1B), or other sources
§Examples
use dotscope::metadata::typesystem::CilType;
use dotscope::metadata::token::Token;
if type_def.is_typeref() {
println!("Type {} needs TypeRef resolution", type_def.fullname());
}pub fn is_compatible_with(&self, target: &CilType) -> bool
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
pub fn accepts_constant(&self, constant: &CilPrimitive) -> bool
pub fn is_structurally_equivalent(&self, other: &CilType) -> bool
pub fn is_structurally_equivalent(&self, other: &CilType) -> bool
Performs deep structural comparison with another type for deduplication purposes
This method compares all structural aspects of types to determine true equivalence, including generic arguments, base types, and source information. This is the authoritative method for determining if two types are semantically identical.
§Arguments
other- The other type to compare with
§Returns
true if the types are structurally equivalent and can be deduplicated
pub fn external_sources_equivalent(&self, other: &CilType) -> bool
pub fn external_sources_equivalent(&self, other: &CilType) -> bool
Compare external source references for equivalence.
Determines if two types originate from the same assembly by comparing their external source references (AssemblyRef, ModuleRef, File, etc.).
§Returns
trueif types are from the same assembly or indeterminate (conservative)falseif types are definitively from different assemblies
§Examples
Types from the same assembly will return true, while types from different
assemblies (different AssemblyRef) will return false.
pub fn is_array_of(&self, base_fullname: &str) -> bool
pub fn is_array_of(&self, base_fullname: &str) -> bool
Check if this type has an array relationship with the given base type.
Returns true if this type is an array type (ends with “[]”) and the base type matches the array’s element type. This handles nested types correctly by checking both direct name matches and nested type patterns.
§Arguments
base_fullname- The full name of the potential base type to check against. Must be a non-empty, valid type name.
§Returns
true- If this type is an array of the specified base typefalse- If this is not an array type, the base name is empty, or there’s no match
§Examples
MyClass[]is an array ofMyClassAdjustmentRule[]is an array ofTimeZoneInfo/AdjustmentRule
pub fn is_pointer_to(&self, base_fullname: &str) -> bool
pub fn is_pointer_to(&self, base_fullname: &str) -> bool
Check if this type has a pointer relationship with the given base type.
Returns true if this type is a pointer type (ends with “*”) and the base type matches the pointer’s target type. This handles nested types correctly by checking both direct name matches and nested type patterns.
§Arguments
base_fullname- The full name of the potential target type to check against. Must be a non-empty, valid type name.
§Returns
true- If this type is a pointer to the specified base typefalse- If this is not a pointer type, the base name is empty, or there’s no match
§Examples
EventData*is a pointer toEventDataMyStruct*is a pointer toOuterClass/MyStruct
pub fn is_generic_of(&self, base_fullname: &str) -> bool
pub fn is_generic_of(&self, base_fullname: &str) -> bool
Check if this type represents a generic relationship with the base type.
Returns true if either type has generic parameters (contains ‘`’) and they share a common base name, indicating a generic instantiation relationship.
§Arguments
base_fullname- The full name of the potential generic base type to check against. Must be a non-empty, valid type name.
§Returns
true- If the types share a generic relationshipfalse- If there’s no generic relationship, or the base name is empty
§Examples
List<int>has a generic relationship withList<T>Dictionary<string, int>has a generic relationship withDictionary<K, V>
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for CilType
impl RefUnwindSafe for CilType
impl Send for CilType
impl Sync for CilType
impl Unpin for CilType
impl UnsafeUnpin for CilType
impl UnwindSafe for CilType
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for T
impl<T> Downcast for T
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 moreSource§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.Source§impl<T> ToCompactString for Twhere
T: Display,
impl<T> ToCompactString for Twhere
T: Display,
Source§fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
ToCompactString::to_compact_string() Read moreSource§fn to_compact_string(&self) -> CompactString
fn to_compact_string(&self) -> CompactString
CompactString. Read more