[ts] Enforce order for the override modifier (#13209)

* [ts] Enforce order for the `override` modifier

* generator

* Add more checks

* Update TS tests
This commit is contained in:
Nicolò Ribaudo
2021-04-27 22:51:15 +02:00
parent 8433cd0c05
commit 22b0eb038f
14 changed files with 682 additions and 266 deletions

View File

@@ -253,6 +253,20 @@ export default (superClass: Class<Parser>): Class<Parser> =>
disallowedModifiers?: TsModifier[],
errorTemplate?: ErrorTemplate,
): void {
const enforceOrder = (pos, modifier, before, after) => {
if (modifier === before && modified[after]) {
this.raise(pos, TSErrors.InvalidModifiersOrder, before, after);
}
};
const incompatible = (pos, modifier, mod1, mod2) => {
if (
(modified[mod1] && modifier === mod2) ||
(modified[mod2] && modifier === mod1)
) {
this.raise(pos, TSErrors.IncompatibleModifiers, mod1, mod2);
}
};
for (;;) {
const startPos = this.state.start;
const modifier: ?TsModifier = this.tsParseModifier(
@@ -265,28 +279,22 @@ export default (superClass: Class<Parser>): Class<Parser> =>
if (modified.accessibility) {
this.raise(startPos, TSErrors.DuplicateAccessibilityModifier);
} else {
enforceOrder(startPos, modifier, modifier, "override");
enforceOrder(startPos, modifier, modifier, "static");
modified.accessibility = modifier;
}
} else {
if (Object.hasOwnProperty.call(modified, modifier)) {
this.raise(startPos, TSErrors.DuplicateModifier, modifier);
} else if (modified.readonly && modifier === "static") {
this.raise(
startPos,
TSErrors.InvalidModifiersOrder,
"static",
"readonly",
);
} else if (
(modified.declare && modifier === "override") ||
(modified.override && modifier === "declare")
) {
this.raise(
startPos,
TSErrors.IncompatibleModifiers,
"declare",
"override",
);
} else {
enforceOrder(startPos, modifier, "static", "readonly");
enforceOrder(startPos, modifier, "static", "override");
enforceOrder(startPos, modifier, "override", "readonly");
enforceOrder(startPos, modifier, "abstract", "override");
incompatible(startPos, modifier, "declare", "override");
incompatible(startPos, modifier, "static", "abstract");
}
modified[modifier] = true;
}
@@ -2320,10 +2328,18 @@ export default (superClass: Class<Parser>): Class<Parser> =>
"public",
"protected",
"override",
"static",
"abstract",
"readonly",
]);
const callParseClassMember = () => {
super.parseClassMember(classBody, member, state);
this.parseClassMemberWithIsStatic(
classBody,
member,
state,
!!member.static,
);
};
if (member.declare) {
this.tsInDeclareContext(callParseClassMember);
@@ -2338,18 +2354,6 @@ export default (superClass: Class<Parser>): Class<Parser> =>
state: N.ParseClassMemberState,
isStatic: boolean,
): void {
this.tsParseModifiers(member, [
"abstract",
"readonly",
"declare",
"static",
"override",
]);
if (isStatic) {
member.static = true;
}
const idx = this.tsTryParseIndexSignature(member);
if (idx) {
classBody.body.push(idx);
@@ -2379,14 +2383,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
}
if ((member: any).override) {
if (isStatic) {
this.raise(
member.start,
TSErrors.IncompatibleModifiers,
"static",
"override",
);
} else if (!state.hadSuperClass) {
if (!state.hadSuperClass) {
this.raise(member.start, TSErrors.OverrideNotInSubClass);
}
}