[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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user