Merge pull request #170 from microsoft/hediet/containsBalancedBrackets
Implements flag "containsBalancedBrackets"
This commit is contained in:
Коммит
12f0e7aa16
|
@ -1,3 +1,4 @@
|
|||
import { BalancedBracketSelectors } from './grammar';
|
||||
import { IRawGrammar, IOnigLib } from './types';
|
||||
export * from './types';
|
||||
/**
|
||||
|
@ -50,6 +51,8 @@ export declare const enum StandardTokenType {
|
|||
export interface IGrammarConfiguration {
|
||||
embeddedLanguages?: IEmbeddedLanguagesMap;
|
||||
tokenTypes?: ITokenTypeMap;
|
||||
balancedBracketSelectors?: string[];
|
||||
unbalancedBracketSelectors?: string[];
|
||||
}
|
||||
/**
|
||||
* The registry that will hold all grammars.
|
||||
|
@ -92,7 +95,7 @@ export declare class Registry {
|
|||
/**
|
||||
* Get the grammar for `scopeName`. The grammar must first be created via `loadGrammar` or `addGrammar`.
|
||||
*/
|
||||
grammarForScopeName(scopeName: string, initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap | null, tokenTypes?: ITokenTypeMap | null): Promise<IGrammar | null>;
|
||||
grammarForScopeName(scopeName: string, initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap | null, tokenTypes?: ITokenTypeMap | null, balancedBracketSelectors?: BalancedBracketSelectors | null): Promise<IGrammar | null>;
|
||||
}
|
||||
/**
|
||||
* A grammar
|
||||
|
@ -137,10 +140,11 @@ export interface ITokenizeLineResult {
|
|||
* 1098 7654 3210 9876 5432 1098 7654 3210
|
||||
* - -------------------------------------------
|
||||
* xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
|
||||
* bbbb bbbb bfff ffff ffFF FFTT LLLL LLLL
|
||||
* bbbb bbbb ffff ffff fFFF FBTT LLLL LLLL
|
||||
* - -------------------------------------------
|
||||
* - L = LanguageId (8 bits)
|
||||
* - T = StandardTokenType (2 bits)
|
||||
* - B = Balanced bracket (1 bit)
|
||||
* - F = FontStyle (4 bits)
|
||||
* - f = foreground color (9 bits)
|
||||
* - b = background color (9 bits)
|
||||
|
@ -148,14 +152,16 @@ export interface ITokenizeLineResult {
|
|||
export declare const enum MetadataConsts {
|
||||
LANGUAGEID_MASK = 255,
|
||||
TOKEN_TYPE_MASK = 768,
|
||||
FONT_STYLE_MASK = 15360,
|
||||
FOREGROUND_MASK = 8372224,
|
||||
BACKGROUND_MASK = 4286578688,
|
||||
BALANCED_BRACKETS_MASK = 1024,
|
||||
FONT_STYLE_MASK = 30720,
|
||||
FOREGROUND_MASK = 16744448,
|
||||
BACKGROUND_MASK = 4278190080,
|
||||
LANGUAGEID_OFFSET = 0,
|
||||
TOKEN_TYPE_OFFSET = 8,
|
||||
FONT_STYLE_OFFSET = 10,
|
||||
FOREGROUND_OFFSET = 14,
|
||||
BACKGROUND_OFFSET = 23
|
||||
BALANCED_BRACKETS_OFFSET = 10,
|
||||
FONT_STYLE_OFFSET = 11,
|
||||
FOREGROUND_OFFSET = 15,
|
||||
BACKGROUND_OFFSET = 24
|
||||
}
|
||||
export interface ITokenizeLineResult2 {
|
||||
/**
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
117
src/grammar.ts
117
src/grammar.ts
|
@ -30,8 +30,8 @@ export const enum OptionalStandardTokenType {
|
|||
NotSet = 8
|
||||
}
|
||||
|
||||
export function createGrammar(scopeName: string, grammar: IRawGrammar, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap | null, tokenTypes: ITokenTypeMap | null, grammarRepository: IGrammarRepository & IThemeProvider, onigLib: IOnigLib): Grammar {
|
||||
return new Grammar(scopeName, grammar, initialLanguage, embeddedLanguages, tokenTypes, grammarRepository, onigLib);//TODO
|
||||
export function createGrammar(scopeName: string, grammar: IRawGrammar, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap | null, tokenTypes: ITokenTypeMap | null, balancedBracketSelectors: BalancedBracketSelectors | null, grammarRepository: IGrammarRepository & IThemeProvider, onigLib: IOnigLib): Grammar {
|
||||
return new Grammar(scopeName, grammar, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors, grammarRepository, onigLib);//TODO
|
||||
}
|
||||
|
||||
export interface IThemeProvider {
|
||||
|
@ -460,7 +460,7 @@ export class Grammar implements IGrammar, IRuleFactoryHelper, IOnigLib {
|
|||
private readonly _tokenTypeMatchers: TokenTypeMatcher[];
|
||||
private readonly _onigLib: IOnigLib;
|
||||
|
||||
constructor(scopeName: string, grammar: IRawGrammar, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap | null, tokenTypes: ITokenTypeMap | null, grammarRepository: IGrammarRepository & IThemeProvider, onigLib: IOnigLib) {
|
||||
constructor(scopeName: string, grammar: IRawGrammar, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap | null, tokenTypes: ITokenTypeMap | null, private readonly balancedBracketSelectors: BalancedBracketSelectors | null, grammarRepository: IGrammarRepository & IThemeProvider, onigLib: IOnigLib) {
|
||||
this._scopeName = scopeName;
|
||||
this._scopeMetadataProvider = new ScopeMetadataProvider(initialLanguage, grammarRepository, embeddedLanguages);
|
||||
|
||||
|
@ -635,7 +635,7 @@ export class Grammar implements IGrammar, IRuleFactoryHelper, IOnigLib {
|
|||
isFirstLine = true;
|
||||
const rawDefaultMetadata = this._scopeMetadataProvider.getDefaultMetadata();
|
||||
const defaultTheme = rawDefaultMetadata.themeData![0];
|
||||
const defaultMetadata = StackElementMetadata.set(0, rawDefaultMetadata.languageId, rawDefaultMetadata.tokenType, defaultTheme.fontStyle, defaultTheme.foreground, defaultTheme.background);
|
||||
const defaultMetadata = StackElementMetadata.set(0, rawDefaultMetadata.languageId, rawDefaultMetadata.tokenType, null, defaultTheme.fontStyle, defaultTheme.foreground, defaultTheme.background);
|
||||
|
||||
const rootScopeName = this.getRule(this._rootId).getName(null, null);
|
||||
const rawRootMetadata = this._scopeMetadataProvider.getMetadataForScope(rootScopeName);
|
||||
|
@ -652,7 +652,7 @@ export class Grammar implements IGrammar, IRuleFactoryHelper, IOnigLib {
|
|||
lineText = lineText + '\n';
|
||||
const onigLineText = this.createOnigString(lineText);
|
||||
const lineLength = onigLineText.content.length;
|
||||
const lineTokens = new LineTokens(emitBinaryTokens, lineText, this._tokenTypeMatchers);
|
||||
const lineTokens = new LineTokens(emitBinaryTokens, lineText, this._tokenTypeMatchers, this.balancedBracketSelectors);
|
||||
const r = _tokenizeString(this, onigLineText, isFirstLine, 0, prevState, lineTokens, true, timeLimit);
|
||||
|
||||
disposeOnigString(onigLineText);
|
||||
|
@ -1231,6 +1231,10 @@ export class StackElementMetadata {
|
|||
return (metadata & MetadataConsts.TOKEN_TYPE_MASK) >>> MetadataConsts.TOKEN_TYPE_OFFSET;
|
||||
}
|
||||
|
||||
public static containsBalancedBrackets(metadata: number): boolean {
|
||||
return (metadata & MetadataConsts.BALANCED_BRACKETS_MASK) !== 0;
|
||||
}
|
||||
|
||||
public static getFontStyle(metadata: number): number {
|
||||
return (metadata & MetadataConsts.FONT_STYLE_MASK) >>> MetadataConsts.FONT_STYLE_OFFSET;
|
||||
}
|
||||
|
@ -1245,11 +1249,12 @@ export class StackElementMetadata {
|
|||
|
||||
/**
|
||||
* Updates the fields in `metadata`.
|
||||
* A value of `0` or `NotSet` indicates that the corresponding field should be left as is.
|
||||
* A value of `0`, `NotSet` or `null` indicates that the corresponding field should be left as is.
|
||||
*/
|
||||
public static set(metadata: number, languageId: number, tokenType: OptionalStandardTokenType, fontStyle: FontStyle, foreground: number, background: number): number {
|
||||
public static set(metadata: number, languageId: number, tokenType: OptionalStandardTokenType, containsBalancedBrackets: boolean | null, fontStyle: FontStyle, foreground: number, background: number): number {
|
||||
let _languageId = StackElementMetadata.getLanguageId(metadata);
|
||||
let _tokenType = StackElementMetadata.getTokenType(metadata);
|
||||
let _containsBalancedBracketsBit: 0 | 1 = StackElementMetadata.containsBalancedBrackets(metadata) ? 1 : 0;
|
||||
let _fontStyle = StackElementMetadata.getFontStyle(metadata);
|
||||
let _foreground = StackElementMetadata.getForeground(metadata);
|
||||
let _background = StackElementMetadata.getBackground(metadata);
|
||||
|
@ -1260,6 +1265,9 @@ export class StackElementMetadata {
|
|||
if (tokenType !== OptionalStandardTokenType.NotSet) {
|
||||
_tokenType = fromOptionalTokenType(tokenType);
|
||||
}
|
||||
if (containsBalancedBrackets !== null) {
|
||||
_containsBalancedBracketsBit = containsBalancedBrackets ? 1 : 0;
|
||||
}
|
||||
if (fontStyle !== FontStyle.NotSet) {
|
||||
_fontStyle = fontStyle;
|
||||
}
|
||||
|
@ -1273,6 +1281,7 @@ export class StackElementMetadata {
|
|||
return (
|
||||
(_languageId << MetadataConsts.LANGUAGEID_OFFSET)
|
||||
| (_tokenType << MetadataConsts.TOKEN_TYPE_OFFSET)
|
||||
| (_containsBalancedBracketsBit << MetadataConsts.BALANCED_BRACKETS_OFFSET)
|
||||
| (_fontStyle << MetadataConsts.FONT_STYLE_OFFSET)
|
||||
| (_foreground << MetadataConsts.FOREGROUND_OFFSET)
|
||||
| (_background << MetadataConsts.BACKGROUND_OFFSET)
|
||||
|
@ -1374,7 +1383,7 @@ export class ScopeListElement {
|
|||
}
|
||||
}
|
||||
|
||||
return StackElementMetadata.set(metadata, source.languageId, source.tokenType, fontStyle, foreground, background);
|
||||
return StackElementMetadata.set(metadata, source.languageId, source.tokenType, null, fontStyle, foreground, background);
|
||||
}
|
||||
|
||||
private static _push(target: ScopeListElement, grammar: Grammar, scopes: string[]): ScopeListElement {
|
||||
|
@ -1626,8 +1635,54 @@ interface TokenTypeMatcher {
|
|||
readonly type: StandardTokenType;
|
||||
}
|
||||
|
||||
class LineTokens {
|
||||
export class BalancedBracketSelectors {
|
||||
private readonly balancedBracketScopes: Matcher<string[]>[];
|
||||
private readonly unbalancedBracketScopes: Matcher<string[]>[];
|
||||
|
||||
private allowAny = false;
|
||||
|
||||
constructor(
|
||||
balancedBracketScopes: string[],
|
||||
unbalancedBracketScopes: string[],
|
||||
) {
|
||||
this.balancedBracketScopes = balancedBracketScopes.flatMap((selector) => {
|
||||
if (selector === '*') {
|
||||
this.allowAny = true;
|
||||
return [];
|
||||
}
|
||||
return createMatchers(selector, nameMatcher).map((m) => m.matcher);
|
||||
}
|
||||
);
|
||||
this.unbalancedBracketScopes = unbalancedBracketScopes.flatMap((selector) =>
|
||||
createMatchers(selector, nameMatcher).map((m) => m.matcher)
|
||||
);
|
||||
}
|
||||
|
||||
public get matchesAlways(): boolean {
|
||||
return this.allowAny && this.unbalancedBracketScopes.length === 0;
|
||||
}
|
||||
|
||||
public get matchesNever(): boolean {
|
||||
return this.balancedBracketScopes.length === 0 && !this.allowAny;
|
||||
}
|
||||
|
||||
public match(scopes: string[]): boolean {
|
||||
for (const excluder of this.unbalancedBracketScopes) {
|
||||
if (excluder(scopes)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const includer of this.balancedBracketScopes) {
|
||||
if (includer(scopes)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return this.allowAny;
|
||||
}
|
||||
}
|
||||
|
||||
class LineTokens {
|
||||
private readonly _emitBinaryTokens: boolean;
|
||||
/**
|
||||
* defined only if `DebugFlags.InDebugMode`.
|
||||
|
@ -1646,7 +1701,12 @@ class LineTokens {
|
|||
|
||||
private readonly _tokenTypeOverrides: TokenTypeMatcher[];
|
||||
|
||||
constructor(emitBinaryTokens: boolean, lineText: string, tokenTypeOverrides: TokenTypeMatcher[]) {
|
||||
constructor(
|
||||
emitBinaryTokens: boolean,
|
||||
lineText: string,
|
||||
tokenTypeOverrides: TokenTypeMatcher[],
|
||||
private readonly balancedBracketSelectors: BalancedBracketSelectors | null,
|
||||
) {
|
||||
this._emitBinaryTokens = emitBinaryTokens;
|
||||
this._tokenTypeOverrides = tokenTypeOverrides;
|
||||
if (DebugFlags.InDebugMode) {
|
||||
|
@ -1663,21 +1723,52 @@ class LineTokens {
|
|||
this.produceFromScopes(stack.contentNameScopesList, endIndex);
|
||||
}
|
||||
|
||||
public produceFromScopes(scopesList: ScopeListElement, endIndex: number): void {
|
||||
public produceFromScopes(
|
||||
scopesList: ScopeListElement,
|
||||
endIndex: number
|
||||
): void {
|
||||
if (this._lastTokenEndIndex >= endIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._emitBinaryTokens) {
|
||||
let metadata = scopesList.metadata;
|
||||
let containsBalancedBrackets = false;
|
||||
if (this.balancedBracketSelectors?.matchesAlways) {
|
||||
containsBalancedBrackets = true;
|
||||
}
|
||||
|
||||
if (this._tokenTypeOverrides.length > 0) {
|
||||
if (this._tokenTypeOverrides.length > 0 || (this.balancedBracketSelectors && !this.balancedBracketSelectors.matchesAlways && !this.balancedBracketSelectors.matchesNever)) {
|
||||
// Only generate scope array when required to improve performance
|
||||
const scopes = scopesList.generateScopes();
|
||||
for (const tokenType of this._tokenTypeOverrides) {
|
||||
if (tokenType.matcher(scopes)) {
|
||||
metadata = StackElementMetadata.set(metadata, 0, toOptionalTokenType(tokenType.type), FontStyle.NotSet, 0, 0);
|
||||
metadata = StackElementMetadata.set(
|
||||
metadata,
|
||||
0,
|
||||
toOptionalTokenType(tokenType.type),
|
||||
null,
|
||||
FontStyle.NotSet,
|
||||
0,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
if (this.balancedBracketSelectors) {
|
||||
containsBalancedBrackets = this.balancedBracketSelectors.match(scopes);
|
||||
}
|
||||
}
|
||||
|
||||
if (containsBalancedBrackets) {
|
||||
metadata = StackElementMetadata.set(
|
||||
metadata,
|
||||
0,
|
||||
OptionalStandardTokenType.NotSet,
|
||||
containsBalancedBrackets,
|
||||
FontStyle.NotSet,
|
||||
0,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
if (this._binaryTokens.length > 0 && this._binaryTokens[this._binaryTokens.length - 1] === metadata) {
|
||||
|
|
42
src/main.ts
42
src/main.ts
|
@ -5,7 +5,7 @@
|
|||
import { SyncRegistry } from './registry';
|
||||
import * as grammarReader from './grammarReader';
|
||||
import { Theme } from './theme';
|
||||
import { StackElement as StackElementImpl, ScopeDependencyProcessor } from './grammar';
|
||||
import { StackElement as StackElementImpl, ScopeDependencyProcessor, BalancedBracketSelectors } from './grammar';
|
||||
import { IRawGrammar, IOnigLib } from './types';
|
||||
|
||||
export * from './types';
|
||||
|
@ -66,6 +66,8 @@ export const enum StandardTokenType {
|
|||
export interface IGrammarConfiguration {
|
||||
embeddedLanguages?: IEmbeddedLanguagesMap;
|
||||
tokenTypes?: ITokenTypeMap;
|
||||
balancedBracketSelectors?: string[];
|
||||
unbalancedBracketSelectors?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,14 +116,23 @@ export class Registry {
|
|||
* Please do not use language id 0.
|
||||
*/
|
||||
public loadGrammarWithConfiguration(initialScopeName: string, initialLanguage: number, configuration: IGrammarConfiguration): Promise<IGrammar | null> {
|
||||
return this._loadGrammar(initialScopeName, initialLanguage, configuration.embeddedLanguages, configuration.tokenTypes);
|
||||
return this._loadGrammar(
|
||||
initialScopeName,
|
||||
initialLanguage,
|
||||
configuration.embeddedLanguages,
|
||||
configuration.tokenTypes,
|
||||
new BalancedBracketSelectors(
|
||||
configuration.balancedBracketSelectors || [],
|
||||
configuration.unbalancedBracketSelectors || []
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
|
||||
*/
|
||||
public loadGrammar(initialScopeName: string): Promise<IGrammar | null> {
|
||||
return this._loadGrammar(initialScopeName, 0, null, null);
|
||||
return this._loadGrammar(initialScopeName, 0, null, null, null);
|
||||
}
|
||||
|
||||
private async _doLoadSingleGrammar(scopeName: string): Promise<void> {
|
||||
|
@ -139,7 +150,7 @@ export class Registry {
|
|||
return this._ensureGrammarCache.get(scopeName);
|
||||
}
|
||||
|
||||
private async _loadGrammar(initialScopeName: string, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap | null | undefined, tokenTypes: ITokenTypeMap | null | undefined): Promise<IGrammar | null> {
|
||||
private async _loadGrammar(initialScopeName: string, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap | null | undefined, tokenTypes: ITokenTypeMap | null | undefined, balancedBracketSelectors: BalancedBracketSelectors | null): Promise<IGrammar | null> {
|
||||
|
||||
const dependencyProcessor = new ScopeDependencyProcessor(this._syncRegistry, initialScopeName);
|
||||
while (dependencyProcessor.Q.length > 0) {
|
||||
|
@ -147,7 +158,7 @@ export class Registry {
|
|||
dependencyProcessor.processQueue();
|
||||
}
|
||||
|
||||
return this.grammarForScopeName(initialScopeName, initialLanguage, embeddedLanguages, tokenTypes);
|
||||
return this.grammarForScopeName(initialScopeName, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,8 +172,8 @@ export class Registry {
|
|||
/**
|
||||
* Get the grammar for `scopeName`. The grammar must first be created via `loadGrammar` or `addGrammar`.
|
||||
*/
|
||||
public grammarForScopeName(scopeName: string, initialLanguage: number = 0, embeddedLanguages: IEmbeddedLanguagesMap | null = null, tokenTypes: ITokenTypeMap | null = null): Promise<IGrammar | null> {
|
||||
return this._syncRegistry.grammarForScopeName(scopeName, initialLanguage, embeddedLanguages, tokenTypes);
|
||||
public grammarForScopeName(scopeName: string, initialLanguage: number = 0, embeddedLanguages: IEmbeddedLanguagesMap | null = null, tokenTypes: ITokenTypeMap | null = null, balancedBracketSelectors: BalancedBracketSelectors | null = null): Promise<IGrammar | null> {
|
||||
return this._syncRegistry.grammarForScopeName(scopeName, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,10 +225,11 @@ export interface ITokenizeLineResult {
|
|||
* 1098 7654 3210 9876 5432 1098 7654 3210
|
||||
* - -------------------------------------------
|
||||
* xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
|
||||
* bbbb bbbb bfff ffff ffFF FFTT LLLL LLLL
|
||||
* bbbb bbbb ffff ffff fFFF FBTT LLLL LLLL
|
||||
* - -------------------------------------------
|
||||
* - L = LanguageId (8 bits)
|
||||
* - T = StandardTokenType (2 bits)
|
||||
* - B = Balanced bracket (1 bit)
|
||||
* - F = FontStyle (4 bits)
|
||||
* - f = foreground color (9 bits)
|
||||
* - b = background color (9 bits)
|
||||
|
@ -225,15 +237,17 @@ export interface ITokenizeLineResult {
|
|||
export const enum MetadataConsts {
|
||||
LANGUAGEID_MASK = 0b00000000000000000000000011111111,
|
||||
TOKEN_TYPE_MASK = 0b00000000000000000000001100000000,
|
||||
FONT_STYLE_MASK = 0b00000000000000000011110000000000,
|
||||
FOREGROUND_MASK = 0b00000000011111111100000000000000,
|
||||
BACKGROUND_MASK = 0b11111111100000000000000000000000,
|
||||
BALANCED_BRACKETS_MASK = 0b00000000000000000000010000000000,
|
||||
FONT_STYLE_MASK = 0b00000000000000000111100000000000,
|
||||
FOREGROUND_MASK = 0b00000000111111111000000000000000,
|
||||
BACKGROUND_MASK = 0b11111111000000000000000000000000,
|
||||
|
||||
LANGUAGEID_OFFSET = 0,
|
||||
TOKEN_TYPE_OFFSET = 8,
|
||||
FONT_STYLE_OFFSET = 10,
|
||||
FOREGROUND_OFFSET = 14,
|
||||
BACKGROUND_OFFSET = 23
|
||||
BALANCED_BRACKETS_OFFSET = 10,
|
||||
FONT_STYLE_OFFSET = 11,
|
||||
FOREGROUND_OFFSET = 15,
|
||||
BACKGROUND_OFFSET = 24
|
||||
}
|
||||
|
||||
export interface ITokenizeLineResult2 {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) Microsoft Corporation. All rights reserved.
|
||||
*--------------------------------------------------------*/
|
||||
|
||||
import { createGrammar, Grammar, IGrammarRepository } from './grammar';
|
||||
import { BalancedBracketSelectors, createGrammar, Grammar, IGrammarRepository } from './grammar';
|
||||
import { IRawGrammar } from './types';
|
||||
import { IGrammar, IEmbeddedLanguagesMap, ITokenTypeMap } from './main';
|
||||
import { Theme, ThemeTrieElementRule } from './theme';
|
||||
|
@ -86,13 +86,13 @@ export class SyncRegistry implements IGrammarRepository {
|
|||
/**
|
||||
* Lookup a grammar.
|
||||
*/
|
||||
public async grammarForScopeName(scopeName: string, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap | null, tokenTypes: ITokenTypeMap | null): Promise<IGrammar | null> {
|
||||
public async grammarForScopeName(scopeName: string, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap | null, tokenTypes: ITokenTypeMap | null, balancedBracketSelectors: BalancedBracketSelectors | null): Promise<IGrammar | null> {
|
||||
if (!this._grammars[scopeName]) {
|
||||
let rawGrammar = this._rawGrammars[scopeName];
|
||||
if (!rawGrammar) {
|
||||
return null;
|
||||
}
|
||||
this._grammars[scopeName] = createGrammar(scopeName, rawGrammar, initialLanguage, embeddedLanguages, tokenTypes, this, await this._onigLibPromise);
|
||||
this._grammars[scopeName] = createGrammar(scopeName, rawGrammar, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors, this, await this._onigLibPromise);
|
||||
}
|
||||
return this._grammars[scopeName];
|
||||
}
|
||||
|
|
|
@ -7,77 +7,90 @@ import { StandardTokenType } from '../main';
|
|||
import { StackElementMetadata, OptionalStandardTokenType } from '../grammar';
|
||||
import { FontStyle } from '../theme';
|
||||
|
||||
function assertEquals(metadata: number, languageId: number, tokenType: StandardTokenType, fontStyle: FontStyle, foreground: number, background: number): void {
|
||||
let actual = {
|
||||
function assertEquals(metadata: number, languageId: number, tokenType: StandardTokenType, containsBalancedBrackets: boolean, fontStyle: FontStyle, foreground: number, background: number): void {
|
||||
const actual = {
|
||||
languageId: StackElementMetadata.getLanguageId(metadata),
|
||||
tokenType: StackElementMetadata.getTokenType(metadata),
|
||||
containsBalancedBrackets: StackElementMetadata.containsBalancedBrackets(metadata),
|
||||
fontStyle: StackElementMetadata.getFontStyle(metadata),
|
||||
foreground: StackElementMetadata.getForeground(metadata),
|
||||
background: StackElementMetadata.getBackground(metadata),
|
||||
};
|
||||
|
||||
let expected = {
|
||||
languageId: languageId,
|
||||
tokenType: tokenType,
|
||||
fontStyle: fontStyle,
|
||||
foreground: foreground,
|
||||
background: background,
|
||||
const expected = {
|
||||
languageId,
|
||||
tokenType,
|
||||
containsBalancedBrackets,
|
||||
fontStyle,
|
||||
foreground,
|
||||
background,
|
||||
};
|
||||
|
||||
assert.deepStrictEqual(actual, expected, 'equals for ' + StackElementMetadata.toBinaryStr(metadata));
|
||||
}
|
||||
|
||||
test('StackElementMetadata works', () => {
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
});
|
||||
|
||||
test('StackElementMetadata can overwrite languageId', () => {
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
|
||||
value = StackElementMetadata.set(value, 2, OptionalStandardTokenType.NotSet, FontStyle.NotSet, 0, 0);
|
||||
assertEquals(value, 2, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
value = StackElementMetadata.set(value, 2, OptionalStandardTokenType.NotSet, false, FontStyle.NotSet, 0, 0);
|
||||
assertEquals(value, 2, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
});
|
||||
|
||||
test('StackElementMetadata can overwrite tokenType', () => {
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.Comment, FontStyle.NotSet, 0, 0);
|
||||
assertEquals(value, 1, StandardTokenType.Comment, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.Comment, false, FontStyle.NotSet, 0, 0);
|
||||
assertEquals(value, 1, StandardTokenType.Comment, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
});
|
||||
|
||||
test('StackElementMetadata can overwrite font style', () => {
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, FontStyle.None, 0, 0);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.None, 101, 102);
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, false, FontStyle.None, 0, 0);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.None, 101, 102);
|
||||
});
|
||||
|
||||
test('StackElementMetadata can overwrite font style with strikethrough', () => {
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, FontStyle.Strikethrough, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.Strikethrough, 101, 102);
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, false, FontStyle.Strikethrough, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Strikethrough, 101, 102);
|
||||
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, FontStyle.None, 0, 0);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.None, 101, 102);
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, false, FontStyle.None, 0, 0);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.None, 101, 102);
|
||||
});
|
||||
|
||||
test('StackElementMetadata can overwrite foreground', () => {
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, FontStyle.NotSet, 5, 0);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 5, 102);
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, false, FontStyle.NotSet, 5, 0);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 5, 102);
|
||||
});
|
||||
|
||||
test('StackElementMetadata can overwrite background', () => {
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, FontStyle.NotSet, 0, 7);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, FontStyle.Underline | FontStyle.Bold, 101, 7);
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, false, FontStyle.NotSet, 0, 7);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 7);
|
||||
});
|
||||
|
||||
test('StackElementMetadata can overwrite balanced backet bit', () => {
|
||||
let value = StackElementMetadata.set(0, 1, OptionalStandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, true, FontStyle.NotSet, 0, 0);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, true, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
|
||||
value = StackElementMetadata.set(value, 0, OptionalStandardTokenType.NotSet, false, FontStyle.NotSet, 0, 0);
|
||||
assertEquals(value, 1, StandardTokenType.RegEx, false, FontStyle.Underline | FontStyle.Bold, 101, 102);
|
||||
});
|
||||
|
||||
test('StackElementMetadata can work at max values', () => {
|
||||
|
@ -85,8 +98,8 @@ test('StackElementMetadata can work at max values', () => {
|
|||
const maxTokenType = StandardTokenType.Comment | StandardTokenType.Other | StandardTokenType.RegEx | StandardTokenType.String;
|
||||
const maxFontStyle = FontStyle.Bold | FontStyle.Italic | FontStyle.Underline;
|
||||
const maxForeground = 511;
|
||||
const maxBackground = 511;
|
||||
const maxBackground = 254;
|
||||
|
||||
let value = StackElementMetadata.set(0, maxLangId, maxTokenType, maxFontStyle, maxForeground, maxBackground);
|
||||
assertEquals(value, maxLangId, maxTokenType, maxFontStyle, maxForeground, maxBackground);
|
||||
let value = StackElementMetadata.set(0, maxLangId, maxTokenType, true, maxFontStyle, maxForeground, maxBackground);
|
||||
assertEquals(value, maxLangId, maxTokenType, true, maxFontStyle, maxForeground, maxBackground);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче