use completion record util
MODIFY
packages/@romejs/js-compiler/__rtests__/__rsnapshots__/lint.ts.rsnap
packages/@romejs/js-compiler/__rtests__/__rsnapshots__/lint.ts.rsnap
"undeclared variable": "Object {\n filters: Array []\n src: 'foobar;'\n diagnostics: Array [\n Object {\n category: 'lint/undeclaredVariables'\n filename: 'unknown'\n language: 'js'\n message: 'Undeclared variable <emphasis>foobar</emphasis>'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 6\n index: 6\n line: 1\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n ]\n}",
"sparse array": "Object {\n filters: Array []\n src: '[1,,2]'\n diagnostics: Array [\n Object {\n category: 'lint/sparseArray'\n filename: 'unknown'\n language: 'js'\n message: 'Your array contains an empty slot'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 6\n index: 6\n line: 1\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n ]\n}",
"unsafe negation": "Object {\n filters: Array []\n src: '!1 in [1,2]'\n diagnostics: Array [\n Object {\n category: 'lint/unsafeNegation'\n filename: 'unknown'\n language: 'js'\n message: 'Unsafe usage of negation operator in left side of binary expression'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 11\n index: 11\n line: 1\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n ]\n}",
- "getter return": "Object {\n filters: Array []\n src: 'class p {\\n get name() {\\n console.log(\\'hello\\');\\n }\\n}\\nconsole.log(new p());\\n'\n diagnostics: Array [\n Object {\n category: 'lint/getterReturn'\n filename: 'unknown'\n language: 'js'\n message: 'Class get method does not have a return statement'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 5\n index: 77\n line: 6\n }\n start: Object {\n column: 4\n index: 5\n line: 2\n }\n }\n ]\n}",
+ "getter return": "Object {\n filters: Array []\n src: 'class p {\\n get name() {\\n console.log(\\'hello\\');\\n }\\n}\\nconsole.log(new p());\\n'\n diagnostics: Array [\n Object {\n category: 'lint/getterReturn'\n filename: 'unknown'\n language: 'js'\n message: 'Expected a \\'return\\' at end of a getter method but got empty block'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 7\n index: 70\n line: 5\n }\n start: Object {\n column: 17\n index: 32\n line: 3\n }\n }\n ]\n}",
"no cond assign": "Object {\n filters: Array []\n src: 'for (let i = 1; i = 10; i++) {\\n console.log(\\'foo\\')\\n }'\n diagnostics: Array [\n Object {\n category: 'lint/noCondAssign'\n filename: 'unknown'\n language: 'js'\n message: 'Cannot assign variable in loop condition'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 5\n index: 61\n line: 3\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n ]\n}",
"disallow var": "Object {\n filters: Array []\n src: 'var foobar;\\nfoobar'\n diagnostics: Array [\n Object {\n category: 'lint/disallowVar'\n filename: 'unknown'\n language: 'js'\n message: 'Variable declarations using `var` are disallowed, use `let` or `const` instead.'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 11\n index: 11\n line: 1\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n ]\n}",
- "getter return: 1": "Object {\n filters: Array []\n src: 'let p;\\np = {\\n get name() {\\n console.log(\\'hello\\');\\n }};\\nconsole.log(p);\\n'\n diagnostics: Array [\n Object {\n category: 'lint/getterReturn'\n filename: 'unknown'\n language: 'js'\n message: 'Class get method does not have a return statement'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 5\n index: 83\n line: 7\n }\n start: Object {\n column: 8\n index: 20\n line: 3\n }\n }\n ]\n}",
+ "getter return: 1": "Object {\n filters: Array []\n src: 'let p;\\np = {\\n get name() {\\n console.log(\\'hello\\');\\n }};\\nconsole.log(p);\\n'\n diagnostics: Array [\n Object {\n category: 'lint/getterReturn'\n filename: 'unknown'\n language: 'js'\n message: 'Expected a \\'return\\' at end of a getter method but got empty block'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 7\n index: 77\n line: 6\n }\n start: Object {\n column: 17\n index: 39\n line: 4\n }\n }\n ]\n}",
"no cond assign: 1": "Object {\n filters: Array []\n src: 'if(foo = \\'bar\\') {\\n console.log(\\'foo\\')\\n }'\n diagnostics: Array [\n Object {\n category: 'lint/noCondAssign'\n filename: 'unknown'\n language: 'js'\n message: 'Cannot assign variable in loop condition'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 5\n index: 48\n line: 3\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n ]\n}",
- "getter return: 2": "Object {\n filters: Array []\n src: 'let p = {};\\nObject.defineProperty(p, {\\n get: function() {\\n console.log(\\'hello\\');\\n }});\\nconsole.log(p);\\n'\n diagnostics: Array [\n Object {\n category: 'lint/getterReturn'\n filename: 'unknown'\n language: 'js'\n message: 'Class get method does not have a return statement'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 7\n index: 110\n line: 6\n }\n start: Object {\n column: 6\n index: 54\n line: 4\n }\n }\n ]\n}",
"no debugger": "Array [\n Object {\n category: 'lint/noDebugger'\n filename: 'unknown'\n fixable: true\n language: 'js'\n message: 'Unexpected \\'debugger\\' statement'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 9\n index: 9\n line: 1\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n]",
+ "getter return: 2": "Object {\n diagnostics: Array []\n filters: Array []\n src: 'let p = {};\\nObject.defineProperty(p, {\\n get: function() {\\n console.log(\\'hello\\');\\n }});\\nconsole.log(p);\\n'\n}",
"no cond assign: 2": "Object {\n filters: Array []\n src: 'while (foo = \\'bar\\' {\\n console.log(\\'foo\\')\\n }'\n diagnostics: Array [\n Object {\n category: 'parse/js'\n filename: 'unknown'\n message: 'Unclosed while test'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'js-parser'}]\n end: Object {\n column: 6\n index: 6\n line: 1\n }\n start: Object {\n column: 6\n index: 6\n line: 1\n }\n advice: Array [\n log {\n category: 'info'\n message: 'We expected to find the closing character <emphasis>)</emphasis> here'\n }\n frame {\n filename: 'unknown'\n end: Object {\n column: 19\n index: 19\n line: 1\n }\n start: Object {\n column: 19\n index: 19\n line: 1\n }\n }\n ]\n }\n Object {\n category: 'lint/noCondAssign'\n filename: 'unknown'\n language: 'js'\n message: 'Cannot assign variable in loop condition'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 5\n index: 51\n line: 3\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n ]\n}",
"no async promise executor": "Object {\n filters: Array []\n src: 'new Promise(async function foo() {})'\n diagnostics: Array [\n Object {\n category: 'lint/noAsyncPromiseExecutor'\n filename: 'unknown'\n language: 'js'\n message: 'Promise executor functions should not be async.'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 35\n index: 35\n line: 1\n }\n start: Object {\n column: 12\n index: 12\n line: 1\n }\n }\n ]\n}",
"no cond assign: 3": "Object {\n filters: Array []\n src: 'do {\\n console.log(\\'foo)\\n } while (foo = \\'bar\\')'\n diagnostics: Array [\n Object {\n advice: undefined\n category: 'parse/js'\n filename: 'unknown'\n message: 'Unterminated string constant'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'js-parser'}]\n end: Object {\n column: 0\n index: 28\n line: 3\n }\n start: Object {\n column: 0\n index: 28\n line: 3\n }\n }\n Object {\n category: 'lint/undeclaredVariables'\n filename: 'unknown'\n language: 'js'\n message: 'Undeclared variable <emphasis>INVALID_PLACEHOLDER</emphasis>'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 50\n index: 55\n line: 2\n }\n start: Object {\n column: 50\n index: 55\n line: 2\n }\n }\n Object {\n category: 'lint/undeclaredVariables'\n filename: 'unknown'\n language: 'js'\n message: 'Undeclared variable <emphasis>bar</emphasis>'\n mtime: undefined\n sourceType: 'module'\n origins: Array [Object {category: 'lint'}]\n end: Object {\n column: 47\n index: 52\n line: 2\n }\n start: Object {\n column: 44\n index: 49\n line: 2\n }\n }\n ]\n}",

