clarity-pattern-parser 11.0.30 → 11.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import { Pattern } from "../patterns/Pattern";
2
+ export type Decorator = (pattern: Pattern, arg?: string | boolean | number | null | Record<string, any> | any[]) => void;
2
3
  export interface GrammarFile {
3
4
  resource: string;
4
5
  expression: string;
@@ -7,6 +8,7 @@ export interface GrammarOptions {
7
8
  resolveImport?: (resource: string, originResource: string | null) => Promise<GrammarFile>;
8
9
  originResource?: string | null;
9
10
  params?: Pattern[];
11
+ decorators?: Record<string, Decorator>;
10
12
  }
11
13
  export declare class Grammar {
12
14
  private _params;
@@ -38,6 +40,7 @@ export declare class Grammar {
38
40
  private _saveConfigurableAnonymous;
39
41
  private _buildComplexAnonymousPattern;
40
42
  private _resolveImports;
43
+ private _applyDecorators;
41
44
  private _getParams;
42
45
  private _getPattern;
43
46
  private _saveAlias;
@@ -0,0 +1,2 @@
1
+ import { Decorator } from "../Grammar";
2
+ export declare const tokens: Decorator;
@@ -0,0 +1,2 @@
1
+ import { Options } from "../../patterns/Options";
2
+ export declare const decoratorStatement: Options;
@@ -1,2 +1,4 @@
1
1
  import { Pattern } from "../patterns/Pattern";
2
+ import { GrammarOptions } from "./Grammar";
2
3
  export declare function patterns(strings: TemplateStringsArray, ...values: any): Record<string, Pattern>;
4
+ export declare function createPatternsTemplate(options: GrammarOptions): (strings: TemplateStringsArray, ...values: any) => Record<string, Pattern>;
@@ -1945,8 +1945,8 @@
1945
1945
  }
1946
1946
  }
1947
1947
 
1948
- const literal = new Regex("literal", '"(?:\\\\.|[^"\\\\])*"');
1949
- literal.setTokens(["[LITERAL]"]);
1948
+ const literal$1 = new Regex("literal", '"(?:\\\\.|[^"\\\\])*"');
1949
+ literal$1.setTokens(["[LITERAL]"]);
1950
1950
 
1951
1951
  const tabs$1 = new Regex("tabs", "\\t+");
1952
1952
  tabs$1.setTokens(["\t"]);
@@ -1965,7 +1965,7 @@
1965
1965
 
1966
1966
  const patternName$3 = name$1.clone("pattern-name");
1967
1967
  const anonymousLiterals = new Options("anonymous-literals", [
1968
- literal,
1968
+ literal$1,
1969
1969
  regexLiteral,
1970
1970
  patternName$3,
1971
1971
  new Reference("repeat-literal"),
@@ -2086,9 +2086,9 @@
2086
2086
  ]);
2087
2087
 
2088
2088
  const optionalSpaces$3 = new Optional("optional-spaces", spaces$1);
2089
- const openBracket$1 = new Literal("repeat-open-bracket", "{");
2090
- const closeBracket$1 = new Literal("repeat-close-bracket", "}");
2091
- const comma = new Literal("comma", ",");
2089
+ const openBracket$2 = new Literal("repeat-open-bracket", "{");
2090
+ const closeBracket$2 = new Literal("repeat-close-bracket", "}");
2091
+ const comma$1 = new Literal("comma", ",");
2092
2092
  const integer = new Regex("integer", "([1-9][0-9]*)|0");
2093
2093
  integer.setTokens(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
2094
2094
  const min = new Optional("optional-min", integer.clone("min"));
@@ -2096,21 +2096,21 @@
2096
2096
  const trimKeyword = new Literal("trim-keyword", "trim");
2097
2097
  const trimFlag = new Optional("optional-trim-flag", new Sequence("trim-flag", [lineSpaces$1, trimKeyword]));
2098
2098
  const bounds = new Sequence("bounds", [
2099
- openBracket$1,
2099
+ openBracket$2,
2100
2100
  optionalSpaces$3,
2101
2101
  min,
2102
2102
  optionalSpaces$3,
2103
- comma,
2103
+ comma$1,
2104
2104
  optionalSpaces$3,
2105
2105
  max,
2106
- closeBracket$1
2106
+ closeBracket$2
2107
2107
  ]);
2108
2108
  const exactCount = new Sequence("exact-count", [
2109
- openBracket$1,
2109
+ openBracket$2,
2110
2110
  optionalSpaces$3,
2111
2111
  integer,
2112
2112
  optionalSpaces$3,
2113
- closeBracket$1,
2113
+ closeBracket$2,
2114
2114
  ]);
2115
2115
  const quantifierShorthand = new Regex("quantifier-shorthand", "\\*|\\+");
2116
2116
  quantifierShorthand.setTokens(["*", "+"]);
@@ -2119,8 +2119,8 @@
2119
2119
  exactCount,
2120
2120
  bounds
2121
2121
  ]);
