@@ -22,14 +22,15 @@ export const fontStylePattern = '^(\\s*(-?italic|-?bold|-?underline))*\\s*$';
2222
2323export interface TokenSelector {
2424 match ( type : string , modifiers : string [ ] ) : number ;
25- asString ( ) : string ;
25+ readonly selectorString : string ;
2626}
2727
2828export interface TokenTypeOrModifierContribution {
2929 readonly num : number ;
3030 readonly id : string ;
31+ readonly superType ?: string ;
3132 readonly description : string ;
32- readonly deprecationMessage : string | undefined ;
33+ readonly deprecationMessage ? : string ;
3334}
3435
3536
@@ -123,7 +124,7 @@ export interface ITokenClassificationRegistry {
123124 * @param id The TokenType id as used in theme description files
124125 * @param description the description
125126 */
126- registerTokenType ( id : string , description : string ) : void ;
127+ registerTokenType ( id : string , description : string , superType ?: string , deprecationMessage ?: string ) : void ;
127128
128129 /**
129130 * Register a token modifier to the registry.
@@ -197,6 +198,8 @@ class TokenClassificationRegistry implements ITokenClassificationRegistry {
197198
198199 private tokenStylingDefaultRules : TokenStylingDefaultRule [ ] = [ ] ;
199200
201+ private typeHierarchy : { [ id : string ] : string [ ] } ;
202+
200203 private tokenStylingSchema : IJSONSchema & { properties : IJSONSchemaMap } = {
201204 type : 'object' ,
202205 properties : { } ,
@@ -233,18 +236,23 @@ class TokenClassificationRegistry implements ITokenClassificationRegistry {
233236 constructor ( ) {
234237 this . tokenTypeById = { } ;
235238 this . tokenModifierById = { } ;
239+ this . typeHierarchy = { } ;
236240 }
237241
238- public registerTokenType ( id : string , description : string , deprecationMessage ?: string ) : void {
242+ public registerTokenType ( id : string , description : string , superType ?: string , deprecationMessage ?: string ) : void {
239243 if ( ! id . match ( typeAndModifierIdPattern ) ) {
240244 throw new Error ( 'Invalid token type id.' ) ;
241245 }
246+ if ( superType && ! superType . match ( typeAndModifierIdPattern ) ) {
247+ throw new Error ( 'Invalid token super type id.' ) ;
248+ }
242249
243250 const num = this . currentTypeNumber ++ ;
244- let tokenStyleContribution : TokenTypeOrModifierContribution = { num, id, description, deprecationMessage } ;
251+ let tokenStyleContribution : TokenTypeOrModifierContribution = { num, id, superType , description, deprecationMessage } ;
245252 this . tokenTypeById [ id ] = tokenStyleContribution ;
246253
247254 this . tokenStylingSchema . properties [ id ] = getStylingSchemeEntry ( description , deprecationMessage ) ;
255+ this . typeHierarchy = { } ;
248256 }
249257
250258 public registerTokenModifier ( id : string , description : string , deprecationMessage ?: string ) : void {
@@ -266,25 +274,30 @@ class TokenClassificationRegistry implements ITokenClassificationRegistry {
266274 if ( ! selectorType ) {
267275 return {
268276 match : ( ) => - 1 ,
269- asString : ( ) => selectorString
277+ selectorString
270278 } ;
271279 }
272- const score = selectorModifiers . length + ( ( selectorString !== TOKEN_TYPE_WILDCARD ) ? 1 : 0 ) ;
273280
274281 return {
275282 match : ( type : string , modifiers : string [ ] ) => {
276- if ( selectorType !== TOKEN_TYPE_WILDCARD && selectorType !== type ) {
277- return - 1 ;
283+ let score = 0 ;
284+ if ( selectorType !== TOKEN_TYPE_WILDCARD ) {
285+ const hierarchy = this . getTypeHierarchy ( type ) ;
286+ const level = hierarchy . indexOf ( selectorType ) ;
287+ if ( level === - 1 ) {
288+ return - 1 ;
289+ }
290+ score = 100 - level ;
278291 }
279292 // all selector modifiers must be present
280293 for ( const selectorModifier of selectorModifiers ) {
281294 if ( modifiers . indexOf ( selectorModifier ) === - 1 ) {
282295 return - 1 ;
283296 }
284297 }
285- return score ;
298+ return score + selectorModifiers . length * 100 ;
286299 } ,
287- asString : ( ) => selectorString
300+ selectorString
288301 } ;
289302 }
290303
@@ -293,13 +306,14 @@ class TokenClassificationRegistry implements ITokenClassificationRegistry {
293306 }
294307
295308 public deregisterTokenStyleDefault ( selector : TokenSelector ) : void {
296- const selectorString = selector . asString ( ) ;
297- this . tokenStylingDefaultRules = this . tokenStylingDefaultRules . filter ( r => ! ( r . selector . asString ( ) === selectorString ) ) ;
309+ const selectorString = selector . selectorString ;
310+ this . tokenStylingDefaultRules = this . tokenStylingDefaultRules . filter ( r => r . selector . selectorString !== selectorString ) ;
298311 }
299312
300313 public deregisterTokenType ( id : string ) : void {
301314 delete this . tokenTypeById [ id ] ;
302315 delete this . tokenStylingSchema . properties [ id ] ;
316+ this . typeHierarchy = { } ;
303317 }
304318
305319 public deregisterTokenModifier ( id : string ) : void {
@@ -323,6 +337,19 @@ class TokenClassificationRegistry implements ITokenClassificationRegistry {
323337 return this . tokenStylingDefaultRules ;
324338 }
325339
340+ private getTypeHierarchy ( typeId : string ) : string [ ] {
341+ let hierarchy = this . typeHierarchy [ typeId ] ;
342+ if ( ! hierarchy ) {
343+ this . typeHierarchy [ typeId ] = hierarchy = [ typeId ] ;
344+ let type = this . tokenTypeById [ typeId ] ;
345+ while ( type && type . superType ) {
346+ hierarchy . push ( type . superType ) ;
347+ type = this . tokenTypeById [ type . superType ] ;
348+ }
349+ }
350+ return hierarchy ;
351+ }
352+
326353
327354 public toString ( ) {
328355 let sorter = ( a : string , b : string ) => {
@@ -346,20 +373,23 @@ platform.Registry.add(Extensions.TokenClassificationContribution, tokenClassific
346373registerDefaultClassifications ( ) ;
347374
348375function registerDefaultClassifications ( ) : void {
349- function registerTokenType ( id : string , description : string , scopesToProbe : ProbeScope [ ] = [ ] , extendsTC ?: string , deprecationMessage ?: string ) : string {
350- tokenClassificationRegistry . registerTokenType ( id , description , deprecationMessage ) ;
351-
352- if ( scopesToProbe || extendsTC ) {
353- try {
354- const selector = tokenClassificationRegistry . parseTokenSelector ( id ) ;
355- tokenClassificationRegistry . registerTokenStyleDefault ( selector , { scopesToProbe, light : extendsTC , dark : extendsTC , hc : extendsTC } ) ;
356- } catch ( e ) {
357- console . log ( e ) ;
358- }
376+ function registerTokenType ( id : string , description : string , scopesToProbe : ProbeScope [ ] = [ ] , superType ?: string , deprecationMessage ?: string ) : string {
377+ tokenClassificationRegistry . registerTokenType ( id , description , superType , deprecationMessage ) ;
378+ if ( scopesToProbe ) {
379+ registerTokenStyleDefault ( id , scopesToProbe ) ;
359380 }
360381 return id ;
361382 }
362383
384+ function registerTokenStyleDefault ( selectorString : string , scopesToProbe : ProbeScope [ ] ) {
385+ try {
386+ const selector = tokenClassificationRegistry . parseTokenSelector ( selectorString ) ;
387+ tokenClassificationRegistry . registerTokenStyleDefault ( selector , { scopesToProbe } ) ;
388+ } catch ( e ) {
389+ console . log ( e ) ;
390+ }
391+ }
392+
363393 // default token types
364394
365395 registerTokenType ( 'comment' , nls . localize ( 'comment' , "Style for comments." ) , [ [ 'comment' ] ] ) ;
0 commit comments