Skip to content

Commit

Permalink
super
Browse files Browse the repository at this point in the history
  • Loading branch information
WearyMonkey committed Feb 9, 2022
1 parent 4c7d762 commit 535e609
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
51 changes: 51 additions & 0 deletions packages/eslint-plugin-mobx/__tests__/missing-make-observable.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,54 @@ constructor() { makeBanana(this); }
}
))

const invalid10 = fields.map(field => ({
code: `
class C extends Component {
@${field}
}
`,
errors: [
{ messageId: 'missingMakeObservable' },
],
output: `
class C extends Component {
constructor(props) { super(props); makeObservable(this); }
@${field}
}
`,
}
))

const invalid11 = fields.map(field => ({
code: `
class C extends React.Component<{ foo: string }> {
@${field}
}
`,
errors: [
{ messageId: 'missingMakeObservable' },
],
output: `
class C extends React.Component<{ foo: string }> {
constructor(props: { foo: string }) { super(props); makeObservable(this); }
@${field}
}
`,
}
))

const invalid12 = fields.map(field => ({
code: `
class C extends Banana {
@${field}
}
`,
errors: [
{ messageId: 'missingMakeObservableSuper' },
],
}
))

tester.run("missing-make-observable", rule, {
valid: [
...valid1,
Expand All @@ -265,5 +313,8 @@ tester.run("missing-make-observable", rule, {
...invalid7,
...invalid8,
...invalid9,
...invalid10,
...invalid11,
...invalid12,
],
});
20 changes: 18 additions & 2 deletions packages/eslint-plugin-mobx/src/missing-make-observable.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ function create(context) {
const constructor = clazz.body.body.find(node => node.kind === 'constructor' && node.value.type === 'FunctionExpression') ??
clazz.body.body.find(node => node.kind === 'constructor');
// MethodDefinition > FunctionExpression > BlockStatement > []
const isReact = clazz.superClass?.name === 'Component'
|| (clazz.superClass?.object?.name === 'React' && clazz.superClass?.property.name === 'Component');
const unsupportedSuper = !isReact && !!clazz.superClass;
const isMakeObservable = node => node.expression?.callee?.name === 'makeObservable' && node.expression?.arguments[0]?.type === 'ThisExpression';
const makeObservable = constructor?.value.body?.body.find(isMakeObservable)?.expression;

Expand All @@ -50,6 +53,10 @@ function create(context) {
}
} else {
const fix = fixer => {
// The class extends a another unknown class so we can not safely create a super call.
if (unsupportedSuper && !constructor) {
return;
}

const fixes = [];
let makeObservableExpr = 'makeObservable';
Expand All @@ -71,7 +78,15 @@ function create(context) {
// constructor() {}
const closingBracket = sourceCode.getLastToken(constructor.value.body);
fixes.push(fixer.insertTextBefore(closingBracket, `;${makeObservableExpr}(this);`));
} else {
} else if (isReact) {
// class C extends Component<{ foo: string }> {}
let propsType = '';
if (clazz.superTypeParameters?.params.length) {
propsType = `: ${sourceCode.getText(clazz.superTypeParameters.params[0])}`;
}
const openingBracket = sourceCode.getFirstToken(clazz.body);
fixes.push(fixer.insertTextAfter(openingBracket, `\nconstructor(props${propsType}) { super(props); ${makeObservableExpr}(this); }`));
} else if (!unsupportedSuper) {
// class C {}
const openingBracket = sourceCode.getFirstToken(clazz.body);
fixes.push(fixer.insertTextAfter(openingBracket, `\nconstructor() { ${makeObservableExpr}(this); }`));
Expand All @@ -82,7 +97,7 @@ function create(context) {

context.report({
node: clazz,
messageId: 'missingMakeObservable',
messageId: unsupportedSuper ? 'missingMakeObservableSuper' : 'missingMakeObservable',
fix,
})
}
Expand All @@ -101,6 +116,7 @@ module.exports = {
},
messages: {
missingMakeObservable: "Constructor is missing `makeObservable(this)`.",
missingMakeObservableSuper: "Constructor is missing `makeObservable(this)`. Can not fix because of missing super call.",
secondArgMustBeNullish: "`makeObservable`'s second argument must be nullish or not provided when using decorators."
},
},
Expand Down

0 comments on commit 535e609

Please sign in to comment.