Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Type Analysis

The type analysis system provides insights into type usage, inheritance hierarchies, and type-related patterns in C# code.


Overview

Status: Planned (module not implemented yet)

Type analysis tracks:

  • Type definitions and their relationships
  • Inheritance hierarchies
  • Interface implementations
  • Generic type usage
  • Type references and dependencies

Type Information

Type Categories

Value Types:

  • Primitives (int, bool, double, etc.)
  • Structs
  • Enums

Reference Types:

  • Classes
  • Interfaces
  • Delegates
  • Arrays

Special Types:

  • Generic type parameters
  • Nullable types
  • Tuple types
  • Anonymous types

Inheritance Analysis

Class Hierarchies

Tracking Inheritance:

public class Animal { }
public class Mammal : Animal { }
public class Dog : Mammal { }

Hierarchy Representation:

Animal
└── Mammal
    └── Dog

Analysis:

#![allow(unused)]
fn main() {
pub struct InheritanceHierarchy {
    // Type -> Base Type
    base_types: HashMap<TypeId, TypeId>,
    // Type -> Derived Types
    derived_types: HashMap<TypeId, Vec<TypeId>>,
}

impl InheritanceHierarchy {
    pub fn get_base_type(&self, type_id: TypeId) -> Option<TypeId>;
    pub fn get_derived_types(&self, type_id: TypeId) -> &[TypeId];
    pub fn get_all_ancestors(&self, type_id: TypeId) -> Vec<TypeId>;
    pub fn get_all_descendants(&self, type_id: TypeId) -> Vec<TypeId>;
    pub fn inheritance_depth(&self, type_id: TypeId) -> usize;
}
}

Interface Implementation

Tracking Implementations:

public interface IRepository { }
public interface IUserRepository : IRepository { }
public class UserRepository : IUserRepository { }

Analysis:

#![allow(unused)]
fn main() {
pub struct InterfaceImplementations {
    // Type -> Interfaces it implements
    implementations: HashMap<TypeId, Vec<TypeId>>,
    // Interface -> Types that implement it
    implementers: HashMap<TypeId, Vec<TypeId>>,
}
}

Generic Type Analysis

Type Parameters

Tracking Generic Definitions:

public class Container<T> where T : class { }
public class Repository<TEntity, TKey> where TEntity : class { }

Analysis:

#![allow(unused)]
fn main() {
pub struct GenericTypeInfo {
    pub type_parameters: Vec<TypeParameter>,
    pub constraints: Vec<TypeConstraint>,
}

pub struct TypeParameter {
    pub name: String,
    pub variance: Option<Variance>,  // in, out
}

pub struct TypeConstraint {
    pub parameter: String,
    pub kind: ConstraintKind,
}

pub enum ConstraintKind {
    Class,              // where T : class
    Struct,             // where T : struct
    New,                // where T : new()
    BaseType(TypeId),   // where T : BaseClass
    Interface(TypeId),  // where T : IInterface
}
}

Generic Type Usage

Tracking Instantiations:

var list = new List<int>();
var dict = new Dictionary<string, User>();

Analysis:

#![allow(unused)]
fn main() {
pub struct GenericInstantiation {
    pub generic_type: TypeId,
    pub type_arguments: Vec<TypeId>,
}

pub fn find_generic_instantiations(cu: &CompilationUnit) -> Vec<GenericInstantiation>;
}

Type Usage Patterns

Frequency Analysis

Most Used Types:

#![allow(unused)]
fn main() {
pub struct TypeUsageStats {
    pub type_references: HashMap<TypeId, usize>,
}

impl TypeUsageStats {
    pub fn most_used_types(&self, limit: usize) -> Vec<(TypeId, usize)>;
    pub fn usage_count(&self, type_id: TypeId) -> usize;
}
}

Type Categories Distribution

#![allow(unused)]
fn main() {
pub struct TypeDistribution {
    pub class_count: usize,
    pub interface_count: usize,
    pub struct_count: usize,
    pub enum_count: usize,
    pub delegate_count: usize,
}
}

Type Metrics

Depth of Inheritance Tree (DIT)

Definition: Maximum depth from type to root of hierarchy

Example:

