mago_typing/
lib.rs

1use mago_interner::ThreadedInterner;
2use mago_names::ResolvedNames;
3use mago_reflection::CodebaseReflection;
4use mago_reflection::r#type::TypeReflection;
5use mago_reflection::r#type::kind::TypeKind;
6use mago_source::Source;
7use mago_span::HasSpan;
8use mago_syntax::ast::Expression;
9
10use crate::resolver::TypeResolver;
11
12mod internal;
13
14pub mod constant;
15pub mod resolver;
16
17/// Infers the type of a given expression by initializing a simple type reflection
18/// that includes the inferred type kind and its source location.
19///
20/// # Arguments
21///
22/// - `interner`: Manages string interning.
23/// - `source`: The source of the expression.
24/// - `names`: The names of the program.
25/// - `expression`: The expression to analyze.
26///
27/// # Returns
28///
29/// Returns a `TypeReflection` with the inferred type kind and span of the expression.
30pub fn infere<'ast>(
31    interner: &ThreadedInterner,
32    source: &'ast Source,
33    names: &'ast ResolvedNames,
34    expression: &'ast Expression,
35) -> TypeReflection {
36    let kind = infere_kind(interner, source, names, expression);
37
38    TypeReflection { kind, inferred: true, span: expression.span() }
39}
40
41/// Infers the general type kind of an expression without using a codebase for context.
42///
43/// # Arguments
44///
45/// - `interner`: Manages string interning.
46/// - `source`: The source of the expression.
47/// - `names`: The names of the program.
48/// - `expression`: The expression to analyze.
49///
50/// # Returns
51///
52/// Returns a `TypeKind` that represents the initial inferred type of the expression.
53pub fn infere_kind<'ast>(
54    interner: &ThreadedInterner,
55    source: &'ast Source,
56    names: &'ast ResolvedNames,
57    expression: &'ast Expression,
58) -> TypeKind {
59    let resolver = TypeResolver::new(interner, source, names, None);
60
61    resolver.resolve(expression)
62}
63
64/// Resolves the type kind of an expression with additional codebase context for more
65/// precise type information.
66///
67/// # Arguments
68///
69/// - `interner`: Manages string interning.
70/// - `source`: The source of the expression.
71/// - `names`: The names of the program.
72/// - `codebase`: The codebase reflection to use for context.
73/// - `expression`: The expression to analyze.
74///
75/// # Returns
76///
77/// Returns a `TypeKind` that represents the resolved type of the expression,
78/// taking into account any known codebase types.
79pub fn resolve_kind<'ast>(
80    interner: &ThreadedInterner,
81    source: &'ast Source,
82    names: &'ast ResolvedNames,
83    codebase: &'ast CodebaseReflection,
84    expression: &'ast Expression,
85) -> TypeKind {
86    let resolver = TypeResolver::new(interner, source, names, Some(codebase));
87
88    resolver.resolve(expression)
89}