@@ -2174,62 +2174,62 @@ module ts {
2174
2174
case SyntaxKind . TryKeyword :
2175
2175
case SyntaxKind . CatchKeyword :
2176
2176
case SyntaxKind . FinallyKeyword :
2177
- result = getTryCatchFinallyOccurrences ( < TryStatement > ( node . parent && node . parent . parent ) ) ;
2177
+ if ( hasKind ( parent ( parent ( node ) ) , SyntaxKind . TryStatement ) ) {
2178
+ result = getTryCatchFinallyOccurrences ( < TryStatement > ( node . parent . parent ) ) ;
2179
+ }
2178
2180
break ;
2179
2181
case SyntaxKind . SwitchKeyword :
2180
- result = getSwitchCaseDefaultOccurrences ( < SwitchStatement > node . parent ) ;
2182
+ if ( hasKind ( node . parent , SyntaxKind . SwitchStatement ) ) {
2183
+ result = getSwitchCaseDefaultOccurrences ( < SwitchStatement > node . parent ) ;
2184
+ }
2181
2185
break ;
2182
2186
case SyntaxKind . CaseKeyword :
2183
2187
case SyntaxKind . DefaultKeyword :
2184
- result = getSwitchCaseDefaultOccurrences ( < SwitchStatement > ( node . parent && node . parent . parent ) ) ;
2188
+ if ( hasKind ( parent ( parent ( node ) ) , SyntaxKind . SwitchStatement ) ) {
2189
+ result = getSwitchCaseDefaultOccurrences ( < SwitchStatement > ( node . parent . parent ) ) ;
2190
+ }
2185
2191
break ;
2186
2192
case SyntaxKind . BreakKeyword :
2187
- result = getBreakStatementOccurences ( < BreakOrContinueStatement > node . parent ) ;
2188
-
2193
+ if ( hasKind ( node . parent , SyntaxKind . BreakStatement ) ) {
2194
+ result = getBreakStatementOccurences ( < BreakOrContinueStatement > node . parent ) ;
2195
+ }
2196
+ break ;
2189
2197
}
2190
2198
2191
2199
return result ;
2192
2200
2193
2201
function getTryCatchFinallyOccurrences ( tryStatement : TryStatement ) : ReferenceEntry [ ] {
2194
- if ( ! tryStatement || tryStatement . kind !== SyntaxKind . TryStatement ) {
2195
- return undefined ;
2196
- }
2197
-
2198
2202
var keywords : Node [ ] = [ ] ;
2199
2203
2200
- pushIfKeyword ( keywords , tryStatement . getFirstToken ( ) ) ;
2204
+ pushIfKeyword ( keywords , tryStatement . getFirstToken ( ) , SyntaxKind . TryKeyword ) ;
2201
2205
2202
2206
if ( tryStatement . catchBlock ) {
2203
- pushIfKeyword ( keywords , tryStatement . catchBlock . getFirstToken ( ) ) ;
2207
+ pushIfKeyword ( keywords , tryStatement . catchBlock . getFirstToken ( ) , SyntaxKind . CatchKeyword ) ;
2204
2208
}
2205
2209
2206
2210
if ( tryStatement . finallyBlock ) {
2207
- pushIfKeyword ( keywords , tryStatement . finallyBlock . getFirstToken ( ) ) ;
2211
+ pushIfKeyword ( keywords , tryStatement . finallyBlock . getFirstToken ( ) , SyntaxKind . FinallyKeyword ) ;
2208
2212
}
2209
2213
2210
2214
return keywordsToReferenceEntries ( keywords ) ;
2211
2215
}
2212
2216
2213
2217
function getSwitchCaseDefaultOccurrences ( switchStatement : SwitchStatement ) {
2214
- if ( ! switchStatement || switchStatement . kind !== SyntaxKind . SwitchStatement ) {
2215
- return undefined ;
2216
- }
2217
-
2218
2218
var keywords : Node [ ] = [ ] ;
2219
2219
2220
- pushIfKeyword ( keywords , switchStatement . getFirstToken ( ) ) ;
2220
+ pushIfKeyword ( keywords , switchStatement . getFirstToken ( ) , SyntaxKind . SwitchKeyword ) ;
2221
2221
2222
2222
// Go through each clause in the switch statement, collecting the clause keywords.
2223
2223
switchStatement . clauses . forEach ( clause => {
2224
- pushIfKeyword ( keywords , clause . getFirstToken ( ) ) ;
2224
+ pushIfKeyword ( keywords , clause . getFirstToken ( ) , [ SyntaxKind . CaseKeyword , SyntaxKind . DefaultKeyword ] ) ;
2225
2225
2226
2226
// For each clause, also recursively traverse the statements where we can find analogous breaks.
2227
2227
forEachChild ( clause , function aggregateBreakKeywords ( node : Node ) : void {
2228
2228
switch ( node . kind ) {
2229
2229
case SyntaxKind . BreakStatement :
2230
- // If the break statement has a label, cannot be part of
2230
+ // If the break statement has a label, it cannot be part of a switch block.
2231
2231
if ( ! ( < BreakOrContinueStatement > node ) . label ) {
2232
- pushIfKeyword ( keywords , node . getFirstToken ( ) ) ;
2232
+ pushIfKeyword ( keywords , node . getFirstToken ( ) , SyntaxKind . BreakKeyword ) ;
2233
2233
}
2234
2234
// Fall through
2235
2235
case SyntaxKind . ForStatement :
@@ -2251,10 +2251,6 @@ module ts {
2251
2251
}
2252
2252
2253
2253
function getBreakStatementOccurences ( breakStatement : BreakOrContinueStatement ) : ReferenceEntry [ ] {
2254
- if ( ! breakStatement || breakStatement . kind !== SyntaxKind . BreakStatement ) {
2255
- return undefined ;
2256
- }
2257
-
2258
2254
// TODO (drosen): Deal with labeled statements.
2259
2255
if ( breakStatement . label ) {
2260
2256
return undefined ;
@@ -2280,10 +2276,30 @@ module ts {
2280
2276
return undefined ;
2281
2277
}
2282
2278
2283
- function pushIfKeyword ( keywordList : Node [ ] , token : Node ) {
2284
- if ( token && isKeyword ( token . kind ) ) {
2279
+ // returns true if 'node' is defined and has a matching 'kind'.
2280
+ function hasKind ( node : Node , kind : SyntaxKind ) {
2281
+ return ! ! ( node && node . kind === kind ) ;
2282
+ }
2283
+
2284
+ // Null-propagating 'parent' function.
2285
+ function parent ( node : Node ) : Node {
2286
+ return node && node . parent ;
2287
+ }
2288
+
2289
+ function pushIfKeyword ( keywordList : Node [ ] , token : Node , expected : SyntaxKind ) : void ;
2290
+ function pushIfKeyword ( keywordList : Node [ ] , token : Node , expected : SyntaxKind [ ] ) : void ;
2291
+ function pushIfKeyword ( keywordList : Node [ ] , token : Node , expected : any ) : void {
2292
+ if ( ! token ) {
2293
+ return ;
2294
+ }
2295
+
2296
+ if ( token . kind === expected ||
2297
+ ( expected . length && ( < SyntaxKind [ ] > expected ) . some ( expectedKind => expectedKind === token . kind ) ) ) {
2285
2298
keywordList . push ( token ) ;
2286
2299
}
2300
+ else {
2301
+ Debug . assert ( "Expected keyword, got " + token . getFullText ( ) . substring ( token . getLeadingTriviaWidth ( ) ) ) ;
2302
+ }
2287
2303
}
2288
2304
2289
2305
function keywordsToReferenceEntries ( keywords : Node [ ] ) : ReferenceEntry [ ] {
0 commit comments