Fork of daniellemaywood.uk/gleam — Wasm codegen work
2

Configure Feed

Select the types of activity you want to include in your feed.

gleam / compiler-core / src / build / package_loader.rs
54 kB 1859 lines
1// SPDX-License-Identifier: Apache-2.0 2// SPDX-FileCopyrightText: 2022 The Gleam contributors 3 4#[cfg(test)] 5mod tests; 6 7use std::{ 8 collections::{HashMap, HashSet}, 9 sync::OnceLock, 10 time::{Duration, SystemTime}, 11}; 12 13use camino::{Utf8Path, Utf8PathBuf}; 14 15// TODO: emit warnings for cached modules even if they are not compiled again. 16 17use ecow::EcoString; 18use itertools::Itertools; 19use regex::Regex; 20use vec1::Vec1; 21 22use crate::{ 23 Error, Result, 24 ast::SrcSpan, 25 build::{Module, Origin, module_loader::ModuleLoader}, 26 config::PackageConfig, 27 dep_tree, 28 error::{DefinedModuleOrigin, FileIoAction, FileKind, ImportCycleLocationDetails}, 29 io::{self, CommandExecutor, FileSystemReader, FileSystemWriter, files_with_extension}, 30 metadata, 31 paths::ProjectPaths, 32 type_, 33 uid::UniqueIdGenerator, 34 warning::WarningEmitter, 35}; 36 37use super::{ 38 Mode, Target, 39 module_loader::read_source, 40 package_compiler::{ 41 CacheMetadata, CachedModule, CachedWarnings, Input, Loaded, UncompiledModule, 42 }, 43}; 44 45#[derive(Debug, Clone, Copy, PartialEq, Eq)] 46pub enum CodegenRequired { 47 Yes, 48 No, 49} 50 51impl CodegenRequired { 52 /// Returns `true` if the codegen required is [`Yes`]. 53 /// 54 /// [`Yes`]: CodegenRequired::Yes 55 #[must_use] 56 pub fn is_required(&self) -> bool { 57 matches!(self, Self::Yes) 58 } 59} 60 61#[derive(Debug)] 62pub struct PackageLoader<'a, IO> { 63 io: IO, 64 ids: UniqueIdGenerator, 65 mode: Mode, 66 paths: ProjectPaths, 67 warnings: &'a WarningEmitter, 68 codegen: CodegenRequired, 69 artefact_directory: &'a Utf8Path, 70 package_name: &'a EcoString, 71 target: Target, 72 stale_modules: &'a mut StaleTracker, 73 already_defined_modules: &'a mut im::HashMap<EcoString, DefinedModuleOrigin>, 74 incomplete_modules: &'a HashSet<EcoString>, 75 cached_warnings: CachedWarnings, 76} 77 78impl<'a, IO> PackageLoader<'a, IO> 79where 80 IO: FileSystemWriter + FileSystemReader + CommandExecutor + Clone, 81{ 82 pub(crate) fn new( 83 io: IO, 84 ids: UniqueIdGenerator, 85 mode: Mode, 86 root: &'a Utf8Path, 87 cached_warnings: CachedWarnings, 88 warnings: &'a WarningEmitter, 89 codegen: CodegenRequired, 90 artefact_directory: &'a Utf8Path, 91 target: Target, 92 package_name: &'a EcoString, 93 stale_modules: &'a mut StaleTracker, 94 already_defined_modules: &'a mut im::HashMap<EcoString, DefinedModuleOrigin>, 95 incomplete_modules: &'a HashSet<EcoString>, 96 ) -> Self { 97 Self { 98 io, 99 ids, 100 mode, 101 paths: ProjectPaths::new(root.into()), 102 warnings, 103 codegen, 104 target, 105 package_name, 106 cached_warnings, 107 artefact_directory, 108 stale_modules, 109 already_defined_modules, 110 incomplete_modules, 111 } 112 } 113 114 pub(crate) fn run(mut self) -> Result<Loaded> { 115 // First read the source files. This will use the `ModuleLoader`, which 116 // will check the mtimes and hashes of sources and caches to determine 117 // which should be loaded. 118 let mut inputs = self.read_sources_and_caches()?; 119 120 // Check for any removed modules, by looking at cache files that don't exist in inputs. 121 // Delete the cache files for removed modules and mark them as stale 122 // to trigger refreshing dependent modules. 123 for module in CacheFiles::modules_with_meta_files(&self.io, &self.artefact_directory) { 124 if (!inputs.contains_key(&module)) { 125 tracing::debug!(%module, "module_removed"); 126 CacheFiles::new(&self.artefact_directory, &module).delete(&self.io)?; 127 self.stale_modules.add(module); 128 } 129 } 130 131 // Determine order in which modules are to be processed 132 let mut dep_location_map = HashMap::new(); 133 let deps = inputs 134 .values() 135 .map(|(_, module)| { 136 let name = module.name().clone(); 137 let _ = dep_location_map.insert(name.clone(), module); 138 (name, module.dependencies()) 139 }) 140 // Making sure that the module order is deterministic, to prevent different 141 // compilations of the same project compiling in different orders. This could impact 142 // any bugged outcomes, though not any where the compiler is working correctly, so it's 143 // mostly to aid debugging. 144 .sorted_by(|(a, _), (b, _)| a.cmp(b)) 145 .collect(); 146 let sequence = dep_tree::toposort_deps(deps) 147 .map_err(|error| self.convert_deps_tree_error(error, dep_location_map))?; 148 149 // Now that we have loaded sources and caches we check to see if any of 150 // the caches need to be invalidated because their dependencies have 151 // changed. 152 let mut loaded = Loaded::default(); 153 for name in sequence { 154 let (_, input) = inputs 155 .remove(&name) 156 .expect("Getting parsed module for name"); 157 158 match input { 159 // A new uncached module is to be compiled 160 Input::New(module) => { 161 tracing::debug!(module = %module.name, "new_module_to_be_compiled"); 162 self.stale_modules.add(module.name.clone()); 163 loaded.to_compile.push(module); 164 } 165 166 // A cached module with dependencies that are stale must be 167 // recompiled as the changes in the dependencies may have affect 168 // the output, making the cache invalid. 169 Input::Cached(info) if self.stale_modules.includes_any(&info.dependencies) => { 170 tracing::debug!(module = %info.name, "stale_module_to_be_compiled"); 171 self.stale_modules.add(info.name.clone()); 172 let module = self.load_stale_module(info)?; 173 loaded.to_compile.push(module); 174 } 175 176 // A cached module with no stale dependencies can be used as-is 177 // and does not need to be recompiled. 178 Input::Cached(info) => { 179 tracing::debug!(module = %info.name, "module_to_load_from_cache"); 180 let module = self.load_cached_module(info)?; 181 loaded.cached.push(module); 182 } 183 } 184 } 185 186 Ok(loaded) 187 } 188 189 fn load_cached_module(&self, info: CachedModule) -> Result<type_::ModuleInterface, Error> { 190 let cache_files = CacheFiles::new(&self.artefact_directory, &info.name); 191 let bytes = self.io.read_bytes(&cache_files.cache_path)?; 192 let mut module = match metadata::decode(bytes.as_slice(), self.ids.clone()) { 193 Ok(module) => module, 194 Err(e) => { 195 return Err(Error::FileIo { 196 kind: FileKind::File, 197 action: FileIoAction::Parse, 198 path: cache_files.cache_path, 199 err: Some(e.to_string()), 200 }); 201 } 202 }; 203 204 // Discard warnings if they should not be cached 205 if !self.cached_warnings.should_use() { 206 module.warnings.clear(); 207 } 208 209 Ok(module) 210 } 211 212 fn read_sources_and_caches( 213 &mut self, 214 ) -> Result<HashMap<EcoString, (DefinedModuleOrigin, Input)>> { 215 let span = tracing::info_span!("load"); 216 let _enter = span.enter(); 217 218 let mut inputs = Inputs::new(self.package_name.clone(), self.already_defined_modules); 219 220 let src = self.paths.src_directory(); 221 let mut loader = ModuleLoader { 222 io: self.io.clone(), 223 warnings: self.warnings, 224 mode: self.mode, 225 target: self.target, 226 codegen: self.codegen, 227 package_name: self.package_name, 228 artefact_directory: self.artefact_directory, 229 origin: Origin::Src, 230 incomplete_modules: self.incomplete_modules, 231 }; 232 233 // Src 234 for file in GleamFile::iterate_files_in_directory(&self.io, &src) { 235 match file { 236 Ok(file) => { 237 let input = loader.load(file)?; 238 inputs.insert(input)?; 239 } 240 Err(warning) => self.warnings.emit(warning), 241 } 242 } 243 244 // Test and dev 245 if self.mode.includes_dev_code() { 246 let test = self.paths.test_directory(); 247 loader.origin = Origin::Test; 248 249 for file in GleamFile::iterate_files_in_directory(&self.io, &test) { 250 match file { 251 Ok(file) => { 252 let input = loader.load(file)?; 253 inputs.insert(input)?; 254 } 255 Err(warning) => self.warnings.emit(warning), 256 } 257 } 258 259 let dev = self.paths.dev_directory(); 260 loader.origin = Origin::Dev; 261 262 for file in GleamFile::iterate_files_in_directory(&self.io, &dev) { 263 match file { 264 Ok(file) => { 265 let input = loader.load(file)?; 266 inputs.insert(input)?; 267 } 268 Err(warning) => self.warnings.emit(warning), 269 } 270 } 271 } 272 273 // If we are compiling for Erlang then modules all live in a single 274 // namespace. If we were to name a module the same as a module that 275 // is included in the standard Erlang distribution then this new 276 // Gleam module would overwrite the existing Erlang one, likely 277 // resulting in cryptic errors. 278 // This would most commonly happen for modules like "user" and 279 // "code". Emit an error so this never happens. 280 if self.target.is_erlang() { 281 for (_, input) in inputs.collection.values() { 282 ensure_gleam_module_does_not_overwrite_standard_erlang_module(&input)?; 283 } 284 } 285 286 Ok(inputs.collection) 287 } 288 289 fn load_stale_module(&self, cached: CachedModule) -> Result<UncompiledModule> { 290 let mtime = self.io.modification_time(&cached.source_path)?; 291 292 // We need to delete any existing cache files for this module. 293 // While we figured it out this time because the module has stale dependencies, 294 // next time the dependencies might no longer be stale, but we still need to be able to tell 295 // that this module needs to be recompiled until it successfully compiles at least once. 296 // This can happen if the stale dependency includes breaking changes. 297 CacheFiles::new(&self.artefact_directory, &cached.name).delete(&self.io)?; 298 299 read_source( 300 self.io.clone(), 301 self.target, 302 cached.origin, 303 cached.source_path, 304 cached.name, 305 self.package_name.clone(), 306 mtime, 307 self.warnings.clone(), 308 ) 309 } 310 311 fn convert_deps_tree_error( 312 &self, 313 e: dep_tree::Error, 314 dep_location_map: HashMap<EcoString, &Input>, 315 ) -> Error { 316 match e { 317 dep_tree::Error::Cycle(modules) => { 318 let modules = modules 319 .iter() 320 .enumerate() 321 .map(|(i, module)| { 322 // cycles are in order of reference so get next in list or loop back to first 323 let index_of_imported = if i == 0 { modules.len() - 1 } else { i - 1 }; 324 let imported_module = modules 325 .get(index_of_imported) 326 .expect("importing module must exist"); 327 let input = dep_location_map.get(module).expect("dependency must exist"); 328 let location = match input { 329 Input::New(module) => { 330 let (_, location) = module 331 .dependencies 332 .iter() 333 .find(|d| &d.0 == imported_module) 334 .expect("import must exist for there to be a cycle"); 335 ImportCycleLocationDetails { 336 location: *location, 337 path: module.path.clone(), 338 src: module.code.clone(), 339 } 340 } 341 Input::Cached(cached_module) => { 342 let (_, location) = cached_module 343 .dependencies 344 .iter() 345 .find(|d| &d.0 == imported_module) 346 .expect("import must exist for there to be a cycle"); 347 let src = self 348 .io 349 .read(&cached_module.source_path) 350 .expect("failed to read source") 351 .into(); 352 ImportCycleLocationDetails { 353 location: *location, 354 path: cached_module.source_path.clone(), 355 src, 356 } 357 } 358 }; 359 (module.clone(), location) 360 }) 361 .collect_vec(); 362 Error::ImportCycle { 363 modules: Vec1::try_from(modules) 364 .expect("at least 1 module must exist in cycle"), 365 } 366 } 367 } 368 } 369} 370 371fn ensure_gleam_module_does_not_overwrite_standard_erlang_module(input: &Input) -> Result<()> { 372 // We only need to check uncached modules as it's not possible for these 373 // to have compiled successfully. 374 let Input::New(input) = input else { 375 return Ok(()); 376 }; 377 378 // These names were got with this Erlang 379 // 380 // ```erl 381 // file:write_file("names.txt", lists:join("\n",lists:map(fun(T) -> erlang:element(1, T) end, code:all_available()))). 382 // ``` 383 // 384 match input.name.as_str() { 385 "alarm_handler" 386 | "application" 387 | "application_controller" 388 | "application_master" 389 | "application_starter" 390 | "appmon_info" 391 | "argparse" 392 | "array" 393 | "asn1_db" 394 | "asn1ct" 395 | "asn1ct_check" 396 | "asn1ct_constructed_ber_bin_v2" 397 | "asn1ct_constructed_per" 398 | "asn1ct_eval_ext" 399 | "asn1ct_func" 400 | "asn1ct_gen" 401 | "asn1ct_gen_ber_bin_v2" 402 | "asn1ct_gen_check" 403 | "asn1ct_gen_jer" 404 | "asn1ct_gen_per" 405 | "asn1ct_imm" 406 | "asn1ct_name" 407 | "asn1ct_parser2" 408 | "asn1ct_pretty_format" 409 | "asn1ct_rtt" 410 | "asn1ct_table" 411 | "asn1ct_tok" 412 | "asn1ct_value" 413 | "asn1rt_nif" 414 | "atomics" 415 | "auth" 416 | "base64" 417 | "beam_a" 418 | "beam_asm" 419 | "beam_block" 420 | "beam_bounds" 421 | "beam_call_types" 422 | "beam_clean" 423 | "beam_dict" 424 | "beam_digraph" 425 | "beam_disasm" 426 | "beam_flatten" 427 | "beam_jump" 428 | "beam_kernel_to_ssa" 429 | "beam_lib" 430 | "beam_listing" 431 | "beam_opcodes" 432 | "beam_ssa" 433 | "beam_ssa_alias" 434 | "beam_ssa_bc_size" 435 | "beam_ssa_bool" 436 | "beam_ssa_bsm" 437 | "beam_ssa_check" 438 | "beam_ssa_codegen" 439 | "beam_ssa_dead" 440 | "beam_ssa_lint" 441 | "beam_ssa_opt" 442 | "beam_ssa_pp" 443 | "beam_ssa_pre_codegen" 444 | "beam_ssa_private_append" 445 | "beam_ssa_recv" 446 | "beam_ssa_share" 447 | "beam_ssa_throw" 448 | "beam_ssa_type" 449 | "beam_trim" 450 | "beam_types" 451 | "beam_utils" 452 | "beam_validator" 453 | "beam_z" 454 | "binary" 455 | "c" 456 | "calendar" 457 | "cdv_atom_cb" 458 | "cdv_bin_cb" 459 | "cdv_detail_wx" 460 | "cdv_dist_cb" 461 | "cdv_ets_cb" 462 | "cdv_fun_cb" 463 | "cdv_gen_cb" 464 | "cdv_html_wx" 465 | "cdv_info_wx" 466 | "cdv_int_tab_cb" 467 | "cdv_mem_cb" 468 | "cdv_mod_cb" 469 | "cdv_multi_wx" 470 | "cdv_persistent_cb" 471 | "cdv_port_cb" 472 | "cdv_proc_cb" 473 | "cdv_sched_cb" 474 | "cdv_table_wx" 475 | "cdv_term_cb" 476 | "cdv_timer_cb" 477 | "cdv_virtual_list_wx" 478 | "cdv_wx" 479 | "cerl" 480 | "cerl_clauses" 481 | "cerl_inline" 482 | "cerl_prettypr" 483 | "cerl_trees" 484 | "code" 485 | "code_server" 486 | "compile" 487 | "core_lib" 488 | "core_lint" 489 | "core_parse" 490 | "core_pp" 491 | "core_scan" 492 | "counters" 493 | "cover" 494 | "cprof" 495 | "cpu_sup" 496 | "crashdump_viewer" 497 | "crypto" 498 | "crypto_ec_curves" 499 | "ct" 500 | "ct_config" 501 | "ct_config_plain" 502 | "ct_config_xml" 503 | "ct_conn_log_h" 504 | "ct_cover" 505 | "ct_default_gl" 506 | "ct_event" 507 | "ct_framework" 508 | "ct_ftp" 509 | "ct_gen_conn" 510 | "ct_groups" 511 | "ct_hooks" 512 | "ct_hooks_lock" 513 | "ct_logs" 514 | "ct_make" 515 | "ct_master" 516 | "ct_master_event" 517 | "ct_master_logs" 518 | "ct_master_status" 519 | "ct_netconfc" 520 | "ct_property_test" 521 | "ct_release_test" 522 | "ct_repeat" 523 | "ct_rpc" 524 | "ct_run" 525 | "ct_slave" 526 | "ct_snmp" 527 | "ct_ssh" 528 | "ct_suite" 529 | "ct_telnet" 530 | "ct_telnet_client" 531 | "ct_testspec" 532 | "ct_util" 533 | "cth_conn_log" 534 | "cth_log_redirect" 535 | "cth_surefire" 536 | "dbg" 537 | "dbg_debugged" 538 | "dbg_icmd" 539 | "dbg_idb" 540 | "dbg_ieval" 541 | "dbg_iload" 542 | "dbg_iserver" 543 | "dbg_istk" 544 | "dbg_wx_break" 545 | "dbg_wx_break_win" 546 | "dbg_wx_code" 547 | "dbg_wx_filedialog_win" 548 | "dbg_wx_interpret" 549 | "dbg_wx_mon" 550 | "dbg_wx_mon_win" 551 | "dbg_wx_settings" 552 | "dbg_wx_src_view" 553 | "dbg_wx_trace" 554 | "dbg_wx_trace_win" 555 | "dbg_wx_view" 556 | "dbg_wx_win" 557 | "dbg_wx_winman" 558 | "debugger" 559 | "dets" 560 | "dets_server" 561 | "dets_sup" 562 | "dets_utils" 563 | "dets_v9" 564 | "dialyzer" 565 | "dialyzer_analysis_callgraph" 566 | "dialyzer_behaviours" 567 | "dialyzer_callgraph" 568 | "dialyzer_cl" 569 | "dialyzer_cl_parse" 570 | "dialyzer_clean_core" 571 | "dialyzer_codeserver" 572 | "dialyzer_contracts" 573 | "dialyzer_coordinator" 574 | "dialyzer_cplt" 575 | "dialyzer_dataflow" 576 | "dialyzer_dep" 577 | "dialyzer_dot" 578 | "dialyzer_explanation" 579 | "dialyzer_gui_wx" 580 | "dialyzer_incremental" 581 | "dialyzer_iplt" 582 | "dialyzer_options" 583 | "dialyzer_plt" 584 | "dialyzer_succ_typings" 585 | "dialyzer_timing" 586 | "dialyzer_typegraph" 587 | "dialyzer_typesig" 588 | "dialyzer_utils" 589 | "dialyzer_worker" 590 | "diameter" 591 | "diameter_app" 592 | "diameter_callback" 593 | "diameter_capx" 594 | "diameter_codec" 595 | "diameter_codegen" 596 | "diameter_config" 597 | "diameter_config_sup" 598 | "diameter_dbg" 599 | "diameter_dict_parser" 600 | "diameter_dict_scanner" 601 | "diameter_dict_util" 602 | "diameter_dist" 603 | "diameter_etcp" 604 | "diameter_etcp_sup" 605 | "diameter_exprecs" 606 | "diameter_gen" 607 | "diameter_gen_acct_rfc6733" 608 | "diameter_gen_base_accounting" 609 | "diameter_gen_base_rfc3588" 610 | "diameter_gen_base_rfc6733" 611 | "diameter_gen_doic_rfc7683" 612 | "diameter_gen_relay" 613 | "diameter_info" 614 | "diameter_lib" 615 | "diameter_make" 616 | "diameter_misc_sup" 617 | "diameter_peer" 618 | "diameter_peer_fsm" 619 | "diameter_peer_fsm_sup" 620 | "diameter_reg" 621 | "diameter_sctp" 622 | "diameter_sctp_sup" 623 | "diameter_service" 624 | "diameter_service_sup" 625 | "diameter_session" 626 | "diameter_stats" 627 | "diameter_sup" 628 | "diameter_sync" 629 | "diameter_tcp" 630 | "diameter_tcp_sup" 631 | "diameter_traffic" 632 | "diameter_transport" 633 | "diameter_transport_sup" 634 | "diameter_types" 635 | "diameter_watchdog" 636 | "diameter_watchdog_sup" 637 | "dict" 638 | "digraph" 639 | "digraph_utils" 640 | "disk_log" 641 | "disk_log_1" 642 | "disk_log_server" 643 | "disk_log_sup" 644 | "disksup" 645 | "dist_ac" 646 | "dist_util" 647 | "docgen_edoc_xml_cb" 648 | "docgen_otp_specs" 649 | "docgen_xmerl_xml_cb" 650 | "docgen_xml_to_chunk" 651 | "dtls_connection" 652 | "dtls_connection_sup" 653 | "dtls_gen_connection" 654 | "dtls_handshake" 655 | "dtls_listener_sup" 656 | "dtls_packet_demux" 657 | "dtls_record" 658 | "dtls_server_session_cache_sup" 659 | "dtls_server_sup" 660 | "dtls_socket" 661 | "dtls_sup" 662 | "dtls_v1" 663 | "dyntrace" 664 | "edlin" 665 | "edlin_context" 666 | "edlin_expand" 667 | "edlin_key" 668 | "edlin_type_suggestion" 669 | "edoc" 670 | "edoc_cli" 671 | "edoc_data" 672 | "edoc_doclet" 673 | "edoc_doclet_chunks" 674 | "edoc_extract" 675 | "edoc_layout" 676 | "edoc_layout_chunks" 677 | "edoc_lib" 678 | "edoc_macros" 679 | "edoc_parser" 680 | "edoc_refs" 681 | "edoc_report" 682 | "edoc_run" 683 | "edoc_scanner" 684 | "edoc_specs" 685 | "edoc_tags" 686 | "edoc_types" 687 | "edoc_wiki" 688 | "eldap" 689 | "epp" 690 | "epp_dodger" 691 | "eprof" 692 | "erl2html2" 693 | "erl_abstract_code" 694 | "erl_anno" 695 | "erl_bif_types" 696 | "erl_bifs" 697 | "erl_bits" 698 | "erl_boot_server" 699 | "erl_comment_scan" 700 | "erl_compile" 701 | "erl_compile_server" 702 | "erl_ddll" 703 | "erl_distribution" 704 | "erl_epmd" 705 | "erl_error" 706 | "erl_erts_errors" 707 | "erl_eval" 708 | "erl_expand_records" 709 | "erl_features" 710 | "erl_init" 711 | "erl_internal" 712 | "erl_kernel_errors" 713 | "erl_lint" 714 | "erl_parse" 715 | "erl_posix_msg" 716 | "erl_pp" 717 | "erl_prettypr" 718 | "erl_prim_loader" 719 | "erl_recomment" 720 | "erl_reply" 721 | "erl_scan" 722 | "erl_signal_handler" 723 | "erl_stdlib_errors" 724 | "erl_syntax" 725 | "erl_syntax_lib" 726 | "erl_tar" 727 | "erl_tracer" 728 | "erl_types" 729 | "erlang" 730 | "erlsrv" 731 | "erpc" 732 | "error_handler" 733 | "error_logger" 734 | "error_logger_file_h" 735 | "error_logger_tty_h" 736 | "erts_alloc_config" 737 | "erts_code_purger" 738 | "erts_debug" 739 | "erts_dirty_process_signal_handler" 740 | "erts_internal" 741 | "erts_literal_area_collector" 742 | "escript" 743 | "et" 744 | "et_collector" 745 | "et_selector" 746 | "et_viewer" 747 | "et_wx_contents_viewer" 748 | "et_wx_viewer" 749 | "etop" 750 | "etop_tr" 751 | "etop_txt" 752 | "ets" 753 | "eunit" 754 | "eunit_autoexport" 755 | "eunit_data" 756 | "eunit_lib" 757 | "eunit_listener" 758 | "eunit_proc" 759 | "eunit_serial" 760 | "eunit_server" 761 | "eunit_striptests" 762 | "eunit_surefire" 763 | "eunit_test" 764 | "eunit_tests" 765 | "eunit_tty" 766 | "eval_bits" 767 | "file" 768 | "file_io_server" 769 | "file_server" 770 | "file_sorter" 771 | "filelib" 772 | "filename" 773 | "format_lib_supp" 774 | "fprof" 775 | "ftp" 776 | "ftp_app" 777 | "ftp_internal" 778 | "ftp_progress" 779 | "ftp_response" 780 | "ftp_sup" 781 | "gb_sets" 782 | "gb_trees" 783 | "gen" 784 | "gen_event" 785 | "gen_fsm" 786 | "gen_sctp" 787 | "gen_server" 788 | "gen_statem" 789 | "gen_tcp" 790 | "gen_tcp_socket" 791 | "gen_udp" 792 | "gen_udp_socket" 793 | "gl" 794 | "global" 795 | "global_group" 796 | "global_search" 797 | "glu" 798 | "group" 799 | "group_history" 800 | "heart" 801 | "http_chunk" 802 | "http_request" 803 | "http_response" 804 | "http_transport" 805 | "http_uri" 806 | "http_util" 807 | "httpc" 808 | "httpc_cookie" 809 | "httpc_handler" 810 | "httpc_handler_sup" 811 | "httpc_manager" 812 | "httpc_profile_sup" 813 | "httpc_request" 814 | "httpc_response" 815 | "httpc_sup" 816 | "httpd" 817 | "httpd_acceptor" 818 | "httpd_acceptor_sup" 819 | "httpd_cgi" 820 | "httpd_conf" 821 | "httpd_connection_sup" 822 | "httpd_custom" 823 | "httpd_custom_api" 824 | "httpd_esi" 825 | "httpd_example" 826 | "httpd_file" 827 | "httpd_instance_sup" 828 | "httpd_log" 829 | "httpd_logger" 830 | "httpd_manager" 831 | "httpd_misc_sup" 832 | "httpd_request" 833 | "httpd_request_handler" 834 | "httpd_response" 835 | "httpd_script_env" 836 | "httpd_socket" 837 | "httpd_sup" 838 | "httpd_util" 839 | "i" 840 | "inet" 841 | "inet6_sctp" 842 | "inet6_tcp" 843 | "inet6_tcp_dist" 844 | "inet6_tls_dist" 845 | "inet6_udp" 846 | "inet_config" 847 | "inet_db" 848 | "inet_dns" 849 | "inet_epmd_dist" 850 | "inet_epmd_socket" 851 | "inet_gethost_native" 852 | "inet_hosts" 853 | "inet_parse" 854 | "inet_res" 855 | "inet_sctp" 856 | "inet_tcp" 857 | "inet_tcp_dist" 858 | "inet_tls_dist" 859 | "inet_udp" 860 | "inets" 861 | "inets_app" 862 | "inets_lib" 863 | "inets_service" 864 | "inets_sup" 865 | "inets_trace" 866 | "init" 867 | "instrument" 868 | "int" 869 | "io" 870 | "io_lib" 871 | "io_lib_format" 872 | "io_lib_fread" 873 | "io_lib_pretty" 874 | "json" 875 | "kernel" 876 | "kernel_config" 877 | "kernel_refc" 878 | "lcnt" 879 | "leex" 880 | "lists" 881 | "local_tcp" 882 | "local_udp" 883 | "log_mf_h" 884 | "logger" 885 | "logger_backend" 886 | "logger_config" 887 | "logger_disk_log_h" 888 | "logger_filters" 889 | "logger_formatter" 890 | "logger_h_common" 891 | "logger_handler_watcher" 892 | "logger_olp" 893 | "logger_proxy" 894 | "logger_server" 895 | "logger_simple_h" 896 | "logger_std_h" 897 | "logger_sup" 898 | "make" 899 | "maps" 900 | "math" 901 | "megaco" 902 | "megaco_ber_encoder" 903 | "megaco_ber_media_gateway_control_v1" 904 | "megaco_ber_media_gateway_control_v2" 905 | "megaco_ber_media_gateway_control_v3" 906 | "megaco_binary_encoder" 907 | "megaco_binary_encoder_lib" 908 | "megaco_binary_name_resolver_v1" 909 | "megaco_binary_name_resolver_v2" 910 | "megaco_binary_name_resolver_v3" 911 | "megaco_binary_term_id" 912 | "megaco_binary_term_id_gen" 913 | "megaco_binary_transformer_v1" 914 | "megaco_binary_transformer_v2" 915 | "megaco_binary_transformer_v3" 916 | "megaco_compact_text_encoder" 917 | "megaco_compact_text_encoder_v1" 918 | "megaco_compact_text_encoder_v2" 919 | "megaco_compact_text_encoder_v3" 920 | "megaco_config" 921 | "megaco_config_misc" 922 | "megaco_digit_map" 923 | "megaco_edist_compress" 924 | "megaco_encoder" 925 | "megaco_erl_dist_encoder" 926 | "megaco_erl_dist_encoder_mc" 927 | "megaco_filter" 928 | "megaco_flex_scanner" 929 | "megaco_flex_scanner_handler" 930 | "megaco_messenger" 931 | "megaco_messenger_misc" 932 | "megaco_misc_sup" 933 | "megaco_monitor" 934 | "megaco_per_encoder" 935 | "megaco_per_media_gateway_control_v1" 936 | "megaco_per_media_gateway_control_v2" 937 | "megaco_per_media_gateway_control_v3" 938 | "megaco_pretty_text_encoder" 939 | "megaco_pretty_text_encoder_v1" 940 | "megaco_pretty_text_encoder_v2" 941 | "megaco_pretty_text_encoder_v3" 942 | "megaco_sdp" 943 | "megaco_stats" 944 | "megaco_sup" 945 | "megaco_tcp" 946 | "megaco_tcp_accept" 947 | "megaco_tcp_accept_sup" 948 | "megaco_tcp_connection" 949 | "megaco_tcp_connection_sup" 950 | "megaco_tcp_sup" 951 | "megaco_text_mini_decoder" 952 | "megaco_text_mini_parser" 953 | "megaco_text_parser_v1" 954 | "megaco_text_parser_v2" 955 | "megaco_text_parser_v3" 956 | "megaco_text_scanner" 957 | "megaco_timer" 958 | "megaco_trans_sender" 959 | "megaco_trans_sup" 960 | "megaco_transport" 961 | "megaco_udp" 962 | "megaco_udp_server" 963 | "megaco_udp_sup" 964 | "megaco_user" 965 | "megaco_user_default" 966 | "memsup" 967 | "merl" 968 | "merl_transform" 969 | "misc_supp" 970 | "mnesia" 971 | "mnesia_app" 972 | "mnesia_backend_type" 973 | "mnesia_backup" 974 | "mnesia_bup" 975 | "mnesia_checkpoint" 976 | "mnesia_checkpoint_sup" 977 | "mnesia_controller" 978 | "mnesia_dumper" 979 | "mnesia_event" 980 | "mnesia_ext_sup" 981 | "mnesia_frag" 982 | "mnesia_frag_hash" 983 | "mnesia_index" 984 | "mnesia_kernel_sup" 985 | "mnesia_late_loader" 986 | "mnesia_lib" 987 | "mnesia_loader" 988 | "mnesia_locker" 989 | "mnesia_log" 990 | "mnesia_monitor" 991 | "mnesia_recover" 992 | "mnesia_registry" 993 | "mnesia_rpc" 994 | "mnesia_schema" 995 | "mnesia_snmp_hook" 996 | "mnesia_sp" 997 | "mnesia_subscr" 998 | "mnesia_sup" 999 | "mnesia_text" 1000 | "mnesia_tm" 1001 | "mod_actions" 1002 | "mod_alias" 1003 | "mod_auth" 1004 | "mod_auth_dets" 1005 | "mod_auth_mnesia" 1006 | "mod_auth_plain" 1007 | "mod_auth_server" 1008 | "mod_cgi" 1009 | "mod_dir" 1010 | "mod_disk_log" 1011 | "mod_esi" 1012 | "mod_get" 1013 | "mod_head" 1014 | "mod_log" 1015 | "mod_range" 1016 | "mod_responsecontrol" 1017 | "mod_security" 1018 | "mod_security_server" 1019 | "mod_trace" 1020 | "ms_transform" 1021 | "msacc" 1022 | "net" 1023 | "net_adm" 1024 | "net_kernel" 1025 | "nteventlog" 1026 | "observer" 1027 | "observer_alloc_wx" 1028 | "observer_app_wx" 1029 | "observer_backend" 1030 | "observer_html_lib" 1031 | "observer_lib" 1032 | "observer_perf_wx" 1033 | "observer_port_wx" 1034 | "observer_pro_wx" 1035 | "observer_procinfo" 1036 | "observer_sock_wx" 1037 | "observer_sys_wx" 1038 | "observer_trace_wx" 1039 | "observer_traceoptions_wx" 1040 | "observer_tv_table" 1041 | "observer_tv_wx" 1042 | "observer_wx" 1043 | "orddict" 1044 | "ordsets" 1045 | "os" 1046 | "os_mon" 1047 | "os_mon_mib" 1048 | "os_mon_sysinfo" 1049 | "os_sup" 1050 | "otp_internal" 1051 | "peer" 1052 | "persistent_term" 1053 | "pg" 1054 | "pg2" 1055 | "pool" 1056 | "prettypr" 1057 | "prim_buffer" 1058 | "prim_eval" 1059 | "prim_file" 1060 | "prim_inet" 1061 | "prim_net" 1062 | "prim_socket" 1063 | "prim_tty" 1064 | "prim_zip" 1065 | "proc_lib" 1066 | "proplists" 1067 | "pubkey_cert" 1068 | "pubkey_cert_records" 1069 | "pubkey_crl" 1070 | "pubkey_ocsp" 1071 | "pubkey_os_cacerts" 1072 | "pubkey_pbe" 1073 | "pubkey_pem" 1074 | "pubkey_policy_tree" 1075 | "pubkey_ssh" 1076 | "public_key" 1077 | "qlc" 1078 | "qlc_pt" 1079 | "queue" 1080 | "ram_file" 1081 | "rand" 1082 | "random" 1083 | "raw_file_io" 1084 | "raw_file_io_compressed" 1085 | "raw_file_io_deflate" 1086 | "raw_file_io_delayed" 1087 | "raw_file_io_inflate" 1088 | "raw_file_io_list" 1089 | "rb" 1090 | "rb_format_supp" 1091 | "re" 1092 | "rec_env" 1093 | "release_handler" 1094 | "release_handler_1" 1095 | "reltool" 1096 | "reltool_app_win" 1097 | "reltool_fgraph" 1098 | "reltool_fgraph_win" 1099 | "reltool_mod_win" 1100 | "reltool_server" 1101 | "reltool_sys_win" 1102 | "reltool_target" 1103 | "reltool_utils" 1104 | "rpc" 1105 | "runtime_tools" 1106 | "runtime_tools_sup" 1107 | "sasl" 1108 | "sasl_report" 1109 | "sasl_report_file_h" 1110 | "sasl_report_tty_h" 1111 | "scheduler" 1112 | "seq_trace" 1113 | "sets" 1114 | "shell" 1115 | "shell_default" 1116 | "shell_docs" 1117 | "slave" 1118 | "snmp" 1119 | "snmp_app" 1120 | "snmp_app_sup" 1121 | "snmp_community_mib" 1122 | "snmp_conf" 1123 | "snmp_config" 1124 | "snmp_framework_mib" 1125 | "snmp_generic" 1126 | "snmp_generic_mnesia" 1127 | "snmp_index" 1128 | "snmp_log" 1129 | "snmp_mini_mib" 1130 | "snmp_misc" 1131 | "snmp_note_store" 1132 | "snmp_notification_mib" 1133 | "snmp_pdus" 1134 | "snmp_shadow_table" 1135 | "snmp_standard_mib" 1136 | "snmp_target_mib" 1137 | "snmp_user_based_sm_mib" 1138 | "snmp_usm" 1139 | "snmp_verbosity" 1140 | "snmp_view_based_acm_mib" 1141 | "snmpa" 1142 | "snmpa_acm" 1143 | "snmpa_agent" 1144 | "snmpa_agent_sup" 1145 | "snmpa_app" 1146 | "snmpa_authentication_service" 1147 | "snmpa_conf" 1148 | "snmpa_discovery_handler" 1149 | "snmpa_discovery_handler_default" 1150 | "snmpa_error" 1151 | "snmpa_error_io" 1152 | "snmpa_error_logger" 1153 | "snmpa_error_report" 1154 | "snmpa_get" 1155 | "snmpa_get_lib" 1156 | "snmpa_get_mechanism" 1157 | "snmpa_local_db" 1158 | "snmpa_mib" 1159 | "snmpa_mib_data" 1160 | "snmpa_mib_data_tttn" 1161 | "snmpa_mib_lib" 1162 | "snmpa_mib_storage" 1163 | "snmpa_mib_storage_dets" 1164 | "snmpa_mib_storage_ets" 1165 | "snmpa_mib_storage_mnesia" 1166 | "snmpa_misc_sup" 1167 | "snmpa_mpd" 1168 | "snmpa_net_if" 1169 | "snmpa_net_if_filter" 1170 | "snmpa_network_interface" 1171 | "snmpa_network_interface_filter" 1172 | "snmpa_notification_delivery_info_receiver" 1173 | "snmpa_notification_filter" 1174 | "snmpa_set" 1175 | "snmpa_set_lib" 1176 | "snmpa_set_mechanism" 1177 | "snmpa_supervisor" 1178 | "snmpa_svbl" 1179 | "snmpa_symbolic_store" 1180 | "snmpa_target_cache" 1181 | "snmpa_trap" 1182 | "snmpa_usm" 1183 | "snmpa_vacm" 1184 | "snmpc" 1185 | "snmpc_lib" 1186 | "snmpc_mib_gram" 1187 | "snmpc_mib_to_hrl" 1188 | "snmpc_misc" 1189 | "snmpc_tok" 1190 | "snmpm" 1191 | "snmpm_conf" 1192 | "snmpm_config" 1193 | "snmpm_misc_sup" 1194 | "snmpm_mpd" 1195 | "snmpm_net_if" 1196 | "snmpm_net_if_filter" 1197 | "snmpm_net_if_mt" 1198 | "snmpm_network_interface" 1199 | "snmpm_network_interface_filter" 1200 | "snmpm_server" 1201 | "snmpm_server_sup" 1202 | "snmpm_supervisor" 1203 | "snmpm_user" 1204 | "snmpm_user_default" 1205 | "snmpm_user_old" 1206 | "snmpm_usm" 1207 | "socket" 1208 | "socket_registry" 1209 | "sofs" 1210 | "ssh" 1211 | "ssh_acceptor" 1212 | "ssh_acceptor_sup" 1213 | "ssh_agent" 1214 | "ssh_app" 1215 | "ssh_auth" 1216 | "ssh_bits" 1217 | "ssh_channel" 1218 | "ssh_channel_sup" 1219 | "ssh_cli" 1220 | "ssh_client_channel" 1221 | "ssh_client_key_api" 1222 | "ssh_connection" 1223 | "ssh_connection_handler" 1224 | "ssh_daemon_channel" 1225 | "ssh_dbg" 1226 | "ssh_file" 1227 | "ssh_fsm_kexinit" 1228 | "ssh_fsm_userauth_client" 1229 | "ssh_fsm_userauth_server" 1230 | "ssh_info" 1231 | "ssh_io" 1232 | "ssh_lib" 1233 | "ssh_message" 1234 | "ssh_no_io" 1235 | "ssh_options" 1236 | "ssh_server_channel" 1237 | "ssh_server_key_api" 1238 | "ssh_sftp" 1239 | "ssh_sftpd" 1240 | "ssh_sftpd_file" 1241 | "ssh_sftpd_file_api" 1242 | "ssh_shell" 1243 | "ssh_subsystem_sup" 1244 | "ssh_system_sup" 1245 | "ssh_tcpip_forward_acceptor" 1246 | "ssh_tcpip_forward_acceptor_sup" 1247 | "ssh_tcpip_forward_client" 1248 | "ssh_tcpip_forward_srv" 1249 | "ssh_transport" 1250 | "ssh_xfer" 1251 | "ssl" 1252 | "ssl_admin_sup" 1253 | "ssl_alert" 1254 | "ssl_app" 1255 | "ssl_certificate" 1256 | "ssl_cipher" 1257 | "ssl_cipher_format" 1258 | "ssl_client_session_cache_db" 1259 | "ssl_config" 1260 | "ssl_connection_sup" 1261 | "ssl_crl" 1262 | "ssl_crl_cache" 1263 | "ssl_crl_cache_api" 1264 | "ssl_crl_hash_dir" 1265 | "ssl_dh_groups" 1266 | "ssl_dist_admin_sup" 1267 | "ssl_dist_connection_sup" 1268 | "ssl_dist_sup" 1269 | "ssl_gen_statem" 1270 | "ssl_handshake" 1271 | "ssl_listen_tracker_sup" 1272 | "ssl_logger" 1273 | "ssl_manager" 1274 | "ssl_pem_cache" 1275 | "ssl_pkix_db" 1276 | "ssl_record" 1277 | "ssl_server_session_cache" 1278 | "ssl_server_session_cache_db" 1279 | "ssl_server_session_cache_sup" 1280 | "ssl_session" 1281 | "ssl_session_cache_api" 1282 | "ssl_srp_primes" 1283 | "ssl_sup" 1284 | "ssl_trace" 1285 | "ssl_upgrade_server_session_cache_sup" 1286 | "standard_error" 1287 | "string" 1288 | "supervisor" 1289 | "supervisor_bridge" 1290 | "sys" 1291 | "sys_core_alias" 1292 | "sys_core_bsm" 1293 | "sys_core_fold" 1294 | "sys_core_fold_lists" 1295 | "sys_core_inline" 1296 | "sys_core_prepare" 1297 | "sys_messages" 1298 | "sys_pre_attributes" 1299 | "system_information" 1300 | "systools" 1301 | "systools_lib" 1302 | "systools_make" 1303 | "systools_rc" 1304 | "systools_relup" 1305 | "tags" 1306 | "test_server" 1307 | "test_server_ctrl" 1308 | "test_server_gl" 1309 | "test_server_io" 1310 | "test_server_node" 1311 | "test_server_sup" 1312 | "tftp" 1313 | "tftp_app" 1314 | "tftp_binary" 1315 | "tftp_engine" 1316 | "tftp_file" 1317 | "tftp_lib" 1318 | "tftp_logger" 1319 | "tftp_sup" 1320 | "timer" 1321 | "tls_bloom_filter" 1322 | "tls_client_connection_1_3" 1323 | "tls_client_ticket_store" 1324 | "tls_connection" 1325 | "tls_connection_sup" 1326 | "tls_dist_server_sup" 1327 | "tls_dist_sup" 1328 | "tls_dtls_connection" 1329 | "tls_dyn_connection_sup" 1330 | "tls_gen_connection" 1331 | "tls_gen_connection_1_3" 1332 | "tls_handshake" 1333 | "tls_handshake_1_3" 1334 | "tls_record" 1335 | "tls_record_1_3" 1336 | "tls_sender" 1337 | "tls_server_connection_1_3" 1338 | "tls_server_session_ticket" 1339 | "tls_server_session_ticket_sup" 1340 | "tls_server_sup" 1341 | "tls_socket" 1342 | "tls_sup" 1343 | "tls_v1" 1344 | "ttb" 1345 | "ttb_autostart" 1346 | "ttb_et" 1347 | "typer" 1348 | "typer_core" 1349 | "unicode" 1350 | "unicode_util" 1351 | "unix_telnet" 1352 | "uri_string" 1353 | "user_drv" 1354 | "user_sup" 1355 | "v3_core" 1356 | "v3_kernel" 1357 | "v3_kernel_pp" 1358 | "win32reg" 1359 | "wrap_log_reader" 1360 | "wx" 1361 | "wxAcceleratorEntry" 1362 | "wxAcceleratorTable" 1363 | "wxActivateEvent" 1364 | "wxArtProvider" 1365 | "wxAuiDockArt" 1366 | "wxAuiManager" 1367 | "wxAuiManagerEvent" 1368 | "wxAuiNotebook" 1369 | "wxAuiNotebookEvent" 1370 | "wxAuiPaneInfo" 1371 | "wxAuiSimpleTabArt" 1372 | "wxAuiTabArt" 1373 | "wxBitmap" 1374 | "wxBitmapButton" 1375 | "wxBitmapDataObject" 1376 | "wxBookCtrlBase" 1377 | "wxBookCtrlEvent" 1378 | "wxBoxSizer" 1379 | "wxBrush" 1380 | "wxBufferedDC" 1381 | "wxBufferedPaintDC" 1382 | "wxButton" 1383 | "wxCalendarCtrl" 1384 | "wxCalendarDateAttr" 1385 | "wxCalendarEvent" 1386 | "wxCaret" 1387 | "wxCheckBox" 1388 | "wxCheckListBox" 1389 | "wxChildFocusEvent" 1390 | "wxChoice" 1391 | "wxChoicebook" 1392 | "wxClientDC" 1393 | "wxClipboard" 1394 | "wxClipboardTextEvent" 1395 | "wxCloseEvent" 1396 | "wxColourData" 1397 | "wxColourDialog" 1398 | "wxColourPickerCtrl" 1399 | "wxColourPickerEvent" 1400 | "wxComboBox" 1401 | "wxCommandEvent" 1402 | "wxContextMenuEvent" 1403 | "wxControl" 1404 | "wxControlWithItems" 1405 | "wxCursor" 1406 | "wxDC" 1407 | "wxDCOverlay" 1408 | "wxDataObject" 1409 | "wxDateEvent" 1410 | "wxDatePickerCtrl" 1411 | "wxDialog" 1412 | "wxDirDialog" 1413 | "wxDirPickerCtrl" 1414 | "wxDisplay" 1415 | "wxDisplayChangedEvent" 1416 | "wxDropFilesEvent" 1417 | "wxEraseEvent" 1418 | "wxEvent" 1419 | "wxEvtHandler" 1420 | "wxFileDataObject" 1421 | "wxFileDialog" 1422 | "wxFileDirPickerEvent" 1423 | "wxFilePickerCtrl" 1424 | "wxFindReplaceData" 1425 | "wxFindReplaceDialog" 1426 | "wxFlexGridSizer" 1427 | "wxFocusEvent" 1428 | "wxFont" 1429 | "wxFontData" 1430 | "wxFontDialog" 1431 | "wxFontPickerCtrl" 1432 | "wxFontPickerEvent" 1433 | "wxFrame" 1434 | "wxGBSizerItem" 1435 | "wxGCDC" 1436 | "wxGLCanvas" 1437 | "wxGLContext" 1438 | "wxGauge" 1439 | "wxGenericDirCtrl" 1440 | "wxGraphicsBrush" 1441 | "wxGraphicsContext" 1442 | "wxGraphicsFont" 1443 | "wxGraphicsGradientStops" 1444 | "wxGraphicsMatrix" 1445 | "wxGraphicsObject" 1446 | "wxGraphicsPath" 1447 | "wxGraphicsPen" 1448 | "wxGraphicsRenderer" 1449 | "wxGrid" 1450 | "wxGridBagSizer" 1451 | "wxGridCellAttr" 1452 | "wxGridCellBoolEditor" 1453 | "wxGridCellBoolRenderer" 1454 | "wxGridCellChoiceEditor" 1455 | "wxGridCellEditor" 1456 | "wxGridCellFloatEditor" 1457 | "wxGridCellFloatRenderer" 1458 | "wxGridCellNumberEditor" 1459 | "wxGridCellNumberRenderer" 1460 | "wxGridCellRenderer" 1461 | "wxGridCellStringRenderer" 1462 | "wxGridCellTextEditor" 1463 | "wxGridEvent" 1464 | "wxGridSizer" 1465 | "wxHelpEvent" 1466 | "wxHtmlEasyPrinting" 1467 | "wxHtmlLinkEvent" 1468 | "wxHtmlWindow" 1469 | "wxIcon" 1470 | "wxIconBundle" 1471 | "wxIconizeEvent" 1472 | "wxIdleEvent" 1473 | "wxImage" 1474 | "wxImageList" 1475 | "wxInitDialogEvent" 1476 | "wxJoystickEvent" 1477 | "wxKeyEvent" 1478 | "wxLayoutAlgorithm" 1479 | "wxListBox" 1480 | "wxListCtrl" 1481 | "wxListEvent" 1482 | "wxListItem" 1483 | "wxListItemAttr" 1484 | "wxListView" 1485 | "wxListbook" 1486 | "wxLocale" 1487 | "wxLogNull" 1488 | "wxMDIChildFrame" 1489 | "wxMDIClientWindow" 1490 | "wxMDIParentFrame" 1491 | "wxMask" 1492 | "wxMaximizeEvent" 1493 | "wxMemoryDC" 1494 | "wxMenu" 1495 | "wxMenuBar" 1496 | "wxMenuEvent" 1497 | "wxMenuItem" 1498 | "wxMessageDialog" 1499 | "wxMiniFrame" 1500 | "wxMirrorDC" 1501 | "wxMouseCaptureChangedEvent" 1502 | "wxMouseCaptureLostEvent" 1503 | "wxMouseEvent" 1504 | "wxMoveEvent" 1505 | "wxMultiChoiceDialog" 1506 | "wxNavigationKeyEvent" 1507 | "wxNotebook" 1508 | "wxNotificationMessage" 1509 | "wxNotifyEvent" 1510 | "wxOverlay" 1511 | "wxPageSetupDialog" 1512 | "wxPageSetupDialogData" 1513 | "wxPaintDC" 1514 | "wxPaintEvent" 1515 | "wxPalette" 1516 | "wxPaletteChangedEvent" 1517 | "wxPanel" 1518 | "wxPasswordEntryDialog" 1519 | "wxPen" 1520 | "wxPickerBase" 1521 | "wxPopupTransientWindow" 1522 | "wxPopupWindow" 1523 | "wxPostScriptDC" 1524 | "wxPreviewCanvas" 1525 | "wxPreviewControlBar" 1526 | "wxPreviewFrame" 1527 | "wxPrintData" 1528 | "wxPrintDialog" 1529 | "wxPrintDialogData" 1530 | "wxPrintPreview" 1531 | "wxPrinter" 1532 | "wxPrintout" 1533 | "wxProgressDialog" 1534 | "wxQueryNewPaletteEvent" 1535 | "wxRadioBox" 1536 | "wxRadioButton" 1537 | "wxRegion" 1538 | "wxSashEvent" 1539 | "wxSashLayoutWindow" 1540 | "wxSashWindow" 1541 | "wxScreenDC" 1542 | "wxScrollBar" 1543 | "wxScrollEvent" 1544 | "wxScrollWinEvent" 1545 | "wxScrolledWindow" 1546 | "wxSetCursorEvent" 1547 | "wxShowEvent" 1548 | "wxSingleChoiceDialog" 1549 | "wxSizeEvent" 1550 | "wxSizer" 1551 | "wxSizerFlags" 1552 | "wxSizerItem" 1553 | "wxSlider" 1554 | "wxSpinButton" 1555 | "wxSpinCtrl" 1556 | "wxSpinEvent" 1557 | "wxSplashScreen" 1558 | "wxSplitterEvent" 1559 | "wxSplitterWindow" 1560 | "wxStaticBitmap" 1561 | "wxStaticBox" 1562 | "wxStaticBoxSizer" 1563 | "wxStaticLine" 1564 | "wxStaticText" 1565 | "wxStatusBar" 1566 | "wxStdDialogButtonSizer" 1567 | "wxStyledTextCtrl" 1568 | "wxStyledTextEvent" 1569 | "wxSysColourChangedEvent" 1570 | "wxSystemOptions" 1571 | "wxSystemSettings" 1572 | "wxTaskBarIcon" 1573 | "wxTaskBarIconEvent" 1574 | "wxTextAttr" 1575 | "wxTextCtrl" 1576 | "wxTextDataObject" 1577 | "wxTextEntryDialog" 1578 | "wxToggleButton" 1579 | "wxToolBar" 1580 | "wxToolTip" 1581 | "wxToolbook" 1582 | "wxTopLevelWindow" 1583 | "wxTreeCtrl" 1584 | "wxTreeEvent" 1585 | "wxTreebook" 1586 | "wxUpdateUIEvent" 1587 | "wxWebView" 1588 | "wxWebViewEvent" 1589 | "wxWindow" 1590 | "wxWindowCreateEvent" 1591 | "wxWindowDC" 1592 | "wxWindowDestroyEvent" 1593 | "wxXmlResource" 1594 | "wx_misc" 1595 | "wx_object" 1596 | "wxe_master" 1597 | "wxe_server" 1598 | "wxe_util" 1599 | "xmerl" 1600 | "xmerl_b64Bin" 1601 | "xmerl_b64Bin_scan" 1602 | "xmerl_eventp" 1603 | "xmerl_html" 1604 | "xmerl_lib" 1605 | "xmerl_otpsgml" 1606 | "xmerl_regexp" 1607 | "xmerl_sax_old_dom" 1608 | "xmerl_sax_parser" 1609 | "xmerl_sax_parser_latin1" 1610 | "xmerl_sax_parser_list" 1611 | "xmerl_sax_parser_utf16be" 1612 | "xmerl_sax_parser_utf16le" 1613 | "xmerl_sax_parser_utf8" 1614 | "xmerl_sax_simple_dom" 1615 | "xmerl_scan" 1616 | "xmerl_sgml" 1617 | "xmerl_simple" 1618 | "xmerl_text" 1619 | "xmerl_ucs" 1620 | "xmerl_uri" 1621 | "xmerl_validate" 1622 | "xmerl_xlate" 1623 | "xmerl_xml" 1624 | "xmerl_xpath" 1625 | "xmerl_xpath_lib" 1626 | "xmerl_xpath_parse" 1627 | "xmerl_xpath_pred" 1628 | "xmerl_xpath_scan" 1629 | "xmerl_xs" 1630 | "xmerl_xsd" 1631 | "xmerl_xsd_type" 1632 | "xref" 1633 | "xref_base" 1634 | "xref_compiler" 1635 | "xref_parser" 1636 | "xref_reader" 1637 | "xref_scanner" 1638 | "xref_utils" 1639 | "yecc" 1640 | "yeccparser" 1641 | "yeccscan" 1642 | "zip" 1643 | "zlib" => (), 1644 _ => return Ok(()), 1645 } 1646 1647 Err(Error::GleamModuleWouldOverwriteStandardErlangModule { 1648 name: input.name.clone(), 1649 path: input.path.to_owned(), 1650 }) 1651} 1652#[derive(Debug, Default)] 1653pub struct StaleTracker(HashSet<EcoString>); 1654 1655impl StaleTracker { 1656 fn add(&mut self, name: EcoString) { 1657 _ = self.0.insert(name); 1658 } 1659 1660 fn includes_any(&self, names: &[(EcoString, SrcSpan)]) -> bool { 1661 names.iter().any(|n| self.0.contains(n.0.as_str())) 1662 } 1663 1664 pub fn empty(&mut self) { 1665 let _ = self.0.drain(); // Clears the set but retains allocated memory 1666 } 1667 1668 pub fn is_empty(&self) -> bool { 1669 self.0.is_empty() 1670 } 1671} 1672 1673#[derive(Debug)] 1674pub struct Inputs<'a> { 1675 /// The name of the package for which we're loading the inputs. 1676 package: EcoString, 1677 collection: HashMap<EcoString, (DefinedModuleOrigin, Input)>, 1678 already_defined_modules: &'a mut im::HashMap<EcoString, DefinedModuleOrigin>, 1679} 1680 1681impl<'a> Inputs<'a> { 1682 fn new( 1683 package: EcoString, 1684 already_defined_modules: &'a mut im::HashMap<EcoString, DefinedModuleOrigin>, 1685 ) -> Self { 1686 Self { 1687 package, 1688 collection: HashMap::new(), 1689 already_defined_modules, 1690 } 1691 } 1692 1693 /// Insert a module into the hashmap. If there is already a module with the 1694 /// same name then an error is returned. 1695 fn insert(&mut self, input: Input) -> Result<()> { 1696 let name = input.name().clone(); 1697 1698 let origin = DefinedModuleOrigin { 1699 package_name: self.package.clone(), 1700 path: input.source_path().to_path_buf(), 1701 }; 1702 1703 if let Some(first) = self 1704 .already_defined_modules 1705 .insert(name.clone(), origin.clone()) 1706 { 1707 return Err(Error::DuplicateModule { 1708 module: name.clone(), 1709 first, 1710 second: origin, 1711 }); 1712 } 1713 1714 if let Some((first, _)) = self 1715 .collection 1716 .insert(name.clone(), (origin.clone(), input)) 1717 { 1718 return Err(Error::DuplicateModule { 1719 module: name, 1720 first, 1721 second: origin, 1722 }); 1723 } 1724 1725 Ok(()) 1726 } 1727} 1728 1729/// A Gleam source file (`.gleam`) and the module name deduced from it 1730pub struct GleamFile { 1731 pub path: Utf8PathBuf, 1732 pub module_name: EcoString, 1733} 1734 1735static IS_GLEAM_PATH_PATTERN: OnceLock<Regex> = OnceLock::new(); 1736 1737impl GleamFile { 1738 pub fn new(dir: &Utf8Path, path: Utf8PathBuf) -> Self { 1739 Self { 1740 module_name: Self::module_name(&path, &dir), 1741 path, 1742 } 1743 } 1744 1745 /// Iterates over Gleam source files (`.gleam`) in a certain directory. 1746 /// Symlinks are followed. 1747 /// If the there is a .gleam file with a path that would be an 1748 /// invalid module name it should not be loaded. For example, if it 1749 /// has a uppercase letter in it. 1750 pub fn iterate_files_in_directory<'b>( 1751 io: &'b impl FileSystemReader, 1752 dir: &'b Utf8Path, 1753 ) -> impl Iterator<Item = Result<Self, crate::Warning>> + 'b { 1754 tracing::trace!("gleam_source_files {:?}", dir); 1755 files_with_extension(io, dir, "gleam").map(move |path| { 1756 if (Self::is_gleam_path(&path, &dir)) { 1757 Ok(Self::new(dir, path)) 1758 } else { 1759 Err(crate::Warning::InvalidSource { path }) 1760 } 1761 }) 1762 } 1763 1764 pub fn cache_files(&self, artefact_directory: &Utf8Path) -> CacheFiles { 1765 CacheFiles::new(artefact_directory, &self.module_name) 1766 } 1767 1768 fn module_name(path: &Utf8Path, dir: &Utf8Path) -> EcoString { 1769 // /path/to/project/_build/default/lib/the_package/src/my/module.gleam 1770 1771 // my/module.gleam 1772 let mut module_path = path 1773 .strip_prefix(dir) 1774 .expect("Stripping package prefix from module path") 1775 .to_path_buf(); 1776 1777 // my/module 1778 let _ = module_path.set_extension(""); 1779 1780 // Stringify 1781 let name = module_path.to_string(); 1782 1783 // normalise windows paths 1784 name.replace("\\", "/").into() 1785 } 1786 1787 fn is_gleam_path(path: &Utf8Path, dir: &Utf8Path) -> bool { 1788 IS_GLEAM_PATH_PATTERN 1789 .get_or_init(|| { 1790 Regex::new(&format!( 1791 "^({module}{slash})*{module}\\.gleam$", 1792 module = "[a-z][_a-z0-9]*", 1793 slash = "(/|\\\\)", 1794 )) 1795 .expect("is_gleam_path() RE regex") 1796 }) 1797 .is_match( 1798 path.strip_prefix(dir) 1799 .expect("is_gleam_path(): strip_prefix") 1800 .as_str(), 1801 ) 1802 } 1803} 1804 1805/// The collection of cache files paths related to a module. 1806/// These files are not guaranteed to exist. 1807pub struct CacheFiles { 1808 pub cache_path: Utf8PathBuf, 1809 pub meta_path: Utf8PathBuf, 1810} 1811 1812impl CacheFiles { 1813 pub fn new(artefact_directory: &Utf8Path, module_name: &EcoString) -> Self { 1814 let file_name = module_name.replace("/", "@"); 1815 let cache_path = artefact_directory 1816 .join(file_name.as_str()) 1817 .with_extension("cache"); 1818 let meta_path = artefact_directory 1819 .join(file_name.as_str()) 1820 .with_extension("cache_meta"); 1821 1822 Self { 1823 cache_path, 1824 meta_path, 1825 } 1826 } 1827 1828 pub fn delete(&self, io: &dyn io::FileSystemWriter) -> Result<()> { 1829 io.delete_file(&self.cache_path)?; 1830 io.delete_file(&self.meta_path) 1831 } 1832 1833 /// Iterates over `.cache_meta` files in the given directory, 1834 /// and returns the respective module names. 1835 /// Symlinks are followed. 1836 pub fn modules_with_meta_files<'a>( 1837 io: &'a impl FileSystemReader, 1838 dir: &'a Utf8Path, 1839 ) -> impl Iterator<Item = EcoString> + 'a { 1840 tracing::trace!("CacheFiles::modules_with_meta_files {:?}", dir); 1841 files_with_extension(io, dir, "cache_meta").map(move |path| Self::module_name(&dir, &path)) 1842 } 1843 1844 fn module_name(dir: &Utf8Path, path: &Utf8Path) -> EcoString { 1845 // /path/to/artefact/dir/my@module.cache_meta 1846 1847 // my@module.cache_meta 1848 let mut module_path = path 1849 .strip_prefix(dir) 1850 .expect("Stripping package prefix from module path") 1851 .to_path_buf(); 1852 1853 // my@module 1854 let _ = module_path.set_extension(""); 1855 1856 // my/module 1857 module_path.to_string().replace("@", "/").into() 1858 } 1859}