2122
- const openParen = new Literal("repeat-open-paren", "(");
2123
- const closeParen = new Literal("repeat-close-paren", ")");
2122
+ const openParen$1 = new Literal("repeat-open-paren", "(");
2123
+ const closeParen$1 = new Literal("repeat-close-paren", ")");
2124
2124
  const dividerComma = new Regex("divider-comma", "\\s*,\\s*");
2125
2125
  dividerComma.setTokens([", "]);
2126
2126
  const patternName$2 = name$1.clone("pattern-name");
@@ -2129,12 +2129,12 @@
2129
2129
  const repeatDividerSection = new Sequence("repeat-divider-section", [dividerComma, repeatDividerPattern, trimFlag]);
2130
2130
  const repeatOptionalDividerSection = new Optional("repeat-optional-divider-section", repeatDividerSection);
2131
2131
  const repeatLiteral = new Sequence("repeat-literal", [
2132
- openParen,
2132
+ openParen$1,
2133
2133
  optionalSpaces$3,
2134
2134
  repeatPattern,
2135
2135
  repeatOptionalDividerSection,
2136
2136
  optionalSpaces$3,
2137
- closeParen,
2137
+ closeParen$1,
2138
2138
  new Sequence("quantifier-section", [quantifier]),
2139
2139
  ]);
2140
2140
 
@@ -2169,7 +2169,7 @@
2169
2169
  const optionalIsOptional = new Optional("optional-flag", new Literal("is-optional", "?"));
2170
2170
  const configurableAnonymousPattern = new Sequence("configurable-anonymous-pattern", [anonymousPattern, optionalIsOptional]);
2171
2171
  const pattern = new Options("pattern", [
2172
- literal,
2172
+ literal$1,
2173
2173
  regexLiteral,
2174
2174
  repeatLiteral,
2175
2175
  aliasLiteral,
@@ -2178,6 +2178,74 @@
2178
2178
  configurableAnonymousPattern,
2179
2179
  ], true);
2180
2180
 
2181
+ const colon = new Literal("colon", ":");
2182
+ const comma = new Regex("comma", "\\s*,\\s*");
2183
+ const openBracket$1 = new Literal("open-bracket", "{");
2184
+ const closeBracket$1 = new Literal("close-bracket", "}");
2185
+ const openSquareBracket = new Literal("open-square-bracket", "[");
2186
+ const closeSquareBracket = new Literal("close-square-bracket", "]");
2187
+ const optionalAllSpaces = new Optional("optional-all-spaces", allSpaces);
2188
+ const stringLiteral = new Regex("string-literal", '"(?:\\\\.|[^"\\\\])*"');
2189
+ const numberLiteral = new Regex("number-literal", '[+-]?\\d+(\\\\.\\d+)?([eE][+-]?\\d+)?');
2190
+ const nullLiteral = new Literal("null-literal", "null");
2191
+ const trueLiteral = new Literal("true-literal", "true");
2192
+ const falseLiteral = new Literal("false-literal", "false");
2193
+ const booleanLiteral = new Options("", [trueLiteral, falseLiteral]);
2194
+ const objectKey = name$1.clone("object-key");
2195
+ const objectProperty = new Sequence("object-property", [
2196
+ objectKey,
2197
+ optionalAllSpaces,
2198
+ colon,
2199
+ optionalAllSpaces,
2200
+ new Reference("literal"),
2201
+ ]);
2202
+ const objectProperies = new Repeat("object-properties", objectProperty, { divider: comma });
2203
+ const objectLiteral = new Sequence("object-literal", [
2204
+ openBracket$1,
2205
+ optionalAllSpaces,
2206
+ new Optional("optional-object-properties", objectProperies),
2207
+ optionalAllSpaces,
2208
+ closeBracket$1
2209
+ ]);
2210
+ const arrayItems = new Repeat("array-items", new Reference("literal"), { divider: comma });
2211
+ const arrayLiteral = new Sequence("array-literal", [
2212
+ openSquareBracket,
2213
+ optionalAllSpaces,
2214
+ arrayItems,
2215
+ optionalAllSpaces,
2216
+ closeSquareBracket,
2217
+ ]);
2218
+ const literal = new Options("literal", [
2219
+ objectLiteral,
2220
+ arrayLiteral,
2221
+ stringLiteral,
2222
+ booleanLiteral,
2223
+ nullLiteral,
2224
+ numberLiteral,
2225
+ ]);
2226
+ const decoratorPrefix = new Literal("decorator-prefix", "@");
2227
+ const decoratorName = name$1.clone("decorator-name");
2228
+ const openParen = new Literal("open-paren", "(");
2229
+ const closeParen = new Literal("close-paren", ")");
2230
+ const methodDecoration = new Sequence("method-decorator", [
2231
+ decoratorPrefix,
2232
+ decoratorName,
2233
+ optionalAllSpaces,
2234
+ openParen,
2235
+ optionalAllSpaces,
2236
+ new Optional("optional-args", literal),
2237
+ optionalAllSpaces,
2238
+ closeParen
2239
+ ]);
2240
+ const nameDecoration = new Sequence("name-decorator", [
2241
+ decoratorPrefix,
2242
+ decoratorName,
2243
+ ]);
2244
+ const decoratorStatement = new Options("decorator-statement", [
2245
+ methodDecoration,
2246
+ nameDecoration,
2247
+ ]);
2248
+
2181
2249
  const optionalSpaces$2 = new Optional("optional-spaces", spaces$1);
