123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- export class Scanner {
- constructor() {
- this.value = '';
- this.pos = 0;
- }
- static isDigitCharacter(ch) {
- return ch >= 48 /* Digit0 */ && ch <= 57 /* Digit9 */;
- }
- static isVariableCharacter(ch) {
- return ch === 95 /* Underline */
- || (ch >= 97 /* a */ && ch <= 122 /* z */)
- || (ch >= 65 /* A */ && ch <= 90 /* Z */);
- }
- text(value) {
- this.value = value;
- this.pos = 0;
- }
- tokenText(token) {
- return this.value.substr(token.pos, token.len);
- }
- next() {
- if (this.pos >= this.value.length) {
- return { type: 14 /* EOF */, pos: this.pos, len: 0 };
- }
- let pos = this.pos;
- let len = 0;
- let ch = this.value.charCodeAt(pos);
- let type;
- // static types
- type = Scanner._table[ch];
- if (typeof type === 'number') {
- this.pos += 1;
- return { type, pos, len: 1 };
- }
- // number
- if (Scanner.isDigitCharacter(ch)) {
- type = 8 /* Int */;
- do {
- len += 1;
- ch = this.value.charCodeAt(pos + len);
- } while (Scanner.isDigitCharacter(ch));
- this.pos += len;
- return { type, pos, len };
- }
- // variable name
- if (Scanner.isVariableCharacter(ch)) {
- type = 9 /* VariableName */;
- do {
- ch = this.value.charCodeAt(pos + (++len));
- } while (Scanner.isVariableCharacter(ch) || Scanner.isDigitCharacter(ch));
- this.pos += len;
- return { type, pos, len };
- }
- // format
- type = 10 /* Format */;
- do {
- len += 1;
- ch = this.value.charCodeAt(pos + len);
- } while (!isNaN(ch)
- && typeof Scanner._table[ch] === 'undefined' // not static token
- && !Scanner.isDigitCharacter(ch) // not number
- && !Scanner.isVariableCharacter(ch) // not variable
- );
- this.pos += len;
- return { type, pos, len };
- }
- }
- Scanner._table = {
- [36 /* DollarSign */]: 0 /* Dollar */,
- [58 /* Colon */]: 1 /* Colon */,
- [44 /* Comma */]: 2 /* Comma */,
- [123 /* OpenCurlyBrace */]: 3 /* CurlyOpen */,
- [125 /* CloseCurlyBrace */]: 4 /* CurlyClose */,
- [92 /* Backslash */]: 5 /* Backslash */,
- [47 /* Slash */]: 6 /* Forwardslash */,
- [124 /* Pipe */]: 7 /* Pipe */,
- [43 /* Plus */]: 11 /* Plus */,
- [45 /* Dash */]: 12 /* Dash */,
- [63 /* QuestionMark */]: 13 /* QuestionMark */,
- };
- export class Marker {
- constructor() {
- this._children = [];
- }
- appendChild(child) {
- if (child instanceof Text && this._children[this._children.length - 1] instanceof Text) {
- // this and previous child are text -> merge them
- this._children[this._children.length - 1].value += child.value;
- }
- else {
- // normal adoption of child
- child.parent = this;
- this._children.push(child);
- }
- return this;
- }
- replace(child, others) {
- const { parent } = child;
- const idx = parent.children.indexOf(child);
- const newChildren = parent.children.slice(0);
- newChildren.splice(idx, 1, ...others);
- parent._children = newChildren;
- (function _fixParent(children, parent) {
- for (const child of children) {
- child.parent = parent;
- _fixParent(child.children, child);
- }
- })(others, parent);
- }
- get children() {
- return this._children;
- }
- get snippet() {
- let candidate = this;
- while (true) {
- if (!candidate) {
- return undefined;
- }
- if (candidate instanceof TextmateSnippet) {
- return candidate;
- }
- candidate = candidate.parent;
- }
- }
- toString() {
- return this.children.reduce((prev, cur) => prev + cur.toString(), '');
- }
- len() {
- return 0;
- }
- }
- export class Text extends Marker {
- constructor(value) {
- super();
- this.value = value;
- }
- toString() {
- return this.value;
- }
- len() {
- return this.value.length;
- }
- clone() {
- return new Text(this.value);
- }
- }
- export class TransformableMarker extends Marker {
- }
- export class Placeholder extends TransformableMarker {
- constructor(index) {
- super();
- this.index = index;
- }
- static compareByIndex(a, b) {
- if (a.index === b.index) {
- return 0;
- }
- else if (a.isFinalTabstop) {
- return 1;
- }
- else if (b.isFinalTabstop) {
- return -1;
- }
- else if (a.index < b.index) {
- return -1;
- }
- else if (a.index > b.index) {
- return 1;
- }
- else {
- return 0;
- }
- }
- get isFinalTabstop() {
- return this.index === 0;
- }
- get choice() {
- return this._children.length === 1 && this._children[0] instanceof Choice
- ? this._children[0]
- : undefined;
- }
- clone() {
- let ret = new Placeholder(this.index);
- if (this.transform) {
- ret.transform = this.transform.clone();
- }
- ret._children = this.children.map(child => child.clone());
- return ret;
- }
- }
- export class Choice extends Marker {
- constructor() {
- super(...arguments);
- this.options = [];
- }
- appendChild(marker) {
- if (marker instanceof Text) {
- marker.parent = this;
- this.options.push(marker);
- }
- return this;
- }
- toString() {
- return this.options[0].value;
- }
- len() {
- return this.options[0].len();
- }
- clone() {
- let ret = new Choice();
- this.options.forEach(ret.appendChild, ret);
- return ret;
- }
- }
- export class Transform extends Marker {
- constructor() {
- super(...arguments);
- this.regexp = new RegExp('');
- }
- resolve(value) {
- const _this = this;
- let didMatch = false;
- let ret = value.replace(this.regexp, function () {
- didMatch = true;
- return _this._replace(Array.prototype.slice.call(arguments, 0, -2));
- });
- // when the regex didn't match and when the transform has
- // else branches, then run those
- if (!didMatch && this._children.some(child => child instanceof FormatString && Boolean(child.elseValue))) {
- ret = this._replace([]);
- }
- return ret;
- }
- _replace(groups) {
- let ret = '';
- for (const marker of this._children) {
- if (marker instanceof FormatString) {
- let value = groups[marker.index] || '';
- value = marker.resolve(value);
- ret += value;
- }
- else {
- ret += marker.toString();
- }
- }
- return ret;
- }
- toString() {
- return '';
- }
- clone() {
- let ret = new Transform();
- ret.regexp = new RegExp(this.regexp.source, '' + (this.regexp.ignoreCase ? 'i' : '') + (this.regexp.global ? 'g' : ''));
- ret._children = this.children.map(child => child.clone());
- return ret;
- }
- }
- export class FormatString extends Marker {
- constructor(index, shorthandName, ifValue, elseValue) {
- super();
- this.index = index;
- this.shorthandName = shorthandName;
- this.ifValue = ifValue;
- this.elseValue = elseValue;
- }
- resolve(value) {
- if (this.shorthandName === 'upcase') {
- return !value ? '' : value.toLocaleUpperCase();
- }
- else if (this.shorthandName === 'downcase') {
- return !value ? '' : value.toLocaleLowerCase();
- }
- else if (this.shorthandName === 'capitalize') {
- return !value ? '' : (value[0].toLocaleUpperCase() + value.substr(1));
- }
- else if (this.shorthandName === 'pascalcase') {
- return !value ? '' : this._toPascalCase(value);
- }
- else if (this.shorthandName === 'camelcase') {
- return !value ? '' : this._toCamelCase(value);
- }
- else if (Boolean(value) && typeof this.ifValue === 'string') {
- return this.ifValue;
- }
- else if (!Boolean(value) && typeof this.elseValue === 'string') {
- return this.elseValue;
- }
- else {
- return value || '';
- }
- }
- _toPascalCase(value) {
- const match = value.match(/[a-z0-9]+/gi);
- if (!match) {
- return value;
- }
- return match.map(word => {
- return word.charAt(0).toUpperCase()
- + word.substr(1).toLowerCase();
- })
- .join('');
- }
- _toCamelCase(value) {
- const match = value.match(/[a-z0-9]+/gi);
- if (!match) {
- return value;
- }
- return match.map((word, index) => {
- if (index === 0) {
- return word.toLowerCase();
- }
- else {
- return word.charAt(0).toUpperCase()
- + word.substr(1).toLowerCase();
- }
- })
- .join('');
- }
- clone() {
- let ret = new FormatString(this.index, this.shorthandName, this.ifValue, this.elseValue);
- return ret;
- }
- }
- export class Variable extends TransformableMarker {
- constructor(name) {
- super();
- this.name = name;
- }
- resolve(resolver) {
- let value = resolver.resolve(this);
- if (this.transform) {
- value = this.transform.resolve(value || '');
- }
- if (value !== undefined) {
- this._children = [new Text(value)];
- return true;
- }
- return false;
- }
- clone() {
- const ret = new Variable(this.name);
- if (this.transform) {
- ret.transform = this.transform.clone();
- }
- ret._children = this.children.map(child => child.clone());
- return ret;
- }
- }
- function walk(marker, visitor) {
- const stack = [...marker];
- while (stack.length > 0) {
- const marker = stack.shift();
- const recurse = visitor(marker);
- if (!recurse) {
- break;
- }
- stack.unshift(...marker.children);
- }
- }
- export class TextmateSnippet extends Marker {
- get placeholderInfo() {
- if (!this._placeholders) {
- // fill in placeholders
- let all = [];
- let last;
- this.walk(function (candidate) {
- if (candidate instanceof Placeholder) {
- all.push(candidate);
- last = !last || last.index < candidate.index ? candidate : last;
- }
- return true;
- });
- this._placeholders = { all, last };
- }
- return this._placeholders;
- }
- get placeholders() {
- const { all } = this.placeholderInfo;
- return all;
- }
- offset(marker) {
- let pos = 0;
- let found = false;
- this.walk(candidate => {
- if (candidate === marker) {
- found = true;
- return false;
- }
- pos += candidate.len();
- return true;
- });
- if (!found) {
- return -1;
- }
- return pos;
- }
- fullLen(marker) {
- let ret = 0;
- walk([marker], marker => {
- ret += marker.len();
- return true;
- });
- return ret;
- }
- enclosingPlaceholders(placeholder) {
- let ret = [];
- let { parent } = placeholder;
- while (parent) {
- if (parent instanceof Placeholder) {
- ret.push(parent);
- }
- parent = parent.parent;
- }
- return ret;
- }
- resolveVariables(resolver) {
- this.walk(candidate => {
- if (candidate instanceof Variable) {
- if (candidate.resolve(resolver)) {
- this._placeholders = undefined;
- }
- }
- return true;
- });
- return this;
- }
- appendChild(child) {
- this._placeholders = undefined;
- return super.appendChild(child);
- }
- replace(child, others) {
- this._placeholders = undefined;
- return super.replace(child, others);
- }
- clone() {
- let ret = new TextmateSnippet();
- this._children = this.children.map(child => child.clone());
- return ret;
- }
- walk(visitor) {
- walk(this.children, visitor);
- }
- }
- export class SnippetParser {
- constructor() {
- this._scanner = new Scanner();
- this._token = { type: 14 /* EOF */, pos: 0, len: 0 };
- }
- static escape(value) {
- return value.replace(/\$|}|\\/g, '\\$&');
- }
- static guessNeedsClipboard(template) {
- return /\${?CLIPBOARD/.test(template);
- }
- parse(value, insertFinalTabstop, enforceFinalTabstop) {
- this._scanner.text(value);
- this._token = this._scanner.next();
- const snippet = new TextmateSnippet();
- while (this._parse(snippet)) {
- // nothing
- }
- // fill in values for placeholders. the first placeholder of an index
- // that has a value defines the value for all placeholders with that index
- const placeholderDefaultValues = new Map();
- const incompletePlaceholders = [];
- let placeholderCount = 0;
- snippet.walk(marker => {
- if (marker instanceof Placeholder) {
- placeholderCount += 1;
- if (marker.isFinalTabstop) {
- placeholderDefaultValues.set(0, undefined);
- }
- else if (!placeholderDefaultValues.has(marker.index) && marker.children.length > 0) {
- placeholderDefaultValues.set(marker.index, marker.children);
- }
- else {
- incompletePlaceholders.push(marker);
- }
- }
- return true;
- });
- for (const placeholder of incompletePlaceholders) {
- const defaultValues = placeholderDefaultValues.get(placeholder.index);
- if (defaultValues) {
- const clone = new Placeholder(placeholder.index);
- clone.transform = placeholder.transform;
- for (const child of defaultValues) {
- clone.appendChild(child.clone());
- }
- snippet.replace(placeholder, [clone]);
- }
- }
- if (!enforceFinalTabstop) {
- enforceFinalTabstop = placeholderCount > 0 && insertFinalTabstop;
- }
- if (!placeholderDefaultValues.has(0) && enforceFinalTabstop) {
- // the snippet uses placeholders but has no
- // final tabstop defined -> insert at the end
- snippet.appendChild(new Placeholder(0));
- }
- return snippet;
- }
- _accept(type, value) {
- if (type === undefined || this._token.type === type) {
- let ret = !value ? true : this._scanner.tokenText(this._token);
- this._token = this._scanner.next();
- return ret;
- }
- return false;
- }
- _backTo(token) {
- this._scanner.pos = token.pos + token.len;
- this._token = token;
- return false;
- }
- _until(type) {
- const start = this._token;
- while (this._token.type !== type) {
- if (this._token.type === 14 /* EOF */) {
- return false;
- }
- else if (this._token.type === 5 /* Backslash */) {
- const nextToken = this._scanner.next();
- if (nextToken.type !== 0 /* Dollar */
- && nextToken.type !== 4 /* CurlyClose */
- && nextToken.type !== 5 /* Backslash */) {
- return false;
- }
- }
- this._token = this._scanner.next();
- }
- const value = this._scanner.value.substring(start.pos, this._token.pos).replace(/\\(\$|}|\\)/g, '$1');
- this._token = this._scanner.next();
- return value;
- }
- _parse(marker) {
- return this._parseEscaped(marker)
- || this._parseTabstopOrVariableName(marker)
- || this._parseComplexPlaceholder(marker)
- || this._parseComplexVariable(marker)
- || this._parseAnything(marker);
- }
- // \$, \\, \} -> just text
- _parseEscaped(marker) {
- let value;
- if (value = this._accept(5 /* Backslash */, true)) {
- // saw a backslash, append escaped token or that backslash
- value = this._accept(0 /* Dollar */, true)
- || this._accept(4 /* CurlyClose */, true)
- || this._accept(5 /* Backslash */, true)
- || value;
- marker.appendChild(new Text(value));
- return true;
- }
- return false;
- }
- // $foo -> variable, $1 -> tabstop
- _parseTabstopOrVariableName(parent) {
- let value;
- const token = this._token;
- const match = this._accept(0 /* Dollar */)
- && (value = this._accept(9 /* VariableName */, true) || this._accept(8 /* Int */, true));
- if (!match) {
- return this._backTo(token);
- }
- parent.appendChild(/^\d+$/.test(value)
- ? new Placeholder(Number(value))
- : new Variable(value));
- return true;
- }
- // ${1:<children>}, ${1} -> placeholder
- _parseComplexPlaceholder(parent) {
- let index;
- const token = this._token;
- const match = this._accept(0 /* Dollar */)
- && this._accept(3 /* CurlyOpen */)
- && (index = this._accept(8 /* Int */, true));
- if (!match) {
- return this._backTo(token);
- }
- const placeholder = new Placeholder(Number(index));
- if (this._accept(1 /* Colon */)) {
- // ${1:<children>}
- while (true) {
- // ...} -> done
- if (this._accept(4 /* CurlyClose */)) {
- parent.appendChild(placeholder);
- return true;
- }
- if (this._parse(placeholder)) {
- continue;
- }
- // fallback
- parent.appendChild(new Text('${' + index + ':'));
- placeholder.children.forEach(parent.appendChild, parent);
- return true;
- }
- }
- else if (placeholder.index > 0 && this._accept(7 /* Pipe */)) {
- // ${1|one,two,three|}
- const choice = new Choice();
- while (true) {
- if (this._parseChoiceElement(choice)) {
- if (this._accept(2 /* Comma */)) {
- // opt, -> more
- continue;
- }
- if (this._accept(7 /* Pipe */)) {
- placeholder.appendChild(choice);
- if (this._accept(4 /* CurlyClose */)) {
- // ..|} -> done
- parent.appendChild(placeholder);
- return true;
- }
- }
- }
- this._backTo(token);
- return false;
- }
- }
- else if (this._accept(6 /* Forwardslash */)) {
- // ${1/<regex>/<format>/<options>}
- if (this._parseTransform(placeholder)) {
- parent.appendChild(placeholder);
- return true;
- }
- this._backTo(token);
- return false;
- }
- else if (this._accept(4 /* CurlyClose */)) {
- // ${1}
- parent.appendChild(placeholder);
- return true;
- }
- else {
- // ${1 <- missing curly or colon
- return this._backTo(token);
- }
- }
- _parseChoiceElement(parent) {
- const token = this._token;
- const values = [];
- while (true) {
- if (this._token.type === 2 /* Comma */ || this._token.type === 7 /* Pipe */) {
- break;
- }
- let value;
- if (value = this._accept(5 /* Backslash */, true)) {
- // \, \|, or \\
- value = this._accept(2 /* Comma */, true)
- || this._accept(7 /* Pipe */, true)
- || this._accept(5 /* Backslash */, true)
- || value;
- }
- else {
- value = this._accept(undefined, true);
- }
- if (!value) {
- // EOF
- this._backTo(token);
- return false;
- }
- values.push(value);
- }
- if (values.length === 0) {
- this._backTo(token);
- return false;
- }
- parent.appendChild(new Text(values.join('')));
- return true;
- }
- // ${foo:<children>}, ${foo} -> variable
- _parseComplexVariable(parent) {
- let name;
- const token = this._token;
- const match = this._accept(0 /* Dollar */)
- && this._accept(3 /* CurlyOpen */)
- && (name = this._accept(9 /* VariableName */, true));
- if (!match) {
- return this._backTo(token);
- }
- const variable = new Variable(name);
- if (this._accept(1 /* Colon */)) {
- // ${foo:<children>}
- while (true) {
- // ...} -> done
- if (this._accept(4 /* CurlyClose */)) {
- parent.appendChild(variable);
- return true;
- }
- if (this._parse(variable)) {
- continue;
- }
- // fallback
- parent.appendChild(new Text('${' + name + ':'));
- variable.children.forEach(parent.appendChild, parent);
- return true;
- }
- }
- else if (this._accept(6 /* Forwardslash */)) {
- // ${foo/<regex>/<format>/<options>}
- if (this._parseTransform(variable)) {
- parent.appendChild(variable);
- return true;
- }
- this._backTo(token);
- return false;
- }
- else if (this._accept(4 /* CurlyClose */)) {
- // ${foo}
- parent.appendChild(variable);
- return true;
- }
- else {
- // ${foo <- missing curly or colon
- return this._backTo(token);
- }
- }
- _parseTransform(parent) {
- // ...<regex>/<format>/<options>}
- let transform = new Transform();
- let regexValue = '';
- let regexOptions = '';
- // (1) /regex
- while (true) {
- if (this._accept(6 /* Forwardslash */)) {
- break;
- }
- let escaped;
- if (escaped = this._accept(5 /* Backslash */, true)) {
- escaped = this._accept(6 /* Forwardslash */, true) || escaped;
- regexValue += escaped;
- continue;
- }
- if (this._token.type !== 14 /* EOF */) {
- regexValue += this._accept(undefined, true);
- continue;
- }
- return false;
- }
- // (2) /format
- while (true) {
- if (this._accept(6 /* Forwardslash */)) {
- break;
- }
- let escaped;
- if (escaped = this._accept(5 /* Backslash */, true)) {
- escaped = this._accept(5 /* Backslash */, true) || this._accept(6 /* Forwardslash */, true) || escaped;
- transform.appendChild(new Text(escaped));
- continue;
- }
- if (this._parseFormatString(transform) || this._parseAnything(transform)) {
- continue;
- }
- return false;
- }
- // (3) /option
- while (true) {
- if (this._accept(4 /* CurlyClose */)) {
- break;
- }
- if (this._token.type !== 14 /* EOF */) {
- regexOptions += this._accept(undefined, true);
- continue;
- }
- return false;
- }
- try {
- transform.regexp = new RegExp(regexValue, regexOptions);
- }
- catch (e) {
- // invalid regexp
- return false;
- }
- parent.transform = transform;
- return true;
- }
- _parseFormatString(parent) {
- const token = this._token;
- if (!this._accept(0 /* Dollar */)) {
- return false;
- }
- let complex = false;
- if (this._accept(3 /* CurlyOpen */)) {
- complex = true;
- }
- let index = this._accept(8 /* Int */, true);
- if (!index) {
- this._backTo(token);
- return false;
- }
- else if (!complex) {
- // $1
- parent.appendChild(new FormatString(Number(index)));
- return true;
- }
- else if (this._accept(4 /* CurlyClose */)) {
- // ${1}
- parent.appendChild(new FormatString(Number(index)));
- return true;
- }
- else if (!this._accept(1 /* Colon */)) {
- this._backTo(token);
- return false;
- }
- if (this._accept(6 /* Forwardslash */)) {
- // ${1:/upcase}
- let shorthand = this._accept(9 /* VariableName */, true);
- if (!shorthand || !this._accept(4 /* CurlyClose */)) {
- this._backTo(token);
- return false;
- }
- else {
- parent.appendChild(new FormatString(Number(index), shorthand));
- return true;
- }
- }
- else if (this._accept(11 /* Plus */)) {
- // ${1:+<if>}
- let ifValue = this._until(4 /* CurlyClose */);
- if (ifValue) {
- parent.appendChild(new FormatString(Number(index), undefined, ifValue, undefined));
- return true;
- }
- }
- else if (this._accept(12 /* Dash */)) {
- // ${2:-<else>}
- let elseValue = this._until(4 /* CurlyClose */);
- if (elseValue) {
- parent.appendChild(new FormatString(Number(index), undefined, undefined, elseValue));
- return true;
- }
- }
- else if (this._accept(13 /* QuestionMark */)) {
- // ${2:?<if>:<else>}
- let ifValue = this._until(1 /* Colon */);
- if (ifValue) {
- let elseValue = this._until(4 /* CurlyClose */);
- if (elseValue) {
- parent.appendChild(new FormatString(Number(index), undefined, ifValue, elseValue));
- return true;
- }
- }
- }
- else {
- // ${1:<else>}
- let elseValue = this._until(4 /* CurlyClose */);
- if (elseValue) {
- parent.appendChild(new FormatString(Number(index), undefined, undefined, elseValue));
- return true;
- }
- }
- this._backTo(token);
- return false;
- }
- _parseAnything(marker) {
- if (this._token.type !== 14 /* EOF */) {
- marker.appendChild(new Text(this._scanner.tokenText(this._token)));
- this._accept(undefined);
- return true;
- }
- return false;
- }
- }
|