rescan gt/lt token after TsAsExpression is parsed (#11912)

* refactor: move inType checks to flow plugin

* polish: replace hardcoded char codes

* fix: rescan greater/less token after asExpression is parsed
This commit is contained in:
Huáng Jùnliàng
2020-08-04 17:00:21 -04:00
committed by GitHub
parent c29138fd72
commit a1eabb84ea
5 changed files with 136 additions and 30 deletions

View File

@@ -2135,6 +2135,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
(code === charCodes.greaterThan || code === charCodes.lessThan)
) {
return this.finishOp(tt.relational, 1);
} else if (this.state.inType && code === charCodes.questionMark) {
// allow double nullable types in Flow: ??string
return this.finishOp(tt.question, 1);
} else if (isIteratorStart(code, next)) {
this.state.isIterator = true;
return super.readWord();

View File

@@ -1884,6 +1884,8 @@ export default (superClass: Class<Parser>): Class<Parser> =>
node.typeAnnotation = this.tsNextThenParseType();
}
this.finishNode(node, "TSAsExpression");
// rescan `<`, `>` because they were scanned when this.state.inType was true
this.reScan_lt_gt();
return this.parseExprOp(
node,
leftStartPos,
@@ -2628,13 +2630,27 @@ export default (superClass: Class<Parser>): Class<Parser> =>
// ensure that inside types, we bypass the jsx parser plugin
getTokenFromCode(code: number): void {
if (this.state.inType && (code === 62 || code === 60)) {
if (
this.state.inType &&
(code === charCodes.greaterThan || code === charCodes.lessThan)
) {
return this.finishOp(tt.relational, 1);
} else {
return super.getTokenFromCode(code);
}
}
// used after we have finished parsing types
reScan_lt_gt() {
if (this.match(tt.relational)) {
const code = this.input.charCodeAt(this.state.start);
if (code === charCodes.lessThan || code === charCodes.greaterThan) {
this.state.pos -= 1;
this.readToken_lt_gt(code);
}
}
}
toAssignableList(exprList: N.Expression[]): $ReadOnlyArray<N.Pattern> {
for (let i = 0; i < exprList.length; i++) {
const expr = exprList[i];

View File

@@ -693,7 +693,7 @@ export default class Tokenizer extends ParserErrors {
// '?'
const next = this.input.charCodeAt(this.state.pos + 1);
const next2 = this.input.charCodeAt(this.state.pos + 2);
if (next === charCodes.questionMark && !this.state.inType) {
if (next === charCodes.questionMark) {
if (next2 === charCodes.equalsTo) {
// '??='
this.finishOp(tt.assign, 3);