11import * as ts from "typescript" ;
22import * as lua from "../../../LuaAST" ;
3- import { assert , getOrUpdate , isNonNull } from "../../../utils" ;
3+ import { getOrUpdate , isNonNull } from "../../../utils" ;
44import { FunctionVisitor , TransformationContext } from "../../context" ;
55import { AnnotationKind , getTypeAnnotations } from "../../utils/annotations" ;
66import {
@@ -59,16 +59,17 @@ export function transformClassAsExpression(
5959 return createImmediatelyInvokedFunctionExpression ( classDeclaration , className , expression ) ;
6060}
6161
62- const classStacks = new WeakMap < TransformationContext , ts . ClassLikeDeclaration [ ] > ( ) ;
62+ const classSuperInfos = new WeakMap < TransformationContext , ClassSuperInfo [ ] > ( ) ;
63+ interface ClassSuperInfo {
64+ className : lua . Identifier ;
65+ extendsTypeNode ?: ts . ExpressionWithTypeArguments ;
66+ }
6367
6468export function transformClassDeclaration (
6569 classDeclaration : ts . ClassLikeDeclaration ,
6670 context : TransformationContext ,
6771 nameOverride ?: lua . Identifier
6872) : OneToManyVisitorResult < lua . Statement > {
69- const classStack = getOrUpdate ( classStacks , context , ( ) => [ ] ) ;
70- classStack . push ( classDeclaration ) ;
71-
7273 let className : lua . Identifier ;
7374 let classNameText : string ;
7475 if ( nameOverride !== undefined ) {
@@ -108,6 +109,9 @@ export function transformClassDeclaration(
108109 const extendsTypeNode = getExtendedTypeNode ( context , classDeclaration ) ;
109110 const extendsType = getExtendedType ( context , classDeclaration ) ;
110111
112+ const superInfo = getOrUpdate ( classSuperInfos , context , ( ) => [ ] ) ;
113+ superInfo . push ( { className, extendsTypeNode } ) ;
114+
111115 if ( extendsType ) {
112116 checkForLuaLibType ( context , extendsType ) ;
113117 }
@@ -308,17 +312,19 @@ export function transformClassDeclaration(
308312 result . push ( decorationStatement ) ;
309313 }
310314
311- classStack . pop ( ) ;
315+ superInfo . pop ( ) ;
312316
313317 return result ;
314318}
315319
316320export const transformSuperExpression : FunctionVisitor < ts . SuperExpression > = ( expression , context ) => {
317- const classStack = getOrUpdate ( classStacks , context , ( ) => [ ] ) ;
318- const classDeclaration = classStack [ classStack . length - 1 ] ;
319- const typeNode = getExtendedTypeNode ( context , classDeclaration ) ;
320- // `undefined` is a TypeScript error
321- const extendsExpression = typeNode ?. expression ;
321+ const superInfos = getOrUpdate ( classSuperInfos , context , ( ) => [ ] ) ;
322+ const superInfo = superInfos [ superInfos . length - 1 ] ;
323+ if ( ! superInfo ) return lua . createAnonymousIdentifier ( expression ) ;
324+ const { className, extendsTypeNode } = superInfo ;
325+
326+ // Using `super` without extended type node is a TypeScript error
327+ const extendsExpression = extendsTypeNode ?. expression ;
322328 let baseClassName : lua . AssignmentLeftHandSideExpression | undefined ;
323329
324330 if ( extendsExpression && ts . isIdentifier ( extendsExpression ) ) {
@@ -330,14 +336,8 @@ export const transformSuperExpression: FunctionVisitor<ts.SuperExpression> = (ex
330336 }
331337
332338 if ( ! baseClassName ) {
333- assert ( classDeclaration . name ) ;
334-
335339 // Use "className.____super" if the base is not a simple identifier
336- baseClassName = lua . createTableIndexExpression (
337- transformIdentifier ( context , classDeclaration . name ) ,
338- lua . createStringLiteral ( "____super" ) ,
339- expression
340- ) ;
340+ baseClassName = lua . createTableIndexExpression ( className , lua . createStringLiteral ( "____super" ) , expression ) ;
341341 }
342342
343343 return lua . createTableIndexExpression ( baseClassName , lua . createStringLiteral ( "prototype" ) ) ;
0 commit comments