@@ -11,6 +11,7 @@ use tracing::warn;
1111use url:: Url ;
1212
1313use crate :: {
14+ args:: Target ,
1415 display:: { Handle , ProgressHandle } ,
1516 error,
1617 git:: { clone_fast, Ref } ,
@@ -19,6 +20,7 @@ use crate::{
1920} ;
2021
2122pub const NUM_STEPS : usize = 3 ;
23+ const WASM_EXTENSION : & str = "wasm" ;
2224
2325pub async fn build_languages ( languages : Vec < Language > ) -> Result < ( ) > {
2426 let buffer = if languages. is_empty ( ) {
@@ -57,6 +59,7 @@ pub struct Language {
5759 out_dir : PathBuf ,
5860 prefix : String ,
5961 repo : Url ,
62+ target : Target ,
6063 ts_cli : Arc < PathBuf > ,
6164}
6265
@@ -72,6 +75,7 @@ impl Language {
7275 out_dir : PathBuf ,
7376 prefix : String ,
7477 repo : Url ,
78+ target : Target ,
7579 ts_cli : Arc < PathBuf > ,
7680 ) -> Self {
7781 Language {
@@ -83,6 +87,7 @@ impl Language {
8387 out_dir,
8488 prefix,
8589 repo,
90+ target,
8691 ts_cli,
8792 }
8893 }
@@ -124,7 +129,24 @@ impl Language {
124129 } else {
125130 warn ! ( "I don't know how to generate parsers when a script/cmd is specified (it's typescript's fault)" ) ;
126131 }
127- self . build ( & dir) . await ?;
132+
133+ if self . target . native ( ) {
134+ self . handle . msg ( format ! (
135+ "Building {} native parser: {}" ,
136+ self . git_ref,
137+ dir. file_name( ) . unwrap( ) . to_str( ) . unwrap( ) ,
138+ ) ) ;
139+ self . build ( & dir, DLL_EXTENSION ) . await ?;
140+ }
141+
142+ if self . target . wasm ( ) {
143+ self . handle . msg ( format ! (
144+ "Building {} wasm parser: {}" ,
145+ self . git_ref,
146+ dir. file_name( ) . unwrap( ) . to_str( ) . unwrap( ) ,
147+ ) ) ;
148+ self . build ( & dir, WASM_EXTENSION ) . await ?;
149+ }
128150 self . handle . msg ( format ! (
129151 "Copying {} parser: {}" ,
130152 self . git_ref,
@@ -134,13 +156,25 @@ impl Language {
134156 Ok ( ( ) )
135157 }
136158
137- async fn build ( & self , dir : & Path ) -> Result < ( ) > {
159+ async fn build ( & self , dir : & Path , ext : & str ) -> Result < ( ) > {
160+ let effective_name = dir
161+ . file_name ( )
162+ . map ( |n| {
163+ n. to_string_lossy ( )
164+ . strip_prefix ( "tree-sitter-" )
165+ . map_or_else ( || n. to_string_lossy ( ) . to_string ( ) , str:: to_string)
166+ } )
167+ . unwrap ( ) ;
138168 self . build_script
139169 . as_ref ( )
140170 . map_or_else (
141171 || {
142172 let mut cmd = Command :: new ( & * self . ts_cli ) ;
143173 cmd. arg ( "build" ) ;
174+ if ext == WASM_EXTENSION {
175+ cmd. arg ( "--wasm" ) ;
176+ }
177+ cmd. args ( [ "--output" , & format ! ( "{effective_name}.{ext}" ) ] ) ;
144178 cmd
145179 } ,
146180 |script| Command :: from_str ( script) ,
@@ -197,22 +231,27 @@ impl Language {
197231 . collect ( )
198232 }
199233
200- async fn copy ( & self , dir : impl Into < PathBuf > ) -> Result < ( ) > {
201- let dir = dir . into ( ) ;
202- let prefix = & self . prefix ;
203- let dll = self . find_dll_files ( & dir ) . await ? ;
204- let name = Self :: extract_parser_name ( & dll ) ;
205- let dst = self
206- . out_dir
207- . clone ( )
208- . join ( format ! ( "{prefix}{name}.{DLL_EXTENSION}" ) ) ;
234+ async fn copy ( & self , dir : & Path ) -> Result < ( ) > {
235+ if self . target . native ( ) {
236+ self . do_copy ( dir , DLL_EXTENSION ) . await ? ;
237+ }
238+ if self . target . wasm ( ) {
239+ self . do_copy ( dir , WASM_EXTENSION ) . await ? ;
240+ }
241+ Ok ( ( ) )
242+ }
209243
244+ async fn do_copy ( & self , dir : & Path , ext : & str ) -> Result < ( ) , miette:: Error > {
245+ let dll = self . find_dll_files ( dir, ext) . await ?;
246+ let name = Self :: extract_parser_name ( & dll, ext) ;
247+ let prefix = & self . prefix ;
248+ let dst = self . out_dir . clone ( ) . join ( format ! ( "{prefix}{name}.{ext}" ) ) ;
210249 fs:: copy ( & dll, & dst)
211250 . await
212251 . into_diagnostic ( )
213252 . wrap_err_with ( || format ! ( "cp {} {}" , & dll. display( ) , dst. display( ) ) )
214- . map_err ( |err| self . create_copy_error ( & dll, err. to_string ( ) ) . into ( ) )
215- . and ( Ok ( ( ) ) )
253+ . map_err ( |err| self . create_copy_error ( & dll, err. to_string ( ) ) ) ? ;
254+ Ok ( ( ) )
216255 }
217256
218257 async fn clone ( & self ) -> Result < ( ) > {
@@ -249,37 +288,35 @@ impl Language {
249288 . and ( Ok ( ( ) ) )
250289 }
251290
252- async fn find_dll_files ( & self , dir : & Path ) -> Result < PathBuf > {
291+ async fn find_dll_files ( & self , dir : & Path , ext : & str ) -> Result < PathBuf > {
253292 let mut files = fs:: read_dir ( & dir) . await . unwrap ( ) ;
254293 let mut dlls = Vec :: with_capacity ( 1 ) ;
255294 while let Ok ( Some ( entry) ) = files. next_entry ( ) . await {
256295 let file_name = entry. file_name ( ) ;
257296 let name = file_name. as_os_str ( ) . to_str ( ) . unwrap ( ) ;
258- if entry. file_type ( ) . await . unwrap ( ) . is_file ( )
259- && name. ends_with ( & format ! ( ".{DLL_EXTENSION}" ) )
260- {
297+ if entry. file_type ( ) . await . unwrap ( ) . is_file ( ) && name. ends_with ( & format ! ( ".{ext}" ) ) {
261298 dlls. push ( dir. join ( name) ) ;
262299 }
263300 }
264301 // Error handling for no DLLs or too many DLLs
265302 match dlls. len ( ) {
266303 0 => Err ( self
267- . create_copy_error ( dir, format ! ( "Couldn't find any {DLL_EXTENSION } file" ) )
304+ . create_copy_error ( dir, format ! ( "Couldn't find any {ext } file" ) )
268305 . into ( ) ) ,
269306 n if n > 1 => Err ( self
270- . create_copy_error ( dir, format ! ( "Found many {DLL_EXTENSION } files: {dlls:?}" ) )
307+ . create_copy_error ( dir, format ! ( "Found many {ext } files: {dlls:?}" ) )
271308 . into ( ) ) ,
272309 _ => Ok ( dlls[ 0 ] . clone ( ) ) ,
273310 }
274311 }
275312
276- fn extract_parser_name ( dll_path : & Path ) -> String {
313+ fn extract_parser_name ( dll_path : & Path , ext : & str ) -> String {
277314 let mut name = dll_path
278315 . file_name ( )
279316 . and_then ( |n| n. to_str ( ) )
280317 . map ( String :: from)
281318 . unwrap ( ) ;
282- if name == format ! ( "parser.{DLL_EXTENSION }" ) {
319+ if name == format ! ( "parser.{ext }" ) {
283320 name = dll_path
284321 . parent ( )
285322 . and_then ( |p| p. file_name ( ) )
@@ -290,10 +327,8 @@ impl Language {
290327 if name. starts_with ( "libtree-sitter-" ) {
291328 name = name. trim_start_matches ( "libtree-sitter-" ) . to_string ( ) ;
292329 }
293- if name. ends_with ( & format ! ( ".{DLL_EXTENSION}" ) ) {
294- name = name
295- . trim_end_matches ( & format ! ( ".{DLL_EXTENSION}" ) )
296- . to_string ( ) ;
330+ if name. ends_with ( & format ! ( ".{ext}" ) ) {
331+ name = name. trim_end_matches ( & format ! ( ".{ext}" ) ) . to_string ( ) ;
297332 }
298333 name
299334 }
0 commit comments