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

Configure Feed

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

1use crate::{ 2 analyse::TargetSupport, 3 build::{Origin, Target}, 4 config::PackageConfig, 5 javascript::*, 6 uid::UniqueIdGenerator, 7 warning::{TypeWarningEmitter, WarningEmitter}, 8}; 9use camino::{Utf8Path, Utf8PathBuf}; 10 11mod assert; 12mod assignments; 13mod bit_arrays; 14mod blocks; 15mod bools; 16mod case; 17mod case_clause_guards; 18mod consts; 19mod custom_types; 20mod echo; 21mod externals; 22mod functions; 23mod generics; 24mod lists; 25mod modules; 26mod numbers; 27mod panic; 28mod prelude; 29mod records; 30mod recursion; 31mod results; 32mod strings; 33mod todo; 34mod tuples; 35mod type_alias; 36mod use_; 37 38pub static CURRENT_PACKAGE: &str = "thepackage"; 39 40#[macro_export] 41macro_rules! assert_js { 42 ($(($name:literal, $module_src:literal)),+, $src:literal $(,)?) => { 43 let compiled = 44 $crate::javascript::tests::compile_js($src, vec![$(($crate::javascript::tests::CURRENT_PACKAGE, $name, $module_src)),*]); 45 let mut output = String::from("----- SOURCE CODE\n"); 46 for (name, src) in [$(($name, $module_src)),*] { 47 output.push_str(&format!("-- {name}.gleam\n{src}\n\n")); 48 } 49 output.push_str(&format!("-- main.gleam\n{}\n\n----- COMPILED JAVASCRIPT\n{compiled}", $src)); 50 insta::assert_snapshot!(insta::internals::AutoName, output, $src); 51 }; 52 53 (($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr $(,)?) => {{ 54 let compiled = 55 $crate::javascript::tests::compile_js($src, vec![($dep_package, $dep_name, $dep_src)]); 56 let output = format!( 57 "----- SOURCE CODE\n{}\n\n----- COMPILED JAVASCRIPT\n{}", 58 $src, compiled 59 ); 60 insta::assert_snapshot!(insta::internals::AutoName, output, $src); 61 }}; 62 63 (($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr, $js:expr $(,)?) => {{ 64 let output = 65 $crate::javascript::tests::compile_js($src, Some(($dep_package, $dep_name, $dep_src))); 66 assert_eq!(($src, output), ($src, $js.to_string())); 67 }}; 68 69 ($src:expr $(,)?) => {{ 70 let compiled = 71 $crate::javascript::tests::compile_js($src, vec![]); 72 let output = format!( 73 "----- SOURCE CODE\n{}\n\n----- COMPILED JAVASCRIPT\n{}", 74 $src, compiled 75 ); 76 insta::assert_snapshot!(insta::internals::AutoName, output, $src); 77 }}; 78 79 ($src:expr, $js:expr $(,)?) => {{ 80 let output = 81 $crate::javascript::tests::compile_js($src, vec![]); 82 assert_eq!(($src, output), ($src, $js.to_string())); 83 }}; 84} 85 86#[macro_export] 87macro_rules! assert_ts_def { 88 (($dep_1_package:expr, $dep_1_name:expr, $dep_1_src:expr), ($dep_2_package:expr, $dep_2_name:expr, $dep_2_src:expr), $src:expr $(,)?) => {{ 89 let compiled = $crate::javascript::tests::compile_ts( 90 $src, 91 vec![ 92 ($dep_1_package, $dep_1_name, $dep_1_src), 93 ($dep_2_package, $dep_2_name, $dep_2_src), 94 ], 95 ); 96 let output = format!( 97 "----- SOURCE CODE\n{}\n\n----- TYPESCRIPT DEFINITIONS\n{}", 98 $src, compiled 99 ); 100 insta::assert_snapshot!(insta::internals::AutoName, output, $src); 101 }}; 102 103 (($dep_package:expr, $dep_name:expr, $dep_src:expr), $src:expr $(,)?) => {{ 104 let compiled = 105 $crate::javascript::tests::compile_ts($src, vec![($dep_package, $dep_name, $dep_src)]); 106 let output = format!( 107 "----- SOURCE CODE\n{}\n\n----- TYPESCRIPT DEFINITIONS\n{}", 108 $src, compiled 109 ); 110 insta::assert_snapshot!(insta::internals::AutoName, output, $src); 111 }}; 112 113 ($src:expr $(,)?) => {{ 114 let compiled = $crate::javascript::tests::compile_ts($src, vec![]); 115 let output = format!( 116 "----- SOURCE CODE\n{}\n\n----- TYPESCRIPT DEFINITIONS\n{}", 117 $src, compiled 118 ); 119 insta::assert_snapshot!(insta::internals::AutoName, output, $src); 120 }}; 121} 122 123pub fn compile(src: &str, deps: Vec<(&str, &str, &str)>) -> TypedModule { 124 let mut modules = im::HashMap::new(); 125 let ids = UniqueIdGenerator::new(); 126 // DUPE: preludeinsertion 127 // TODO: Currently we do this here and also in the tests. It would be better 128 // to have one place where we create all this required state for use in each 129 // place. 130 let _ = modules.insert( 131 PRELUDE_MODULE_NAME.into(), 132 crate::type_::build_prelude(&ids), 133 ); 134 let mut direct_dependencies = std::collections::HashMap::from_iter(vec![]); 135 136 deps.iter().for_each(|(dep_package, dep_name, dep_src)| { 137 let mut dep_config = PackageConfig::default(); 138 dep_config.name = (*dep_package).into(); 139 let parsed = crate::parse::parse_module( 140 Utf8PathBuf::from("test/path"), 141 dep_src, 142 &WarningEmitter::null(), 143 ) 144 .expect("dep syntax error"); 145 let mut ast = parsed.module; 146 ast.name = (*dep_name).into(); 147 let line_numbers = LineNumbers::new(dep_src); 148 149 let dep = crate::analyse::ModuleAnalyzerConstructor::<()> { 150 target: Target::JavaScript, 151 ids: &ids, 152 origin: Origin::Src, 153 importable_modules: &modules, 154 warnings: &TypeWarningEmitter::null(), 155 direct_dependencies: &std::collections::HashMap::new(), 156 target_support: TargetSupport::Enforced, 157 package_config: &dep_config, 158 } 159 .infer_module(ast, line_numbers, "".into()) 160 .expect("should successfully infer"); 161 let _ = modules.insert((*dep_name).into(), dep.type_info); 162 let _ = direct_dependencies.insert((*dep_package).into(), ()); 163 }); 164 165 let parsed = 166 crate::parse::parse_module(Utf8PathBuf::from("test/path"), src, &WarningEmitter::null()) 167 .expect("syntax error"); 168 let mut ast = parsed.module; 169 ast.name = "my/mod".into(); 170 let line_numbers = LineNumbers::new(src); 171 let mut config = PackageConfig::default(); 172 config.name = "thepackage".into(); 173 174 crate::analyse::ModuleAnalyzerConstructor::<()> { 175 target: Target::JavaScript, 176 ids: &ids, 177 origin: Origin::Src, 178 importable_modules: &modules, 179 warnings: &TypeWarningEmitter::null(), 180 direct_dependencies: &direct_dependencies, 181 target_support: TargetSupport::NotEnforced, 182 package_config: &config, 183 } 184 .infer_module(ast, line_numbers, "src/module.gleam".into()) 185 .expect("should successfully infer") 186} 187 188pub fn compile_js(src: &str, deps: Vec<(&str, &str, &str)>) -> String { 189 let ast = compile(src, deps); 190 let line_numbers = LineNumbers::new(src); 191 let stdlib_package = StdlibPackage::Present; 192 let output = module(ModuleConfig { 193 module: &ast, 194 line_numbers: &line_numbers, 195 src: &"".into(), 196 typescript: TypeScriptDeclarations::None, 197 stdlib_package, 198 path: Utf8Path::new("src/module.gleam"), 199 project_root: "project/root".into(), 200 }); 201 202 output.replace( 203 std::include_str!("../../templates/echo.mjs"), 204 "// ...omitted code from `templates/echo.mjs`...", 205 ) 206} 207 208pub fn compile_ts(src: &str, deps: Vec<(&str, &str, &str)>) -> String { 209 let ast = compile(src, deps); 210 ts_declaration(&ast) 211}