@@ -21,6 +21,38 @@ class Test262BaselineRunner extends RunnerBase {
2121 return Test262BaselineRunner . basePath + "/" + filename ;
2222 }
2323
24+ private static checkInvariants ( node : ts . Node , parent : ts . Node ) : void {
25+ if ( node ) {
26+ if ( node . pos < 0 ) {
27+ throw new Error ( "node.pos < 0" ) ;
28+ }
29+ if ( node . end < 0 ) {
30+ throw new Error ( "node.end < 0" ) ;
31+ }
32+ if ( node . end < node . pos ) {
33+ throw new Error ( "node.end < node.pos" ) ;
34+ }
35+ if ( node . parent !== parent ) {
36+ throw new Error ( "node.parent !== parent" ) ;
37+ }
38+ ts . forEachChild ( node , child => {
39+ Test262BaselineRunner . checkInvariants ( child , node ) ;
40+ } ) ;
41+
42+ var childNodesAndArrays : any [ ] = [ ] ;
43+ ts . forEachChild ( node , child => { childNodesAndArrays . push ( child ) } , array => { childNodesAndArrays . push ( array ) } ) ;
44+
45+ for ( var childName in node ) {
46+ var child = ( < any > node ) [ childName ] ;
47+ if ( Test262BaselineRunner . isNodeOrArray ( child ) ) {
48+ if ( childNodesAndArrays . indexOf ( child ) < 0 ) {
49+ throw new Error ( "Child when forEach'ing over node. " + ( < any > ts ) . SyntaxKind [ node . kind ] + "-" + childName ) ;
50+ }
51+ }
52+ }
53+ }
54+ }
55+
2456 private static serializeSourceFile ( file : ts . SourceFile ) : string {
2557 function getKindName ( k : number ) : string {
2658 return ( < any > ts ) . SyntaxKind [ k ]
@@ -104,10 +136,14 @@ class Test262BaselineRunner extends RunnerBase {
104136 }
105137
106138 return JSON . stringify ( file , ( k , v ) => {
107- return ( v && typeof v . pos === "number" ) ? serializeNode ( v ) : v ;
139+ return Test262BaselineRunner . isNodeOrArray ( v ) ? serializeNode ( v ) : v ;
108140 } , " " ) ;
109141 }
110142
143+ private static isNodeOrArray ( a : any ) : boolean {
144+ return a !== undefined && typeof a . pos === "number" ;
145+ }
146+
111147 private runTest ( filePath : string ) {
112148 describe ( 'test262 test for ' + filePath , ( ) => {
113149 // Mocha holds onto the closure environment of the describe callback even after the test is done.
@@ -164,6 +200,11 @@ class Test262BaselineRunner extends RunnerBase {
164200 } , false , Test262BaselineRunner . baselineOptions ) ;
165201 } ) ;
166202
203+ it ( 'satisfies invariants' , ( ) => {
204+ var sourceFile = testState . checker . getProgram ( ) . getSourceFile ( Test262BaselineRunner . getTestFilePath ( testState . filename ) ) ;
205+ Test262BaselineRunner . checkInvariants ( sourceFile , /*parent:*/ undefined ) ;
206+ } ) ;
207+
167208 it ( 'has the expected AST' , ( ) => {
168209 Harness . Baseline . runBaseline ( 'has the expected AST' , testState . filename + '.AST.txt' , ( ) => {
169210 var sourceFile = testState . checker . getProgram ( ) . getSourceFile ( Test262BaselineRunner . getTestFilePath ( testState . filename ) ) ;
0 commit comments