Skip to content

Commit 9a3fbb6

Browse files
authored
feat: more strict Typescript APIs (#2183)
1 parent 111484e commit 9a3fbb6

5 files changed

Lines changed: 441 additions & 145 deletions

File tree

packages/chevrotain/src/parse/parser/traits/gast_recorder.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@ export class GastRecorder {
196196
}
197197

198198
// Executing backtracking logic will break our recording logic assumptions
199-
BACKTRACK_RECORD<T>(
200-
grammarRule: (...args: any[]) => T,
201-
args?: any[],
199+
BACKTRACK_RECORD<ARGS extends unknown[], T>(
200+
grammarRule: (...args: ARGS) => T,
201+
args?: ARGS,
202202
): () => boolean {
203203
return () => true;
204204
}

packages/chevrotain/src/parse/parser/traits/recognizer_api.ts

Lines changed: 87 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
DSLMethodOpts,
55
DSLMethodOptsWithErr,
66
GrammarAction,
7+
InferOr,
78
IOrAlt,
89
IRuleConfig,
910
ISerializedGast,
@@ -61,26 +62,29 @@ export class RecognizerApi {
6162
return this.optionInternal(actionORMethodDef, idx);
6263
}
6364

64-
or(
65+
or<Alts extends readonly IOrAlt<any>[]>(
6566
this: MixedInParser,
6667
idx: number,
67-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<any>,
68-
): any {
69-
return this.orInternal(altsOrOpts, idx);
68+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
69+
): InferOr<Alts> {
70+
return this.orInternal(
71+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
72+
idx,
73+
);
7074
}
7175

72-
many(
76+
many<OUT>(
7377
this: MixedInParser,
7478
idx: number,
75-
actionORMethodDef: GrammarAction<any> | DSLMethodOpts<any>,
79+
actionORMethodDef: GrammarAction<OUT> | DSLMethodOpts<OUT>,
7680
): void {
7781
return this.manyInternal(idx, actionORMethodDef);
7882
}
7983

80-
atLeastOne(
84+
atLeastOne<OUT>(
8185
this: MixedInParser,
8286
idx: number,
83-
actionORMethodDef: GrammarAction<any> | DSLMethodOptsWithErr<any>,
87+
actionORMethodDef: GrammarAction<OUT> | DSLMethodOptsWithErr<OUT>,
8488
): void {
8589
return this.atLeastOneInternal(idx, actionORMethodDef);
8690
}
@@ -315,74 +319,104 @@ export class RecognizerApi {
315319
return this.optionInternal(actionORMethodDef, 9);
316320
}
317321

318-
OR<T>(
322+
OR<Alts extends readonly IOrAlt<any>[]>(
319323
this: MixedInParser,
320-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
321-
): T {
322-
return this.orInternal(altsOrOpts, 0);
324+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
325+
): InferOr<Alts> {
326+
return this.orInternal(
327+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
328+
0,
329+
);
323330
}
324331

325-
OR1<T>(
332+
OR1<Alts extends readonly IOrAlt<any>[]>(
326333
this: MixedInParser,
327-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
328-
): T {
329-
return this.orInternal(altsOrOpts, 1);
334+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
335+
): InferOr<Alts> {
336+
return this.orInternal(
337+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
338+
1,
339+
);
330340
}
331341

332-
OR2<T>(
342+
OR2<Alts extends readonly IOrAlt<any>[]>(
333343
this: MixedInParser,
334-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
335-
): T {
336-
return this.orInternal(altsOrOpts, 2);
344+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
345+
): InferOr<Alts> {
346+
return this.orInternal(
347+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
348+
2,
349+
);
337350
}
338351

339-
OR3<T>(
352+
OR3<Alts extends readonly IOrAlt<any>[]>(
340353
this: MixedInParser,
341-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
342-
): T {
343-
return this.orInternal(altsOrOpts, 3);
354+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
355+
): InferOr<Alts> {
356+
return this.orInternal(
357+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
358+
3,
359+
);
344360
}
345361

346-
OR4<T>(
362+
OR4<Alts extends readonly IOrAlt<any>[]>(
347363
this: MixedInParser,
348-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
349-
): T {
350-
return this.orInternal(altsOrOpts, 4);
364+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
365+
): InferOr<Alts> {
366+
return this.orInternal(
367+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
368+
4,
369+
);
351370
}
352371

353-
OR5<T>(
372+
OR5<Alts extends readonly IOrAlt<any>[]>(
354373
this: MixedInParser,
355-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
356-
): T {
357-
return this.orInternal(altsOrOpts, 5);
374+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
375+
): InferOr<Alts> {
376+
return this.orInternal(
377+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
378+
5,
379+
);
358380
}
359381

360-
OR6<T>(
382+
OR6<Alts extends readonly IOrAlt<any>[]>(
361383
this: MixedInParser,
362-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
363-
): T {
364-
return this.orInternal(altsOrOpts, 6);
384+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
385+
): InferOr<Alts> {
386+
return this.orInternal(
387+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
388+
6,
389+
);
365390
}
366391

367-
OR7<T>(
392+
OR7<Alts extends readonly IOrAlt<any>[]>(
368393
this: MixedInParser,
369-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
370-
): T {
371-
return this.orInternal(altsOrOpts, 7);
394+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
395+
): InferOr<Alts> {
396+
return this.orInternal(
397+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
398+
7,
399+
);
372400
}
373401

374-
OR8<T>(
402+
OR8<Alts extends readonly IOrAlt<any>[]>(
375403
this: MixedInParser,
376-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
377-
): T {
378-
return this.orInternal(altsOrOpts, 8);
404+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
405+
): InferOr<Alts> {
406+
return this.orInternal(
407+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
408+
8,
409+
);
379410
}
380411

381-
OR9<T>(
412+
OR9<Alts extends readonly IOrAlt<any>[]>(
382413
this: MixedInParser,
383-
altsOrOpts: IOrAlt<any>[] | OrMethodOpts<unknown>,
384-
): T {
385-
return this.orInternal(altsOrOpts, 9);
414+
altsOrOpts: [...Alts] | OrMethodOpts<unknown>,
415+
): InferOr<Alts> {
416+
return this.orInternal(
417+
altsOrOpts as IOrAlt<any>[] | OrMethodOpts<unknown>,
418+
9,
419+
);
386420
}
387421

388422
MANY<OUT>(
@@ -640,7 +674,7 @@ export class RecognizerApi {
640674
name: string,
641675
implementation: (...implArgs: any[]) => T,
642676
config: IRuleConfig<T> = DEFAULT_RULE_CONFIG,
643-
): (idxInCallingRule?: number, ...args: any[]) => T | any {
677+
): ParserMethodInternal<any[], T> {
644678
if (this.definedRulesNames.includes(name)) {
645679
const errMsg =
646680
defaultGrammarValidatorErrorProvider.buildDuplicateRuleNameError({
@@ -668,7 +702,7 @@ export class RecognizerApi {
668702
name: string,
669703
impl: (...implArgs: any[]) => T,
670704
config: IRuleConfig<T> = DEFAULT_RULE_CONFIG,
671-
): (idxInCallingRule?: number, ...args: any[]) => T {
705+
): ParserMethodInternal<any[], T> {
672706
const ruleErrors: IParserDefinitionError[] = validateRuleIsOverridden(
673707
name,
674708
this.definedRulesNames,
@@ -681,10 +715,10 @@ export class RecognizerApi {
681715
return ruleImplementation;
682716
}
683717

684-
BACKTRACK<T>(
718+
BACKTRACK<ARGS extends unknown[], T>(
685719
this: MixedInParser,
686-
grammarRule: (...args: any[]) => T,
687-
args?: any[],
720+
grammarRule: (...args: ARGS) => T,
721+
args?: ARGS,
688722
): () => boolean {
689723
// Use coreRule to bypass root-level hooks (onBeforeParse/onAfterParse).
690724
// Backtracking is speculative and should not trigger parse lifecycle hooks.

0 commit comments

Comments
 (0)