// src/utils.ts function clone(something) { return doClone(something); } function doClone(something) { if (Array.isArray(something)) { return cloneArray(something); } if (something instanceof RegExp) { return something; } if (typeof something === "object") { return cloneObj(something); } return something; } function cloneArray(arr) { let r = []; for (let i = 0, len = arr.length; i < len; i++) { r[i] = doClone(arr[i]); } return r; } function cloneObj(obj) { let r = {}; for (let key in obj) { r[key] = doClone(obj[key]); } return r; } function mergeObjects(target, ...sources) { sources.forEach((source) => { for (let key in source) { target[key] = source[key]; } }); return target; } function basename(path) { const idx = ~path.lastIndexOf("/") || ~path.lastIndexOf("\\"); if (idx === 0) { return path; } else if (~idx === path.length - 1) { return basename(path.substring(0, path.length - 1)); } else { return path.substr(~idx + 1); } } var CAPTURING_REGEX_SOURCE = /\$(\d+)|\${(\d+):\/(downcase|upcase)}/g; var RegexSource = class { static hasCaptures(regexSource) { if (regexSource === null) { return false; } CAPTURING_REGEX_SOURCE.lastIndex = 0; return CAPTURING_REGEX_SOURCE.test(regexSource); } static replaceCaptures(regexSource, captureSource, captureIndices) { return regexSource.replace(CAPTURING_REGEX_SOURCE, (match, index, commandIndex, command) => { let capture = captureIndices[parseInt(index || commandIndex, 10)]; if (capture) { let result = captureSource.substring(capture.start, capture.end); while (result[0] === ".") { result = result.substring(1); } switch (command) { case "downcase": return result.toLowerCase(); case "upcase": return result.toUpperCase(); default: return result; } } else { return match; } }); } }; function strcmp(a, b) { if (a < b) { return -1; } if (a > b) { return 1; } return 0; } function strArrCmp(a, b) { if (a === null && b === null) { return 0; } if (!a) { return -1; } if (!b) { return 1; } let len1 = a.length; let len2 = b.length; if (len1 === len2) { for (let i = 0; i < len1; i++) { let res = strcmp(a[i], b[i]); if (res !== 0) { return res; } } return 0; } return len1 - len2; } function isValidHexColor(hex) { if (/^#[0-9a-f]{6}$/i.test(hex)) { return true; } if (/^#[0-9a-f]{8}$/i.test(hex)) { return true; } if (/^#[0-9a-f]{3}$/i.test(hex)) { return true; } if (/^#[0-9a-f]{4}$/i.test(hex)) { return true; } return false; } function escapeRegExpCharacters(value) { return value.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g, "\\$&"); } var CachedFn = class { constructor(fn) { this.fn = fn; } cache = /* @__PURE__ */ new Map(); get(key) { if (this.cache.has(key)) { return this.cache.get(key); } const value = this.fn(key); this.cache.set(key, value); return value; } }; // src/theme.ts var Theme = class { constructor(_colorMap, _defaults, _root) { this._colorMap = _colorMap; this._defaults = _defaults; this._root = _root; } static createFromRawTheme(source, colorMap) { return this.createFromParsedTheme(parseTheme(source), colorMap); } static createFromParsedTheme(source, colorMap) { return resolveParsedThemeRules(source, colorMap); } _cachedMatchRoot = new CachedFn( (scopeName) => this._root.match(scopeName) ); getColorMap() { return this._colorMap.getColorMap(); } getDefaults() { return this._defaults; } match(scopePath) { if (scopePath === null) { return this._defaults; } const scopeName = scopePath.scopeName; const matchingTrieElements = this._cachedMatchRoot.get(scopeName); const effectiveRule = matchingTrieElements.find( (v) => _scopePathMatchesParentScopes(scopePath.parent, v.parentScopes) ); if (!effectiveRule) { return null; } return new StyleAttributes( effectiveRule.fontStyle, effectiveRule.foreground, effectiveRule.background ); } }; var ScopeStack = class _ScopeStack { constructor(parent, scopeName) { this.parent = parent; this.scopeName = scopeName; } static push(path, scopeNames) { for (const name of scopeNames) { path = new _ScopeStack(path, name); } return path; } static from(...segments) { let result = null; for (let i = 0; i < segments.length; i++) { result = new _ScopeStack(result, segments[i]); } return result; } push(scopeName) { return new _ScopeStack(this, scopeName); } getSegments() { let item = this; const result = []; while (item) { result.push(item.scopeName); item = item.parent; } result.reverse(); return result; } toString() { return this.getSegments().join(" "); } extends(other) { if (this === other) { return true; } if (this.parent === null) { return false; } return this.parent.extends(other); } getExtensionIfDefined(base) { const result = []; let item = this; while (item && item !== base) { result.push(item.scopeName); item = item.parent; } return item === base ? result.reverse() : void 0; } }; function _scopePathMatchesParentScopes(scopePath, parentScopes) { if (parentScopes.length === 0) { return true; } for (let index = 0; index < parentScopes.length; index++) { let scopePattern = parentScopes[index]; let scopeMustMatch = false; if (scopePattern === ">") { if (index === parentScopes.length - 1) { return false; } scopePattern = parentScopes[++index]; scopeMustMatch = true; } while (scopePath) { if (_matchesScope(scopePath.scopeName, scopePattern)) { break; } if (scopeMustMatch) { return false; } scopePath = scopePath.parent; } if (!scopePath) { return false; } scopePath = scopePath.parent; } return true; } function _matchesScope(scopeName, scopePattern) { return scopePattern === scopeName || scopeName.startsWith(scopePattern) && scopeName[scopePattern.length] === "."; } var StyleAttributes = class { constructor(fontStyle, foregroundId, backgroundId) { this.fontStyle = fontStyle; this.foregroundId = foregroundId; this.backgroundId = backgroundId; } }; function parseTheme(source) { if (!source) { return []; } if (!source.settings || !Array.isArray(source.settings)) { return []; } let settings = source.settings; let result = [], resultLen = 0; for (let i = 0, len = settings.length; i < len; i++) { let entry = settings[i]; if (!entry.settings) { continue; } let scopes; if (typeof entry.scope === "string") { let _scope = entry.scope; _scope = _scope.replace(/^[,]+/, ""); _scope = _scope.replace(/[,]+$/, ""); scopes = _scope.split(","); } else if (Array.isArray(entry.scope)) { scopes = entry.scope; } else { scopes = [""]; } let fontStyle = -1 /* NotSet */; if (typeof entry.settings.fontStyle === "string") { fontStyle = 0 /* None */; let segments = entry.settings.fontStyle.split(" "); for (let j = 0, lenJ = segments.length; j < lenJ; j++) { let segment = segments[j]; switch (segment) { case "italic": fontStyle = fontStyle | 1 /* Italic */; break; case "bold": fontStyle = fontStyle | 2 /* Bold */; break; case "underline": fontStyle = fontStyle | 4 /* Underline */; break; case "strikethrough": fontStyle = fontStyle | 8 /* Strikethrough */; break; } } } let foreground = null; if (typeof entry.settings.foreground === "string" && isValidHexColor(entry.settings.foreground)) { foreground = entry.settings.foreground; } let background = null; if (typeof entry.settings.background === "string" && isValidHexColor(entry.settings.background)) { background = entry.settings.background; } for (let j = 0, lenJ = scopes.length; j < lenJ; j++) { let _scope = scopes[j].trim(); let segments = _scope.split(" "); let scope = segments[segments.length - 1]; let parentScopes = null; if (segments.length > 1) { parentScopes = segments.slice(0, segments.length - 1); parentScopes.reverse(); } result[resultLen++] = new ParsedThemeRule( scope, parentScopes, i, fontStyle, foreground, background ); } } return result; } var ParsedThemeRule = class { constructor(scope, parentScopes, index, fontStyle, foreground, background) { this.scope = scope; this.parentScopes = parentScopes; this.index = index; this.fontStyle = fontStyle; this.foreground = foreground; this.background = background; } }; var FontStyle = /* @__PURE__ */ ((FontStyle2) => { FontStyle2[FontStyle2["NotSet"] = -1] = "NotSet"; FontStyle2[FontStyle2["None"] = 0] = "None"; FontStyle2[FontStyle2["Italic"] = 1] = "Italic"; FontStyle2[FontStyle2["Bold"] = 2] = "Bold"; FontStyle2[FontStyle2["Underline"] = 4] = "Underline"; FontStyle2[FontStyle2["Strikethrough"] = 8] = "Strikethrough"; return FontStyle2; })(FontStyle || {}); function resolveParsedThemeRules(parsedThemeRules, _colorMap) { parsedThemeRules.sort((a, b) => { let r = strcmp(a.scope, b.scope); if (r !== 0) { return r; } r = strArrCmp(a.parentScopes, b.parentScopes); if (r !== 0) { return r; } return a.index - b.index; }); let defaultFontStyle = 0 /* None */; let defaultForeground = "#000000"; let defaultBackground = "#ffffff"; while (parsedThemeRules.length >= 1 && parsedThemeRules[0].scope === "") { let incomingDefaults = parsedThemeRules.shift(); if (incomingDefaults.fontStyle !== -1 /* NotSet */) { defaultFontStyle = incomingDefaults.fontStyle; } if (incomingDefaults.foreground !== null) { defaultForeground = incomingDefaults.foreground; } if (incomingDefaults.background !== null) { defaultBackground = incomingDefaults.background; } } let colorMap = new ColorMap(_colorMap); let defaults = new StyleAttributes(defaultFontStyle, colorMap.getId(defaultForeground), colorMap.getId(defaultBackground)); let root = new ThemeTrieElement(new ThemeTrieElementRule(0, null, -1 /* NotSet */, 0, 0), []); for (let i = 0, len = parsedThemeRules.length; i < len; i++) { let rule = parsedThemeRules[i]; root.insert(0, rule.scope, rule.parentScopes, rule.fontStyle, colorMap.getId(rule.foreground), colorMap.getId(rule.background)); } return new Theme(colorMap, defaults, root); } var ColorMap = class { _isFrozen; _lastColorId; _id2color; _color2id; constructor(_colorMap) { this._lastColorId = 0; this._id2color = []; this._color2id = /* @__PURE__ */ Object.create(null); if (Array.isArray(_colorMap)) { this._isFrozen = true; for (let i = 0, len = _colorMap.length; i < len; i++) { this._color2id[_colorMap[i]] = i; this._id2color[i] = _colorMap[i]; } } else { this._isFrozen = false; } } getId(color) { if (color === null) { return 0; } color = color.toUpperCase(); let value = this._color2id[color]; if (value) { return value; } if (this._isFrozen) { throw new Error(`Missing color in color map - ${color}`); } value = ++this._lastColorId; this._color2id[color] = value; this._id2color[value] = color; return value; } getColorMap() { return this._id2color.slice(0); } }; var emptyParentScopes = Object.freeze([]); var ThemeTrieElementRule = class _ThemeTrieElementRule { scopeDepth; parentScopes; fontStyle; foreground; background; constructor(scopeDepth, parentScopes, fontStyle, foreground, background) { this.scopeDepth = scopeDepth; this.parentScopes = parentScopes || emptyParentScopes; this.fontStyle = fontStyle; this.foreground = foreground; this.background = background; } clone() { return new _ThemeTrieElementRule(this.scopeDepth, this.parentScopes, this.fontStyle, this.foreground, this.background); } static cloneArr(arr) { let r = []; for (let i = 0, len = arr.length; i < len; i++) { r[i] = arr[i].clone(); } return r; } acceptOverwrite(scopeDepth, fontStyle, foreground, background) { if (this.scopeDepth > scopeDepth) { console.log("how did this happen?"); } else { this.scopeDepth = scopeDepth; } if (fontStyle !== -1 /* NotSet */) { this.fontStyle = fontStyle; } if (foreground !== 0) { this.foreground = foreground; } if (background !== 0) { this.background = background; } } }; var ThemeTrieElement = class _ThemeTrieElement { constructor(_mainRule, rulesWithParentScopes = [], _children = {}) { this._mainRule = _mainRule; this._children = _children; this._rulesWithParentScopes = rulesWithParentScopes; } _rulesWithParentScopes; static _cmpBySpecificity(a, b) { if (a.scopeDepth !== b.scopeDepth) { return b.scopeDepth - a.scopeDepth; } let aParentIndex = 0; let bParentIndex = 0; while (true) { if (a.parentScopes[aParentIndex] === ">") { aParentIndex++; } if (b.parentScopes[bParentIndex] === ">") { bParentIndex++; } if (aParentIndex >= a.parentScopes.length || bParentIndex >= b.parentScopes.length) { break; } const parentScopeLengthDiff = b.parentScopes[bParentIndex].length - a.parentScopes[aParentIndex].length; if (parentScopeLengthDiff !== 0) { return parentScopeLengthDiff; } aParentIndex++; bParentIndex++; } return b.parentScopes.length - a.parentScopes.length; } match(scope) { if (scope !== "") { let dotIndex = scope.indexOf("."); let head; let tail; if (dotIndex === -1) { head = scope; tail = ""; } else { head = scope.substring(0, dotIndex); tail = scope.substring(dotIndex + 1); } if (this._children.hasOwnProperty(head)) { return this._children[head].match(tail); } } const rules = this._rulesWithParentScopes.concat(this._mainRule); rules.sort(_ThemeTrieElement._cmpBySpecificity); return rules; } insert(scopeDepth, scope, parentScopes, fontStyle, foreground, background) { if (scope === "") { this._doInsertHere(scopeDepth, parentScopes, fontStyle, foreground, background); return; } let dotIndex = scope.indexOf("."); let head; let tail; if (dotIndex === -1) { head = scope; tail = ""; } else { head = scope.substring(0, dotIndex); tail = scope.substring(dotIndex + 1); } let child; if (this._children.hasOwnProperty(head)) { child = this._children[head]; } else { child = new _ThemeTrieElement(this._mainRule.clone(), ThemeTrieElementRule.cloneArr(this._rulesWithParentScopes)); this._children[head] = child; } child.insert(scopeDepth + 1, tail, parentScopes, fontStyle, foreground, background); } _doInsertHere(scopeDepth, parentScopes, fontStyle, foreground, background) { if (parentScopes === null) { this._mainRule.acceptOverwrite(scopeDepth, fontStyle, foreground, background); return; } for (let i = 0, len = this._rulesWithParentScopes.length; i < len; i++) { let rule = this._rulesWithParentScopes[i]; if (strArrCmp(rule.parentScopes, parentScopes) === 0) { rule.acceptOverwrite(scopeDepth, fontStyle, foreground, background); return; } } if (fontStyle === -1 /* NotSet */) { fontStyle = this._mainRule.fontStyle; } if (foreground === 0) { foreground = this._mainRule.foreground; } if (background === 0) { background = this._mainRule.background; } this._rulesWithParentScopes.push(new ThemeTrieElementRule(scopeDepth, parentScopes, fontStyle, foreground, background)); } }; // src/encodedTokenAttributes.ts var EncodedTokenMetadata = class _EncodedTokenMetadata { static toBinaryStr(encodedTokenAttributes) { return encodedTokenAttributes.toString(2).padStart(32, "0"); } static print(encodedTokenAttributes) { const languageId = _EncodedTokenMetadata.getLanguageId(encodedTokenAttributes); const tokenType = _EncodedTokenMetadata.getTokenType(encodedTokenAttributes); const fontStyle = _EncodedTokenMetadata.getFontStyle(encodedTokenAttributes); const foreground = _EncodedTokenMetadata.getForeground(encodedTokenAttributes); const background = _EncodedTokenMetadata.getBackground(encodedTokenAttributes); console.log({ languageId, tokenType, fontStyle, foreground, background }); } static getLanguageId(encodedTokenAttributes) { return (encodedTokenAttributes & 255 /* LANGUAGEID_MASK */) >>> 0 /* LANGUAGEID_OFFSET */; } static getTokenType(encodedTokenAttributes) { return (encodedTokenAttributes & 768 /* TOKEN_TYPE_MASK */) >>> 8 /* TOKEN_TYPE_OFFSET */; } static containsBalancedBrackets(encodedTokenAttributes) { return (encodedTokenAttributes & 1024 /* BALANCED_BRACKETS_MASK */) !== 0; } static getFontStyle(encodedTokenAttributes) { return (encodedTokenAttributes & 30720 /* FONT_STYLE_MASK */) >>> 11 /* FONT_STYLE_OFFSET */; } static getForeground(encodedTokenAttributes) { return (encodedTokenAttributes & 16744448 /* FOREGROUND_MASK */) >>> 15 /* FOREGROUND_OFFSET */; } static getBackground(encodedTokenAttributes) { return (encodedTokenAttributes & 4278190080 /* BACKGROUND_MASK */) >>> 24 /* BACKGROUND_OFFSET */; } /** * Updates the fields in `metadata`. * A value of `0`, `NotSet` or `null` indicates that the corresponding field should be left as is. */ static set(encodedTokenAttributes, languageId, tokenType, containsBalancedBrackets, fontStyle, foreground, background) { let _languageId = _EncodedTokenMetadata.getLanguageId(encodedTokenAttributes); let _tokenType = _EncodedTokenMetadata.getTokenType(encodedTokenAttributes); let _containsBalancedBracketsBit = _EncodedTokenMetadata.containsBalancedBrackets(encodedTokenAttributes) ? 1 : 0; let _fontStyle = _EncodedTokenMetadata.getFontStyle(encodedTokenAttributes); let _foreground = _EncodedTokenMetadata.getForeground(encodedTokenAttributes); let _background = _EncodedTokenMetadata.getBackground(encodedTokenAttributes); if (languageId !== 0) { _languageId = languageId; } if (tokenType !== 8 /* NotSet */) { _tokenType = fromOptionalTokenType(tokenType); } if (containsBalancedBrackets !== null) { _containsBalancedBracketsBit = containsBalancedBrackets ? 1 : 0; } if (fontStyle !== -1 /* NotSet */) { _fontStyle = fontStyle; } if (foreground !== 0) { _foreground = foreground; } if (background !== 0) { _background = background; } return (_languageId << 0 /* LANGUAGEID_OFFSET */ | _tokenType << 8 /* TOKEN_TYPE_OFFSET */ | _containsBalancedBracketsBit << 10 /* BALANCED_BRACKETS_OFFSET */ | _fontStyle << 11 /* FONT_STYLE_OFFSET */ | _foreground << 15 /* FOREGROUND_OFFSET */ | _background << 24 /* BACKGROUND_OFFSET */) >>> 0; } }; function toOptionalTokenType(standardType) { return standardType; } function fromOptionalTokenType(standardType) { return standardType; } // src/matcher.ts function createMatchers(selector, matchesName) { const results = []; const tokenizer = newTokenizer(selector); let token = tokenizer.next(); while (token !== null) { let priority = 0; if (token.length === 2 && token.charAt(1) === ":") { switch (token.charAt(0)) { case "R": priority = 1; break; case "L": priority = -1; break; default: console.log(`Unknown priority ${token} in scope selector`); } token = tokenizer.next(); } let matcher = parseConjunction(); results.push({ matcher, priority }); if (token !== ",") { break; } token = tokenizer.next(); } return results; function parseOperand() { if (token === "-") { token = tokenizer.next(); const expressionToNegate = parseOperand(); return (matcherInput) => !!expressionToNegate && !expressionToNegate(matcherInput); } if (token === "(") { token = tokenizer.next(); const expressionInParents = parseInnerExpression(); if (token === ")") { token = tokenizer.next(); } return expressionInParents; } if (isIdentifier(token)) { const identifiers = []; do { identifiers.push(token); token = tokenizer.next(); } while (isIdentifier(token)); return (matcherInput) => matchesName(identifiers, matcherInput); } return null; } function parseConjunction() { const matchers = []; let matcher = parseOperand(); while (matcher) { matchers.push(matcher); matcher = parseOperand(); } return (matcherInput) => matchers.every((matcher2) => matcher2(matcherInput)); } function parseInnerExpression() { const matchers = []; let matcher = parseConjunction(); while (matcher) { matchers.push(matcher); if (token === "|" || token === ",") { do { token = tokenizer.next(); } while (token === "|" || token === ","); } else { break; } matcher = parseConjunction(); } return (matcherInput) => matchers.some((matcher2) => matcher2(matcherInput)); } } function isIdentifier(token) { return !!token && !!token.match(/[\w\.:]+/); } function newTokenizer(input) { let regex = /([LR]:|[\w\.:][\w\.:\-]*|[\,\|\-\(\)])/g; let match = regex.exec(input); return { next: () => { if (!match) { return null; } const res = match[0]; match = regex.exec(input); return res; } }; } // src/onigLib.ts var FindOption = /* @__PURE__ */ ((FindOption2) => { FindOption2[FindOption2["None"] = 0] = "None"; FindOption2[FindOption2["NotBeginString"] = 1] = "NotBeginString"; FindOption2[FindOption2["NotEndString"] = 2] = "NotEndString"; FindOption2[FindOption2["NotBeginPosition"] = 4] = "NotBeginPosition"; FindOption2[FindOption2["DebugCall"] = 8] = "DebugCall"; return FindOption2; })(FindOption || {}); function disposeOnigString(str) { if (typeof str.dispose === "function") { str.dispose(); } } // src/grammar/grammarDependencies.ts var TopLevelRuleReference = class { constructor(scopeName) { this.scopeName = scopeName; } toKey() { return this.scopeName; } }; var TopLevelRepositoryRuleReference = class { constructor(scopeName, ruleName) { this.scopeName = scopeName; this.ruleName = ruleName; } toKey() { return `${this.scopeName}#${this.ruleName}`; } }; var ExternalReferenceCollector = class { _references = []; _seenReferenceKeys = /* @__PURE__ */ new Set(); get references() { return this._references; } visitedRule = /* @__PURE__ */ new Set(); add(reference) { const key = reference.toKey(); if (this._seenReferenceKeys.has(key)) { return; } this._seenReferenceKeys.add(key); this._references.push(reference); } }; var ScopeDependencyProcessor = class { constructor(repo, initialScopeName) { this.repo = repo; this.initialScopeName = initialScopeName; this.seenFullScopeRequests.add(this.initialScopeName); this.Q = [new TopLevelRuleReference(this.initialScopeName)]; } seenFullScopeRequests = /* @__PURE__ */ new Set(); seenPartialScopeRequests = /* @__PURE__ */ new Set(); Q; processQueue() { const q = this.Q; this.Q = []; const deps = new ExternalReferenceCollector(); for (const dep of q) { collectReferencesOfReference(dep, this.initialScopeName, this.repo, deps); } for (const dep of deps.references) { if (dep instanceof TopLevelRuleReference) { if (this.seenFullScopeRequests.has(dep.scopeName)) { continue; } this.seenFullScopeRequests.add(dep.scopeName); this.Q.push(dep); } else { if (this.seenFullScopeRequests.has(dep.scopeName)) { continue; } if (this.seenPartialScopeRequests.has(dep.toKey())) { continue; } this.seenPartialScopeRequests.add(dep.toKey()); this.Q.push(dep); } } } }; function collectReferencesOfReference(reference, baseGrammarScopeName, repo, result) { const selfGrammar = repo.lookup(reference.scopeName); if (!selfGrammar) { if (reference.scopeName === baseGrammarScopeName) { throw new Error(`No grammar provided for <${baseGrammarScopeName}>`); } return; } const baseGrammar = repo.lookup(baseGrammarScopeName); if (reference instanceof TopLevelRuleReference) { collectExternalReferencesInTopLevelRule({ baseGrammar, selfGrammar }, result); } else { collectExternalReferencesInTopLevelRepositoryRule( reference.ruleName, { baseGrammar, selfGrammar, repository: selfGrammar.repository }, result ); } const injections = repo.injections(reference.scopeName); if (injections) { for (const injection of injections) { result.add(new TopLevelRuleReference(injection)); } } } function collectExternalReferencesInTopLevelRepositoryRule(ruleName, context, result) { if (context.repository && context.repository[ruleName]) { const rule = context.repository[ruleName]; collectExternalReferencesInRules([rule], context, result); } } function collectExternalReferencesInTopLevelRule(context, result) { if (context.selfGrammar.patterns && Array.isArray(context.selfGrammar.patterns)) { collectExternalReferencesInRules( context.selfGrammar.patterns, { ...context, repository: context.selfGrammar.repository }, result ); } if (context.selfGrammar.injections) { collectExternalReferencesInRules( Object.values(context.selfGrammar.injections), { ...context, repository: context.selfGrammar.repository }, result ); } } function collectExternalReferencesInRules(rules, context, result) { for (const rule of rules) { if (result.visitedRule.has(rule)) { continue; } result.visitedRule.add(rule); const patternRepository = rule.repository ? mergeObjects({}, context.repository, rule.repository) : context.repository; if (Array.isArray(rule.patterns)) { collectExternalReferencesInRules(rule.patterns, { ...context, repository: patternRepository }, result); } const include = rule.include; if (!include) { continue; } const reference = parseInclude(include); switch (reference.kind) { case 0 /* Base */: collectExternalReferencesInTopLevelRule({ ...context, selfGrammar: context.baseGrammar }, result); break; case 1 /* Self */: collectExternalReferencesInTopLevelRule(context, result); break; case 2 /* RelativeReference */: collectExternalReferencesInTopLevelRepositoryRule(reference.ruleName, { ...context, repository: patternRepository }, result); break; case 3 /* TopLevelReference */: case 4 /* TopLevelRepositoryReference */: const selfGrammar = reference.scopeName === context.selfGrammar.scopeName ? context.selfGrammar : reference.scopeName === context.baseGrammar.scopeName ? context.baseGrammar : void 0; if (selfGrammar) { const newContext = { baseGrammar: context.baseGrammar, selfGrammar, repository: patternRepository }; if (reference.kind === 4 /* TopLevelRepositoryReference */) { collectExternalReferencesInTopLevelRepositoryRule(reference.ruleName, newContext, result); } else { collectExternalReferencesInTopLevelRule(newContext, result); } } else { if (reference.kind === 4 /* TopLevelRepositoryReference */) { result.add(new TopLevelRepositoryRuleReference(reference.scopeName, reference.ruleName)); } else { result.add(new TopLevelRuleReference(reference.scopeName)); } } break; } } } var BaseReference = class { kind = 0 /* Base */; }; var SelfReference = class { kind = 1 /* Self */; }; var RelativeReference = class { constructor(ruleName) { this.ruleName = ruleName; } kind = 2 /* RelativeReference */; }; var TopLevelReference = class { constructor(scopeName) { this.scopeName = scopeName; } kind = 3 /* TopLevelReference */; }; var TopLevelRepositoryReference = class { constructor(scopeName, ruleName) { this.scopeName = scopeName; this.ruleName = ruleName; } kind = 4 /* TopLevelRepositoryReference */; }; function parseInclude(include) { if (include === "$base") { return new BaseReference(); } else if (include === "$self") { return new SelfReference(); } const indexOfSharp = include.indexOf("#"); if (indexOfSharp === -1) { return new TopLevelReference(include); } else if (indexOfSharp === 0) { return new RelativeReference(include.substring(1)); } else { const scopeName = include.substring(0, indexOfSharp); const ruleName = include.substring(indexOfSharp + 1); return new TopLevelRepositoryReference(scopeName, ruleName); } } // src/rule.ts var HAS_BACK_REFERENCES = /\\(\d+)/; var BACK_REFERENCING_END = /\\(\d+)/g; var ruleIdSymbol = Symbol("RuleId"); var endRuleId = -1; var whileRuleId = -2; function ruleIdFromNumber(id) { return id; } function ruleIdToNumber(id) { return id; } var Rule = class { $location; id; _nameIsCapturing; _name; _contentNameIsCapturing; _contentName; constructor($location, id, name, contentName) { this.$location = $location; this.id = id; this._name = name || null; this._nameIsCapturing = RegexSource.hasCaptures(this._name); this._contentName = contentName || null; this._contentNameIsCapturing = RegexSource.hasCaptures(this._contentName); } get debugName() { const location = this.$location ? `${basename(this.$location.filename)}:${this.$location.line}` : "unknown"; return `${this.constructor.name}#${this.id} @ ${location}`; } getName(lineText, captureIndices) { if (!this._nameIsCapturing || this._name === null || lineText === null || captureIndices === null) { return this._name; } return RegexSource.replaceCaptures(this._name, lineText, captureIndices); } getContentName(lineText, captureIndices) { if (!this._contentNameIsCapturing || this._contentName === null) { return this._contentName; } return RegexSource.replaceCaptures(this._contentName, lineText, captureIndices); } }; var CaptureRule = class extends Rule { retokenizeCapturedWithRuleId; constructor($location, id, name, contentName, retokenizeCapturedWithRuleId) { super($location, id, name, contentName); this.retokenizeCapturedWithRuleId = retokenizeCapturedWithRuleId; } dispose() { } collectPatterns(grammar, out) { throw new Error("Not supported!"); } compile(grammar, endRegexSource) { throw new Error("Not supported!"); } compileAG(grammar, endRegexSource, allowA, allowG) { throw new Error("Not supported!"); } }; var MatchRule = class extends Rule { _match; captures; _cachedCompiledPatterns; constructor($location, id, name, match, captures) { super($location, id, name, null); this._match = new RegExpSource(match, this.id); this.captures = captures; this._cachedCompiledPatterns = null; } dispose() { if (this._cachedCompiledPatterns) { this._cachedCompiledPatterns.dispose(); this._cachedCompiledPatterns = null; } } get debugMatchRegExp() { return `${this._match.source}`; } collectPatterns(grammar, out) { out.push(this._match); } compile(grammar, endRegexSource) { return this._getCachedCompiledPatterns(grammar).compile(grammar); } compileAG(grammar, endRegexSource, allowA, allowG) { return this._getCachedCompiledPatterns(grammar).compileAG(grammar, allowA, allowG); } _getCachedCompiledPatterns(grammar) { if (!this._cachedCompiledPatterns) { this._cachedCompiledPatterns = new RegExpSourceList(); this.collectPatterns(grammar, this._cachedCompiledPatterns); } return this._cachedCompiledPatterns; } }; var IncludeOnlyRule = class extends Rule { hasMissingPatterns; patterns; _cachedCompiledPatterns; constructor($location, id, name, contentName, patterns) { super($location, id, name, contentName); this.patterns = patterns.patterns; this.hasMissingPatterns = patterns.hasMissingPatterns; this._cachedCompiledPatterns = null; } dispose() { if (this._cachedCompiledPatterns) { this._cachedCompiledPatterns.dispose(); this._cachedCompiledPatterns = null; } } collectPatterns(grammar, out) { for (const pattern of this.patterns) { const rule = grammar.getRule(pattern); rule.collectPatterns(grammar, out); } } compile(grammar, endRegexSource) { return this._getCachedCompiledPatterns(grammar).compile(grammar); } compileAG(grammar, endRegexSource, allowA, allowG) { return this._getCachedCompiledPatterns(grammar).compileAG(grammar, allowA, allowG); } _getCachedCompiledPatterns(grammar) { if (!this._cachedCompiledPatterns) { this._cachedCompiledPatterns = new RegExpSourceList(); this.collectPatterns(grammar, this._cachedCompiledPatterns); } return this._cachedCompiledPatterns; } }; var BeginEndRule = class extends Rule { _begin; beginCaptures; _end; endHasBackReferences; endCaptures; applyEndPatternLast; hasMissingPatterns; patterns; _cachedCompiledPatterns; constructor($location, id, name, contentName, begin, beginCaptures, end, endCaptures, applyEndPatternLast, patterns) { super($location, id, name, contentName); this._begin = new RegExpSource(begin, this.id); this.beginCaptures = beginCaptures; this._end = new RegExpSource(end ? end : "\uFFFF", -1); this.endHasBackReferences = this._end.hasBackReferences; this.endCaptures = endCaptures; this.applyEndPatternLast = applyEndPatternLast || false; this.patterns = patterns.patterns; this.hasMissingPatterns = patterns.hasMissingPatterns; this._cachedCompiledPatterns = null; } dispose() { if (this._cachedCompiledPatterns) { this._cachedCompiledPatterns.dispose(); this._cachedCompiledPatterns = null; } } get debugBeginRegExp() { return `${this._begin.source}`; } get debugEndRegExp() { return `${this._end.source}`; } getEndWithResolvedBackReferences(lineText, captureIndices) { return this._end.resolveBackReferences(lineText, captureIndices); } collectPatterns(grammar, out) { out.push(this._begin); } compile(grammar, endRegexSource) { return this._getCachedCompiledPatterns(grammar, endRegexSource).compile(grammar); } compileAG(grammar, endRegexSource, allowA, allowG) { return this._getCachedCompiledPatterns(grammar, endRegexSource).compileAG(grammar, allowA, allowG); } _getCachedCompiledPatterns(grammar, endRegexSource) { if (!this._cachedCompiledPatterns) { this._cachedCompiledPatterns = new RegExpSourceList(); for (const pattern of this.patterns) { const rule = grammar.getRule(pattern); rule.collectPatterns(grammar, this._cachedCompiledPatterns); } if (this.applyEndPatternLast) { this._cachedCompiledPatterns.push(this._end.hasBackReferences ? this._end.clone() : this._end); } else { this._cachedCompiledPatterns.unshift(this._end.hasBackReferences ? this._end.clone() : this._end); } } if (this._end.hasBackReferences) { if (this.applyEndPatternLast) { this._cachedCompiledPatterns.setSource(this._cachedCompiledPatterns.length() - 1, endRegexSource); } else { this._cachedCompiledPatterns.setSource(0, endRegexSource); } } return this._cachedCompiledPatterns; } }; var BeginWhileRule = class extends Rule { _begin; beginCaptures; whileCaptures; _while; whileHasBackReferences; hasMissingPatterns; patterns; _cachedCompiledPatterns; _cachedCompiledWhilePatterns; constructor($location, id, name, contentName, begin, beginCaptures, _while, whileCaptures, patterns) { super($location, id, name, contentName); this._begin = new RegExpSource(begin, this.id); this.beginCaptures = beginCaptures; this.whileCaptures = whileCaptures; this._while = new RegExpSource(_while, whileRuleId); this.whileHasBackReferences = this._while.hasBackReferences; this.patterns = patterns.patterns; this.hasMissingPatterns = patterns.hasMissingPatterns; this._cachedCompiledPatterns = null; this._cachedCompiledWhilePatterns = null; } dispose() { if (this._cachedCompiledPatterns) { this._cachedCompiledPatterns.dispose(); this._cachedCompiledPatterns = null; } if (this._cachedCompiledWhilePatterns) { this._cachedCompiledWhilePatterns.dispose(); this._cachedCompiledWhilePatterns = null; } } get debugBeginRegExp() { return `${this._begin.source}`; } get debugWhileRegExp() { return `${this._while.source}`; } getWhileWithResolvedBackReferences(lineText, captureIndices) { return this._while.resolveBackReferences(lineText, captureIndices); } collectPatterns(grammar, out) { out.push(this._begin); } compile(grammar, endRegexSource) { return this._getCachedCompiledPatterns(grammar).compile(grammar); } compileAG(grammar, endRegexSource, allowA, allowG) { return this._getCachedCompiledPatterns(grammar).compileAG(grammar, allowA, allowG); } _getCachedCompiledPatterns(grammar) { if (!this._cachedCompiledPatterns) { this._cachedCompiledPatterns = new RegExpSourceList(); for (const pattern of this.patterns) { const rule = grammar.getRule(pattern); rule.collectPatterns(grammar, this._cachedCompiledPatterns); } } return this._cachedCompiledPatterns; } compileWhile(grammar, endRegexSource) { return this._getCachedCompiledWhilePatterns(grammar, endRegexSource).compile(grammar); } compileWhileAG(grammar, endRegexSource, allowA, allowG) { return this._getCachedCompiledWhilePatterns(grammar, endRegexSource).compileAG(grammar, allowA, allowG); } _getCachedCompiledWhilePatterns(grammar, endRegexSource) { if (!this._cachedCompiledWhilePatterns) { this._cachedCompiledWhilePatterns = new RegExpSourceList(); this._cachedCompiledWhilePatterns.push(this._while.hasBackReferences ? this._while.clone() : this._while); } if (this._while.hasBackReferences) { this._cachedCompiledWhilePatterns.setSource(0, endRegexSource ? endRegexSource : "\uFFFF"); } return this._cachedCompiledWhilePatterns; } }; var RuleFactory = class _RuleFactory { static createCaptureRule(helper, $location, name, contentName, retokenizeCapturedWithRuleId) { return helper.registerRule((id) => { return new CaptureRule($location, id, name, contentName, retokenizeCapturedWithRuleId); }); } static getCompiledRuleId(desc, helper, repository) { if (!desc.id) { helper.registerRule((id) => { desc.id = id; if (desc.match) { return new MatchRule( desc.$vscodeTextmateLocation, desc.id, desc.name, desc.match, _RuleFactory._compileCaptures(desc.captures, helper, repository) ); } if (typeof desc.begin === "undefined") { if (desc.repository) { repository = mergeObjects({}, repository, desc.repository); } let patterns = desc.patterns; if (typeof patterns === "undefined" && desc.include) { patterns = [{ include: desc.include }]; } return new IncludeOnlyRule( desc.$vscodeTextmateLocation, desc.id, desc.name, desc.contentName, _RuleFactory._compilePatterns(patterns, helper, repository) ); } if (desc.while) { return new BeginWhileRule( desc.$vscodeTextmateLocation, desc.id, desc.name, desc.contentName, desc.begin, _RuleFactory._compileCaptures(desc.beginCaptures || desc.captures, helper, repository), desc.while, _RuleFactory._compileCaptures(desc.whileCaptures || desc.captures, helper, repository), _RuleFactory._compilePatterns(desc.patterns, helper, repository) ); } return new BeginEndRule( desc.$vscodeTextmateLocation, desc.id, desc.name, desc.contentName, desc.begin, _RuleFactory._compileCaptures(desc.beginCaptures || desc.captures, helper, repository), desc.end, _RuleFactory._compileCaptures(desc.endCaptures || desc.captures, helper, repository), desc.applyEndPatternLast, _RuleFactory._compilePatterns(desc.patterns, helper, repository) ); }); } return desc.id; } static _compileCaptures(captures, helper, repository) { let r = []; if (captures) { let maximumCaptureId = 0; for (const captureId in captures) { if (captureId === "$vscodeTextmateLocation") { continue; } const numericCaptureId = parseInt(captureId, 10); if (numericCaptureId > maximumCaptureId) { maximumCaptureId = numericCaptureId; } } for (let i = 0; i <= maximumCaptureId; i++) { r[i] = null; } for (const captureId in captures) { if (captureId === "$vscodeTextmateLocation") { continue; } const numericCaptureId = parseInt(captureId, 10); let retokenizeCapturedWithRuleId = 0; if (captures[captureId].patterns) { retokenizeCapturedWithRuleId = _RuleFactory.getCompiledRuleId(captures[captureId], helper, repository); } r[numericCaptureId] = _RuleFactory.createCaptureRule(helper, captures[captureId].$vscodeTextmateLocation, captures[captureId].name, captures[captureId].contentName, retokenizeCapturedWithRuleId); } } return r; } static _compilePatterns(patterns, helper, repository) { let r = []; if (patterns) { for (let i = 0, len = patterns.length; i < len; i++) { const pattern = patterns[i]; let ruleId = -1; if (pattern.include) { const reference = parseInclude(pattern.include); switch (reference.kind) { case 0 /* Base */: case 1 /* Self */: ruleId = _RuleFactory.getCompiledRuleId(repository[pattern.include], helper, repository); break; case 2 /* RelativeReference */: let localIncludedRule = repository[reference.ruleName]; if (localIncludedRule) { ruleId = _RuleFactory.getCompiledRuleId(localIncludedRule, helper, repository); } else { } break; case 3 /* TopLevelReference */: case 4 /* TopLevelRepositoryReference */: const externalGrammarName = reference.scopeName; const externalGrammarInclude = reference.kind === 4 /* TopLevelRepositoryReference */ ? reference.ruleName : null; const externalGrammar = helper.getExternalGrammar(externalGrammarName, repository); if (externalGrammar) { if (externalGrammarInclude) { let externalIncludedRule = externalGrammar.repository[externalGrammarInclude]; if (externalIncludedRule) { ruleId = _RuleFactory.getCompiledRuleId(externalIncludedRule, helper, externalGrammar.repository); } else { } } else { ruleId = _RuleFactory.getCompiledRuleId(externalGrammar.repository.$self, helper, externalGrammar.repository); } } else { } break; } } else { ruleId = _RuleFactory.getCompiledRuleId(pattern, helper, repository); } if (ruleId !== -1) { const rule = helper.getRule(ruleId); let skipRule = false; if (rule instanceof IncludeOnlyRule || rule instanceof BeginEndRule || rule instanceof BeginWhileRule) { if (rule.hasMissingPatterns && rule.patterns.length === 0) { skipRule = true; } } if (skipRule) { continue; } r.push(ruleId); } } } return { patterns: r, hasMissingPatterns: (patterns ? patterns.length : 0) !== r.length }; } }; var RegExpSource = class _RegExpSource { source; ruleId; hasAnchor; hasBackReferences; _anchorCache; constructor(regExpSource, ruleId) { if (regExpSource && typeof regExpSource === "string") { const len = regExpSource.length; let lastPushedPos = 0; let output = []; let hasAnchor = false; for (let pos = 0; pos < len; pos++) { const ch = regExpSource.charAt(pos); if (ch === "\\") { if (pos + 1 < len) { const nextCh = regExpSource.charAt(pos + 1); if (nextCh === "z") { output.push(regExpSource.substring(lastPushedPos, pos)); output.push("$(?!\\n)(? { return lineText.substring(capture.start, capture.end); }); BACK_REFERENCING_END.lastIndex = 0; return this.source.replace(BACK_REFERENCING_END, (match, g1) => { return escapeRegExpCharacters(capturedValues[parseInt(g1, 10)] || ""); }); } _buildAnchorCache() { if (typeof this.source !== "string") { throw new Error("This method should only be called if the source is a string"); } let A0_G0_result = []; let A0_G1_result = []; let A1_G0_result = []; let A1_G1_result = []; let pos, len, ch, nextCh; for (pos = 0, len = this.source.length; pos < len; pos++) { ch = this.source.charAt(pos); A0_G0_result[pos] = ch; A0_G1_result[pos] = ch; A1_G0_result[pos] = ch; A1_G1_result[pos] = ch; if (ch === "\\") { if (pos + 1 < len) { nextCh = this.source.charAt(pos + 1); if (nextCh === "A") { A0_G0_result[pos + 1] = "\uFFFF"; A0_G1_result[pos + 1] = "\uFFFF"; A1_G0_result[pos + 1] = "A"; A1_G1_result[pos + 1] = "A"; } else if (nextCh === "G") { A0_G0_result[pos + 1] = "\uFFFF"; A0_G1_result[pos + 1] = "G"; A1_G0_result[pos + 1] = "\uFFFF"; A1_G1_result[pos + 1] = "G"; } else { A0_G0_result[pos + 1] = nextCh; A0_G1_result[pos + 1] = nextCh; A1_G0_result[pos + 1] = nextCh; A1_G1_result[pos + 1] = nextCh; } pos++; } } } return { A0_G0: A0_G0_result.join(""), A0_G1: A0_G1_result.join(""), A1_G0: A1_G0_result.join(""), A1_G1: A1_G1_result.join("") }; } resolveAnchors(allowA, allowG) { if (!this.hasAnchor || !this._anchorCache || typeof this.source !== "string") { return this.source; } if (allowA) { if (allowG) { return this._anchorCache.A1_G1; } else { return this._anchorCache.A1_G0; } } else { if (allowG) { return this._anchorCache.A0_G1; } else { return this._anchorCache.A0_G0; } } } }; var RegExpSourceList = class { _items; _hasAnchors; _cached; _anchorCache; constructor() { this._items = []; this._hasAnchors = false; this._cached = null; this._anchorCache = { A0_G0: null, A0_G1: null, A1_G0: null, A1_G1: null }; } dispose() { this._disposeCaches(); } _disposeCaches() { if (this._cached) { this._cached.dispose(); this._cached = null; } if (this._anchorCache.A0_G0) { this._anchorCache.A0_G0.dispose(); this._anchorCache.A0_G0 = null; } if (this._anchorCache.A0_G1) { this._anchorCache.A0_G1.dispose(); this._anchorCache.A0_G1 = null; } if (this._anchorCache.A1_G0) { this._anchorCache.A1_G0.dispose(); this._anchorCache.A1_G0 = null; } if (this._anchorCache.A1_G1) { this._anchorCache.A1_G1.dispose(); this._anchorCache.A1_G1 = null; } } push(item) { this._items.push(item); this._hasAnchors = this._hasAnchors || item.hasAnchor; } unshift(item) { this._items.unshift(item); this._hasAnchors = this._hasAnchors || item.hasAnchor; } length() { return this._items.length; } setSource(index, newSource) { if (this._items[index].source !== newSource) { this._disposeCaches(); this._items[index].setSource(newSource); } } compile(onigLib) { if (!this._cached) { let regExps = this._items.map((e) => e.source); this._cached = new CompiledRule(onigLib, regExps, this._items.map((e) => e.ruleId)); } return this._cached; } compileAG(onigLib, allowA, allowG) { if (!this._hasAnchors) { return this.compile(onigLib); } else { if (allowA) { if (allowG) { if (!this._anchorCache.A1_G1) { this._anchorCache.A1_G1 = this._resolveAnchors(onigLib, allowA, allowG); } return this._anchorCache.A1_G1; } else { if (!this._anchorCache.A1_G0) { this._anchorCache.A1_G0 = this._resolveAnchors(onigLib, allowA, allowG); } return this._anchorCache.A1_G0; } } else { if (allowG) { if (!this._anchorCache.A0_G1) { this._anchorCache.A0_G1 = this._resolveAnchors(onigLib, allowA, allowG); } return this._anchorCache.A0_G1; } else { if (!this._anchorCache.A0_G0) { this._anchorCache.A0_G0 = this._resolveAnchors(onigLib, allowA, allowG); } return this._anchorCache.A0_G0; } } } } _resolveAnchors(onigLib, allowA, allowG) { let regExps = this._items.map((e) => e.resolveAnchors(allowA, allowG)); return new CompiledRule(onigLib, regExps, this._items.map((e) => e.ruleId)); } }; var CompiledRule = class { constructor(onigLib, regExps, rules) { this.regExps = regExps; this.rules = rules; this.scanner = onigLib.createOnigScanner(regExps); } scanner; dispose() { if (typeof this.scanner.dispose === "function") { this.scanner.dispose(); } } toString() { const r = []; for (let i = 0, len = this.rules.length; i < len; i++) { r.push(" - " + this.rules[i] + ": " + this.regExps[i]); } return r.join("\n"); } findNextMatchSync(string, startPosition, options) { const result = this.scanner.findNextMatchSync(string, startPosition, options); if (!result) { return null; } return { ruleId: this.rules[result.index], captureIndices: result.captureIndices }; } }; // src/grammar/basicScopesAttributeProvider.ts var BasicScopeAttributes = class { constructor(languageId, tokenType) { this.languageId = languageId; this.tokenType = tokenType; } }; var BasicScopeAttributesProvider = class _BasicScopeAttributesProvider { _defaultAttributes; _embeddedLanguagesMatcher; constructor(initialLanguageId, embeddedLanguages) { this._defaultAttributes = new BasicScopeAttributes(initialLanguageId, 8 /* NotSet */); this._embeddedLanguagesMatcher = new ScopeMatcher(Object.entries(embeddedLanguages || {})); } getDefaultAttributes() { return this._defaultAttributes; } getBasicScopeAttributes(scopeName) { if (scopeName === null) { return _BasicScopeAttributesProvider._NULL_SCOPE_METADATA; } return this._getBasicScopeAttributes.get(scopeName); } static _NULL_SCOPE_METADATA = new BasicScopeAttributes(0, 0); _getBasicScopeAttributes = new CachedFn((scopeName) => { const languageId = this._scopeToLanguage(scopeName); const standardTokenType = this._toStandardTokenType(scopeName); return new BasicScopeAttributes(languageId, standardTokenType); }); /** * Given a produced TM scope, return the language that token describes or null if unknown. * e.g. source.html => html, source.css.embedded.html => css, punctuation.definition.tag.html => null */ _scopeToLanguage(scope) { return this._embeddedLanguagesMatcher.match(scope) || 0; } _toStandardTokenType(scopeName) { const m = scopeName.match(_BasicScopeAttributesProvider.STANDARD_TOKEN_TYPE_REGEXP); if (!m) { return 8 /* NotSet */; } switch (m[1]) { case "comment": return 1 /* Comment */; case "string": return 2 /* String */; case "regex": return 3 /* RegEx */; case "meta.embedded": return 0 /* Other */; } throw new Error("Unexpected match for standard token type!"); } static STANDARD_TOKEN_TYPE_REGEXP = /\b(comment|string|regex|meta\.embedded)\b/; }; var ScopeMatcher = class { values; scopesRegExp; constructor(values) { if (values.length === 0) { this.values = null; this.scopesRegExp = null; } else { this.values = new Map(values); const escapedScopes = values.map( ([scopeName, value]) => escapeRegExpCharacters(scopeName) ); escapedScopes.sort(); escapedScopes.reverse(); this.scopesRegExp = new RegExp( `^((${escapedScopes.join(")|(")}))($|\\.)`, "" ); } } match(scope) { if (!this.scopesRegExp) { return void 0; } const m = scope.match(this.scopesRegExp); if (!m) { return void 0; } return this.values.get(m[1]); } }; // src/debug.ts var DebugFlags = { InDebugMode: typeof process !== "undefined" && !!process.env["VSCODE_TEXTMATE_DEBUG"] }; var UseOnigurumaFindOptions = false; // src/grammar/tokenizeString.ts var TokenizeStringResult = class { constructor(stack, stoppedEarly) { this.stack = stack; this.stoppedEarly = stoppedEarly; } }; function _tokenizeString(grammar, lineText, isFirstLine, linePos, stack, lineTokens, checkWhileConditions, timeLimit) { const lineLength = lineText.content.length; let STOP = false; let anchorPosition = -1; if (checkWhileConditions) { const whileCheckResult = _checkWhileConditions( grammar, lineText, isFirstLine, linePos, stack, lineTokens ); stack = whileCheckResult.stack; linePos = whileCheckResult.linePos; isFirstLine = whileCheckResult.isFirstLine; anchorPosition = whileCheckResult.anchorPosition; } const startTime = Date.now(); while (!STOP) { if (timeLimit !== 0) { const elapsedTime = Date.now() - startTime; if (elapsedTime > timeLimit) { return new TokenizeStringResult(stack, true); } } scanNext(); } return new TokenizeStringResult(stack, false); function scanNext() { if (false) { console.log(""); console.log( `@@scanNext ${linePos}: |${lineText.content.substr(linePos).replace(/\n$/, "\\n")}|` ); } const r = matchRuleOrInjections( grammar, lineText, isFirstLine, linePos, stack, anchorPosition ); if (!r) { lineTokens.produce(stack, lineLength); STOP = true; return; } const captureIndices = r.captureIndices; const matchedRuleId = r.matchedRuleId; const hasAdvanced = captureIndices && captureIndices.length > 0 ? captureIndices[0].end > linePos : false; if (matchedRuleId === endRuleId) { const poppedRule = stack.getRule(grammar); if (false) { console.log( " popping " + poppedRule.debugName + " - " + poppedRule.debugEndRegExp ); } lineTokens.produce(stack, captureIndices[0].start); stack = stack.withContentNameScopesList(stack.nameScopesList); handleCaptures( grammar, lineText, isFirstLine, stack, lineTokens, poppedRule.endCaptures, captureIndices ); lineTokens.produce(stack, captureIndices[0].end); const popped = stack; stack = stack.parent; anchorPosition = popped.getAnchorPos(); if (!hasAdvanced && popped.getEnterPos() === linePos) { if (false) { console.error( "[1] - Grammar is in an endless loop - Grammar pushed & popped a rule without advancing" ); } stack = popped; lineTokens.produce(stack, lineLength); STOP = true; return; } } else { const _rule = grammar.getRule(matchedRuleId); lineTokens.produce(stack, captureIndices[0].start); const beforePush = stack; const scopeName = _rule.getName(lineText.content, captureIndices); const nameScopesList = stack.contentNameScopesList.pushAttributed( scopeName, grammar ); stack = stack.push( matchedRuleId, linePos, anchorPosition, captureIndices[0].end === lineLength, null, nameScopesList, nameScopesList ); if (_rule instanceof BeginEndRule) { const pushedRule = _rule; if (false) { console.log( " pushing " + pushedRule.debugName + " - " + pushedRule.debugBeginRegExp ); } handleCaptures( grammar, lineText, isFirstLine, stack, lineTokens, pushedRule.beginCaptures, captureIndices ); lineTokens.produce(stack, captureIndices[0].end); anchorPosition = captureIndices[0].end; const contentName = pushedRule.getContentName( lineText.content, captureIndices ); const contentNameScopesList = nameScopesList.pushAttributed( contentName, grammar ); stack = stack.withContentNameScopesList(contentNameScopesList); if (pushedRule.endHasBackReferences) { stack = stack.withEndRule( pushedRule.getEndWithResolvedBackReferences( lineText.content, captureIndices ) ); } if (!hasAdvanced && beforePush.hasSameRuleAs(stack)) { if (false) { console.error( "[2] - Grammar is in an endless loop - Grammar pushed the same rule without advancing" ); } stack = stack.pop(); lineTokens.produce(stack, lineLength); STOP = true; return; } } else if (_rule instanceof BeginWhileRule) { const pushedRule = _rule; if (false) { console.log(" pushing " + pushedRule.debugName); } handleCaptures( grammar, lineText, isFirstLine, stack, lineTokens, pushedRule.beginCaptures, captureIndices ); lineTokens.produce(stack, captureIndices[0].end); anchorPosition = captureIndices[0].end; const contentName = pushedRule.getContentName( lineText.content, captureIndices ); const contentNameScopesList = nameScopesList.pushAttributed( contentName, grammar ); stack = stack.withContentNameScopesList(contentNameScopesList); if (pushedRule.whileHasBackReferences) { stack = stack.withEndRule( pushedRule.getWhileWithResolvedBackReferences( lineText.content, captureIndices ) ); } if (!hasAdvanced && beforePush.hasSameRuleAs(stack)) { if (false) { console.error( "[3] - Grammar is in an endless loop - Grammar pushed the same rule without advancing" ); } stack = stack.pop(); lineTokens.produce(stack, lineLength); STOP = true; return; } } else { const matchingRule = _rule; if (false) { console.log( " matched " + matchingRule.debugName + " - " + matchingRule.debugMatchRegExp ); } handleCaptures( grammar, lineText, isFirstLine, stack, lineTokens, matchingRule.captures, captureIndices ); lineTokens.produce(stack, captureIndices[0].end); stack = stack.pop(); if (!hasAdvanced) { if (false) { console.error( "[4] - Grammar is in an endless loop - Grammar is not advancing, nor is it pushing/popping" ); } stack = stack.safePop(); lineTokens.produce(stack, lineLength); STOP = true; return; } } } if (captureIndices[0].end > linePos) { linePos = captureIndices[0].end; isFirstLine = false; } } } function _checkWhileConditions(grammar, lineText, isFirstLine, linePos, stack, lineTokens) { let anchorPosition = stack.beginRuleCapturedEOL ? 0 : -1; const whileRules = []; for (let node = stack; node; node = node.pop()) { const nodeRule = node.getRule(grammar); if (nodeRule instanceof BeginWhileRule) { whileRules.push({ rule: nodeRule, stack: node }); } } for (let whileRule = whileRules.pop(); whileRule; whileRule = whileRules.pop()) { const { ruleScanner, findOptions } = prepareRuleWhileSearch(whileRule.rule, grammar, whileRule.stack.endRule, isFirstLine, linePos === anchorPosition); const r = ruleScanner.findNextMatchSync(lineText, linePos, findOptions); if (false) { console.log(" scanning for while rule"); console.log(ruleScanner.toString()); } if (r) { const matchedRuleId = r.ruleId; if (matchedRuleId !== whileRuleId) { stack = whileRule.stack.pop(); break; } if (r.captureIndices && r.captureIndices.length) { lineTokens.produce(whileRule.stack, r.captureIndices[0].start); handleCaptures(grammar, lineText, isFirstLine, whileRule.stack, lineTokens, whileRule.rule.whileCaptures, r.captureIndices); lineTokens.produce(whileRule.stack, r.captureIndices[0].end); anchorPosition = r.captureIndices[0].end; if (r.captureIndices[0].end > linePos) { linePos = r.captureIndices[0].end; isFirstLine = false; } } } else { if (false) { console.log(" popping " + whileRule.rule.debugName + " - " + whileRule.rule.debugWhileRegExp); } stack = whileRule.stack.pop(); break; } } return { stack, linePos, anchorPosition, isFirstLine }; } function matchRuleOrInjections(grammar, lineText, isFirstLine, linePos, stack, anchorPosition) { const matchResult = matchRule(grammar, lineText, isFirstLine, linePos, stack, anchorPosition); const injections = grammar.getInjections(); if (injections.length === 0) { return matchResult; } const injectionResult = matchInjections(injections, grammar, lineText, isFirstLine, linePos, stack, anchorPosition); if (!injectionResult) { return matchResult; } if (!matchResult) { return injectionResult; } const matchResultScore = matchResult.captureIndices[0].start; const injectionResultScore = injectionResult.captureIndices[0].start; if (injectionResultScore < matchResultScore || injectionResult.priorityMatch && injectionResultScore === matchResultScore) { return injectionResult; } return matchResult; } function matchRule(grammar, lineText, isFirstLine, linePos, stack, anchorPosition) { const rule = stack.getRule(grammar); const { ruleScanner, findOptions } = prepareRuleSearch(rule, grammar, stack.endRule, isFirstLine, linePos === anchorPosition); const r = ruleScanner.findNextMatchSync(lineText, linePos, findOptions); if (r) { return { captureIndices: r.captureIndices, matchedRuleId: r.ruleId }; } return null; } function matchInjections(injections, grammar, lineText, isFirstLine, linePos, stack, anchorPosition) { let bestMatchRating = Number.MAX_VALUE; let bestMatchCaptureIndices = null; let bestMatchRuleId; let bestMatchResultPriority = 0; const scopes = stack.contentNameScopesList.getScopeNames(); for (let i = 0, len = injections.length; i < len; i++) { const injection = injections[i]; if (!injection.matcher(scopes)) { continue; } const rule = grammar.getRule(injection.ruleId); const { ruleScanner, findOptions } = prepareRuleSearch(rule, grammar, null, isFirstLine, linePos === anchorPosition); const matchResult = ruleScanner.findNextMatchSync(lineText, linePos, findOptions); if (!matchResult) { continue; } if (false) { console.log(` matched injection: ${injection.debugSelector}`); console.log(ruleScanner.toString()); } const matchRating = matchResult.captureIndices[0].start; if (matchRating >= bestMatchRating) { continue; } bestMatchRating = matchRating; bestMatchCaptureIndices = matchResult.captureIndices; bestMatchRuleId = matchResult.ruleId; bestMatchResultPriority = injection.priority; if (bestMatchRating === linePos) { break; } } if (bestMatchCaptureIndices) { return { priorityMatch: bestMatchResultPriority === -1, captureIndices: bestMatchCaptureIndices, matchedRuleId: bestMatchRuleId }; } return null; } function prepareRuleSearch(rule, grammar, endRegexSource, allowA, allowG) { if (UseOnigurumaFindOptions) { const ruleScanner2 = rule.compile(grammar, endRegexSource); const findOptions = getFindOptions(allowA, allowG); return { ruleScanner: ruleScanner2, findOptions }; } const ruleScanner = rule.compileAG(grammar, endRegexSource, allowA, allowG); return { ruleScanner, findOptions: 0 /* None */ }; } function prepareRuleWhileSearch(rule, grammar, endRegexSource, allowA, allowG) { if (UseOnigurumaFindOptions) { const ruleScanner2 = rule.compileWhile(grammar, endRegexSource); const findOptions = getFindOptions(allowA, allowG); return { ruleScanner: ruleScanner2, findOptions }; } const ruleScanner = rule.compileWhileAG(grammar, endRegexSource, allowA, allowG); return { ruleScanner, findOptions: 0 /* None */ }; } function getFindOptions(allowA, allowG) { let options = 0 /* None */; if (!allowA) { options |= 1 /* NotBeginString */; } if (!allowG) { options |= 4 /* NotBeginPosition */; } return options; } function handleCaptures(grammar, lineText, isFirstLine, stack, lineTokens, captures, captureIndices) { if (captures.length === 0) { return; } const lineTextContent = lineText.content; const len = Math.min(captures.length, captureIndices.length); const localStack = []; const maxEnd = captureIndices[0].end; for (let i = 0; i < len; i++) { const captureRule = captures[i]; if (captureRule === null) { continue; } const captureIndex = captureIndices[i]; if (captureIndex.length === 0) { continue; } if (captureIndex.start > maxEnd) { break; } while (localStack.length > 0 && localStack[localStack.length - 1].endPos <= captureIndex.start) { lineTokens.produceFromScopes(localStack[localStack.length - 1].scopes, localStack[localStack.length - 1].endPos); localStack.pop(); } if (localStack.length > 0) { lineTokens.produceFromScopes(localStack[localStack.length - 1].scopes, captureIndex.start); } else { lineTokens.produce(stack, captureIndex.start); } if (captureRule.retokenizeCapturedWithRuleId) { const scopeName = captureRule.getName(lineTextContent, captureIndices); const nameScopesList = stack.contentNameScopesList.pushAttributed(scopeName, grammar); const contentName = captureRule.getContentName(lineTextContent, captureIndices); const contentNameScopesList = nameScopesList.pushAttributed(contentName, grammar); const stackClone = stack.push(captureRule.retokenizeCapturedWithRuleId, captureIndex.start, -1, false, null, nameScopesList, contentNameScopesList); const onigSubStr = grammar.createOnigString(lineTextContent.substring(0, captureIndex.end)); _tokenizeString( grammar, onigSubStr, isFirstLine && captureIndex.start === 0, captureIndex.start, stackClone, lineTokens, false, /* no time limit */ 0 ); disposeOnigString(onigSubStr); continue; } const captureRuleScopeName = captureRule.getName(lineTextContent, captureIndices); if (captureRuleScopeName !== null) { const base = localStack.length > 0 ? localStack[localStack.length - 1].scopes : stack.contentNameScopesList; const captureRuleScopesList = base.pushAttributed(captureRuleScopeName, grammar); localStack.push(new LocalStackElement(captureRuleScopesList, captureIndex.end)); } } while (localStack.length > 0) { lineTokens.produceFromScopes(localStack[localStack.length - 1].scopes, localStack[localStack.length - 1].endPos); localStack.pop(); } } var LocalStackElement = class { scopes; endPos; constructor(scopes, endPos) { this.scopes = scopes; this.endPos = endPos; } }; // src/grammar/grammar.ts function createGrammar(scopeName, grammar, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors, grammarRepository, onigLib) { return new Grammar( scopeName, grammar, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors, grammarRepository, onigLib ); } function collectInjections(result, selector, rule, ruleFactoryHelper, grammar) { const matchers = createMatchers(selector, nameMatcher); const ruleId = RuleFactory.getCompiledRuleId(rule, ruleFactoryHelper, grammar.repository); for (const matcher of matchers) { result.push({ debugSelector: selector, matcher: matcher.matcher, ruleId, grammar, priority: matcher.priority }); } } function nameMatcher(identifers, scopes) { if (scopes.length < identifers.length) { return false; } let lastIndex = 0; return identifers.every((identifier) => { for (let i = lastIndex; i < scopes.length; i++) { if (scopesAreMatching(scopes[i], identifier)) { lastIndex = i + 1; return true; } } return false; }); } function scopesAreMatching(thisScopeName, scopeName) { if (!thisScopeName) { return false; } if (thisScopeName === scopeName) { return true; } const len = scopeName.length; return thisScopeName.length > len && thisScopeName.substr(0, len) === scopeName && thisScopeName[len] === "."; } var Grammar = class { constructor(_rootScopeName, grammar, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors, grammarRepository, _onigLib) { this._rootScopeName = _rootScopeName; this.balancedBracketSelectors = balancedBracketSelectors; this._onigLib = _onigLib; this._basicScopeAttributesProvider = new BasicScopeAttributesProvider( initialLanguage, embeddedLanguages ); this._rootId = -1; this._lastRuleId = 0; this._ruleId2desc = [null]; this._includedGrammars = {}; this._grammarRepository = grammarRepository; this._grammar = initGrammar(grammar, null); this._injections = null; this._tokenTypeMatchers = []; if (tokenTypes) { for (const selector of Object.keys(tokenTypes)) { const matchers = createMatchers(selector, nameMatcher); for (const matcher of matchers) { this._tokenTypeMatchers.push({ matcher: matcher.matcher, type: tokenTypes[selector] }); } } } } _rootId; _lastRuleId; _ruleId2desc; _includedGrammars; _grammarRepository; _grammar; _injections; _basicScopeAttributesProvider; _tokenTypeMatchers; get themeProvider() { return this._grammarRepository; } dispose() { for (const rule of this._ruleId2desc) { if (rule) { rule.dispose(); } } } createOnigScanner(sources) { return this._onigLib.createOnigScanner(sources); } createOnigString(sources) { return this._onigLib.createOnigString(sources); } getMetadataForScope(scope) { return this._basicScopeAttributesProvider.getBasicScopeAttributes(scope); } _collectInjections() { const grammarRepository = { lookup: (scopeName2) => { if (scopeName2 === this._rootScopeName) { return this._grammar; } return this.getExternalGrammar(scopeName2); }, injections: (scopeName2) => { return this._grammarRepository.injections(scopeName2); } }; const result = []; const scopeName = this._rootScopeName; const grammar = grammarRepository.lookup(scopeName); if (grammar) { const rawInjections = grammar.injections; if (rawInjections) { for (let expression in rawInjections) { collectInjections( result, expression, rawInjections[expression], this, grammar ); } } const injectionScopeNames = this._grammarRepository.injections(scopeName); if (injectionScopeNames) { injectionScopeNames.forEach((injectionScopeName) => { const injectionGrammar = this.getExternalGrammar(injectionScopeName); if (injectionGrammar) { const selector = injectionGrammar.injectionSelector; if (selector) { collectInjections( result, selector, injectionGrammar, this, injectionGrammar ); } } }); } } result.sort((i1, i2) => i1.priority - i2.priority); return result; } getInjections() { if (this._injections === null) { this._injections = this._collectInjections(); } return this._injections; } registerRule(factory) { const id = ++this._lastRuleId; const result = factory(ruleIdFromNumber(id)); this._ruleId2desc[id] = result; return result; } getRule(ruleId) { return this._ruleId2desc[ruleIdToNumber(ruleId)]; } getExternalGrammar(scopeName, repository) { if (this._includedGrammars[scopeName]) { return this._includedGrammars[scopeName]; } else if (this._grammarRepository) { const rawIncludedGrammar = this._grammarRepository.lookup(scopeName); if (rawIncludedGrammar) { this._includedGrammars[scopeName] = initGrammar( rawIncludedGrammar, repository && repository.$base ); return this._includedGrammars[scopeName]; } } return void 0; } tokenizeLine(lineText, prevState, timeLimit = 0) { const r = this._tokenize(lineText, prevState, false, timeLimit); return { tokens: r.lineTokens.getResult(r.ruleStack, r.lineLength), ruleStack: r.ruleStack, stoppedEarly: r.stoppedEarly }; } tokenizeLine2(lineText, prevState, timeLimit = 0) { const r = this._tokenize(lineText, prevState, true, timeLimit); return { tokens: r.lineTokens.getBinaryResult(r.ruleStack, r.lineLength), ruleStack: r.ruleStack, stoppedEarly: r.stoppedEarly }; } _tokenize(lineText, prevState, emitBinaryTokens, timeLimit) { if (this._rootId === -1) { this._rootId = RuleFactory.getCompiledRuleId( this._grammar.repository.$self, this, this._grammar.repository ); this.getInjections(); } let isFirstLine; if (!prevState || prevState === StateStackImpl.NULL) { isFirstLine = true; const rawDefaultMetadata = this._basicScopeAttributesProvider.getDefaultAttributes(); const defaultStyle = this.themeProvider.getDefaults(); const defaultMetadata = EncodedTokenMetadata.set( 0, rawDefaultMetadata.languageId, rawDefaultMetadata.tokenType, null, defaultStyle.fontStyle, defaultStyle.foregroundId, defaultStyle.backgroundId ); const rootScopeName = this.getRule(this._rootId).getName( null, null ); let scopeList; if (rootScopeName) { scopeList = AttributedScopeStack.createRootAndLookUpScopeName( rootScopeName, defaultMetadata, this ); } else { scopeList = AttributedScopeStack.createRoot( "unknown", defaultMetadata ); } prevState = new StateStackImpl( null, this._rootId, -1, -1, false, null, scopeList, scopeList ); } else { isFirstLine = false; prevState.reset(); } lineText = lineText + "\n"; const onigLineText = this.createOnigString(lineText); const lineLength = onigLineText.content.length; const lineTokens = new LineTokens( emitBinaryTokens, lineText, this._tokenTypeMatchers, this.balancedBracketSelectors ); const r = _tokenizeString( this, onigLineText, isFirstLine, 0, prevState, lineTokens, true, timeLimit ); disposeOnigString(onigLineText); return { lineLength, lineTokens, ruleStack: r.stack, stoppedEarly: r.stoppedEarly }; } }; function initGrammar(grammar, base) { grammar = clone(grammar); grammar.repository = grammar.repository || {}; grammar.repository.$self = { $vscodeTextmateLocation: grammar.$vscodeTextmateLocation, patterns: grammar.patterns, name: grammar.scopeName }; grammar.repository.$base = base || grammar.repository.$self; return grammar; } var AttributedScopeStack = class _AttributedScopeStack { /** * Invariant: * ``` * if (parent && !scopePath.extends(parent.scopePath)) { * throw new Error(); * } * ``` */ constructor(parent, scopePath, tokenAttributes) { this.parent = parent; this.scopePath = scopePath; this.tokenAttributes = tokenAttributes; } static fromExtension(namesScopeList, contentNameScopesList) { let current = namesScopeList; let scopeNames = namesScopeList?.scopePath ?? null; for (const frame of contentNameScopesList) { scopeNames = ScopeStack.push(scopeNames, frame.scopeNames); current = new _AttributedScopeStack(current, scopeNames, frame.encodedTokenAttributes); } return current; } static createRoot(scopeName, tokenAttributes) { return new _AttributedScopeStack(null, new ScopeStack(null, scopeName), tokenAttributes); } static createRootAndLookUpScopeName(scopeName, tokenAttributes, grammar) { const rawRootMetadata = grammar.getMetadataForScope(scopeName); const scopePath = new ScopeStack(null, scopeName); const rootStyle = grammar.themeProvider.themeMatch(scopePath); const resolvedTokenAttributes = _AttributedScopeStack.mergeAttributes( tokenAttributes, rawRootMetadata, rootStyle ); return new _AttributedScopeStack(null, scopePath, resolvedTokenAttributes); } get scopeName() { return this.scopePath.scopeName; } toString() { return this.getScopeNames().join(" "); } equals(other) { return _AttributedScopeStack.equals(this, other); } static equals(a, b) { do { if (a === b) { return true; } if (!a && !b) { return true; } if (!a || !b) { return false; } if (a.scopeName !== b.scopeName || a.tokenAttributes !== b.tokenAttributes) { return false; } a = a.parent; b = b.parent; } while (true); } static mergeAttributes(existingTokenAttributes, basicScopeAttributes, styleAttributes) { let fontStyle = -1 /* NotSet */; let foreground = 0; let background = 0; if (styleAttributes !== null) { fontStyle = styleAttributes.fontStyle; foreground = styleAttributes.foregroundId; background = styleAttributes.backgroundId; } return EncodedTokenMetadata.set( existingTokenAttributes, basicScopeAttributes.languageId, basicScopeAttributes.tokenType, null, fontStyle, foreground, background ); } pushAttributed(scopePath, grammar) { if (scopePath === null) { return this; } if (scopePath.indexOf(" ") === -1) { return _AttributedScopeStack._pushAttributed(this, scopePath, grammar); } const scopes = scopePath.split(/ /g); let result = this; for (const scope of scopes) { result = _AttributedScopeStack._pushAttributed(result, scope, grammar); } return result; } static _pushAttributed(target, scopeName, grammar) { const rawMetadata = grammar.getMetadataForScope(scopeName); const newPath = target.scopePath.push(scopeName); const scopeThemeMatchResult = grammar.themeProvider.themeMatch(newPath); const metadata = _AttributedScopeStack.mergeAttributes( target.tokenAttributes, rawMetadata, scopeThemeMatchResult ); return new _AttributedScopeStack(target, newPath, metadata); } getScopeNames() { return this.scopePath.getSegments(); } getExtensionIfDefined(base) { const result = []; let self = this; while (self && self !== base) { result.push({ encodedTokenAttributes: self.tokenAttributes, scopeNames: self.scopePath.getExtensionIfDefined(self.parent?.scopePath ?? null) }); self = self.parent; } return self === base ? result.reverse() : void 0; } }; var StateStackImpl = class _StateStackImpl { /** * Invariant: * ``` * if (contentNameScopesList !== nameScopesList && contentNameScopesList?.parent !== nameScopesList) { * throw new Error(); * } * if (this.parent && !nameScopesList.extends(this.parent.contentNameScopesList)) { * throw new Error(); * } * ``` */ constructor(parent, ruleId, enterPos, anchorPos, beginRuleCapturedEOL, endRule, nameScopesList, contentNameScopesList) { this.parent = parent; this.ruleId = ruleId; this.beginRuleCapturedEOL = beginRuleCapturedEOL; this.endRule = endRule; this.nameScopesList = nameScopesList; this.contentNameScopesList = contentNameScopesList; this.depth = this.parent ? this.parent.depth + 1 : 1; this._enterPos = enterPos; this._anchorPos = anchorPos; } _stackElementBrand = void 0; // TODO remove me static NULL = new _StateStackImpl( null, 0, 0, 0, false, null, null, null ); /** * The position on the current line where this state was pushed. * This is relevant only while tokenizing a line, to detect endless loops. * Its value is meaningless across lines. */ _enterPos; /** * The captured anchor position when this stack element was pushed. * This is relevant only while tokenizing a line, to restore the anchor position when popping. * Its value is meaningless across lines. */ _anchorPos; /** * The depth of the stack. */ depth; equals(other) { if (other === null) { return false; } return _StateStackImpl._equals(this, other); } static _equals(a, b) { if (a === b) { return true; } if (!this._structuralEquals(a, b)) { return false; } return AttributedScopeStack.equals(a.contentNameScopesList, b.contentNameScopesList); } /** * A structural equals check. Does not take into account `scopes`. */ static _structuralEquals(a, b) { do { if (a === b) { return true; } if (!a && !b) { return true; } if (!a || !b) { return false; } if (a.depth !== b.depth || a.ruleId !== b.ruleId || a.endRule !== b.endRule) { return false; } a = a.parent; b = b.parent; } while (true); } clone() { return this; } static _reset(el) { while (el) { el._enterPos = -1; el._anchorPos = -1; el = el.parent; } } reset() { _StateStackImpl._reset(this); } pop() { return this.parent; } safePop() { if (this.parent) { return this.parent; } return this; } push(ruleId, enterPos, anchorPos, beginRuleCapturedEOL, endRule, nameScopesList, contentNameScopesList) { return new _StateStackImpl( this, ruleId, enterPos, anchorPos, beginRuleCapturedEOL, endRule, nameScopesList, contentNameScopesList ); } getEnterPos() { return this._enterPos; } getAnchorPos() { return this._anchorPos; } getRule(grammar) { return grammar.getRule(this.ruleId); } toString() { const r = []; this._writeString(r, 0); return "[" + r.join(",") + "]"; } _writeString(res, outIndex) { if (this.parent) { outIndex = this.parent._writeString(res, outIndex); } res[outIndex++] = `(${this.ruleId}, ${this.nameScopesList?.toString()}, ${this.contentNameScopesList?.toString()})`; return outIndex; } withContentNameScopesList(contentNameScopeStack) { if (this.contentNameScopesList === contentNameScopeStack) { return this; } return this.parent.push( this.ruleId, this._enterPos, this._anchorPos, this.beginRuleCapturedEOL, this.endRule, this.nameScopesList, contentNameScopeStack ); } withEndRule(endRule) { if (this.endRule === endRule) { return this; } return new _StateStackImpl( this.parent, this.ruleId, this._enterPos, this._anchorPos, this.beginRuleCapturedEOL, endRule, this.nameScopesList, this.contentNameScopesList ); } // Used to warn of endless loops hasSameRuleAs(other) { let el = this; while (el && el._enterPos === other._enterPos) { if (el.ruleId === other.ruleId) { return true; } el = el.parent; } return false; } toStateStackFrame() { return { ruleId: ruleIdToNumber(this.ruleId), beginRuleCapturedEOL: this.beginRuleCapturedEOL, endRule: this.endRule, nameScopesList: this.nameScopesList?.getExtensionIfDefined(this.parent?.nameScopesList ?? null) ?? [], contentNameScopesList: this.contentNameScopesList?.getExtensionIfDefined(this.nameScopesList) ?? [] }; } static pushFrame(self, frame) { const namesScopeList = AttributedScopeStack.fromExtension(self?.nameScopesList ?? null, frame.nameScopesList); return new _StateStackImpl( self, ruleIdFromNumber(frame.ruleId), frame.enterPos ?? -1, frame.anchorPos ?? -1, frame.beginRuleCapturedEOL, frame.endRule, namesScopeList, AttributedScopeStack.fromExtension(namesScopeList, frame.contentNameScopesList) ); } }; var BalancedBracketSelectors = class { balancedBracketScopes; unbalancedBracketScopes; allowAny = false; constructor(balancedBracketScopes, unbalancedBracketScopes) { 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) ); } get matchesAlways() { return this.allowAny && this.unbalancedBracketScopes.length === 0; } get matchesNever() { return this.balancedBracketScopes.length === 0 && !this.allowAny; } match(scopes) { 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; } }; var LineTokens = class { constructor(emitBinaryTokens, lineText, tokenTypeOverrides, balancedBracketSelectors) { this.balancedBracketSelectors = balancedBracketSelectors; this._emitBinaryTokens = emitBinaryTokens; this._tokenTypeOverrides = tokenTypeOverrides; if (false) { this._lineText = lineText; } else { this._lineText = null; } this._tokens = []; this._binaryTokens = []; this._lastTokenEndIndex = 0; } _emitBinaryTokens; /** * defined only if `false`. */ _lineText; /** * used only if `_emitBinaryTokens` is false. */ _tokens; /** * used only if `_emitBinaryTokens` is true. */ _binaryTokens; _lastTokenEndIndex; _tokenTypeOverrides; produce(stack, endIndex) { this.produceFromScopes(stack.contentNameScopesList, endIndex); } produceFromScopes(scopesList, endIndex) { if (this._lastTokenEndIndex >= endIndex) { return; } if (this._emitBinaryTokens) { let metadata = scopesList?.tokenAttributes ?? 0; let containsBalancedBrackets = false; if (this.balancedBracketSelectors?.matchesAlways) { containsBalancedBrackets = true; } if (this._tokenTypeOverrides.length > 0 || this.balancedBracketSelectors && !this.balancedBracketSelectors.matchesAlways && !this.balancedBracketSelectors.matchesNever) { const scopes2 = scopesList?.getScopeNames() ?? []; for (const tokenType of this._tokenTypeOverrides) { if (tokenType.matcher(scopes2)) { metadata = EncodedTokenMetadata.set( metadata, 0, toOptionalTokenType(tokenType.type), null, -1 /* NotSet */, 0, 0 ); } } if (this.balancedBracketSelectors) { containsBalancedBrackets = this.balancedBracketSelectors.match(scopes2); } } if (containsBalancedBrackets) { metadata = EncodedTokenMetadata.set( metadata, 0, 8 /* NotSet */, containsBalancedBrackets, -1 /* NotSet */, 0, 0 ); } if (this._binaryTokens.length > 0 && this._binaryTokens[this._binaryTokens.length - 1] === metadata) { this._lastTokenEndIndex = endIndex; return; } this._binaryTokens.push(this._lastTokenEndIndex); this._binaryTokens.push(metadata); this._lastTokenEndIndex = endIndex; return; } const scopes = scopesList?.getScopeNames() ?? []; this._tokens.push({ startIndex: this._lastTokenEndIndex, endIndex, // value: lineText.substring(lastTokenEndIndex, endIndex), scopes }); this._lastTokenEndIndex = endIndex; } getResult(stack, lineLength) { if (this._tokens.length > 0 && this._tokens[this._tokens.length - 1].startIndex === lineLength - 1) { this._tokens.pop(); } if (this._tokens.length === 0) { this._lastTokenEndIndex = -1; this.produce(stack, lineLength); this._tokens[this._tokens.length - 1].startIndex = 0; } return this._tokens; } getBinaryResult(stack, lineLength) { if (this._binaryTokens.length > 0 && this._binaryTokens[this._binaryTokens.length - 2] === lineLength - 1) { this._binaryTokens.pop(); this._binaryTokens.pop(); } if (this._binaryTokens.length === 0) { this._lastTokenEndIndex = -1; this.produce(stack, lineLength); this._binaryTokens[this._binaryTokens.length - 2] = 0; } const result = new Uint32Array(this._binaryTokens.length); for (let i = 0, len = this._binaryTokens.length; i < len; i++) { result[i] = this._binaryTokens[i]; } return result; } }; // src/registry.ts var SyncRegistry = class { constructor(theme, _onigLib) { this._onigLib = _onigLib; this._theme = theme; } _grammars = /* @__PURE__ */ new Map(); _rawGrammars = /* @__PURE__ */ new Map(); _injectionGrammars = /* @__PURE__ */ new Map(); _theme; dispose() { for (const grammar of this._grammars.values()) { grammar.dispose(); } } setTheme(theme) { this._theme = theme; } getColorMap() { return this._theme.getColorMap(); } /** * Add `grammar` to registry and return a list of referenced scope names */ addGrammar(grammar, injectionScopeNames) { this._rawGrammars.set(grammar.scopeName, grammar); if (injectionScopeNames) { this._injectionGrammars.set(grammar.scopeName, injectionScopeNames); } } /** * Lookup a raw grammar. */ lookup(scopeName) { return this._rawGrammars.get(scopeName); } /** * Returns the injections for the given grammar */ injections(targetScope) { return this._injectionGrammars.get(targetScope); } /** * Get the default theme settings */ getDefaults() { return this._theme.getDefaults(); } /** * Match a scope in the theme. */ themeMatch(scopePath) { return this._theme.match(scopePath); } /** * Lookup a grammar. */ grammarForScopeName(scopeName, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors) { if (!this._grammars.has(scopeName)) { let rawGrammar = this._rawGrammars.get(scopeName); if (!rawGrammar) { return null; } this._grammars.set(scopeName, createGrammar( scopeName, rawGrammar, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors, this, this._onigLib )); } return this._grammars.get(scopeName); } }; // src/index.ts var Registry = class { _options; _syncRegistry; _ensureGrammarCache; constructor(options) { this._options = options; this._syncRegistry = new SyncRegistry( Theme.createFromRawTheme(options.theme, options.colorMap), options.onigLib ); this._ensureGrammarCache = /* @__PURE__ */ new Map(); } dispose() { this._syncRegistry.dispose(); } /** * Change the theme. Once called, no previous `ruleStack` should be used anymore. */ setTheme(theme, colorMap) { this._syncRegistry.setTheme(Theme.createFromRawTheme(theme, colorMap)); } /** * Returns a lookup array for color ids. */ getColorMap() { return this._syncRegistry.getColorMap(); } /** * Load the grammar for `scopeName` and all referenced included grammars asynchronously. * Please do not use language id 0. */ loadGrammarWithEmbeddedLanguages(initialScopeName, initialLanguage, embeddedLanguages) { return this.loadGrammarWithConfiguration(initialScopeName, initialLanguage, { embeddedLanguages }); } /** * Load the grammar for `scopeName` and all referenced included grammars asynchronously. * Please do not use language id 0. */ loadGrammarWithConfiguration(initialScopeName, initialLanguage, configuration) { 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. */ loadGrammar(initialScopeName) { return this._loadGrammar(initialScopeName, 0, null, null, null); } _loadGrammar(initialScopeName, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors) { const dependencyProcessor = new ScopeDependencyProcessor(this._syncRegistry, initialScopeName); while (dependencyProcessor.Q.length > 0) { dependencyProcessor.Q.map((request) => this._loadSingleGrammar(request.scopeName)); dependencyProcessor.processQueue(); } return this._grammarForScopeName( initialScopeName, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors ); } _loadSingleGrammar(scopeName) { if (!this._ensureGrammarCache.has(scopeName)) { this._doLoadSingleGrammar(scopeName); this._ensureGrammarCache.set(scopeName, true); } } _doLoadSingleGrammar(scopeName) { const grammar = this._options.loadGrammar(scopeName); if (grammar) { const injections = typeof this._options.getInjections === "function" ? this._options.getInjections(scopeName) : void 0; this._syncRegistry.addGrammar(grammar, injections); } } /** * Adds a rawGrammar. */ addGrammar(rawGrammar, injections = [], initialLanguage = 0, embeddedLanguages = null) { this._syncRegistry.addGrammar(rawGrammar, injections); return this._grammarForScopeName(rawGrammar.scopeName, initialLanguage, embeddedLanguages); } /** * Get the grammar for `scopeName`. The grammar must first be created via `loadGrammar` or `addGrammar`. */ _grammarForScopeName(scopeName, initialLanguage = 0, embeddedLanguages = null, tokenTypes = null, balancedBracketSelectors = null) { return this._syncRegistry.grammarForScopeName( scopeName, initialLanguage, embeddedLanguages, tokenTypes, balancedBracketSelectors ); } }; var INITIAL = StateStackImpl.NULL; export { EncodedTokenMetadata, FindOption, FontStyle, INITIAL, Registry, Theme, disposeOnigString };