Skip to content

Commit

Permalink
feat(typescript-estree): throw errors for object methods without func…
Browse files Browse the repository at this point in the history
…tion bodies (#6589)
  • Loading branch information
fisker committed Mar 13, 2023
1 parent 1b39cfd commit 1d78576
Show file tree
Hide file tree
Showing 15 changed files with 79 additions and 11 deletions.
@@ -0,0 +1 @@
({get foo();})
@@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures expression ObjectExpression _error_ missing-getter-body TSESTree - Error 1`] = `
"TSError
> 1 | ({get foo();})
| ^ '{' expected.
2 |"
`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures expression ObjectExpression _error_ missing-getter-body Babel - Error 1`] = `[SyntaxError: Unexpected token, expected "{" (1:11)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures expression ObjectExpression _error_ missing-getter-body Error Alignment 1`] = `"Both errored"`;
@@ -0,0 +1 @@
({method();})
@@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures expression ObjectExpression _error_ missing-method-body TSESTree - Error 1`] = `
"TSError
> 1 | ({method();})
| ^ '{' expected.
2 |"
`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures expression ObjectExpression _error_ missing-method-body Babel - Error 1`] = `[SyntaxError: Unexpected token, expected "{" (1:10)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures expression ObjectExpression _error_ missing-method-body Error Alignment 1`] = `"Both errored"`;
@@ -0,0 +1 @@
({set foo(value);})
@@ -0,0 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures expression ObjectExpression _error_ missing-setter-body TSESTree - Error 1`] = `
"TSError
> 1 | ({set foo(value);})
| ^ '{' expected.
2 |"
`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures expression ObjectExpression _error_ missing-setter-body Babel - Error 1`] = `[SyntaxError: Unexpected token, expected "{" (1:16)]`;
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures expression ObjectExpression _error_ missing-setter-body Error Alignment 1`] = `"Both errored"`;
Expand Up @@ -113,7 +113,7 @@ class Foo {
'const x = new Set<any>();',
'const x = { y: 1 };',
'const x = { y = 1 };',
noFormat`const x = { y(); };`,
noFormat`const x = { y(){} };`,
'const x: { y: number } = { y: 1 };',
'const x = [...[1, 2, 3]];',
'const [{ [`x${1}`]: x }] = [{ [`x`]: 1 }] as [{ [`x`]: any }];',
Expand Down
Expand Up @@ -290,7 +290,7 @@ ruleTester.run('prefer-readonly-parameter-types', rule, {
new (arg: readonly string[]): void;
}
`, // TSConstructSignatureDeclaration
noFormat`const x = { foo(arg: readonly string[]): void; };`, // TSEmptyBodyFunctionExpression
noFormat`class Foo { foo(arg: readonly string[]): void; };`, // TSEmptyBodyFunctionExpression
'function foo(arg: readonly string[]);', // TSDeclareFunction
'type Foo = (arg: readonly string[]) => void;', // TSFunctionType
`
Expand Down Expand Up @@ -667,7 +667,7 @@ ruleTester.run('prefer-readonly-parameter-types', rule, {
},
{
// TSEmptyBodyFunctionExpression
code: noFormat`const x = { foo(arg: string[]): void; };`,
code: noFormat`class Foo { foo(arg: string[]): void; };`,
errors: [
{
messageId: 'shouldBeReadonly',
Expand Down
39 changes: 31 additions & 8 deletions packages/typescript-estree/src/convert.ts
Expand Up @@ -1029,12 +1029,26 @@ export class Converter {
properties: node.properties.map(el => this.convertPattern(el)),
typeAnnotation: undefined,
});
} else {
return this.createNode<TSESTree.ObjectExpression>(node, {
type: AST_NODE_TYPES.ObjectExpression,
properties: node.properties.map(el => this.convertChild(el)),
});
}

const properties: TSESTree.Property[] = [];
for (const property of node.properties) {
if (
(property.kind === SyntaxKind.GetAccessor ||
property.kind === SyntaxKind.SetAccessor ||
property.kind === SyntaxKind.MethodDeclaration) &&
!property.body
) {
this.#throwUnlessAllowInvalidAST(property.end - 1, "'{' expected.");
}

properties.push(this.convertChild(property) as TSESTree.Property);
}

return this.createNode<TSESTree.ObjectExpression>(node, {
type: AST_NODE_TYPES.ObjectExpression,
properties,
});
}

case SyntaxKind.PropertyAssignment: {
Expand Down Expand Up @@ -3077,15 +3091,24 @@ export class Converter {
}

#throwUnlessAllowInvalidAST(
node: ts.Node,
node: ts.Node | number,
message: string,
): asserts node is never {
if (!this.options.allowInvalidAST) {
this.#throwError(node, message);
}
}

#throwError(node: ts.Node, message: string): asserts node is never {
throw createError(message, this.ast, node.getStart(), node.getEnd());
#throwError(node: ts.Node | number, message: string): asserts node is never {
let start;
let end;
if (typeof node === 'number') {
start = end = node;
} else {
start = node.getStart(this.ast);
end = node.getEnd();
}

throw createError(message, this.ast, start, end);
}
}

0 comments on commit 1d78576

Please sign in to comment.