class A { }              // DIT = 0 (or 1 from Object)
class B : A { }          // DIT = 1 (or 2 from Object)
class C : B { }          // DIT = 2 (or 3 from Object)

Interpretation:

  • Low DIT (0-2): Simple hierarchy, easy to understand
  • Medium DIT (3-4): Moderate complexity
  • High DIT (5+): Complex hierarchy, may indicate over-engineering

Number of Children (NOC)

Definition: Number of immediate subclasses

Example:

class Animal { }
class Dog : Animal { }
class Cat : Animal { }
class Bird : Animal { }
// Animal has NOC = 3

Interpretation:

  • High NOC: Type is heavily reused (good abstraction or god class)
  • Low NOC: Specialized type or leaf in hierarchy

Lack of Cohesion of Methods (LCOM)

Definition: Measure of how well methods in a class are related

Simplified Calculation:

  • Count pairs of methods that don't share instance variables
  • High LCOM suggests class should be split

Type Compatibility Analysis

Assignability

Checking Compatibility:

#![allow(unused)]
fn main() {
pub fn is_assignable_to(from: &Type, to: &Type, context: &TypeContext) -> bool {
    // Check if 'from' type can be assigned to 'to' type
    // Considers inheritance, interface implementation, variance, etc.
}
}

Rules:

  • Derived type assignable to base type
  • Type assignable to implemented interface
  • Covariant/contravariant generic types
  • Nullable value types
  • Implicit conversions

Type Conversions

Tracking Conversions:

int x = 42;
long y = x;              // Implicit conversion
string s = x.ToString(); // Explicit conversion

Analysis:

#![allow(unused)]
fn main() {
pub enum ConversionKind {
    Implicit,
    Explicit,
    UserDefined,
}

pub struct TypeConversion {
    pub from: TypeId,
    pub to: TypeId,
    pub kind: ConversionKind,
}
}

Nullable Reference Types Analysis

Nullability Tracking

C# 8+ Nullable Annotations:

string? nullable = null;      // Nullable reference
string nonNull = "value";     // Non-nullable reference

Analysis:

#![allow(unused)]
fn main() {
pub struct NullabilityInfo {
    pub is_nullable: bool,
    pub nullability_context: NullabilityContext,
}

pub enum NullabilityContext {
    Enabled,
    Disabled,
    Warnings,
}
}

Null Safety Diagnostics

Potential Null Reference:

warning[TYPE001]: Possible null reference
  --> src/UserService.cs:15:9
   |
15 |     user.Name = "John";
   |     ^^^^ 'user' may be null here
   |
   = help: Add null check or use null-conditional operator

Type Analysis in Pipeline

Integration

Type analysis is not part of the default registry yet. The intended phase is Semantic (after symbol indexing and global artifacts). This page outlines the planned scope.


Programmatic Usage

Analyzing Type Hierarchy

Planned APIs will expose hierarchy queries once implemented.

Finding Generic Instantiations

Planned helper(s) to enumerate generic instantiations will be documented here after implementation.


Future Enhancements

Planned Features

  1. Type Inference Tracking

    • Track var usage and inferred types
    • Analyze type inference patterns
  2. Variance Analysis

    • Detect variance violations
    • Suggest covariant/contravariant annotations
  3. Type Safety Metrics

    • Measure use of dynamic
    • Track unsafe casts
    • Nullable reference type coverage
  4. Design Pattern Detection

    • Identify common patterns (Factory, Strategy, etc.)
    • Detect anti-patterns

Implementation Status

Current State:

  • Basic type tracking infrastructure in place
  • Type analysis module integrated with analysis framework
  • Foundation for inheritance and generic analysis established

In Progress:

  • Full inheritance hierarchy analysis
  • Generic type instantiation tracking
  • Type usage statistics collection
  • Comprehensive test coverage

Planned:

  • Variance analysis
  • Type safety metrics
  • Design pattern detection based on type relationships


References

  • Implementation: Planned
  • Tests: Planned (under src/bsharp_tests/src/analysis/types/)
  • Related: docs/analysis/dependencies.md, docs/parser/ast-structure.md
2025-11-17 15:18:26 • commit: 03a4e25