feat(semantic): check for non-declared, non-abstract object accessors without bodies (#5461)

This commit is contained in:
DonIsaac 2024-09-05 01:33:10 +00:00
parent 540714393a
commit 62f7fff88f
4 changed files with 38 additions and 4 deletions

View file

@ -448,6 +448,15 @@ impl<'a> PropertyKey<'a> {
}
}
impl PropertyKind {
/// Returns `true` if this property is a getter or setter.
///
/// Analogous to [`MethodDefinitionKind::is_accessor`].
pub fn is_accessor(self) -> bool {
matches!(self, Self::Get | Self::Set)
}
}
impl<'a> TemplateLiteral<'a> {
pub fn is_no_substitution_template(&self) -> bool {
self.expressions.is_empty() && self.quasis.len() == 1
@ -1424,6 +1433,8 @@ impl MethodDefinitionKind {
}
/// Returns `true` if this method is a getter or a setter.
///
/// Analogous to [`PropertyKind::is_accessor`].
pub fn is_accessor(&self) -> bool {
matches!(self, Self::Get | Self::Set)
}

View file

@ -77,7 +77,10 @@ pub fn check<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) {
ts::check_method_definition(method, ctx);
}
AstKind::PropertyDefinition(prop) => ts::check_property_definition(prop, ctx),
AstKind::ObjectProperty(prop) => js::check_object_property(prop, ctx),
AstKind::ObjectProperty(prop) => {
js::check_object_property(prop, ctx);
ts::check_object_property(prop, ctx);
}
AstKind::Super(sup) => js::check_super(sup, node, ctx),
AstKind::FormalParameters(params) => {

View file

@ -359,3 +359,13 @@ pub fn check_property_definition<'a>(prop: &PropertyDefinition<'a>, ctx: &Semant
ctx.error(abstract_property_cannot_have_initializer(prop_name, span));
}
}
pub fn check_object_property(prop: &ObjectProperty, ctx: &SemanticBuilder<'_>) {
if let Expression::FunctionExpression(func) = &prop.value {
if prop.kind.is_accessor()
&& matches!(func.r#type, FunctionType::TSEmptyBodyFunctionExpression)
{
ctx.error(accessor_without_body(prop.key.span()));
}
}
}

View file

@ -3,7 +3,7 @@ commit: a709f989
parser_typescript Summary:
AST Parsed : 6470/6479 (99.86%)
Positive Passed: 6445/6479 (99.48%)
Negative Passed: 1201/5715 (21.01%)
Negative Passed: 1203/5715 (21.05%)
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ClassDeclaration10.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ClassDeclaration11.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ClassDeclaration13.ts
@ -31,8 +31,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/accessorAcci
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/accessorDeclarationEmitVisibilityErrors.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/accessorInferredReturnTypeErrorInReturnStatement.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/accessorWithInitializer.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/accessorWithoutBody1.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/accessorWithoutBody2.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/accessorsInAmbientContext.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/accessors_spec_section-4.5_error-cases.ts
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/addMoreOverloadsToBaseSignature.ts
@ -5077,6 +5075,18 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/typeFro
4 │ }
╰────
× Getters and setters must have an implementation.
╭─[typescript/tests/cases/compiler/accessorWithoutBody1.ts:1:15]
1 │ var v = { get foo() }
· ───
╰────
× Getters and setters must have an implementation.
╭─[typescript/tests/cases/compiler/accessorWithoutBody2.ts:1:15]
1 │ var v = { set foo(a) }
· ───
╰────
× Unexpected token
╭─[typescript/tests/cases/compiler/aliasErrors.ts:13:12]
12 │ import m2 = no.mod;