@@ -138,44 +138,41 @@ export class ColorThemeData implements IColorTheme {
138138 /** Public for testing reasons */
139139 public findTokenStyleForScope ( scope : ProbeScope ) : TokenStyle | undefined {
140140
141+ let foreground : string | null = null ;
142+ let fontStyle : string | null = null ;
143+ let foregroundScore = - 1 ;
144+ let fontStyleScore = - 1 ;
145+
141146 function findTokenStyleForScopeInScopes ( scopeMatchers : Matcher < ProbeScope > [ ] , tokenColors : ITokenColorizationRule [ ] ) {
142- for ( let i = scopeMatchers . length - 1 ; i >= 0 ; i -- ) {
147+ for ( let i = 0 ; i < scopeMatchers . length ; i ++ ) {
148+ const settings = tokenColors [ i ] . settings ;
149+ if ( ! settings ) {
150+ continue ;
151+ }
143152 let matcher = scopeMatchers [ i ] ;
144153 if ( ! matcher ) {
145154 scopeMatchers [ i ] = matcher = getScopeMatcher ( tokenColors [ i ] ) ;
146155 }
147- if ( matcher ( scope ) ) {
148- const settings = tokenColors [ i ] . settings ;
149- if ( settings ) {
150- if ( foreground === null && settings . foreground ) {
151- foreground = settings . foreground ;
152- }
153- if ( fontStyle === null && types . isString ( settings . fontStyle ) ) {
154- fontStyle = settings . fontStyle ;
155- }
156- if ( foreground !== null && fontStyle !== null ) {
157- break ;
158- }
159- }
156+ const score = matcher ( scope ) ;
157+ if ( score > foregroundScore && settings . foreground ) {
158+ foreground = settings . foreground ;
159+ }
160+ if ( score > fontStyleScore && types . isString ( settings . fontStyle ) ) {
161+ fontStyle = settings . fontStyle ;
160162 }
161163 }
162164 }
163165
164- let foreground : string | null = null ;
165- let fontStyle : string | null = null ;
166+ if ( ! this . themeTokenScopeMatchers ) {
167+ this . themeTokenScopeMatchers = new Array ( this . themeTokenColors . length ) ;
168+ }
169+ findTokenStyleForScopeInScopes ( this . themeTokenScopeMatchers , this . themeTokenColors ) ;
166170
167171 if ( ! this . customTokenScopeMatchers ) {
168172 this . customTokenScopeMatchers = new Array ( this . customTokenColors . length ) ;
169173 }
170174 findTokenStyleForScopeInScopes ( this . customTokenScopeMatchers , this . customTokenColors ) ;
171175
172- if ( foreground === null || fontStyle === null ) {
173- if ( ! this . themeTokenScopeMatchers ) {
174- this . themeTokenScopeMatchers = new Array ( this . themeTokenColors . length ) ;
175- }
176- findTokenStyleForScopeInScopes ( this . themeTokenScopeMatchers , this . themeTokenColors ) ;
177- }
178-
179176 if ( foreground !== null || fontStyle !== null ) {
180177 return getTokenStyle ( foreground , fontStyle ) ;
181178 }
@@ -462,27 +459,43 @@ let defaultThemeColors: { [baseTheme: string]: ITokenColorizationRule[] } = {
462459 ] ,
463460} ;
464461
465- const noMatch = ( _scope : ProbeScope ) => false ;
462+ const noMatch = ( _scope : ProbeScope ) => - 1 ;
466463
467- function nameMatcher ( identifers : string [ ] , scope : ProbeScope ) {
464+ function nameMatcher ( identifers : string [ ] , scope : ProbeScope ) : number {
465+ function findInIdents ( s : string , lastIndent : number ) : number {
466+ for ( let i = lastIndent - 1 ; i >= 0 ; i -- ) {
467+ if ( scopesAreMatching ( identifers [ i ] , s ) ) {
468+ return i ;
469+ }
470+ }
471+ return - 1 ;
472+ }
468473 if ( ! Array . isArray ( scope ) ) {
469- scope = [ scope ] ;
474+ const idx = findInIdents ( scope , identifers . length ) ;
475+ if ( idx >= 0 ) {
476+ return idx * 0x10000 + scope . length ;
477+ }
478+ return - 1 ;
470479 }
471480 if ( scope . length < identifers . length ) {
472- return false ;
473- }
474- let lastIndex = 0 ;
475- return identifers . every ( identifier => {
476- for ( let i = lastIndex ; i < scope . length ; i ++ ) {
477- if ( scopesAreMatching ( scope [ i ] , identifier ) ) {
478- lastIndex = i + 1 ;
479- return true ;
481+ return - 1 ;
482+ }
483+ let lastScopeIndex = scope . length - 1 ;
484+ let lastIdentifierIndex = findInIdents ( scope [ lastScopeIndex -- ] , identifers . length ) ;
485+ if ( lastIdentifierIndex >= 0 ) {
486+ const score = lastIdentifierIndex * 0x10000 + scope . length ;
487+ while ( lastScopeIndex >= 0 ) {
488+ lastIdentifierIndex = findInIdents ( scope [ lastScopeIndex -- ] , lastIdentifierIndex ) ;
489+ if ( lastIdentifierIndex === - 1 ) {
490+ return - 1 ;
480491 }
481492 }
482- return false ;
483- } ) ;
493+ return score ;
494+ }
495+ return - 1 ;
484496}
485497
498+
486499function scopesAreMatching ( thisScopeName : string , scopeName : string ) : boolean {
487500 if ( ! thisScopeName ) {
488501 return false ;
@@ -507,7 +520,13 @@ function getScopeMatcher(rule: ITokenColorizationRule): Matcher<ProbeScope> {
507520 } else {
508521 matchers . push ( ...createMatchers ( ruleScope , nameMatcher ) ) ;
509522 }
510- return ( scope : ProbeScope ) => matchers . some ( m => m . matcher ( scope ) ) ;
523+ return ( scope : ProbeScope ) => {
524+ let max = 0 ;
525+ for ( const m of matchers ) {
526+ max = Math . max ( max , m . matcher ( scope ) ) ;
527+ }
528+ return max ;
529+ } ;
511530}
512531
513532function getTokenStyle ( foreground : string | null , fontStyle : string | null ) : TokenStyle | undefined {
0 commit comments