@@ -3519,40 +3519,6 @@ export class Parser extends DiagnosticEmitter {
3519
3519
return null ;
3520
3520
}
3521
3521
3522
- private getRecursiveDepthForTypeDeclaration (
3523
- identifierName : string ,
3524
- type : TypeNode ,
3525
- depth : i32 = 0
3526
- ) : i32 {
3527
- switch ( type . kind ) {
3528
- case NodeKind . NamedType : {
3529
- let typeArguments = ( < NamedTypeNode > type ) . typeArguments ;
3530
- if ( typeArguments ) {
3531
- for ( let i = 0 , k = typeArguments . length ; i < k ; i ++ ) {
3532
- let res = this . getRecursiveDepthForTypeDeclaration ( identifierName , typeArguments [ i ] , depth + 1 ) ;
3533
- if ( res != - 1 ) return res ;
3534
- }
3535
- }
3536
- if ( ( < NamedTypeNode > type ) . name . identifier . text == identifierName ) {
3537
- return depth ;
3538
- }
3539
- break ;
3540
- }
3541
- case NodeKind . FunctionType : {
3542
- let fnType = < FunctionTypeNode > type ;
3543
- let res = this . getRecursiveDepthForTypeDeclaration ( identifierName , fnType . returnType , depth + 1 ) ;
3544
- if ( res != - 1 ) return res ;
3545
- let params = fnType . parameters ;
3546
- for ( let i = 0 , k = params . length ; i < k ; i ++ ) {
3547
- res = this . getRecursiveDepthForTypeDeclaration ( identifierName , params [ i ] . type , depth + 1 ) ;
3548
- if ( res != - 1 ) return res ;
3549
- }
3550
- break ;
3551
- }
3552
- }
3553
- return - 1 ;
3554
- }
3555
-
3556
3522
parseTypeDeclaration (
3557
3523
tn : Tokenizer ,
3558
3524
flags : CommonFlags ,
@@ -3574,19 +3540,11 @@ export class Parser extends DiagnosticEmitter {
3574
3540
tn . skip ( Token . Bar ) ;
3575
3541
let type = this . parseType ( tn ) ;
3576
3542
if ( ! type ) return null ;
3577
- let depth = this . getRecursiveDepthForTypeDeclaration ( name . text , type ) ;
3578
- if ( depth >= 0 ) {
3579
- if ( depth == 0 ) {
3580
- this . error (
3581
- DiagnosticCode . Type_alias_0_circularly_references_itself ,
3582
- tn . range ( ) , name . text
3583
- ) ;
3584
- } else {
3585
- this . error (
3586
- DiagnosticCode . Not_implemented_0 ,
3587
- tn . range ( ) , "Recursion in type aliases"
3588
- ) ;
3589
- }
3543
+ if ( isCircularTypeAlias ( name . text , type ) ) {
3544
+ this . error (
3545
+ DiagnosticCode . Type_alias_0_circularly_references_itself ,
3546
+ name . range , name . text
3547
+ ) ;
3590
3548
return null ;
3591
3549
}
3592
3550
let ret = Node . createTypeDeclaration (
@@ -4593,3 +4551,32 @@ function determinePrecedence(kind: Token): Precedence {
4593
4551
}
4594
4552
return Precedence . None ;
4595
4553
}
4554
+
4555
+ /** Checks if the type alias of the given name and type is circular. */
4556
+ function isCircularTypeAlias ( name : string , type : TypeNode ) : bool {
4557
+ switch ( type . kind ) {
4558
+ case NodeKind . NamedType : {
4559
+ if ( ( < NamedTypeNode > type ) . name . identifier . text == name ) {
4560
+ return true ;
4561
+ }
4562
+ let typeArguments = ( < NamedTypeNode > type ) . typeArguments ;
4563
+ if ( typeArguments ) {
4564
+ for ( let i = 0 , k = typeArguments . length ; i < k ; i ++ ) {
4565
+ if ( isCircularTypeAlias ( name , typeArguments [ i ] ) ) return true ;
4566
+ }
4567
+ }
4568
+ break ;
4569
+ }
4570
+ case NodeKind . FunctionType : {
4571
+ let functionType = < FunctionTypeNode > type ;
4572
+ if ( isCircularTypeAlias ( name , functionType . returnType ) ) return true ;
4573
+ let parameters = functionType . parameters ;
4574
+ for ( let i = 0 , k = parameters . length ; i < k ; i ++ ) {
4575
+ if ( isCircularTypeAlias ( name , parameters [ i ] . type ) ) return true ;
4576
+ }
4577
+ break ;
4578
+ }
4579
+ default : assert ( false ) ;
4580
+ }
4581
+ return false ;
4582
+ }
0 commit comments