@@ -182,7 +182,8 @@ import {
182182 findDecorator ,
183183 isTypeOmitted ,
184184 Source ,
185- TypeDeclaration
185+ TypeDeclaration ,
186+ ParameterKind
186187} from "./ast" ;
187188
188189import {
@@ -6171,16 +6172,7 @@ export class Compiler extends DiagnosticEmitter {
61716172 return false ;
61726173 }
61736174
6174- // not yet implemented (TODO: maybe some sort of an unmanaged/lightweight array?)
61756175 let hasRest = signature . hasRest ;
6176- if ( hasRest ) {
6177- this . error (
6178- DiagnosticCode . Not_implemented_0 ,
6179- reportNode . range , "Rest parameters"
6180- ) ;
6181- return false ;
6182- }
6183-
61846176 let minimum = signature . requiredParameters ;
61856177 let maximum = signature . parameterTypes . length ;
61866178
@@ -6225,6 +6217,37 @@ export class Compiler extends DiagnosticEmitter {
62256217 }
62266218 }
62276219
6220+ private adjustArgumentsForRestParams (
6221+ argumentExpressions : Expression [ ] ,
6222+ signature : Signature ,
6223+ reportNode : Node
6224+ ) : Expression [ ] {
6225+
6226+ // if no rest args, return the original args
6227+ if ( ! signature . hasRest ) {
6228+ return argumentExpressions ;
6229+ }
6230+
6231+ // if there are fewer args than params, then the rest args were not provided
6232+ // so return the original args
6233+ const numArguments = argumentExpressions . length ;
6234+ const numParams = signature . parameterTypes . length ;
6235+ if ( numArguments < numParams ) {
6236+ return argumentExpressions ;
6237+ }
6238+
6239+ // make an array literal expression from the rest args
6240+ let elements = argumentExpressions . slice ( numParams - 1 ) ;
6241+ let range = new Range ( elements [ 0 ] . range . start , elements [ elements . length - 1 ] . range . end ) ;
6242+ range . source = reportNode . range . source ;
6243+ let arrExpr = new ArrayLiteralExpression ( elements , range ) ;
6244+
6245+ // return the original args, but replace the rest args with the array
6246+ const exprs = argumentExpressions . slice ( 0 , numParams - 1 ) ;
6247+ exprs . push ( arrExpr ) ;
6248+ return exprs ;
6249+ }
6250+
62286251 /** Compiles a direct call to a concrete function. */
62296252 compileCallDirect (
62306253 instance : Function ,
@@ -6246,6 +6269,9 @@ export class Compiler extends DiagnosticEmitter {
62466269 }
62476270 if ( instance . hasDecorator ( DecoratorFlags . Unsafe ) ) this . checkUnsafe ( reportNode ) ;
62486271
6272+ argumentExpressions = this . adjustArgumentsForRestParams ( argumentExpressions , signature , reportNode ) ;
6273+ numArguments = argumentExpressions . length ;
6274+
62496275 // handle call on `this` in constructors
62506276 let sourceFunction = this . currentFlow . sourceFunction ;
62516277 if ( sourceFunction . is ( CommonFlags . Constructor ) && reportNode . isAccessOnThis ) {
@@ -6477,7 +6503,11 @@ export class Compiler extends DiagnosticEmitter {
64776503 let declaration = originalParameterDeclarations [ minArguments + i ] ;
64786504 let initializer = declaration . initializer ;
64796505 let initExpr : ExpressionRef ;
6480- if ( initializer ) {
6506+ if ( declaration . parameterKind === ParameterKind . Rest ) {
6507+ const arrExpr = new ArrayLiteralExpression ( [ ] , declaration . range . atEnd ) ;
6508+ initExpr = this . compileArrayLiteral ( arrExpr , type , Constraints . ConvExplicit ) ;
6509+ initExpr = module . local_set ( operandIndex , initExpr , type . isManaged ) ;
6510+ } else if ( initializer ) {
64816511 initExpr = this . compileExpression (
64826512 initializer ,
64836513 type ,
@@ -6863,6 +6893,9 @@ export class Compiler extends DiagnosticEmitter {
68636893 return this . module . unreachable ( ) ;
68646894 }
68656895
6896+ argumentExpressions = this . adjustArgumentsForRestParams ( argumentExpressions , signature , reportNode ) ;
6897+ numArguments = argumentExpressions . length ;
6898+
68666899 let numArgumentsInclThis = thisArg ? numArguments + 1 : numArguments ;
68676900 let operands = new Array < ExpressionRef > ( numArgumentsInclThis ) ;
68686901 let index = 0 ;
0 commit comments