2182
2250
  const assignOperator = new Literal("assign-operator", "=");
2183
2251
  const assignStatement = new Sequence("assign-statement", [
@@ -2188,7 +2256,7 @@
2188
2256
  optionalSpaces$2,
2189
2257
  pattern,
2190
2258
  ]);
2191
- const statement = new Options("statement", [assignStatement, name$1.clone("export-name")]);
2259
+ const statement = new Options("statement", [decoratorStatement, assignStatement, name$1.clone("export-name")]);
2192
2260
 
2193
2261
  const bodyLineContent = new Options("body-line-content", [
2194
2262
  comment,
@@ -2219,7 +2287,7 @@
2219
2287
  const importedNames = new Repeat("imported-names", new Options("import-names", [importAlias, name]), { divider: importNameDivider });
2220
2288
  const paramName = name.clone("param-name");
2221
2289
  const paramNames = new Repeat("param-names", paramName, { divider: importNameDivider });
2222
- const resource = literal.clone("resource");
2290
+ const resource = literal$1.clone("resource");
2223
2291
  const useParams = new Sequence("import-params", [
2224
2292
  useParamsKeyword,
2225
2293
  optionalLineSpaces$1,
@@ -3178,7 +3246,23 @@
3178
3246
  return suggestions.map(s => s.trim()).filter(s => s.length > 0);
3179
3247
  }
3180
3248
 
3249
+ const tokens = (pattern, arg) => {
3250
+ if (pattern.type === "regex" && Array.isArray(arg)) {
3251
+ const regex = pattern;
3252
+ const tokens = [];
3253
+ arg.forEach(token => {
3254
+ if (typeof token === "string") {
3255
+ tokens.push(token);
3256
+ }
3257
+ });
3258
+ regex.setTokens(tokens);
3259
+ }
3260
+ };
3261
+
3181
3262
  let anonymousIndexId = 0;
3263
+ const defaultDecorators = {
3264
+ tokens: tokens
3265
+ };
3182
3266
  const patternNodes = {
3183
3267
  "literal": true,
3184
3268
  "regex-literal": true,
@@ -3189,11 +3273,12 @@
3189
3273
  "configurable-anonymous-pattern": true
3190
3274
  };
3191
3275
  class ParseContext {
3192
- constructor(params) {
3276
+ constructor(params, decorators = {}) {
3193
3277
  this.patternsByName = new Map();
3194
3278
  this.importedPatternsByName = new Map();
3195
3279
  this.paramsByName = new Map();
3196
3280
  params.forEach(p => this.paramsByName.set(p.name, p));
3281
+ this.decorators = Object.assign(Object.assign({}, decorators), defaultDecorators);
3197
3282
  }
3198
3283
  }
3199
3284
  function defaultImportResolver(_path, _basePath) {
@@ -3204,7 +3289,7 @@
3204
3289
  this._params = (options === null || options === void 0 ? void 0 : options.params) == null ? [] : options.params;
3205
3290
  this._originResource = (options === null || options === void 0 ? void 0 : options.originResource) == null ? null : options.originResource;
3206
3291
  this._resolveImport = options.resolveImport == null ? defaultImportResolver : options.resolveImport;
3207
- this._parseContext = new ParseContext(this._params);
3292
+ this._parseContext = new ParseContext(this._params, options.decorators || {});
3208
3293
  }
3209
3294
  import(path) {
3210
3295
  return __awaiter(this, void 0, void 0, function* () {
@@ -3212,14 +3297,15 @@
3212
3297
  const grammar = new Grammar({
3213
3298
  resolveImport: this._resolveImport,
3214
3299
  originResource: grammarFile.resource,
3215
- params: this._params
3300
+ params: this._params,
3301
+ decorators: this._parseContext.decorators
3216
3302
  });
3217
3303
  return grammar.parse(grammarFile.expression);
3218
3304
  });
3219
3305
  }
3220
3306
  parse(expression) {
3221
3307
  return __awaiter(this, void 0, void 0, function* () {
3222
- this._parseContext = new ParseContext(this._params);
3308
+ this._parseContext = new ParseContext(this._params, this._parseContext.decorators);
3223
3309
  const ast = this._tryToParse(expression);
3224
3310
  yield this._resolveImports(ast);
3225
3311
  this._buildPatterns(ast);
@@ -3227,7 +3313,7 @@
3227
3313
  });
3228
3314
  }
3229
3315
  parseString(expression) {
3230
- this._parseContext = new ParseContext(this._params);
3316
+ this._parseContext = new ParseContext(this._params, this._parseContext.decorators);
3231
3317
  const ast = this._tryToParse(expression);
3232
3318
  if (this._hasImports(ast)) {
3233
3319
  throw new Error("Cannot use imports on parseString, use parse instead.");
@@ -3310,6 +3396,7 @@
3310
3396
  const literalNode = statementNode.find(n => n.name === "literal");
3311
3397
  const name = nameNode.value;
3312
3398
  const literal = this._buildLiteral(name, literalNode);
3399
+ this._applyDecorators(statementNode, literal);
3313
3400
  this._parseContext.patternsByName.set(name, literal);
3314
3401
  }
3315
3402
  _buildLiteral(name, node) {
@@ -3332,6 +3419,7 @@
3332
3419
  const regexNode = statementNode.find(n => n.name === "regex-literal");
3333
3420
  const name = nameNode.value;
3334
3421
  const regex = this._buildRegex(name, regexNode);
3422
+ this._applyDecorators(statementNode, regex);
3335
3423
  this._parseContext.patternsByName.set(name, regex);
3336
3424
  }
3337
3425
  _buildRegex(name, node) {
@@ -3343,6 +3431,7 @@
3343
3431
  const name = nameNode.value;
3344
3432
  const optionsNode = statementNode.find(n => n.name === "options-literal");
3345
3433
  const options = this._buildOptions(name, optionsNode);
3434
+ this._applyDecorators(statementNode, options);
3346
3435
  this._parseContext.patternsByName.set(name, options);
3347
3436
  }
3348
3437
  _buildOptions(name, node) {
@@ -3421,6 +3510,7 @@
3421
3510
  const name = nameNode.value;
3422
3511
  const sequenceNode = statementNode.find(n => n.name === "sequence-literal");
3423
3512
  const sequence = this._buildSequence(name, sequenceNode);
3513
+ this._applyDecorators(statementNode, sequence);
3424
3514
  this._parseContext.patternsByName.set(name, sequence);
3425
3515
  }
3426
3516
  _buildSequence(name, node) {
@@ -3443,6 +3533,7 @@
3443
3533
  const name = nameNode.value;
3444
3534
  const repeatNode = statementNode.find(n => n.name === "repeat-literal");
3445
3535
  const repeat = this._buildRepeat(name, repeatNode);
3536
+ this._applyDecorators(statementNode, repeat);
3446
3537
  this._parseContext.patternsByName.set(name, repeat);
3447
3538
  }
3448
3539
  _buildRepeat(name, repeatNode) {
@@ -3497,6 +3588,7 @@
3497
3588
  const anonymousNode = node.find(n => n.name === "configurable-anonymous-pattern");
3498
3589
  const isOptional = node.children[1] != null;
3499
3590
  const anonymous = isOptional ? new Optional(name, this._buildPattern(anonymousNode.children[0])) : this._buildPattern(anonymousNode.children[0]);
3591
+ this._applyDecorators(node, anonymous);
3500
3592
  this._parseContext.patternsByName.set(name, anonymous);
3501
3593
  }
3502
3594
  _buildComplexAnonymousPattern(node) {
@@ -3515,7 +3607,8 @@
3515
3607
  const grammar = new Grammar({
3516
3608
  resolveImport: this._resolveImport,
3517
3609
  originResource: grammarFile.resource,
3518
- params
3610
+ params,
3611
+ decorators: this._parseContext.decorators
3519
3612
  });
3520
3613
  try {
3521
3614
  const patterns = yield grammar.parse(grammarFile.expression);
@@ -3558,6 +3651,46 @@
3558
3651
  }
3559
3652
  });
3560
3653
  }
3654
+ _applyDecorators(statementNode, pattern) {
3655
+ const decorators = this._parseContext.decorators;
3656
+ const bodyLine = statementNode.parent;
3657
+ if (bodyLine == null) {
3658
+ return;
3659
+ }
3660
+ let prevSibling = bodyLine.previousSibling();
3661
+ let decoratorNodes = [];
3662
+ while (prevSibling != null) {
3663
+ if (prevSibling.find(n => n.name === "assign-statement")) {
3664
+ break;
3665
+ }
3666
+ decoratorNodes.push(prevSibling);
3667
+ prevSibling = prevSibling.previousSibling();
3668
+ }
3669
+ decoratorNodes = decoratorNodes.filter(n => n.find(n => n.name.includes("decorator")) != null);
3670
+ decoratorNodes.forEach((d) => {
3671
+ const nameNode = d.find(n => n.name === "decorator-name");
3672
+ if (nameNode == null || decorators[nameNode.value] == null) {
3673
+ return;
3674
+ }
3675
+ const nameDocorator = d.find(n => n.name === "name-decorator");
3676
+ if (nameDocorator != null) {
3677
+ decorators[nameNode.value](pattern);
3678
+ return;
3679
+ }
3680
+ const methodDecorator = d.find(n => n.name === "method-decorator");
3681
+ if (methodDecorator == null) {
3682
+ return;
3683
+ }
3684
+ methodDecorator.findAll(n => n.name.includes("space")).forEach(n => n.remove());
3685
+ const argsNode = methodDecorator.children[3];
3686
+ if (argsNode == null || argsNode.name === "close-paren") {
3687
+ decorators[nameNode.value](pattern);
3688
+ }
3689
+ else {
3690
+ decorators[nameNode.value](pattern, JSON.parse(argsNode.value));
3691
+ }
3692
+ });
3693
+ }
3561
3694
  _getParams(importStatement) {
3562
3695
  let params = [];
3563
3696
  const paramsStatement = importStatement.find(n => n.name === "with-params-statement");
@@ -3572,7 +3705,8 @@
3572
3705
  const grammar = new Grammar({
3573
3706
  params: [...importedValues, ...this._parseContext.paramsByName.values()],
3574
3707
  originResource: this._originResource,
3575
- resolveImport: this._resolveImport
3708
+ resolveImport: this._resolveImport,
3709
+ decorators: this._parseContext.decorators
3576
3710
  });
3577
3711
  const patterns = grammar.parseString(expression);
3578
3712
  params = Array.from(Object.values(patterns));
@@ -3602,10 +3736,12 @@
3602
3736
  // This solves the problem for an alias pointing to a reference.
3603
3737
  if (aliasPattern.type === "reference") {
3604
3738
  const reference = new Reference(name, aliasName);
3739
+ this._applyDecorators(statementNode, reference);
3605
3740
  this._parseContext.patternsByName.set(name, reference);
3606
3741
  }
3607
3742
  else {
3608
3743
  const alias = aliasPattern.clone(name);
3744
+ this._applyDecorators(statementNode, alias);
3609
3745
  this._parseContext.patternsByName.set(name, alias);
3610
3746
  }
3611
3747
  }