Skip to content

Commit bb5ee94

Browse files
author
Anatoly Ostrovsky
committed
Type fixes
1 parent 08a6570 commit bb5ee94

File tree

4 files changed

+41
-37
lines changed

4 files changed

+41
-37
lines changed

@types/core/parse/ast/ast.d.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,8 @@ export class AST {
88
constructor(lexer: import("../lexer/lexer.js").Lexer);
99
/** @type {import('../lexer/lexer.js').Lexer} */
1010
_lexer: import("../lexer/lexer.js").Lexer;
11-
_selfReferential: {
12-
this: {
13-
type: number;
14-
};
15-
$locals: {
16-
type: number;
17-
};
18-
};
11+
/** @type {Record<string, any>} */
12+
_selfReferential: Record<string, any>;
1913
_index: number;
2014
/**
2115
* Parses the input text and generates an AST.
@@ -124,9 +118,9 @@ export class AST {
124118
/**
125119
* Throws a syntax error.
126120
* @param {string} msg - The error message.
127-
* @param {import("../lexer/lexer.js").Token} [token] - The token that caused the error.
121+
* @param {import("../lexer/lexer.js").Token} token - The token that caused the error.
128122
*/
129-
_throwError(msg: string, token?: import("../lexer/lexer.js").Token): void;
123+
_throwError(msg: string, token: import("../lexer/lexer.js").Token): void;
130124
/**
131125
* Consumes a token if it matches the expected type.
132126
* @param {string} [e1] - The expected token type.
@@ -140,13 +134,13 @@ export class AST {
140134
_peekToken(): import("../lexer/lexer.js").Token;
141135
/**
142136
* Checks if the next token matches any of the expected types.
143-
* @param {...string} [expected] - The expected token types.
137+
* @param {...string} expected - The expected token types.
144138
* @returns {import('../lexer/lexer.js').Token|boolean} The next token if it matches, otherwise false.
145139
*/
146140
_peek(...expected: string[]): import("../lexer/lexer.js").Token | boolean;
147141
/**
148142
* Consumes the next token if it matches any of the expected types.
149-
* @param {...string} [expected] - The expected token types.
143+
* @param {...string} expected - The expected token types.
150144
* @returns {import("../lexer/lexer.js").Token|boolean} The consumed token if it matches, otherwise false.
151145
*/
152146
_expect(...expected: string[]): import("../lexer/lexer.js").Token | boolean;

@types/core/parse/lexer/lexer.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ export class Lexer {
1515
constructor(options: LexerOptions);
1616
/** @type {LexerOptions} */
1717
_options: LexerOptions;
18+
_text: string;
19+
_index: number;
1820
/**
1921
* Tokenizes the input text.
2022
* @param {string} text Input text to lex.
2123
* @returns {Array<Token>} Array of tokens.
2224
*/
2325
_lex(text: string): Array<Token>;
24-
_text: string;
25-
_index: number;
2626
/** @type {Array<Token>} */
2727
_tokens: Array<Token>;
2828
/**

src/core/parse/ast/ast.js

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { isAssignable } from "../interpreter.js";
22
import { ASTType } from "../ast-type.js";
3-
import { hasOwn, minErr } from "../../../shared/utils.js";
3+
import { hasOwn, isDefined, minErr } from "../../../shared/utils.js";
44

55
/**
66
* @typedef {import("./ast-node.ts").ASTNode} ASTNode
@@ -9,6 +9,7 @@ import { hasOwn, minErr } from "../../../shared/utils.js";
99

1010
const $parseMinErr = minErr("$parse");
1111

12+
/** @type {Record<string, any>} */
1213
const literals = {
1314
true: true,
1415
false: false,
@@ -26,6 +27,7 @@ export class AST {
2627
constructor(lexer) {
2728
/** @type {import('../lexer/lexer.js').Lexer} */
2829
this._lexer = lexer;
30+
/** @type {Record<string, any>} */
2931
this._selfReferential = {
3032
this: { type: ASTType._ThisExpression },
3133
$locals: { type: ASTType._LocalsExpression },
@@ -61,7 +63,11 @@ export class AST {
6163
let hasMore = true;
6264

6365
while (hasMore) {
64-
if (this._tokens.length > this._index && !this._peek("}", ")", ";", "]"))
66+
if (
67+
this._tokens &&
68+
this._tokens.length > this._index &&
69+
!this._peek("}", ")", ";", "]")
70+
)
6571
body.push(this._expressionStatement());
6672

6773
if (!this._expect(";")) {
@@ -364,7 +370,7 @@ export class AST {
364370
computed: false,
365371
};
366372
} else {
367-
this._throwError("IMPOSSIBLE");
373+
throw new Error("IMPOSSIBLE");
368374
}
369375
}
370376

@@ -475,10 +481,7 @@ export class AST {
475481
}
476482
property = { type: ASTType._Property, kind: "init" };
477483

478-
if (
479-
/** @type {import("../lexer/lexer.js").Token} */ (this._peek())
480-
.constant
481-
) {
484+
if (/** @type {Token} */ (this._peek()).constant) {
482485
property.key = this._constant();
483486
property.computed = false;
484487
this._consume(":");
@@ -520,7 +523,7 @@ export class AST {
520523
/**
521524
* Throws a syntax error.
522525
* @param {string} msg - The error message.
523-
* @param {import("../lexer/lexer.js").Token} [token] - The token that caused the error.
526+
* @param {import("../lexer/lexer.js").Token} token - The token that caused the error.
524527
*/
525528
_throwError(msg, token) {
526529
throw $parseMinErr(
@@ -530,7 +533,7 @@ export class AST {
530533
msg,
531534
token.index + 1,
532535
this._text,
533-
this._text.substring(token.index),
536+
this._text?.substring(token.index),
534537
);
535538
}
536539

@@ -540,58 +543,62 @@ export class AST {
540543
* @returns {import("../lexer/lexer.js").Token} The consumed token.
541544
*/
542545
_consume(e1) {
543-
if (this._tokens.length === this._index) {
546+
if (this._tokens && this._tokens.length === this._index) {
544547
throw $parseMinErr(
545548
"ueoe",
546549
"Unexpected end of expression: {0}",
547550
this._text,
548551
);
549552
}
550553

551-
const token = this._expect(e1);
554+
const token = isDefined(e1) ? this._expect(e1) : this._expect();
552555

553556
if (!token) {
554557
this._throwError(
555558
`is unexpected, expecting [${e1}]`,
556559
/** @type {import("../lexer/lexer.js").Token} */ (this._peek()),
557560
);
561+
562+
return /** @type {never} */ (undefined);
558563
} else {
559564
return /** @type {import("../lexer/lexer.js").Token} */ (token);
560565
}
561-
562-
return undefined;
563566
}
564567

565568
/**
566569
* Returns the next token without consuming it.
567570
* @returns {import("../lexer/lexer.js").Token} The next token.
568571
*/
569572
_peekToken() {
570-
if (this._tokens.length === this._index) {
573+
if (!this._tokens || this._tokens.length === this._index) {
571574
throw $parseMinErr(
572575
"ueoe",
573576
"Unexpected end of expression: {0}",
574577
this._text,
575578
);
579+
} else {
580+
return this._tokens[this._index];
576581
}
577-
578-
return this._tokens[this._index];
579582
}
580583

581584
/**
582585
* Checks if the next token matches any of the expected types.
583-
* @param {...string} [expected] - The expected token types.
586+
* @param {...string} expected - The expected token types.
584587
* @returns {import('../lexer/lexer.js').Token|boolean} The next token if it matches, otherwise false.
585588
*/
586589
_peek(...expected) {
587-
const token = this._tokens[this._index];
590+
const token = this._tokens && this._tokens[this._index];
591+
592+
if (!token) return false;
588593

589594
const j = expected.length;
590595

591-
if (!token || !j) return token;
596+
if (!j) return token;
592597

593598
const txt = token.text;
594599

600+
if (expected.length === 1) return expected[0] === txt ? token : false;
601+
595602
for (let i = 0; i < j; i++) {
596603
if (expected[i] === txt || !expected[i]) return token;
597604
}
@@ -601,7 +608,7 @@ export class AST {
601608

602609
/**
603610
* Consumes the next token if it matches any of the expected types.
604-
* @param {...string} [expected] - The expected token types.
611+
* @param {...string} expected - The expected token types.
605612
* @returns {import("../lexer/lexer.js").Token|boolean} The consumed token if it matches, otherwise false.
606613
*/
607614
_expect(...expected) {

src/core/parse/lexer/lexer.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { isDefined, minErr } from "../../../shared/utils.js";
88

99
const $parseMinErr = minErr("$parse");
1010

11+
/** @type {Record<string, any>} */
1112
const ESCAPE = {
1213
n: "\n",
1314
f: "\f",
@@ -40,6 +41,8 @@ export class Lexer {
4041
constructor(options) {
4142
/** @type {LexerOptions} */
4243
this._options = options;
44+
this._text = "";
45+
this._index = 0;
4346
}
4447

4548
/**
@@ -278,7 +281,7 @@ export class Lexer {
278281
}
279282
this._index++;
280283
}
281-
this._tokens.push({
284+
/** @type {Array<Token>} */ (this._tokens).push({
282285
index: start,
283286
text: number,
284287
constant: true,
@@ -302,7 +305,7 @@ export class Lexer {
302305
}
303306
this._index += ch.length;
304307
}
305-
this._tokens.push({
308+
/** @type {Array<Token>} */ (this._tokens).push({
306309
index: start,
307310
text: this._text.slice(start, this._index),
308311
identifier: true,
@@ -337,7 +340,7 @@ export class Lexer {
337340
} else if (ch === "\\") {
338341
escape = true;
339342
} else if (ch === quote) {
340-
this._tokens.push({
343+
/** @type {Array<Token>} */ (this._tokens).push({
341344
index: start,
342345
text: this._text.slice(start, this._index + 1),
343346
constant: true,

0 commit comments

Comments
 (0)