Skip to content

Commit

Permalink
fix(ast-spec): remove more invalid properties (#6243)
Browse files Browse the repository at this point in the history
* fix(ast-spec): remove more invalid properties

* Error on all seven deprecated node properties

* A few more error cases, per review
  • Loading branch information
JoshuaKGoldberg committed Feb 15, 2023
1 parent 71adbc5 commit aa20f63
Show file tree
Hide file tree
Showing 22 changed files with 101 additions and 40 deletions.
2 changes: 0 additions & 2 deletions packages/ast-spec/src/base/MethodDefinitionBase.ts
@@ -1,7 +1,6 @@
import type { FunctionExpression } from '../expression/FunctionExpression/spec';
import type { TSEmptyBodyFunctionExpression } from '../expression/TSEmptyBodyFunctionExpression/spec';
import type { Decorator } from '../special/Decorator/spec';
import type { TSTypeParameterDeclaration } from '../special/TSTypeParameterDeclaration/spec';
import type {
ClassPropertyNameNonComputed,
PropertyName,
Expand All @@ -21,7 +20,6 @@ interface MethodDefinitionBase extends BaseNode {
optional?: boolean;
decorators?: Decorator[];
accessibility?: Accessibility;
typeParameters?: TSTypeParameterDeclaration;
override?: boolean;
}

Expand Down
1 change: 0 additions & 1 deletion packages/ast-spec/src/element/TSIndexSignature/spec.ts
Expand Up @@ -10,6 +10,5 @@ export interface TSIndexSignature extends BaseNode {
typeAnnotation?: TSTypeAnnotation;
readonly?: boolean;
accessibility?: Accessibility;
export?: boolean;
static?: boolean;
}
1 change: 0 additions & 1 deletion packages/ast-spec/src/element/TSMethodSignature/spec.ts
Expand Up @@ -20,7 +20,6 @@ interface TSMethodSignatureBase extends BaseNode {
readonly?: boolean;
typeParameters?: TSTypeParameterDeclaration;
accessibility?: Accessibility;
export?: boolean;
static?: boolean;
kind: 'get' | 'method' | 'set';
}
Expand Down
3 changes: 0 additions & 3 deletions packages/ast-spec/src/element/TSPropertySignature/spec.ts
Expand Up @@ -2,7 +2,6 @@ import type { AST_NODE_TYPES } from '../../ast-node-types';
import type { Accessibility } from '../../base/Accessibility';
import type { BaseNode } from '../../base/BaseNode';
import type { TSTypeAnnotation } from '../../special/TSTypeAnnotation/spec';
import type { Expression } from '../../unions/Expression';
import type {
PropertyName,
PropertyNameComputed,
Expand All @@ -15,10 +14,8 @@ interface TSPropertySignatureBase extends BaseNode {
optional?: boolean;
computed: boolean;
typeAnnotation?: TSTypeAnnotation;
initializer?: Expression;
readonly?: boolean;
static?: boolean;
export?: boolean;
accessibility?: Accessibility;
}

Expand Down
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures basics _error_ class-with-export-parameter-properties TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures basics _error_ class-with-export-parameter-properties TSESTree - Error 1`] = `[TSError: A parameter cannot have an export modifier.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures basics _error_ class-with-export-parameter-properties Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures basics _error_ class-with-export-parameter-properties Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-index-signature-export TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-index-signature-export TSESTree - Error 1`] = `[TSError: An index signature cannot have an export modifier.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-index-signature-export Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-index-signature-export Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-method-export TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-method-export TSESTree - Error 1`] = `[TSError: A method signature cannot have an export modifier.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-method-export Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-method-export Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-property-export TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-property-export TSESTree - Error 1`] = `[TSError: A property signature cannot have an export modifier.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-property-export Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-property-export Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-property-with-default-value TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-property-with-default-value TSESTree - Error 1`] = `[TSError: A property signature cannot have an initializer.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-property-with-default-value Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ interface-property-with-default-value Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ object-assertion-not-allowed TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ object-assertion-not-allowed TSESTree - Error 1`] = `[TSError: A shorthand property assignment cannot have an exclamation token.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ object-assertion-not-allowed Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ object-assertion-not-allowed Error Alignment 1`] = `"Both errored"`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ object-optional-not-allowed TSESTree - Error 1`] = `"NO ERROR"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ object-optional-not-allowed TSESTree - Error 1`] = `[TSError: A shorthand property assignment cannot have a question token.]`;
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AST Fixtures legacy-fixtures errorRecovery _error_ object-optional-not-allowed Error Alignment 1`] = `"Babel errored but TSESTree didn't"`;
exports[`AST Fixtures legacy-fixtures errorRecovery _error_ object-optional-not-allowed Error Alignment 1`] = `"Both errored"`;
Expand Up @@ -11,7 +11,6 @@ export interface TSParameterProperty extends BaseNode {
accessibility?: Accessibility;
readonly?: boolean;
static?: boolean;
export?: boolean;
override?: boolean;
parameter: AssignmentPattern | BindingName | RestElement;
decorators?: Decorator[];
Expand Down
7 changes: 0 additions & 7 deletions packages/ast-spec/tests/fixtures-with-differences-errors.shot
Expand Up @@ -28,7 +28,6 @@ Object {
"legacy-fixtures/basics/fixtures/_error_/await-without-async-function/fixture.ts",
"legacy-fixtures/basics/fixtures/_error_/class-private-identifier-field-with-accessibility-error/fixture.ts",
"legacy-fixtures/basics/fixtures/_error_/class-with-constructor-and-type-parameters/fixture.ts",
"legacy-fixtures/basics/fixtures/_error_/class-with-export-parameter-properties/fixture.ts",
"legacy-fixtures/basics/fixtures/_error_/class-with-implements-and-extends/fixture.ts",
"legacy-fixtures/basics/fixtures/_error_/class-with-static-parameter-properties/fixture.ts",
"legacy-fixtures/basics/fixtures/_error_/class-with-two-methods-computed-constructor/fixture.ts",
Expand Down Expand Up @@ -63,27 +62,21 @@ Object {
"legacy-fixtures/errorRecovery/fixtures/_error_/index-signature-parameters/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-empty-extends/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-implements/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-index-signature-export/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-index-signature-private/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-index-signature-protected/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-index-signature-public/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-index-signature-static/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-method-export/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-method-private/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-method-protected/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-method-public/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-method-readonly/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-method-static/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-multiple-extends/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-property-export/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-property-private/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-property-protected/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-property-public/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-property-static/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-property-with-default-value/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/interface-with-optional-index-signature/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/object-assertion-not-allowed/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/object-optional-not-allowed/fixture.ts",
"legacy-fixtures/errorRecovery/fixtures/_error_/solo-const/fixture.ts",
"legacy-fixtures/parameter-decorators/fixtures/_error_/parameter-array-pattern-decorator/fixture.ts",
"legacy-fixtures/parameter-decorators/fixtures/_error_/parameter-rest-element-decorator/fixture.ts",
Expand Down
94 changes: 85 additions & 9 deletions packages/typescript-estree/src/convert.ts
Expand Up @@ -662,7 +662,11 @@ export class Converter {
}

if (hasModifier(SyntaxKind.ExportKeyword, node)) {
result.export = true;
throw createError(
this.ast,
node.pos,
'A method signature cannot have an export modifier.',
);
}

if (hasModifier(SyntaxKind.StaticKeyword, node)) {
Expand Down Expand Up @@ -1047,6 +1051,20 @@ export class Converter {
}

case SyntaxKind.PropertyAssignment:
this.#throwErrorIfDeprecatedPropertyExists(
node,
// eslint-disable-next-line deprecation/deprecation
node.questionToken,
'A property assignment cannot have a question token.',
);

this.#throwErrorIfDeprecatedPropertyExists(
node,
// eslint-disable-next-line deprecation/deprecation
node.exclamationToken,
'A property assignment cannot have an exclamation token.',
);

return this.createNode<TSESTree.Property>(node, {
type: AST_NODE_TYPES.Property,
key: this.convertChild(node.name),
Expand All @@ -1058,6 +1076,27 @@ export class Converter {
});

case SyntaxKind.ShorthandPropertyAssignment: {
this.#throwErrorIfDeprecatedPropertyExists(
node,
// eslint-disable-next-line deprecation/deprecation
node.modifiers,
'A shorthand property assignment cannot have modifiers.',
);

this.#throwErrorIfDeprecatedPropertyExists(
node,
// eslint-disable-next-line deprecation/deprecation
node.questionToken,
'A shorthand property assignment cannot have a question token.',
);

this.#throwErrorIfDeprecatedPropertyExists(
node,
// eslint-disable-next-line deprecation/deprecation
node.exclamationToken,
'A shorthand property assignment cannot have an exclamation token.',
);

if (node.objectAssignmentInitializer) {
return this.createNode<TSESTree.Property>(node, {
type: AST_NODE_TYPES.Property,
Expand Down Expand Up @@ -1609,13 +1648,20 @@ export class Converter {

const modifiers = getModifiers(node);
if (modifiers) {
if (hasModifier(SyntaxKind.ExportKeyword, node)) {
throw createError(
this.ast,
node.pos,
'A parameter cannot have an export modifier.',
);
}

return this.createNode<TSESTree.TSParameterProperty>(node, {
type: AST_NODE_TYPES.TSParameterProperty,
accessibility: getTSNodeAccessibility(node) ?? undefined,
readonly:
hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined,
static: hasModifier(SyntaxKind.StaticKeyword, node) || undefined,
export: hasModifier(SyntaxKind.ExportKeyword, node) || undefined,
override:
hasModifier(SyntaxKind.OverrideKeyword, node) || undefined,
parameter: result,
Expand Down Expand Up @@ -2458,6 +2504,21 @@ export class Converter {
}

case SyntaxKind.PropertySignature: {
this.#throwErrorIfDeprecatedPropertyExists(
node,
// eslint-disable-next-line deprecation/deprecation
node.initializer,
'A property signature cannot have an initializer.',
);

if (hasModifier(SyntaxKind.ExportKeyword, node)) {
throw createError(
this.ast,
node.pos,
'A property signature cannot have an export modifier.',
);
}

const result = this.createNode<TSESTree.TSPropertySignature>(node, {
type: AST_NODE_TYPES.TSPropertySignature,
optional: isOptional(node) || undefined,
Expand All @@ -2466,14 +2527,8 @@ export class Converter {
typeAnnotation: node.type
? this.convertTypeAnnotation(node.type, node)
: undefined,
initializer:
this.convertChild(
// eslint-disable-next-line deprecation/deprecation -- TODO breaking change remove this from the AST
node.initializer,
) || undefined,
readonly: hasModifier(SyntaxKind.ReadonlyKeyword, node) || undefined,
static: hasModifier(SyntaxKind.StaticKeyword, node) || undefined,
export: hasModifier(SyntaxKind.ExportKeyword, node) || undefined,
});

const accessibility = getTSNodeAccessibility(node);
Expand Down Expand Up @@ -2504,7 +2559,11 @@ export class Converter {
}

if (hasModifier(SyntaxKind.ExportKeyword, node)) {
result.export = true;
throw createError(
this.ast,
node.pos,
'An index signature cannot have an export modifier.',
);
}

if (hasModifier(SyntaxKind.StaticKeyword, node)) {
Expand All @@ -2531,6 +2590,13 @@ export class Converter {
}

case SyntaxKind.FunctionType:
this.#throwErrorIfDeprecatedPropertyExists(
node,
// eslint-disable-next-line deprecation/deprecation
node.modifiers,
'A function type cannot have modifiers.',
);
// intentional fallthrough
case SyntaxKind.ConstructSignature:
case SyntaxKind.CallSignature: {
const type =
Expand Down Expand Up @@ -2959,4 +3025,14 @@ export class Converter {
return this.deeplyCopy(node);
}
}

#throwErrorIfDeprecatedPropertyExists<Node extends ts.Node>(
node: Node,
property: unknown,
message: string,
): void {
if (property) {
throw createError(this.ast, node.pos, message);
}
}
}
4 changes: 2 additions & 2 deletions packages/visitor-keys/src/visitor-keys.ts
Expand Up @@ -170,7 +170,7 @@ const additionalKeys: AdditionalKeys = {
JSXOpeningElement: ['name', 'typeParameters', 'attributes'],
JSXOpeningFragment: [],
JSXSpreadChild: ['expression'],
MethodDefinition: ['decorators', 'key', 'value', 'typeParameters'],
MethodDefinition: ['decorators', 'key', 'value'],
NewExpression: ['callee', 'typeParameters', 'arguments'],
ObjectPattern: ['decorators', 'properties', 'typeAnnotation'],
PropertyDefinition: SharedVisitorKeys.PropertyDefinition,
Expand Down Expand Up @@ -227,7 +227,7 @@ const additionalKeys: AdditionalKeys = {
TSOptionalType: ['typeAnnotation'],
TSParameterProperty: ['decorators', 'parameter'],
TSPrivateKeyword: [],
TSPropertySignature: ['typeAnnotation', 'key', 'initializer'],
TSPropertySignature: ['typeAnnotation', 'key'],
TSProtectedKeyword: [],
TSPublicKeyword: [],
TSQualifiedName: ['left', 'right'],
Expand Down

0 comments on commit aa20f63

Please sign in to comment.