MODIFY
packages/@romejs/js-compiler/transforms/lint/getterReturn.ts
packages/@romejs/js-compiler/transforms/lint/getterReturn.ts
*/
import {Path} from '@romejs/js-compiler';
-import {AnyNode, ObjectMethod} from '@romejs/js-ast';
+import {AnyNode} from '@romejs/js-ast';
+import {getCompletionRecords} from '@romejs/js-ast-utils';
export default {
name: 'getterReturn',
enter(path: Path): AnyNode {
const {node} = path;
- switch (node.type) {
- case 'ObjectExpression':
if (
- node.properties.length !== 0 &&
- (node.properties.find(
- node => node.type === 'ObjectMethod' && node.kind === 'get',
- ) as ObjectMethod) &&
- (node.properties.find(
- node => node.type === 'ObjectMethod' && node.kind === 'get',
- ) as ObjectMethod).body &&
- (node.properties.find(
- node => node.type === 'ObjectMethod' && node.kind === 'get',
- ) as ObjectMethod).body.body &&
- (node.properties.find(
- node => node.type === 'ObjectMethod' && node.kind === 'get',
- ) as ObjectMethod).body.body.find(
- node => node.type === 'ReturnStatement',
- ) === undefined
+ (node.type === 'ClassMethod' || node.type === 'ObjectMethod') &&
+ node.kind === 'get'
) {
- path.context.addNodeDiagnostic(node, {
+ for (const record of getCompletionRecords(node.body)) {
+ if (record.type === 'INVALID') {
+ path.context.addNodeDiagnostic(record.node, {
category: 'lint/getterReturn',
- message: 'Class get method does not have a return statement',
+ message: `Expected a 'return' at end of a getter method but got ${record.description}`,
});
}
- break;
- case 'ObjectProperty':
- if (
- node.value &&
- node.value.type === 'FunctionExpression' &&
- node.value.body &&
- node.value.body.body &&
- node.value.body.body.find(node => node.type === 'ReturnStatement') ===
- undefined
- ) {
- path.context.addNodeDiagnostic(node, {
- category: 'lint/getterReturn',
- message: 'Class get method does not have a return statement',
- });
- }
- break;
- case 'ClassDeclaration':
- if (
- node.meta.body[0] &&
- node.meta.body[0].type === 'ClassMethod' &&
- node.meta.body[0].kind === 'get' &&
- node.meta.body[0].body.body.filter(
- node => node.type === 'ReturnStatement',
- ).length === 0
- ) {
- path.context.addNodeDiagnostic(node, {
- category: 'lint/getterReturn',
- message: 'Class get method does not have a return statement',
- });
}
- break;
- default:
- break;
}
return node;
},

use completion record util