More fine grained dependency resolution:

Only load the subsets of a grammar that are needed. For example, when having include patterns like text.html.markdown#fenced_code_block_js, only process and load needed scopes for the fenced_code_block_js rule in the markdown's grammar rule repository.

Also improves the loading of grammars to load them in parallel.

fixes microsoft/vscode#77990
This commit is contained in:
Alexandru Dima 2019-10-28 15:43:19 +01:00
Родитель 1d44906143
Коммит 9aafda40f3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 6E58D7B045760DA0
6 изменённых файлов: 4138 добавлений и 3906 удалений

366
release/main.d.ts поставляемый
Просмотреть файл

@ -1,181 +1,185 @@
import { IRawGrammar, IOnigLib } from './types';
export * from './types';
/**
* A single theme setting.
*/
export interface IRawThemeSetting {
readonly name?: string;
readonly scope?: string | string[];
readonly settings: {
readonly fontStyle?: string;
readonly foreground?: string;
readonly background?: string;
};
}
/**
* A TextMate theme.
*/
export interface IRawTheme {
readonly name?: string;
readonly settings: IRawThemeSetting[];
}
export interface Thenable<T> extends PromiseLike<T> {
}
/**
* A registry helper that can locate grammar file paths given scope names.
*/
export interface RegistryOptions {
theme?: IRawTheme;
loadGrammar(scopeName: string): Thenable<IRawGrammar | undefined | null>;
getInjections?(scopeName: string): string[];
getOnigLib?(): Thenable<IOnigLib>;
}
/**
* A map from scope name to a language id. Please do not use language id 0.
*/
export interface IEmbeddedLanguagesMap {
[scopeName: string]: number;
}
/**
* A map from selectors to token types.
*/
export interface ITokenTypeMap {
[selector: string]: StandardTokenType;
}
export declare const enum StandardTokenType {
Other = 0,
Comment = 1,
String = 2,
RegEx = 4
}
export interface IGrammarConfiguration {
embeddedLanguages?: IEmbeddedLanguagesMap;
tokenTypes?: ITokenTypeMap;
}
/**
* The registry that will hold all grammars.
*/
export declare class Registry {
private readonly _locator;
private readonly _syncRegistry;
constructor(locator?: RegistryOptions);
/**
* Change the theme. Once called, no previous `ruleStack` should be used anymore.
*/
setTheme(theme: IRawTheme): void;
/**
* Returns a lookup array for color ids.
*/
getColorMap(): string[];
/**
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
* Please do not use language id 0.
*/
loadGrammarWithEmbeddedLanguages(initialScopeName: string, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap): Thenable<IGrammar>;
/**
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
* Please do not use language id 0.
*/
loadGrammarWithConfiguration(initialScopeName: string, initialLanguage: number, configuration: IGrammarConfiguration): Thenable<IGrammar>;
/**
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
*/
loadGrammar(initialScopeName: string): Thenable<IGrammar>;
private _loadGrammar;
/**
* Adds a rawGrammar.
*/
addGrammar(rawGrammar: IRawGrammar, injections?: string[], initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap): Thenable<IGrammar>;
/**
* Get the grammar for `scopeName`. The grammar must first be created via `loadGrammar` or `addGrammar`.
*/
grammarForScopeName(scopeName: string, initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap, tokenTypes?: ITokenTypeMap): Thenable<IGrammar>;
}
/**
* A grammar
*/
export interface IGrammar {
/**
* Tokenize `lineText` using previous line state `prevState`.
*/
tokenizeLine(lineText: string, prevState: StackElement): ITokenizeLineResult;
/**
* Tokenize `lineText` using previous line state `prevState`.
* The result contains the tokens in binary format, resolved with the following information:
* - language
* - token type (regex, string, comment, other)
* - font style
* - foreground color
* - background color
* e.g. for getting the languageId: `(metadata & MetadataConsts.LANGUAGEID_MASK) >>> MetadataConsts.LANGUAGEID_OFFSET`
*/
tokenizeLine2(lineText: string, prevState: StackElement): ITokenizeLineResult2;
}
export interface ITokenizeLineResult {
readonly tokens: IToken[];
/**
* The `prevState` to be passed on to the next line tokenization.
*/
readonly ruleStack: StackElement;
}
/**
* Helpers to manage the "collapsed" metadata of an entire StackElement stack.
* The following assumptions have been made:
* - languageId < 256 => needs 8 bits
* - unique color count < 512 => needs 9 bits
*
* The binary format is:
* - -------------------------------------------
* 3322 2222 2222 1111 1111 1100 0000 0000
* 1098 7654 3210 9876 5432 1098 7654 3210
* - -------------------------------------------
* xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
* bbbb bbbb bfff ffff ffFF FTTT LLLL LLLL
* - -------------------------------------------
* - L = LanguageId (8 bits)
* - T = StandardTokenType (3 bits)
* - F = FontStyle (3 bits)
* - f = foreground color (9 bits)
* - b = background color (9 bits)
*/
export declare const enum MetadataConsts {
LANGUAGEID_MASK = 255,
TOKEN_TYPE_MASK = 1792,
FONT_STYLE_MASK = 14336,
FOREGROUND_MASK = 8372224,
BACKGROUND_MASK = 4286578688,
LANGUAGEID_OFFSET = 0,
TOKEN_TYPE_OFFSET = 8,
FONT_STYLE_OFFSET = 11,
FOREGROUND_OFFSET = 14,
BACKGROUND_OFFSET = 23
}
export interface ITokenizeLineResult2 {
/**
* The tokens in binary format. Each token occupies two array indices. For token i:
* - at offset 2*i => startIndex
* - at offset 2*i + 1 => metadata
*
*/
readonly tokens: Uint32Array;
/**
* The `prevState` to be passed on to the next line tokenization.
*/
readonly ruleStack: StackElement;
}
export interface IToken {
startIndex: number;
readonly endIndex: number;
readonly scopes: string[];
}
/**
* **IMPORTANT** - Immutable!
*/
export interface StackElement {
_stackElementBrand: void;
readonly depth: number;
clone(): StackElement;
equals(other: StackElement): boolean;
}
export declare const INITIAL: StackElement;
export declare const parseRawGrammar: (content: string, filePath?: string) => IRawGrammar;
import { IRawGrammar, IOnigLib } from './types';
export * from './types';
/**
* A single theme setting.
*/
export interface IRawThemeSetting {
readonly name?: string;
readonly scope?: string | string[];
readonly settings: {
readonly fontStyle?: string;
readonly foreground?: string;
readonly background?: string;
};
}
/**
* A TextMate theme.
*/
export interface IRawTheme {
readonly name?: string;
readonly settings: IRawThemeSetting[];
}
export interface Thenable<T> extends PromiseLike<T> {
}
/**
* A registry helper that can locate grammar file paths given scope names.
*/
export interface RegistryOptions {
theme?: IRawTheme;
loadGrammar(scopeName: string): Thenable<IRawGrammar | undefined | null>;
getInjections?(scopeName: string): string[];
getOnigLib?(): Thenable<IOnigLib>;
}
/**
* A map from scope name to a language id. Please do not use language id 0.
*/
export interface IEmbeddedLanguagesMap {
[scopeName: string]: number;
}
/**
* A map from selectors to token types.
*/
export interface ITokenTypeMap {
[selector: string]: StandardTokenType;
}
export declare const enum StandardTokenType {
Other = 0,
Comment = 1,
String = 2,
RegEx = 4
}
export interface IGrammarConfiguration {
embeddedLanguages?: IEmbeddedLanguagesMap;
tokenTypes?: ITokenTypeMap;
}
/**
* The registry that will hold all grammars.
*/
export declare class Registry {
private readonly _locator;
private readonly _syncRegistry;
private readonly _ensureGrammarCache;
constructor(locator?: RegistryOptions);
/**
* Change the theme. Once called, no previous `ruleStack` should be used anymore.
*/
setTheme(theme: IRawTheme): void;
/**
* Returns a lookup array for color ids.
*/
getColorMap(): string[];
/**
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
* Please do not use language id 0.
*/
loadGrammarWithEmbeddedLanguages(initialScopeName: string, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap): Thenable<IGrammar>;
/**
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
* Please do not use language id 0.
*/
loadGrammarWithConfiguration(initialScopeName: string, initialLanguage: number, configuration: IGrammarConfiguration): Thenable<IGrammar>;
/**
* Load the grammar for `scopeName` and all referenced included grammars asynchronously.
*/
loadGrammar(initialScopeName: string): Thenable<IGrammar>;
private _doLoadSingleGrammar;
private _loadSingleGrammar;
private _collectDependenciesForDep;
private _loadGrammar;
/**
* Adds a rawGrammar.
*/
addGrammar(rawGrammar: IRawGrammar, injections?: string[], initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap): Thenable<IGrammar>;
/**
* Get the grammar for `scopeName`. The grammar must first be created via `loadGrammar` or `addGrammar`.
*/
grammarForScopeName(scopeName: string, initialLanguage?: number, embeddedLanguages?: IEmbeddedLanguagesMap, tokenTypes?: ITokenTypeMap): Thenable<IGrammar>;
}
/**
* A grammar
*/
export interface IGrammar {
/**
* Tokenize `lineText` using previous line state `prevState`.
*/
tokenizeLine(lineText: string, prevState: StackElement): ITokenizeLineResult;
/**
* Tokenize `lineText` using previous line state `prevState`.
* The result contains the tokens in binary format, resolved with the following information:
* - language
* - token type (regex, string, comment, other)
* - font style
* - foreground color
* - background color
* e.g. for getting the languageId: `(metadata & MetadataConsts.LANGUAGEID_MASK) >>> MetadataConsts.LANGUAGEID_OFFSET`
*/
tokenizeLine2(lineText: string, prevState: StackElement): ITokenizeLineResult2;
}
export interface ITokenizeLineResult {
readonly tokens: IToken[];
/**
* The `prevState` to be passed on to the next line tokenization.
*/
readonly ruleStack: StackElement;
}
/**
* Helpers to manage the "collapsed" metadata of an entire StackElement stack.
* The following assumptions have been made:
* - languageId < 256 => needs 8 bits
* - unique color count < 512 => needs 9 bits
*
* The binary format is:
* - -------------------------------------------
* 3322 2222 2222 1111 1111 1100 0000 0000
* 1098 7654 3210 9876 5432 1098 7654 3210
* - -------------------------------------------
* xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
* bbbb bbbb bfff ffff ffFF FTTT LLLL LLLL
* - -------------------------------------------
* - L = LanguageId (8 bits)
* - T = StandardTokenType (3 bits)
* - F = FontStyle (3 bits)
* - f = foreground color (9 bits)
* - b = background color (9 bits)
*/
export declare const enum MetadataConsts {
LANGUAGEID_MASK = 255,
TOKEN_TYPE_MASK = 1792,
FONT_STYLE_MASK = 14336,
FOREGROUND_MASK = 8372224,
BACKGROUND_MASK = 4286578688,
LANGUAGEID_OFFSET = 0,
TOKEN_TYPE_OFFSET = 8,
FONT_STYLE_OFFSET = 11,
FOREGROUND_OFFSET = 14,
BACKGROUND_OFFSET = 23
}
export interface ITokenizeLineResult2 {
/**
* The tokens in binary format. Each token occupies two array indices. For token i:
* - at offset 2*i => startIndex
* - at offset 2*i + 1 => metadata
*
*/
readonly tokens: Uint32Array;
/**
* The `prevState` to be passed on to the next line tokenization.
*/
readonly ruleStack: StackElement;
}
export interface IToken {
startIndex: number;
readonly endIndex: number;
readonly scopes: string[];
}
/**
* **IMPORTANT** - Immutable!
*/
export interface StackElement {
_stackElementBrand: void;
readonly depth: number;
clone(): StackElement;
equals(other: StackElement): boolean;
}
export declare const INITIAL: StackElement;
export declare const parseRawGrammar: (content: string, filePath?: string) => IRawGrammar;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

