11import * as path from "path" ;
22import { EmitHost } from "./transpilation" ;
3+ import * as lua from "./LuaAST" ;
34
45export enum LuaLibFeature {
56 ArrayConcat = "ArrayConcat" ,
@@ -99,81 +100,54 @@ export enum LuaLibFeature {
99100 Unpack = "Unpack" ,
100101}
101102
102- /* eslint-disable @typescript-eslint/naming-convention */
103- const luaLibDependencies : Partial < Record < LuaLibFeature , LuaLibFeature [ ] > > = {
104- ArrayConcat : [ LuaLibFeature . ArrayIsArray ] ,
105- ArrayFlat : [ LuaLibFeature . ArrayConcat , LuaLibFeature . ArrayIsArray ] ,
106- ArrayFlatMap : [ LuaLibFeature . ArrayConcat , LuaLibFeature . ArrayIsArray ] ,
107- Await : [ LuaLibFeature . InstanceOf , LuaLibFeature . New , LuaLibFeature . Promise ] ,
108- Decorate : [ LuaLibFeature . ObjectGetOwnPropertyDescriptor , LuaLibFeature . SetDescriptor , LuaLibFeature . ObjectAssign ] ,
109- DelegatedYield : [ LuaLibFeature . StringAccess ] ,
110- Delete : [ LuaLibFeature . ObjectGetOwnPropertyDescriptors , LuaLibFeature . Error , LuaLibFeature . New ] ,
111- Error : [ LuaLibFeature . Class , LuaLibFeature . ClassExtends , LuaLibFeature . New ] ,
112- FunctionBind : [ LuaLibFeature . Unpack ] ,
113- Generator : [ LuaLibFeature . Symbol ] ,
114- InstanceOf : [ LuaLibFeature . Symbol ] ,
115- Iterator : [ LuaLibFeature . Symbol ] ,
116- NumberToString : [ LuaLibFeature . StringAccess ] ,
117- ObjectDefineProperty : [ LuaLibFeature . CloneDescriptor , LuaLibFeature . SetDescriptor ] ,
118- ObjectFromEntries : [ LuaLibFeature . Iterator , LuaLibFeature . Symbol ] ,
119- Promise : [
120- LuaLibFeature . ArrayPush ,
121- LuaLibFeature . Class ,
122- LuaLibFeature . FunctionBind ,
123- LuaLibFeature . InstanceOf ,
124- LuaLibFeature . New ,
125- ] ,
126- PromiseAll : [ LuaLibFeature . InstanceOf , LuaLibFeature . New , LuaLibFeature . Promise , LuaLibFeature . Iterator ] ,
127- PromiseAllSettled : [ LuaLibFeature . InstanceOf , LuaLibFeature . New , LuaLibFeature . Promise , LuaLibFeature . Iterator ] ,
128- PromiseAny : [
129- LuaLibFeature . ArrayPush ,
130- LuaLibFeature . InstanceOf ,
131- LuaLibFeature . New ,
132- LuaLibFeature . Promise ,
133- LuaLibFeature . Iterator ,
134- ] ,
135- PromiseRace : [
136- LuaLibFeature . ArrayPush ,
137- LuaLibFeature . InstanceOf ,
138- LuaLibFeature . New ,
139- LuaLibFeature . Promise ,
140- LuaLibFeature . Iterator ,
141- ] ,
142- ParseFloat : [ LuaLibFeature . StringAccess ] ,
143- ParseInt : [ LuaLibFeature . StringSubstr , LuaLibFeature . StringSubstring ] ,
144- SetDescriptor : [ LuaLibFeature . CloneDescriptor ] ,
145- Spread : [ LuaLibFeature . Iterator , LuaLibFeature . StringAccess , LuaLibFeature . Unpack ] ,
146- StringSplit : [ LuaLibFeature . StringSubstring , LuaLibFeature . StringAccess ] ,
147- SymbolRegistry : [ LuaLibFeature . Symbol ] ,
148-
149- Map : [ LuaLibFeature . InstanceOf , LuaLibFeature . Iterator , LuaLibFeature . Symbol , LuaLibFeature . Class ] ,
150- Set : [ LuaLibFeature . InstanceOf , LuaLibFeature . Iterator , LuaLibFeature . Symbol , LuaLibFeature . Class ] ,
151- WeakMap : [ LuaLibFeature . InstanceOf , LuaLibFeature . Iterator , LuaLibFeature . Symbol , LuaLibFeature . Class ] ,
152- WeakSet : [ LuaLibFeature . InstanceOf , LuaLibFeature . Iterator , LuaLibFeature . Symbol , LuaLibFeature . Class ] ,
153- } ;
154- /* eslint-enable @typescript-eslint/naming-convention */
155-
156- export function loadLuaLibFeatures ( features : Iterable < LuaLibFeature > , emitHost : EmitHost ) : string {
157- let result = "" ;
103+ export interface LuaLibFeatureInfo {
104+ dependencies ?: LuaLibFeature [ ] ;
105+ exports : string [ ] ;
106+ }
107+ export type LuaLibModulesInfo = Record < LuaLibFeature , LuaLibFeatureInfo > ;
108+
109+ export const luaLibModulesInfoFileName = "lualib_module_info.json" ;
110+ let luaLibModulesInfo : LuaLibModulesInfo | undefined ;
111+ export function getLuaLibModulesInfo ( emitHost : EmitHost ) : LuaLibModulesInfo {
112+ if ( luaLibModulesInfo === undefined ) {
113+ const lualibPath = path . resolve ( __dirname , `../dist/lualib/${ luaLibModulesInfoFileName } ` ) ;
114+ const result = emitHost . readFile ( lualibPath ) ;
115+ if ( result !== undefined ) {
116+ luaLibModulesInfo = JSON . parse ( result ) as LuaLibModulesInfo ;
117+ } else {
118+ throw new Error ( `Could not load lualib dependencies from '${ lualibPath } '` ) ;
119+ }
120+ }
121+ return luaLibModulesInfo ;
122+ }
158123
124+ export function readLuaLibFeature ( feature : LuaLibFeature , emitHost : EmitHost ) : string {
125+ const featurePath = path . resolve ( __dirname , `../dist/lualib/${ feature } .lua` ) ;
126+ const luaLibFeature = emitHost . readFile ( featurePath ) ;
127+ if ( luaLibFeature === undefined ) {
128+ throw new Error ( `Could not load lualib feature from '${ featurePath } '` ) ;
129+ }
130+ return luaLibFeature ;
131+ }
132+
133+ export function resolveRecursiveLualibFeatures (
134+ features : Iterable < LuaLibFeature > ,
135+ emitHost : EmitHost ,
136+ luaLibModulesInfo : LuaLibModulesInfo = getLuaLibModulesInfo ( emitHost )
137+ ) : LuaLibFeature [ ] {
159138 const loadedFeatures = new Set < LuaLibFeature > ( ) ;
139+ const result : LuaLibFeature [ ] = [ ] ;
160140
161141 function load ( feature : LuaLibFeature ) : void {
162142 if ( loadedFeatures . has ( feature ) ) return ;
163143 loadedFeatures . add ( feature ) ;
164144
165- const dependencies = luaLibDependencies [ feature ] ;
145+ const dependencies = luaLibModulesInfo [ feature ] ?. dependencies ;
166146 if ( dependencies ) {
167147 dependencies . forEach ( load ) ;
168148 }
169149
170- const featurePath = path . resolve ( __dirname , `../dist/lualib/${ feature } .lua` ) ;
171- const luaLibFeature = emitHost . readFile ( featurePath ) ;
172- if ( luaLibFeature !== undefined ) {
173- result += luaLibFeature + "\n" ;
174- } else {
175- throw new Error ( `Could not load lualib feature from '${ featurePath } '` ) ;
176- }
150+ result . push ( feature ) ;
177151 }
178152
179153 for ( const feature of features ) {
@@ -183,6 +157,44 @@ export function loadLuaLibFeatures(features: Iterable<LuaLibFeature>, emitHost:
183157 return result ;
184158}
185159
160+ export function loadInlineLualibFeatures ( features : Iterable < LuaLibFeature > , emitHost : EmitHost ) : string {
161+ let result = "" ;
162+
163+ for ( const feature of resolveRecursiveLualibFeatures ( features , emitHost ) ) {
164+ const luaLibFeature = readLuaLibFeature ( feature , emitHost ) ;
165+ result += luaLibFeature + "\n" ;
166+ }
167+
168+ return result ;
169+ }
170+
171+ export function loadImportedLualibFeatures ( features : Iterable < LuaLibFeature > , emitHost : EmitHost ) : lua . Statement [ ] {
172+ const luaLibModuleInfo = getLuaLibModulesInfo ( emitHost ) ;
173+
174+ const imports = Array . from ( features ) . flatMap ( feature => luaLibModuleInfo [ feature ] . exports ) ;
175+
176+ const requireCall = lua . createCallExpression ( lua . createIdentifier ( "require" ) , [
177+ lua . createStringLiteral ( "lualib_bundle" ) ,
178+ ] ) ;
179+ if ( imports . length === 0 ) {
180+ return [ ] ;
181+ }
182+
183+ const luaLibId = lua . createIdentifier ( "____lualib" ) ;
184+ const importStatement = lua . createVariableDeclarationStatement ( luaLibId , requireCall ) ;
185+ const statements : lua . Statement [ ] = [ importStatement ] ;
186+ // local <export> = ____luaLib.<export>
187+ for ( const item of imports ) {
188+ statements . push (
189+ lua . createVariableDeclarationStatement (
190+ lua . createIdentifier ( item ) ,
191+ lua . createTableIndexExpression ( luaLibId , lua . createStringLiteral ( item ) )
192+ )
193+ ) ;
194+ }
195+ return statements ;
196+ }
197+
186198let luaLibBundleContent : string ;
187199export function getLuaLibBundle ( emitHost : EmitHost ) : string {
188200 if ( luaLibBundleContent === undefined ) {
0 commit comments