(file: ts.SourceFile, context: tstl.TransformationContext)
| 80 | protected featureDependencies: Map<tstl.LuaLibFeature, Set<tstl.LuaLibFeature>> = new Map(); |
| 81 | |
| 82 | protected lualibFileVisitor(file: ts.SourceFile, context: tstl.TransformationContext): tstl.File { |
| 83 | const featureName = path.basename(file.fileName, ".ts") as tstl.LuaLibFeature; |
| 84 | if (!(featureName in tstl.LuaLibFeature)) { |
| 85 | context.diagnostics.push(lualibDiagnostic(`File is not a lualib feature: ${featureName}`, file)); |
| 86 | } |
| 87 | |
| 88 | // Transpile file as normal with tstl |
| 89 | const fileResult = context.superTransformNode(file)[0] as tstl.File; |
| 90 | |
| 91 | const usedFeatures = new Set<tstl.LuaLibFeature>(context.usedLuaLibFeatures); |
| 92 | |
| 93 | // Get all imports in file |
| 94 | const importNames = new Set<string>(); |
| 95 | const imports = file.statements.filter(ts.isImportDeclaration); |
| 96 | for (const { importClause, moduleSpecifier } of imports) { |
| 97 | if (importClause?.namedBindings && ts.isNamedImports(importClause.namedBindings)) { |
| 98 | for (const { name } of importClause.namedBindings.elements) { |
| 99 | importNames.add(name.text); |
| 100 | } |
| 101 | } |
| 102 | // track lualib imports |
| 103 | if (ts.isStringLiteral(moduleSpecifier)) { |
| 104 | const featureName = path.basename(moduleSpecifier.text, ".ts") as tstl.LuaLibFeature; |
| 105 | if (featureName in tstl.LuaLibFeature) { |
| 106 | usedFeatures.add(featureName); |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | const filteredStatements = fileResult.statements |
| 112 | .filter( |
| 113 | s => !isExportTableDeclaration(s) && !isRequire(s) && !isImport(s, importNames) && !isExportsReturn(s) |
| 114 | ) |
| 115 | .map(statement => { |
| 116 | if (isExportAlias(statement)) { |
| 117 | const name = statement.left[0]; |
| 118 | const exportName = statement.right[0].index.value; |
| 119 | if (name.text === exportName) return undefined; // Remove "x = x" statements |
| 120 | return tstl.createAssignmentStatement(name, tstl.createIdentifier(exportName)); |
| 121 | } |
| 122 | return statement; |
| 123 | }) |
| 124 | .filter(statement => statement !== undefined); |
| 125 | |
| 126 | const exportNames = filteredStatements.filter(isExportAssignment).map(s => s.left[0].index.value); |
| 127 | if (!filteredStatements.every(isExportAssignment)) { |
| 128 | // If there are local statements, wrap them in a do ... end with exports outside |
| 129 | const exports = tstl.createVariableDeclarationStatement(exportNames.map(k => tstl.createIdentifier(k))); |
| 130 | // transform export assignments to local assignments |
| 131 | const bodyStatements = filteredStatements.map(s => |
| 132 | isExportAssignment(s) |
| 133 | ? tstl.createAssignmentStatement(tstl.createIdentifier(s.left[0].index.value), s.right[0]) |
| 134 | : s |
| 135 | ); |
| 136 | |
| 137 | fileResult.statements = [exports, tstl.createDoStatement(bodyStatements)]; |
| 138 | } else { |
| 139 | // transform export assignments to local variable declarations |
nothing calls this directly
no test coverage detected