136
release/types.d.ts поставляемый
Просмотреть файл

@ -1,68 +1,68 @@
export interface ILocation {
readonly filename: string;
readonly line: number;
readonly char: number;
}
export interface ILocatable {
readonly $vscodeTextmateLocation?: ILocation;
}
export interface IRawGrammar extends ILocatable {
repository: IRawRepository;
readonly scopeName: string;
readonly patterns: IRawRule[];
readonly injections?: {
[expression: string]: IRawRule;
};
readonly injectionSelector?: string;
readonly fileTypes?: string[];
readonly name?: string;
readonly firstLineMatch?: string;
}
export interface IRawRepositoryMap {
[name: string]: IRawRule;
$self: IRawRule;
$base: IRawRule;
}
export declare type IRawRepository = IRawRepositoryMap & ILocatable;
export interface IRawRule extends ILocatable {
id?: number;
readonly include?: string;
readonly name?: string;
readonly contentName?: string;
readonly match?: string;
readonly captures?: IRawCaptures;
readonly begin?: string;
readonly beginCaptures?: IRawCaptures;
readonly end?: string;
readonly endCaptures?: IRawCaptures;
readonly while?: string;
readonly whileCaptures?: IRawCaptures;
readonly patterns?: IRawRule[];
readonly repository?: IRawRepository;
readonly applyEndPatternLast?: boolean;
}
export interface IRawCapturesMap {
[captureId: string]: IRawRule;
}
export declare type IRawCaptures = IRawCapturesMap & ILocatable;
export interface IOnigLib {
createOnigScanner(sources: string[]): OnigScanner;
createOnigString(sources: string): OnigString;
}
export interface IOnigCaptureIndex {
start: number;
end: number;
length: number;
}
export interface IOnigMatch {
index: number;
captureIndices: IOnigCaptureIndex[];
scanner: OnigScanner;
}
export interface OnigScanner {
findNextMatchSync(string: string | OnigString, startPosition: number): IOnigMatch;
}
export interface OnigString {
readonly content: string;
readonly dispose?: () => void;
}
export interface ILocation {
readonly filename: string;
readonly line: number;
readonly char: number;
}
export interface ILocatable {
readonly $vscodeTextmateLocation?: ILocation;
}
export interface IRawGrammar extends ILocatable {
repository: IRawRepository;
readonly scopeName: string;
readonly patterns: IRawRule[];
readonly injections?: {
[expression: string]: IRawRule;
};
readonly injectionSelector?: string;
readonly fileTypes?: string[];
readonly name?: string;
readonly firstLineMatch?: string;
}
export interface IRawRepositoryMap {
[name: string]: IRawRule;
$self: IRawRule;
$base: IRawRule;
}
export declare type IRawRepository = IRawRepositoryMap & ILocatable;
export interface IRawRule extends ILocatable {
id?: number;
readonly include?: string;
readonly name?: string;
readonly contentName?: string;
readonly match?: string;
readonly captures?: IRawCaptures;
readonly begin?: string;
readonly beginCaptures?: IRawCaptures;
readonly end?: string;
readonly endCaptures?: IRawCaptures;
readonly while?: string;
readonly whileCaptures?: IRawCaptures;
readonly patterns?: IRawRule[];
readonly repository?: IRawRepository;
readonly applyEndPatternLast?: boolean;
}
export interface IRawCapturesMap {
[captureId: string]: IRawRule;
}
export declare type IRawCaptures = IRawCapturesMap & ILocatable;
export interface IOnigLib {
createOnigScanner(sources: string[]): OnigScanner;
createOnigString(sources: string): OnigString;
}
export interface IOnigCaptureIndex {
start: number;
end: number;
length: number;
}
export interface IOnigMatch {
index: number;
captureIndices: IOnigCaptureIndex[];
scanner: OnigScanner;
}
export interface OnigScanner {
findNextMatchSync(string: string | OnigString, startPosition: number): IOnigMatch;
}
export interface OnigString {
readonly content: string;
readonly dispose?: () => void;
}

