@@ -709,6 +709,7 @@ export class Parser extends DiagnosticEmitter {
709709 let startPos = tn . tokenPos ;
710710 let parameters : ParameterNode [ ] | null = null ;
711711 let thisType : NamedTypeNode | null = null ;
712+ let thisDecorators : DecoratorNode [ ] | null = null ;
712713 let isSignature : bool = false ;
713714 let firstParamNameNoType : IdentifierExpression | null = null ;
714715 let firstParamKind : ParameterKind = ParameterKind . Default ;
@@ -723,6 +724,12 @@ export class Parser extends DiagnosticEmitter {
723724 do {
724725 let paramStart = - 1 ;
725726 let kind = ParameterKind . Default ;
727+ let decorators = this . parseParameterDecorators ( tn ) ;
728+ if ( decorators ) {
729+ paramStart = decorators [ 0 ] . range . start ;
730+ isSignature = true ;
731+ tn . discard ( state ) ;
732+ }
726733 if ( tn . skip ( Token . Dot_Dot_Dot ) ) {
727734 paramStart = tn . tokenPos ;
728735 isSignature = true ;
@@ -745,6 +752,7 @@ export class Parser extends DiagnosticEmitter {
745752 return null ;
746753 }
747754 thisType = < NamedTypeNode > type ;
755+ thisDecorators = decorators ;
748756 } else {
749757 tn . reset ( state ) ;
750758 this . tryParseSignatureIsSignature = false ;
@@ -773,7 +781,7 @@ export class Parser extends DiagnosticEmitter {
773781 this . tryParseSignatureIsSignature = isSignature ;
774782 return null ;
775783 }
776- let param = Node . createParameter ( kind , name , type , null , tn . range ( paramStart , tn . pos ) ) ;
784+ let param = Node . createParameter ( kind , name , type , null , tn . range ( paramStart , tn . pos ) , decorators ) ;
777785 if ( ! parameters ) parameters = [ param ] ;
778786 else parameters . push ( param ) ;
779787 } else {
@@ -784,7 +792,7 @@ export class Parser extends DiagnosticEmitter {
784792 }
785793 }
786794 if ( isSignature ) {
787- let param = Node . createParameter ( kind , name , Node . createOmittedType ( tn . range ( tn . pos ) ) , null , tn . range ( paramStart , tn . pos ) ) ;
795+ let param = Node . createParameter ( kind , name , Node . createOmittedType ( tn . range ( tn . pos ) ) , null , tn . range ( paramStart , tn . pos ) , decorators ) ;
788796 if ( ! parameters ) parameters = [ param ] ;
789797 else parameters . push ( param ) ;
790798 this . error (
@@ -869,13 +877,15 @@ export class Parser extends DiagnosticEmitter {
869877
870878 if ( ! parameters ) parameters = [ ] ;
871879
872- return Node . createFunctionType (
880+ let functionType = Node . createFunctionType (
873881 parameters ,
874882 returnType ,
875883 thisType ,
876884 false ,
877885 tn . range ( startPos , tn . pos )
878886 ) ;
887+ functionType . explicitThisDecorators = thisDecorators ;
888+ return functionType ;
879889 }
880890
881891 // statements
@@ -924,6 +934,19 @@ export class Parser extends DiagnosticEmitter {
924934 return null ;
925935 }
926936
937+ private parseParameterDecorators (
938+ tn : Tokenizer
939+ ) : DecoratorNode [ ] | null {
940+ let decorators : DecoratorNode [ ] | null = null ;
941+ while ( tn . skip ( Token . At ) ) {
942+ let decorator = this . parseDecorator ( tn ) ;
943+ if ( ! decorator ) break ;
944+ if ( ! decorators ) decorators = [ decorator ] ;
945+ else decorators . push ( decorator ) ;
946+ }
947+ return decorators ;
948+ }
949+
927950 parseVariable (
928951 tn : Tokenizer ,
929952 flags : CommonFlags ,
@@ -1227,6 +1250,7 @@ export class Parser extends DiagnosticEmitter {
12271250 }
12281251
12291252 private parseParametersThis : NamedTypeNode | null = null ;
1253+ private parseParametersThisDecorators : DecoratorNode [ ] | null = null ;
12301254
12311255 parseParameters (
12321256 tn : Tokenizer ,
@@ -1243,40 +1267,50 @@ export class Parser extends DiagnosticEmitter {
12431267
12441268 // check if there is a leading `this` parameter
12451269 this . parseParametersThis = null ;
1246- if ( tn . skip ( Token . This ) ) {
1247- if ( tn . skip ( Token . Colon ) ) {
1248- thisType = this . parseType ( tn ) ; // reports
1249- if ( ! thisType ) return null ;
1250- if ( thisType . kind == NodeKind . NamedType ) {
1251- this . parseParametersThis = < NamedTypeNode > thisType ;
1252- } else {
1253- this . error (
1254- DiagnosticCode . Identifier_expected ,
1255- thisType . range
1256- ) ;
1257- }
1258- } else {
1259- this . error (
1260- DiagnosticCode . _0_expected ,
1261- tn . range ( ) , ":"
1262- ) ;
1263- return null ;
1264- }
1265- if ( ! tn . skip ( Token . Comma ) ) {
1266- if ( tn . skip ( Token . CloseParen ) ) {
1267- return parameters ;
1270+ this . parseParametersThisDecorators = null ;
1271+
1272+ let first = true ;
1273+ while ( true ) {
1274+ if ( tn . skip ( Token . CloseParen ) ) break ;
1275+
1276+ let paramDecorators = this . parseParameterDecorators ( tn ) ;
1277+
1278+ if ( first && tn . skip ( Token . This ) ) {
1279+ if ( tn . skip ( Token . Colon ) ) {
1280+ thisType = this . parseType ( tn ) ; // reports
1281+ if ( ! thisType ) return null ;
1282+ if ( thisType . kind == NodeKind . NamedType ) {
1283+ this . parseParametersThis = < NamedTypeNode > thisType ;
1284+ this . parseParametersThisDecorators = paramDecorators ;
1285+ } else {
1286+ this . error (
1287+ DiagnosticCode . Identifier_expected ,
1288+ thisType . range
1289+ ) ;
1290+ }
12681291 } else {
12691292 this . error (
12701293 DiagnosticCode . _0_expected ,
1271- tn . range ( ) , ") "
1294+ tn . range ( ) , ": "
12721295 ) ;
12731296 return null ;
12741297 }
1298+ first = false ;
1299+ if ( ! tn . skip ( Token . Comma ) ) {
1300+ if ( tn . skip ( Token . CloseParen ) ) {
1301+ break ;
1302+ } else {
1303+ this . error (
1304+ DiagnosticCode . _0_expected ,
1305+ tn . range ( ) , ")"
1306+ ) ;
1307+ return null ;
1308+ }
1309+ }
1310+ continue ;
12751311 }
1276- }
12771312
1278- while ( ! tn . skip ( Token . CloseParen ) ) {
1279- let param = this . parseParameter ( tn , isConstructor ) ; // reports
1313+ let param = this . parseParameter ( tn , isConstructor , paramDecorators ) ; // reports
12801314 if ( ! param ) return null ;
12811315 if ( seenRest && ! reportedRest ) {
12821316 this . error (
@@ -1305,6 +1339,7 @@ export class Parser extends DiagnosticEmitter {
13051339 }
13061340 }
13071341 parameters . push ( param ) ;
1342+ first = false ;
13081343 if ( ! tn . skip ( Token . Comma ) ) {
13091344 if ( tn . skip ( Token . CloseParen ) ) {
13101345 break ;
@@ -1322,24 +1357,27 @@ export class Parser extends DiagnosticEmitter {
13221357
13231358 parseParameter (
13241359 tn : Tokenizer ,
1325- isConstructor : bool = false
1360+ isConstructor : bool = false ,
1361+ decorators : DecoratorNode [ ] | null = null
13261362 ) : ParameterNode | null {
13271363
13281364 // before: ('public' | 'private' | 'protected' | '...')? Identifier '?'? (':' Type)? ('=' Expression)?
13291365
13301366 let isRest = false ;
13311367 let isOptional = false ;
1332- let startRange : Range | null = null ;
1368+ let startRange : Range | null = decorators
1369+ ? decorators [ 0 ] . range
1370+ : null ;
13331371 let accessFlags : CommonFlags = CommonFlags . None ;
13341372 if ( isConstructor ) {
13351373 if ( tn . skip ( Token . Public ) ) {
1336- startRange = tn . range ( ) ;
1374+ if ( ! startRange ) startRange = tn . range ( ) ;
13371375 accessFlags |= CommonFlags . Public ;
13381376 } else if ( tn . skip ( Token . Protected ) ) {
1339- startRange = tn . range ( ) ;
1377+ if ( ! startRange ) startRange = tn . range ( ) ;
13401378 accessFlags |= CommonFlags . Protected ;
13411379 } else if ( tn . skip ( Token . Private ) ) {
1342- startRange = tn . range ( ) ;
1380+ if ( ! startRange ) startRange = tn . range ( ) ;
13431381 accessFlags |= CommonFlags . Private ;
13441382 }
13451383 if ( tn . peek ( ) == Token . Readonly ) {
@@ -1361,12 +1399,12 @@ export class Parser extends DiagnosticEmitter {
13611399 tn . range ( )
13621400 ) ;
13631401 } else {
1364- startRange = tn . range ( ) ;
1402+ if ( ! startRange ) startRange = tn . range ( ) ;
13651403 }
13661404 isRest = true ;
13671405 }
13681406 if ( tn . skipIdentifier ( ) ) {
1369- if ( ! isRest ) startRange = tn . range ( ) ;
1407+ if ( ! isRest && ! startRange ) startRange = tn . range ( ) ;
13701408 let identifier = Node . createIdentifierExpression ( tn . readIdentifier ( ) , tn . range ( ) ) ;
13711409 let type : TypeNode | null = null ;
13721410 if ( isOptional = tn . skip ( Token . Question ) ) {
@@ -1411,7 +1449,8 @@ export class Parser extends DiagnosticEmitter {
14111449 identifier ,
14121450 type ,
14131451 initializer ,
1414- Range . join ( assert ( startRange ) , tn . range ( ) )
1452+ Range . join ( assert ( startRange ) , tn . range ( ) ) ,
1453+ decorators
14151454 ) ;
14161455 param . flags |= accessFlags ;
14171456 return param ;
@@ -1523,6 +1562,7 @@ export class Parser extends DiagnosticEmitter {
15231562 false ,
15241563 tn . range ( signatureStart , tn . pos )
15251564 ) ;
1565+ signature . explicitThisDecorators = this . parseParametersThisDecorators ;
15261566
15271567 let body : Statement | null = null ;
15281568 if ( tn . skip ( Token . OpenBrace ) ) {
@@ -1597,14 +1637,24 @@ export class Parser extends DiagnosticEmitter {
15971637 let parameters = this . parseParameters ( tn ) ;
15981638 if ( ! parameters ) return null ;
15991639
1600- return this . parseFunctionExpressionCommon ( tn , name , parameters , this . parseParametersThis , arrowKind , startPos , signatureStart ) ;
1640+ return this . parseFunctionExpressionCommon (
1641+ tn ,
1642+ name ,
1643+ parameters ,
1644+ this . parseParametersThis ,
1645+ this . parseParametersThisDecorators ,
1646+ arrowKind ,
1647+ startPos ,
1648+ signatureStart
1649+ ) ;
16011650 }
16021651
16031652 private parseFunctionExpressionCommon (
16041653 tn : Tokenizer ,
16051654 name : IdentifierExpression ,
16061655 parameters : ParameterNode [ ] ,
16071656 explicitThis : NamedTypeNode | null ,
1657+ explicitThisDecorators : DecoratorNode [ ] | null ,
16081658 arrowKind : ArrowKind ,
16091659 startPos : i32 = - 1 ,
16101660 signatureStart : i32 = - 1
@@ -1637,6 +1687,7 @@ export class Parser extends DiagnosticEmitter {
16371687 false ,
16381688 tn . range ( signatureStart , tn . pos )
16391689 ) ;
1690+ signature . explicitThisDecorators = explicitThisDecorators ;
16401691
16411692 let body : Statement | null = null ;
16421693 if ( arrowKind ) {
@@ -2282,6 +2333,7 @@ export class Parser extends DiagnosticEmitter {
22822333 false ,
22832334 tn . range ( signatureStart , tn . pos )
22842335 ) ;
2336+ signature . explicitThisDecorators = this . parseParametersThisDecorators ;
22852337
22862338 let body : Statement | null = null ;
22872339 if ( tn . skip ( Token . OpenBrace ) ) {
@@ -3729,6 +3781,7 @@ export class Parser extends DiagnosticEmitter {
37293781 Node . createEmptyIdentifierExpression ( tn . range ( startPos ) ) ,
37303782 [ ] ,
37313783 null ,
3784+ null ,
37323785 ArrowKind . Parenthesized
37333786 ) ;
37343787 }
@@ -3738,6 +3791,7 @@ export class Parser extends DiagnosticEmitter {
37383791 switch ( tn . next ( IdentifierHandling . Prefer ) ) {
37393792
37403793 // function expression
3794+ case Token . At :
37413795 case Token . Dot_Dot_Dot : {
37423796 tn . reset ( state ) ;
37433797 return this . parseFunctionExpression ( tn ) ;
@@ -3930,6 +3984,7 @@ export class Parser extends DiagnosticEmitter {
39303984 )
39313985 ] ,
39323986 null ,
3987+ null ,
39333988 ArrowKind . Single ,
39343989 startPos
39353990 ) ;
0 commit comments