#![doc = include_str!("../README.md")]
#![allow(
unreachable_code,
unused_variables,
unused_mut,
dead_code,
irrefutable_let_patterns,
deprecated
)]
mod behavior;
pub mod context;
pub mod diagnostics;
pub mod events;
pub mod range_map;
mod serialization;
mod settings;
pub mod structures;
pub mod temp;
mod type_mappings;
pub mod types;
mod utils;
pub const INTERNAL_DEFINITION_FILE_PATH: &str = "internal.d.ts";
pub const INTERNAL_DEFINITION_FILE: &str = include_str!("../definitions/internal.d.ts");
#[cfg(feature = "ezno-parser")]
pub mod synthesis;
use diagnostics::{TypeCheckError, TypeCheckWarning};
pub(crate) use serialization::BinarySerializable;
use context::store::ExistingContextStore;
use indexmap::IndexMap;
use std::{
collections::{HashMap, HashSet},
path::PathBuf,
};
use structures::functions::AutoConstructorId;
use types::{
subtyping::{type_is_subtype, BasicEquality, SubTypeResult},
TypeStore,
};
pub use behavior::{
assignments::{
Assignable, AssignmentKind, AssignmentReturnStatus, IncrementOrDecrement, Reference,
SynthesizableExpression,
},
functions::{
GetterSetterGeneratorOrNone, RegisterAsType, RegisterOnExisting, RegisterOnExistingObject,
SynthesizableFunction,
},
variables::check_variable_initialization,
};
pub use context::{GeneralContext, Root};
pub use diagnostics::{Diagnostic, DiagnosticKind, DiagnosticsContainer};
pub use settings::TypeCheckSettings;
pub use structures::{
functions::{FunctionPointer, InternalFunctionId},
jsx::*,
modules::SynthesizedModule,
variables::Variable,
};
pub use types::{
calling::call_type_handle_errors, operations::*, poly_types::GenericTypeParameters, subtyping,
};
pub use type_mappings::*;
pub use types::{properties::Property, Constant, Type, TypeId};
pub use context::{Environment, Scope};
pub(crate) use structures::modules::ModuleFromPathError;
pub trait FSResolver: Fn(&std::path::Path) -> Option<String> {}
impl<T> FSResolver for T where T: Fn(&std::path::Path) -> Option<String> {}
pub use source_map::{SourceId, Span};
pub struct ModuleData<'a, T> {
pub(crate) currently_checking_modules: HashSet<PathBuf>,
pub(crate) synthesized_modules: IndexMap<PathBuf, SynthesizedModule>,
pub(crate) fs_resolver: &'a T,
pub(crate) current_working_directory: PathBuf,
}
impl<'a, T: crate::FSResolver> ModuleData<'a, T> {
pub(crate) fn new_with_custom_module_resolvers(
fs_resolver: &'a T,
current_working_directory: PathBuf,
) -> Self {
Self {
synthesized_modules: Default::default(),
currently_checking_modules: Default::default(),
fs_resolver,
current_working_directory,
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, binary_serialize_derive::BinarySerializable)]
pub struct VariableId(pub SourceId, pub u32);
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, binary_serialize_derive::BinarySerializable)]
pub struct FunctionId(pub SourceId, pub u32);
impl FunctionId {
pub const NULL: Self = Self(SourceId::NULL, 0);
}
pub enum TruthyFalsy {
Decidable(bool),
Unknown,
}
pub struct CheckingData<'a, T> {
pub diagnostics_container: DiagnosticsContainer,
pub type_mappings: TypeMappings,
pub(crate) modules: ModuleData<'a, T>,
pub(crate) settings: TypeCheckSettings,
pub(crate) existing_contexts: ExistingContextStore,
pub types: TypeStore,
unimplemented_items: HashSet<&'static str>,
}
impl<'a, T: crate::FSResolver> CheckingData<'a, T> {
pub fn new(settings: TypeCheckSettings, resolver: &'a T) -> Self {
let cwd = Default::default();
let modules = ModuleData::new_with_custom_module_resolvers(resolver, cwd);
Self {
settings,
type_mappings: Default::default(),
diagnostics_container: Default::default(),
modules,
existing_contexts: Default::default(),
types: Default::default(),
unimplemented_items: Default::default(),
}
}
pub(crate) fn load_and_check_module(
&mut self,
path: PathBuf,
base_environment: &mut Root,
) -> Result<
(&HashMap<String, Variable>, &mut DiagnosticsContainer, &mut TypeMappings),
ModuleFromPathError,
> {
todo!()
}
pub fn raise_decidable_result_error(&mut self, span: Span, value: bool) {
self.diagnostics_container.add_error(TypeCheckWarning::DeadBranch {
expression_span: span,
expression_value: value,
})
}
pub fn raise_unimplemented_error(&mut self, item: &'static str, span: Span) {
if self.unimplemented_items.insert(item) {
self.diagnostics_container
.add_warning(TypeCheckWarning::Unimplemented { thing: item, at: span });
}
}
pub fn add_expression_mapping(&mut self, span: Span, instance: Instance) {
self.type_mappings.expressions_to_instances.push(span, instance);
}
pub fn check_satisfies(
&mut self,
expr_ty: TypeId,
to_satisfy: TypeId,
pos: Span,
environment: &mut Environment,
) {
let result = type_is_subtype(
to_satisfy,
expr_ty,
None,
&mut BasicEquality { add_property_restrictions: false, position: pos.clone() },
environment,
&self.types,
);
if let SubTypeResult::IsNotSubType(_) = result {
let expected = diagnostics::TypeStringRepresentation::from_type_id(
to_satisfy,
&environment.into_general_context(),
&self.types,
false,
);
let found = diagnostics::TypeStringRepresentation::from_type_id(
expr_ty,
&environment.into_general_context(),
&self.types,
false,
);
self.diagnostics_container.add_error(TypeCheckError::NotSatisfied {
at: pos,
expected,
found,
})
}
}
}