[ts] support optional chain call with generic (#13513)

* support optional chain call with generic

* Add testcase handling new line

* allow only call if optional chain type parameter

* use exact error message

* add transform-typescript optional-chain call test

* use exact error message

* apply feedbacks

* Fix lint error

Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
This commit is contained in:
Yeonju Hwang
2021-08-05 00:29:44 +09:00
committed by GitHub
parent d5b0d9e33d
commit 0671afcf87
9 changed files with 203 additions and 5 deletions

View File

@@ -2082,7 +2082,21 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.finishNode(nonNullExpression, "TSNonNullExpression");
}
let isOptionalCall = false;
if (
this.match(tt.questionDot) &&
this.lookaheadCharCode() === charCodes.lessThan
) {
if (noCalls) {
state.stop = true;
return base;
}
state.optionalChainMember = isOptionalCall = true;
this.next();
}
if (this.isRelational("<")) {
let missingParenErrorPos;
// tsTryParseAndCatch is expensive, so avoid if not necessary.
// There are number of things we are going to "maybe" parse, like type arguments on
// tagged template expressions. If any of them fail, walk it back and continue.
@@ -2105,6 +2119,11 @@ export default (superClass: Class<Parser>): Class<Parser> =>
const typeArguments = this.tsParseTypeArguments();
if (typeArguments) {
if (isOptionalCall && !this.match(tt.parenL)) {
missingParenErrorPos = this.state.pos;
this.unexpected();
}
if (!noCalls && this.eat(tt.parenL)) {
// possibleAsync always false here, because we would have handled it above.
// $FlowIgnore (won't be any undefined arguments)
@@ -2119,8 +2138,9 @@ export default (superClass: Class<Parser>): Class<Parser> =>
node.typeParameters = typeArguments;
if (state.optionalChainMember) {
// $FlowIgnore
node.optional = false;
node.optional = isOptionalCall;
}
return this.finishCallExpression(node, state.optionalChainMember);
} else if (this.match(tt.backQuote)) {
const result = this.parseTaggedTemplateExpression(
@@ -2137,6 +2157,10 @@ export default (superClass: Class<Parser>): Class<Parser> =>
this.unexpected();
});
if (missingParenErrorPos) {
this.unexpected(missingParenErrorPos, tt.parenL);
}
if (result) return result;
}