Просмотреть файл

@ -37,14 +37,63 @@ export interface IScopeNameSet {
[scopeName: string]: boolean;
}
export class FullScopeDependency {
constructor(
public readonly scopeName: string
) { }
}
export class PartialScopeDependency {
constructor(
public readonly scopeName: string,
public readonly include: string
) { }
public toKey(): string {
return `${this.scopeName}#${this.include}`;
}
}
export type ScopeDependency = FullScopeDependency | PartialScopeDependency;
export class ScopeDependencyCollector {
public readonly full: FullScopeDependency[];
public readonly partial: PartialScopeDependency[];
private readonly _seenFull: Set<string>;
private readonly _seenPartial: Set<string>;
constructor() {
this.full = [];
this.partial = [];
this._seenFull = new Set<string>();
this._seenPartial = new Set<string>();
}
public add(dep: ScopeDependency): void {
if (dep instanceof FullScopeDependency) {
if (!this._seenFull.has(dep.scopeName)) {
this._seenFull.add(dep.scopeName);
this.full.push(dep);
}
} else {
if (!this._seenPartial.has(dep.toKey())) {
this._seenPartial.add(dep.toKey());
this.partial.push(dep);
}
}
}
}
/**
* Fill in `result` all external included scopes in `patterns`
*/
function _extractIncludedScopesInPatterns(result: IScopeNameSet, patterns: IRawRule[]): void {
function _extractIncludedScopesInPatterns(result: ScopeDependencyCollector, grammarScopeName: string, patterns: IRawRule[]): void {
for (const pattern of patterns) {
if (Array.isArray(pattern.patterns)) {
_extractIncludedScopesInPatterns(result, pattern.patterns);
_extractIncludedScopesInPatterns(result, grammarScopeName, pattern.patterns);
}
const include = pattern.include;
@ -65,9 +114,14 @@ function _extractIncludedScopesInPatterns(result: IScopeNameSet, patterns: IRawR
const sharpIndex = include.indexOf('#');
if (sharpIndex >= 0) {
result[include.substring(0, sharpIndex)] = true;
const scopeName = include.substring(0, sharpIndex);
if (scopeName !== grammarScopeName) {
result.add(new PartialScopeDependency(scopeName, include.substring(sharpIndex + 1)));
}
} else {
result[include] = true;
if (include !== grammarScopeName) {
result.add(new FullScopeDependency(include));
}
}
}
}
@ -75,16 +129,33 @@ function _extractIncludedScopesInPatterns(result: IScopeNameSet, patterns: IRawR
/**
* Fill in `result` all external included scopes in `repository`
*/
function _extractIncludedScopesInRepository(result: IScopeNameSet, repository: IRawRepository): void {
function _extractIncludedScopesInRepository(result: ScopeDependencyCollector, grammarScopeName: string, repository: IRawRepository): void {
for (let name in repository) {
const rule = repository[name];
if (rule.patterns && Array.isArray(rule.patterns)) {
_extractIncludedScopesInPatterns(result, rule.patterns);
_extractIncludedScopesInPatterns(result, grammarScopeName, rule.patterns);
}
if (rule.repository) {
_extractIncludedScopesInRepository(result, rule.repository);
_extractIncludedScopesInRepository(result, grammarScopeName, rule.repository);
}
}
}
/**
* Collect a specific dependency from the grammar's repository
*/
export function collectSpecificDependencies(result: ScopeDependencyCollector, grammar: IRawGrammar, include: string): void {
if (grammar.repository && grammar.repository[include]) {
const rule = grammar.repository[include];
if (rule.patterns && Array.isArray(rule.patterns)) {
_extractIncludedScopesInPatterns(result, grammar.scopeName, rule.patterns);
}
if (rule.repository) {
_extractIncludedScopesInRepository(result, grammar.scopeName, rule.repository);
}
}
}
@ -92,17 +163,14 @@ function _extractIncludedScopesInRepository(result: IScopeNameSet, repository: I
/**
* Collects the list of all external included scopes in `grammar`.
*/
export function collectIncludedScopes(result: IScopeNameSet, grammar: IRawGrammar): void {
export function collectDependencies(result: ScopeDependencyCollector, grammar: IRawGrammar): void {
if (grammar.patterns && Array.isArray(grammar.patterns)) {
_extractIncludedScopesInPatterns(result, grammar.patterns);
_extractIncludedScopesInPatterns(result, grammar.scopeName, grammar.patterns);
}
if (grammar.repository) {
_extractIncludedScopesInRepository(result, grammar.repository);
_extractIncludedScopesInRepository(result, grammar.scopeName, grammar.repository);
}
// remove references to own scope (avoid recursion)
delete result[grammar.scopeName];
}
export interface Injection {

Просмотреть файл

@ -6,7 +6,7 @@
import { SyncRegistry } from './registry';
import * as grammarReader from './grammarReader';
import { Theme } from './theme';
import { StackElement as StackElementImpl } from './grammar';
import { StackElement as StackElementImpl, collectDependencies, ScopeDependencyCollector, collectSpecificDependencies, FullScopeDependency, PartialScopeDependency, ScopeDependency } from './grammar';
import { IRawGrammar, IOnigLib } from './types';
export * from './types';
@ -78,10 +78,12 @@ export class Registry {
private readonly _locator: RegistryOptions;
private readonly _syncRegistry: SyncRegistry;
private readonly _ensureGrammarCache: Map<string, Promise<void>>;
constructor(locator: RegistryOptions = { loadGrammar: () => null }) {
this._locator = locator;
this._syncRegistry = new SyncRegistry(Theme.createFromRawTheme(locator.theme), locator.getOnigLib && locator.getOnigLib());
this._ensureGrammarCache = new Map<string, Promise<void>>();
}
/**
@ -121,34 +123,83 @@ export class Registry {
return this._loadGrammar(initialScopeName, 0, null, null);
}
private async _doLoadSingleGrammar(scopeName: string): Promise<void> {
const grammar = await this._locator.loadGrammar(scopeName);
if (grammar) {
const injections = (typeof this._locator.getInjections === 'function') && this._locator.getInjections(scopeName);
this._syncRegistry.addGrammar(grammar, injections);
}
}
private async _loadSingleGrammar(scopeName: string): Promise<void> {
if (!this._ensureGrammarCache.has(scopeName)) {
this._ensureGrammarCache.set(scopeName, this._doLoadSingleGrammar(scopeName));
}
return this._ensureGrammarCache.get(scopeName);
}
private _collectDependenciesForDep(initialScopeName: string, result: ScopeDependencyCollector, dep: FullScopeDependency | PartialScopeDependency) {
const grammar = this._syncRegistry.lookup(dep.scopeName);
if (!grammar) {
if (dep.scopeName === initialScopeName) {
throw new Error(`No grammar provided for <${initialScopeName}>`);
}
return;
}
if (dep instanceof FullScopeDependency) {
collectDependencies(result, grammar);
} else {
collectSpecificDependencies(result, grammar, dep.include);
}
const injections = this._syncRegistry.injections(dep.scopeName);
if (injections) {
for (const injection of injections) {
result.add(new FullScopeDependency(injection));
}
}
}
private async _loadGrammar(initialScopeName: string, initialLanguage: number, embeddedLanguages: IEmbeddedLanguagesMap, tokenTypes: ITokenTypeMap): Promise<IGrammar> {
let remainingScopeNames = [initialScopeName];
const seenFullScopeRequests = new Set<string>();
const seenPartialScopeRequests = new Set<string>();
let seenScopeNames: { [name: string]: boolean; } = {};
seenScopeNames[initialScopeName] = true;
seenFullScopeRequests.add(initialScopeName);
let Q: ScopeDependency[] = [new FullScopeDependency(initialScopeName)];
while (remainingScopeNames.length > 0) {
let scopeName = remainingScopeNames.shift();
while (Q.length > 0) {
const q = Q;
Q = [];
if (this._syncRegistry.lookup(scopeName)) {
continue;
await Promise.all(q.map(request => this._loadSingleGrammar(request.scopeName)));
const deps = new ScopeDependencyCollector();
for (const dep of q) {
this._collectDependenciesForDep(initialScopeName, deps, dep);
}
let grammar = await this._locator.loadGrammar(scopeName);
if (!grammar) {
if (scopeName === initialScopeName) {
throw new Error(`No grammar provided for <${initialScopeName}>`);
for (const dep of deps.full) {
if (seenFullScopeRequests.has(dep.scopeName)) {
// already processed
continue;
}
} else {
let injections = (typeof this._locator.getInjections === 'function') && this._locator.getInjections(scopeName);
let deps = this._syncRegistry.addGrammar(grammar, injections);
deps.forEach((dep) => {
if (!seenScopeNames[dep]) {
seenScopeNames[dep] = true;
remainingScopeNames.push(dep);
}
});
seenFullScopeRequests.add(dep.scopeName);
Q.push(dep);
}
for (const dep of deps.partial) {
if (seenFullScopeRequests.has(dep.scopeName)) {
// already processed in full
continue;
}
if (seenPartialScopeRequests.has(dep.toKey())) {
// already processed
continue;
}
seenPartialScopeRequests.add(dep.toKey());
Q.push(dep);
}
}

Просмотреть файл

@ -3,7 +3,7 @@
*--------------------------------------------------------*/
'use strict';
import { createGrammar, Grammar, collectIncludedScopes, IGrammarRepository, IScopeNameSet } from './grammar';
import { createGrammar, Grammar, IGrammarRepository } from './grammar';
import { IRawGrammar } from './types';
import { Thenable } from './main';
import { IGrammar, IEmbeddedLanguagesMap, ITokenTypeMap } from './main';
@ -42,19 +42,12 @@ export class SyncRegistry implements IGrammarRepository {
/**
* Add `grammar` to registry and return a list of referenced scope names
*/
public addGrammar(grammar: IRawGrammar, injectionScopeNames?: string[]): string[] {
public addGrammar(grammar: IRawGrammar, injectionScopeNames?: string[]): void {
this._rawGrammars[grammar.scopeName] = grammar;
let includedScopes: IScopeNameSet = {};
collectIncludedScopes(includedScopes, grammar);
if (injectionScopeNames) {
this._injectionGrammars[grammar.scopeName] = injectionScopeNames;
injectionScopeNames.forEach(scopeName => {
includedScopes[scopeName] = true;
});
}
return Object.keys(includedScopes);
}
/**