2021-11-03 05:34:38 +01:00
const fs = require ( 'fs/promises' ) ;
const path = require ( 'path' ) ;
const chalk = require ( 'chalk' ) ;
2021-12-16 02:48:46 +01:00
const { program } = require ( 'commander' ) ;
2021-11-03 05:34:38 +01:00
const declarationsPath = path . resolve ( _ _dirname , './isaac-typescript-definitions/typings/' ) ;
const outPath = path . resolve ( _ _dirname , './out/' ) ;
2021-11-04 06:35:56 +01:00
const overridePath = path . resolve ( _ _dirname , './override/' ) ;
2021-11-03 05:34:38 +01:00
2021-12-16 02:48:46 +01:00
program
. name ( 'isaac-lua-definitions-transpiler' )
. version ( '0.0.1' )
. option ( '-W, --no-warn' , 'don\'t show warnings' )
. option ( '-s' , 'don\'t show file info' )
. option ( '-ss' , 'don\'t show files' )
. option ( '-sss' , 'don\'t show anything' )
. option ( '-v' , 'show class names' )
. option ( '-e, --exclude [files...]' , 'don\'t compile specified files' , '' )
. option ( '-o, --only [files...]' , 'only compile specified files' , '' ) ;
program . parse ( process . argv ) ;
const options = program . opts ( ) ;
2021-11-03 07:27:08 +01:00
let classes = { } ;
2021-11-03 09:24:05 +01:00
let tsToLuaTypes = {
undefined : 'nil' ,
unknown : 'any' ,
}
function transpileType ( type ) {
2021-11-03 10:19:28 +01:00
if ( ! type ) return 'what' ;
2021-11-03 09:24:05 +01:00
type = type . trim ( ) ;
if ( type . startsWith ( '(' ) && type . endsWith ( ')' ) ) type = type . slice ( 1 , - 1 ) ;
if ( tsToLuaTypes [ type ] ) {
return tsToLuaTypes [ type ] ;
}
if ( type . endsWith ( '[]' ) ) {
return transpileType ( type . slice ( 0 , - 2 ) ) + '[]' ;
}
2021-11-04 07:15:10 +01:00
if ( type . startsWith ( 'LuaMultiReturn<[' ) && type . endsWith ( ']>' ) ) {
2021-11-10 12:09:30 +01:00
return type . replace ( 'LuaMultiReturn<[' , '' ) . replace ( ']>' , '' ) . split ( ',' ) . map ( t => transpileType ( t . split ( ':' ) [ 1 ] || t ) ) . join ( ', ' ) ;
2021-11-04 07:15:10 +01:00
}
2021-11-03 09:24:05 +01:00
if ( type . includes ( '|' ) ) {
return type . split ( '|' ) . map ( t => transpileType ( t ) ) . join ( ' | ' ) ;
}
2021-11-03 10:19:28 +01:00
if ( type . startsWith ( '"' ) ) {
return 'string' ;
}
if ( type . startsWith ( 'Record<' ) && type . endsWith ( '>' ) ) {
2021-11-03 09:24:05 +01:00
return 'table<' + transpileType ( type . split ( ',' ) [ 0 ] . replace ( 'Record<' , '' ) ) + ', ' + transpileType ( type . split ( ',' ) [ 1 ] . replace ( '>' , '' ) ) + '>' ;
}
2021-11-03 10:19:28 +01:00
if ( type . startsWith ( 'LuaTable<' ) && type . endsWith ( '>' ) ) {
2021-11-03 09:24:05 +01:00
return 'table<' + transpileType ( type . split ( ',' ) [ 0 ] . replace ( 'LuaTable<' , '' ) ) + ', ' + transpileType ( type . split ( ',' ) [ 1 ] . replace ( '>' , '' ) ) + '>' ;
}
let match ;
if ( match = /\((.*?)\) ?=> ?(.*)/ . exec ( type ) ) { // functions
return ` fun( ${ match [ 1 ] !== '' ? match [ 1 ] . split ( ',' ) . map ( c => c . split ( ':' ) [ 0 ] + ':' + transpileType ( c . split ( ':' ) [ 1 ] ) ) . join ( ',' ) : '' } ): ${ transpileType ( match [ 2 ] ) } ` ;
}
if ( match = /(?:Array)|(?:Map)<(.*?)>/ . exec ( type ) ) {
return transpileType ( match [ 1 ] ) + '[]' ;
}
if ( match = /(.*?)<(.*?)>/ . exec ( type ) ) { // any other weird type we just discard
return transpileType ( match [ 2 ] ) ;
}
return type ;
}
2021-12-16 00:31:00 +01:00
function transpile ( parsed , indent , prefix , gl ) {
2021-11-03 05:34:38 +01:00
let global = false ;
indent = indent || 0 ;
const type = parsed [ 0 ] ;
const d = parsed [ 1 ] ;
let n = '\n' + ' ' . repeat ( indent ) ; // newline
2021-11-09 12:37:08 +01:00
const comments = d . comment ? d . comment . split ( '\n' ) . map ( l => l . trim ( ) ) . map ( l => l . startsWith ( '*' ) ? l . replace ( '*' , '' ) : l ) . filter ( l => l . trim ( ) . length !== 0 && ! l . trim ( ) . startsWith ( '@' ) ) . map ( l => '---' + l . trim ( ) ) . join ( '\n' ) + '\n' : '' ;
2021-11-03 05:34:38 +01:00
switch ( type ) {
case 'namespace' :
global = true ;
case 'interface' :
2021-11-03 07:27:08 +01:00
let contents = d . contents ;
if ( d . extends ) {
if ( classes [ d . extends ] ) {
contents . push ( ... classes [ d . extends ] ) ;
} else {
throw new Error ( ` Class not found in class storage: ${ d . extends } ` )
}
}
classes [ d . name ] = contents ;
2022-05-08 23:06:22 +02:00
return ` ${ comments } ---@class ${ d . name } ${ d . extends ? ' : ' + d . extends : '' } ${ n } ${ contents . filter ( e => e [ 0 ] === 'const' ) . map ( c => ` ---@field ${ c [ 1 ] . type . startsWith ( 'Readonly<' ) ? 'protected' : 'public' } ${ c [ 1 ] . name } ${ transpileType ( c [ 1 ] . type ) } ${ n } ` ) . join ( '' ) } ${ global ? '' : '__class_' } ${ d . name } = {} ${ n } ${ contents . filter ( e => e [ 0 ] !== 'const' ) . map ( c => transpile ( c , indent , ` ${ global ? '' : '__class_' } ${ d . name } ` , global ) ) . join ( n ) } \n ` ;
2021-11-03 05:34:38 +01:00
case 'function' :
2021-11-04 11:15:57 +01:00
if ( d . arguments [ 0 ] && d . arguments [ 0 ] . type === 'void' ) d . arguments = d . arguments . slice ( 1 ) ;
2022-01-14 11:08:39 +01:00
return ` ${ comments } ${ d . arguments . map ( p => ` ---@param ${ p . name . replace ( '?' , '' ) } ${ transpileType ( p . type ) } ${ p . comment ? ' @' + p . comment : '' } ${ n } ` ) . join ( '' ) } ---@return ${ transpileType ( d . returns ) } ${ d . returnsComment ? ' @' + d . returnsComment : '' } ${ n } function ${ prefix ? prefix + ( gl ? '.' : ':' ) : '' } ${ d . name } ( ${ d . arguments . map ( a => a . name . replace ( '?' , '' ) ) . join ( ', ' ) } ) end ` ;
2021-11-03 05:34:38 +01:00
case 'const' :
2021-11-09 12:37:08 +01:00
return ` ${ comments } ---@type ${ transpileType ( d . type ) } ${ n } ${ prefix ? prefix + '.' : '' } ${ d . name } = nil ` ;
2021-11-03 05:34:38 +01:00
case 'enum' :
2021-11-09 12:37:08 +01:00
return ` ${ comments } ${ prefix ? prefix + '.' : '' } ${ d . name } = { ${ n } ${ d . contents . map ( c => ` ${ c . name } = ${ c . value } ` ) . join ( ` , ${ n } ` ) } ${ n } } ` ;
2021-11-03 05:34:38 +01:00
}
return '' ;
}
2021-11-03 08:40:28 +01:00
function removeComments ( code ) {
// remove /* */ style comments, for now
code = code . replace ( / \ / \ * ( . * ? ) \ * \ / / g s , ' ' ) ;
code = code . split ( '\n' ) . filter ( c => ! c . trim ( ) . startsWith ( '//' ) ) . join ( '\n' ) ;
return code ;
}
2021-11-03 09:37:52 +01:00
let parsedElements = 0 ;
2021-11-03 05:34:38 +01:00
/ * *
* @ param { string } code
* /
2021-11-09 12:37:08 +01:00
function parse ( code , originalCode ) {
2021-11-03 05:34:38 +01:00
// console.log(code);
// we're left with code containing "declare" statements
// other code will pass stuff in here recursively, but the declare doesnt _really_ matter
// were gonna end up with an ast of sorts anyways as a result, which we can then use instead of declares
// sanitize stuff
2021-11-09 12:37:08 +01:00
if ( ! originalCode ) originalCode = code ;
2021-11-03 08:40:28 +01:00
code = removeComments ( code ) ;
2021-11-03 05:34:38 +01:00
2021-11-03 09:24:05 +01:00
let match ;
2021-11-03 10:53:40 +01:00
let elements = [ ] ;
2021-11-03 05:34:38 +01:00
// look for interfaces
let interfaceFreeCode = code ;
2021-11-03 07:27:08 +01:00
const interface = /interface (\w+)(?: extends (\w+))? ?{([^}]*)}/g ;
2021-11-03 05:34:38 +01:00
while ( ( match = interface . exec ( code ) ) !== null ) {
2021-11-03 09:37:52 +01:00
parsedElements ++ ;
2021-11-03 05:34:38 +01:00
interfaceFreeCode = interfaceFreeCode . replace ( match [ 0 ] , '' ) ;
2021-12-16 02:48:46 +01:00
if ( options . v ) log ( undefined , ' interface ' + chalk . blueBright ( match [ 1 ] ) ) ;
2021-11-09 12:37:08 +01:00
elements . push ( [ 'interface' , { name : match [ 1 ] , extends : match [ 2 ] , contents : parse ( match [ 3 ] , originalCode ) } ] ) ;
2021-11-03 05:34:38 +01:00
}
code = interfaceFreeCode ;
// look for namespaces
let namespaceFreeCode = code ;
const namespace = /namespace (\w+) ?{([^}]*)}/g ;
while ( ( match = namespace . exec ( code ) ) !== null ) {
2021-11-03 09:37:52 +01:00
parsedElements ++ ;
2021-11-03 05:34:38 +01:00
namespaceFreeCode = namespaceFreeCode . replace ( match [ 0 ] , '' ) ;
2021-12-16 02:48:46 +01:00
if ( options . v ) log ( undefined , ' namespace ' + chalk . redBright ( match [ 1 ] ) ) ;
2021-11-09 12:37:08 +01:00
elements . push ( [ 'namespace' , { name : match [ 1 ] , contents : parse ( match [ 2 ] , originalCode ) } ] ) ;
2021-11-03 05:34:38 +01:00
}
code = namespaceFreeCode ;
// look for functions
let functionFreeCode = code ;
2022-05-08 23:06:22 +02:00
const functions = /(function)?\s([\w_]+)\s*\(([^;]*)\)(\s*:\s*([\w\[\]\s|<>,:]+))?/g ; // wow this sucks
2021-11-03 05:34:38 +01:00
while ( ( match = functions . exec ( code ) ) !== null ) {
2021-11-03 09:37:52 +01:00
parsedElements ++ ;
2021-11-03 05:34:38 +01:00
functionFreeCode = functionFreeCode . replace ( match [ 0 ] , '' ) ;
let arguments = match [ 3 ] . split ( ',' ) . map ( s => {
const split = s . split ( ':' ) . map ( s => s . trim ( ) ) ;
return { type : split [ 1 ] , name : split [ 0 ] }
} ) . filter ( c => c . type && c . name ) ;
2021-11-09 12:37:08 +01:00
const origIndex = originalCode . indexOf ( match [ 0 ] ) ;
const comment = / \ / \ * ( . * ? ) \ * \ / / g s ;
let comments = [ ] ;
let comm ;
while ( ( comm = comment . exec ( originalCode . slice ( 0 , origIndex ) ) ) !== null ) {
comments . push ( [ comm [ 1 ] , comm . index + comm [ 0 ] . length ] ) ;
}
comments = comments . filter ( c => Math . abs ( origIndex - c [ 1 ] ) < 10 ) ;
const c = comments . pop ( ) ;
//if (c) c[0] += 'isaac-lua-definitions debug: comment distance = ' + (origIndex - c[1]).toString();
2022-01-14 11:08:39 +01:00
let returnsComment ;
2022-01-14 10:56:07 +01:00
// add parameter comments
if ( c ) {
c [ 0 ] . split ( '\n' ) . map ( l => l . trim ( ) ) . filter ( l => l . startsWith ( '* @param ' ) ) . forEach ( p => {
p = p . slice ( '* @param ' . length ) ;
let indx = arguments . findIndex ( arg => arg . name . replace ( '?' , '' ) . trim ( ) === p . split ( ' ' ) [ 0 ] ) ;
if ( p . split ( ' ' ) [ 1 ] && indx !== - 1 ) {
let comment = p . split ( ' ' ) . slice ( 1 ) . join ( ' ' ) ;
arguments [ indx ] . comment = comment ;
}
2022-01-14 11:08:39 +01:00
} ) ;
// add returns comments, if found
let returns = c [ 0 ] . split ( '\n' ) . map ( l => l . trim ( ) ) . find ( l => l . startsWith ( '* @returns ' ) ) ;
if ( returns ) {
returnsComment = returns . slice ( '* @returns ' . length ) ;
}
2022-01-14 10:56:07 +01:00
}
2022-01-14 11:08:39 +01:00
elements . push ( [ 'function' , { name : match [ 2 ] , arguments : arguments , returns : match [ 5 ] , returnsComment : returnsComment , comment : ( c || [ null ] ) [ 0 ] } ] ) ;
2021-11-03 05:34:38 +01:00
}
code = functionFreeCode ;
// looks for enums
let enumFreeCode = code ;
2022-05-08 23:06:22 +02:00
const enums = /enum ([_\w]+) ?{([^}]*)}/g ;
2021-11-03 05:34:38 +01:00
while ( ( match = enums . exec ( code ) ) !== null ) {
2021-11-03 09:37:52 +01:00
parsedElements ++ ;
2021-11-03 05:34:38 +01:00
enumFreeCode = enumFreeCode . replace ( match [ 0 ] , '' ) ;
2021-11-10 12:10:14 +01:00
const origIndex = originalCode . indexOf ( match [ 0 ] ) ;
const comment = / \ / \ * ( . * ? ) \ * \ / / g s ;
let comments = [ ] ;
let comm ;
while ( ( comm = comment . exec ( originalCode . slice ( 0 , origIndex ) ) ) !== null ) {
comments . push ( [ comm [ 1 ] , comm . index + comm [ 0 ] . length ] ) ;
}
comments = comments . filter ( c => Math . abs ( origIndex - c [ 1 ] ) < 10 ) ;
const c = comments . pop ( ) ;
//if (c) c[0] += 'isaac-lua-definitions debug: comment distance = ' + (origIndex - c[1]).toString();
2021-12-16 02:48:46 +01:00
if ( options . v ) log ( undefined , ' enum ' + chalk . greenBright ( match [ 1 ] ) ) ;
2021-11-10 12:10:14 +01:00
elements . push ( [ 'enum' , { name : match [ 1 ] , contents : match [ 2 ] . split ( ',' ) . filter ( c => c . split ( '=' ) . length === 2 ) . map ( c => { return { name : c . split ( '=' ) [ 0 ] . trim ( ) , value : c . split ( '=' ) [ 1 ] . trim ( ) } } ) , comment : ( c || [ null ] ) [ 0 ] } ] ) ;
2021-11-03 05:34:38 +01:00
}
code = enumFreeCode ;
// looks for constants / properties
let constFreeCode = code ;
2022-05-08 23:06:22 +02:00
const consts = /([\w_]+)\s*:\s*([\w<>\s,]+)/g ;
2021-11-03 05:34:38 +01:00
while ( ( match = consts . exec ( code ) ) !== null ) {
2021-11-03 09:37:52 +01:00
parsedElements ++ ;
2021-11-03 05:34:38 +01:00
constFreeCode = constFreeCode . replace ( match [ 0 ] , '' ) ;
2021-11-10 12:10:14 +01:00
const origIndex = originalCode . indexOf ( match [ 0 ] ) ;
const comment = / \ / \ * ( . * ? ) \ * \ / / g s ;
let comments = [ ] ;
let comm ;
while ( ( comm = comment . exec ( originalCode . slice ( 0 , origIndex ) ) ) !== null ) {
comments . push ( [ comm [ 1 ] , comm . index + comm [ 0 ] . length ] ) ;
}
comments = comments . filter ( c => Math . abs ( origIndex - c [ 1 ] ) < 10 ) ;
const c = comments . pop ( ) ;
//if (c) c[0] += 'isaac-lua-definitions debug: comment distance = ' + (origIndex - c[1]).toString();
elements . push ( [ 'const' , { name : match [ 1 ] , type : match [ 2 ] , comment : ( c || [ null ] ) [ 0 ] } ] ) ;
2021-11-03 05:34:38 +01:00
}
code = constFreeCode ;
2021-11-03 10:53:40 +01:00
elements = elements . sort ( ( a , b ) => b [ 1 ] . extends ? 1 : 0 - a [ 1 ] . extends ? 1 : 0 ) . reverse ( ) ; // for extending bullshit
2021-11-03 05:34:38 +01:00
return elements ;
}
2021-11-04 07:19:28 +01:00
async function recursiveReaddir ( rpath , p ) {
2021-11-03 09:58:21 +01:00
p = p || '' ;
2021-11-04 07:19:28 +01:00
let fileNames = [ ] ;
2021-11-03 09:58:21 +01:00
const files = await fs . readdir ( rpath ) ;
for ( const f of files ) {
const stat = await fs . lstat ( path . join ( rpath , f ) ) ;
if ( stat . isDirectory ( ) || stat . isSymbolicLink ( ) ) {
2021-11-04 07:19:28 +01:00
fileNames . push ( ... await recursiveReaddir ( path . join ( rpath , f ) , p + f + '/' ) ) ;
2021-11-03 09:58:21 +01:00
} else {
fileNames . push ( p + f ) ;
}
}
return fileNames ;
}
2021-12-16 02:48:46 +01:00
let loggedFile = { } ;
function warn ( file , string ) {
if ( ! options . warn ) return ;
if ( options . Sss ) return ;
if ( ! loggedFile [ file ] ) {
console . log ( ` ${ chalk . cyanBright ( file ) } ` ) ;
loggedFile [ file ] = true ;
}
console . log ( ` ${ chalk . redBright ( '!' ) } ${ string } ` ) ;
}
function log ( file , string ) {
if ( options . s && string ) return ;
if ( options . Ss ) return ;
if ( options . Sss ) return ;
if ( file && ! loggedFile [ file ] ) {
console . log ( ` ${ chalk . cyanBright ( file ) } ` ) ;
loggedFile [ file ] = true ;
}
if ( string ) console . log ( ' ' + string ) ;
}
2021-11-03 05:34:38 +01:00
( async ( ) => {
let timeParsing = 0 ;
let timeTotal = 0 ;
try {
const d = await fs . lstat ( outPath )
if ( ! d . isDirectory ( ) ) throw new Error ( ` ${ outPath } exists, and isn't a directory! ` ) ;
} catch ( err ) {
if ( err . code === 'ENOENT' ) {
await fs . mkdir ( outPath ) ;
} else {
console . error ( err ) ;
process . exit ( ) ;
}
}
2021-11-03 07:27:08 +01:00
let errored = [ ] ;
let errorReason = { } ;
2021-12-16 02:48:46 +01:00
const files = ( await recursiveReaddir ( declarationsPath ) ) . filter ( f => {
return ! f . includes ( 'unofficial/' ) && ( options . exclude . length == 0 || ! options . exclude . includes ( f ) ) && ( options . only . length === 0 || options . only . includes ( f ) )
} ) ;
2021-11-03 09:37:52 +01:00
const filesAmt = files . length ;
2021-11-03 07:27:08 +01:00
let i = 0 ;
2021-11-03 05:34:38 +01:00
for ( const f of files ) {
2021-11-03 07:27:08 +01:00
i ++ ;
2021-11-03 05:34:38 +01:00
const filePath = path . resolve ( declarationsPath , f ) ;
2021-12-16 02:48:46 +01:00
if ( ! options . Ss ) log ( f ) ;
2021-11-04 06:35:56 +01:00
const override = path . resolve ( overridePath , f . replace ( '.d.ts' , '.lua' ) ) ;
const luaFilename = f . replace ( '.d.ts' , '.lua' ) . split ( '/' ) . join ( '_' ) ;
try {
if ( await fs . stat ( override ) ) {
2021-12-16 02:48:46 +01:00
log ( 'file exists in override/, ignoring' ) ;
2021-11-04 06:35:56 +01:00
await fs . copyFile ( override , path . resolve ( outPath , luaFilename ) ) ;
continue ;
}
} catch ( err ) { }
2021-11-03 09:58:21 +01:00
const file = await fs . readFile ( filePath , 'utf8' ) ;
2021-11-03 05:34:38 +01:00
2021-11-03 09:58:21 +01:00
let startParse = Date . now ( ) ;
parsedElements = 0 ;
const parsed = parse ( file ) ;
2021-12-16 02:48:46 +01:00
log ( f , ` parsed ${ chalk . magentaBright ( parsedElements ) } objects from ${ chalk . cyanBright ( f ) } ` ) ;
2021-11-03 09:58:21 +01:00
timeParsing += Date . now ( ) - startParse ;
2021-11-03 05:34:38 +01:00
2021-11-03 09:58:21 +01:00
if ( parsed . length === 0 ) {
2021-12-16 02:48:46 +01:00
warn ( f , ` no elements parsed, ${ chalk . gray ( 'not writing anything' ) } ` ) ;
2021-11-03 09:58:21 +01:00
continue ;
}
if ( parsed . length > 10 ) {
2021-12-16 02:48:46 +01:00
warn ( f , ` over 10 top-level objects were parsed - this may be a bad idea ` ) ;
2021-11-03 09:58:21 +01:00
}
2021-11-03 07:27:08 +01:00
2021-11-03 09:58:21 +01:00
let transpiled ;
try {
transpiled = parsed . map ( p => transpile ( p ) ) . join ( '\n' ) . trim ( ) ;
errored = errored . filter ( e => e !== f ) ;
} catch ( err ) {
errorReason [ f ] = err ;
if ( errored . length > files . length - i ) {
console . error ( ` ${ chalk . redBright ( '!' ) } failed resolving extends! ` ) ;
2021-11-03 10:19:28 +01:00
errored = [ ... new Set ( errored ) ] ;
2021-11-03 09:58:21 +01:00
console . error ( ` ${ chalk . redBright ( '!' ) } abandoned ${ chalk . magentaBright ( errored . length ) } files: ` ) ;
let longest = errored . reduce ( ( a , b ) => Math . max ( a . length || a || 0 , b . length ) ) ;
errored . forEach ( e => console . error ( ` - ${ chalk . cyanBright ( e ) } ${ ' ' . repeat ( longest - e . length + 2 ) } ${ chalk . gray ( ' → ' + errorReason [ e ] . message . replace ( 'Class not found in class storage: ' , '' ) ) } ` ) ) ;
break ;
}
2021-11-03 07:27:08 +01:00
2021-11-03 09:58:21 +01:00
console . error ( ` ${ chalk . yellowBright ( '!' ) } ${ err } ` ) ;
console . error ( ` ${ chalk . yellowBright ( '!' ) } pushing to end of queue ` ) ;
files . push ( f ) ;
errored . push ( f ) ;
2021-11-03 07:27:08 +01:00
2021-11-03 05:34:38 +01:00
timeTotal += Date . now ( ) - startParse ;
2021-11-03 09:58:21 +01:00
continue ;
}
2021-12-16 02:48:46 +01:00
log ( f , ` transpiled w/ final length of ${ chalk . magentaBright ( transpiled . length + ' chars' ) } ` ) ;
2021-11-03 09:58:21 +01:00
timeTotal += Date . now ( ) - startParse ;
2021-11-03 05:34:38 +01:00
2021-11-03 09:58:21 +01:00
if ( transpiled . length === 0 ) {
2021-12-16 02:48:46 +01:00
warn ( f , ` nothing transpiled, ${ chalk . gray ( 'not writing anything' ) } ` ) ;
2021-11-03 09:58:21 +01:00
continue ;
2021-11-03 05:34:38 +01:00
}
2021-11-03 09:58:21 +01:00
//console.log(inspect(parsed, false, 10));
await fs . writeFile ( path . resolve ( outPath , luaFilename ) , transpiled ) ;
2021-11-03 10:54:51 +01:00
//console.log(` wrote ${chalk.cyanBright(luaFilename)}`);
2021-11-03 05:34:38 +01:00
}
2021-11-04 06:09:28 +01:00
console . log ( ` \n finished transpiling ${ chalk . magentaBright ( filesAmt ) } ${ chalk . gray ( ` + ${ files . length - filesAmt } ` ) } files in ${ chalk . magentaBright ( timeTotal + 'ms' ) } avg ${ chalk . magentaBright ( ( Math . floor ( timeTotal / filesAmt * 100 ) / 100 ) + 'ms' ) } ${ chalk . gray ( ` ( ${ Math . floor ( timeParsing / timeTotal * 1000 + 0.5 ) / 10 } % spent parsing) ` ) } ` ) ;
console . log ( ` total class cache size: ${ chalk . magentaBright ( Object . keys ( classes ) . length + ' classes' ) } ` )
2021-11-03 05:34:38 +01:00
console . log ( ` check ${ chalk . cyanBright ( outPath ) } ` ) ;
2021-11-19 19:30:29 +01:00
} ) ( ) ;