@@ -2,7 +2,11 @@ import * as ts from "typescript";
22import * as lua from "../../LuaAST" ;
33import { assertNever } from "../../utils" ;
44import { FunctionVisitor , TransformationContext , Visitors } from "../context" ;
5- import { invalidMultiFunctionUse , unsupportedAccessorInObjectLiteral } from "../utils/diagnostics" ;
5+ import {
6+ invalidMultiFunctionUse ,
7+ undefinedInArrayLiteral ,
8+ unsupportedAccessorInObjectLiteral ,
9+ } from "../utils/diagnostics" ;
610import { createExportedIdentifier , getSymbolExportScope } from "../utils/export" ;
711import { LuaLibFeature , transformLuaLibFunction } from "../utils/lualib" ;
812import { createSafeName , hasUnsafeIdentifierName , hasUnsafeSymbolName } from "../utils/safe-names" ;
@@ -196,6 +200,9 @@ const transformObjectLiteralExpression: FunctionVisitor<ts.ObjectLiteralExpressi
196200} ;
197201
198202const transformArrayLiteralExpression : FunctionVisitor < ts . ArrayLiteralExpression > = ( expression , context ) => {
203+ // Disallow using undefined/null in array literals
204+ checkForUndefinedOrNullInArrayLiteral ( expression , context ) ;
205+
199206 const filteredElements = expression . elements . map ( e =>
200207 ts . isOmittedExpression ( e ) ? ts . factory . createIdentifier ( "undefined" ) : e
201208 ) ;
@@ -204,6 +211,31 @@ const transformArrayLiteralExpression: FunctionVisitor<ts.ArrayLiteralExpression
204211 return lua . createTableExpression ( values , expression ) ;
205212} ;
206213
214+ function checkForUndefinedOrNullInArrayLiteral ( array : ts . ArrayLiteralExpression , context : TransformationContext ) {
215+ // Look for last non-nil element in literal
216+ let lastNonUndefinedIndex = array . elements . length - 1 ;
217+ for ( ; lastNonUndefinedIndex >= 0 ; lastNonUndefinedIndex -- ) {
218+ if ( ! isUndefinedOrNull ( array . elements [ lastNonUndefinedIndex ] ) ) {
219+ break ;
220+ }
221+ }
222+
223+ // Add diagnostics for non-trailing nil elements in array literal
224+ for ( let i = 0 ; i < array . elements . length ; i ++ ) {
225+ if ( i < lastNonUndefinedIndex && isUndefinedOrNull ( array . elements [ i ] ) ) {
226+ context . diagnostics . push ( undefinedInArrayLiteral ( array . elements [ i ] ) ) ;
227+ }
228+ }
229+ }
230+
231+ function isUndefinedOrNull ( node : ts . Node ) {
232+ return (
233+ node . kind === ts . SyntaxKind . UndefinedKeyword ||
234+ node . kind === ts . SyntaxKind . NullKeyword ||
235+ ( ts . isIdentifier ( node ) && node . text === "undefined" )
236+ ) ;
237+ }
238+
207239export const literalVisitors : Visitors = {
208240 [ ts . SyntaxKind . NullKeyword ] : node => lua . createNilLiteral ( node ) ,
209241 [ ts . SyntaxKind . TrueKeyword ] : node => lua . createBooleanLiteral ( true , node ) ,
0 commit comments