Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: made BaseNode.parent non-optional #5252

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
671a7b6
feat\!: made BaseNode.parent non-optional
JoshuaKGoldberg Jun 26, 2022
946894b
Also fixed up for non-null assertions now being redundant
JoshuaKGoldberg Jun 26, 2022
3c9951b
Also fixed up for non-null assertions now being redundant (again)
JoshuaKGoldberg Jun 26, 2022
d1b7951
Merge branch 'main'
JoshuaKGoldberg Oct 25, 2022
72edf54
Merge branch 'main' into base-node-parent-non-optional
JoshuaKGoldberg Oct 25, 2022
4d55ee6
Fix lint: value type
JoshuaKGoldberg Oct 25, 2022
0414e4d
fix(utils): removed `TRuleListener` generic from the `createRule` (#5…
Andarist Oct 25, 2022
04488c2
feat: create TSTypeQuery node when TSImportType has isTypeOf (#3076)
armano2 Oct 26, 2022
ee2fbfa
Merge branch 'main' into v6
JoshuaKGoldberg Oct 26, 2022
c446386
feat(scope-manager): ignore ECMA version (#5889)
JoshuaKGoldberg Oct 26, 2022
cf2956f
feat: remove semantically invalid properties from TSEnumDeclaration, …
juank1809 Oct 26, 2022
b90e7c3
fix(eslint-plugin): remove valid-typeof disable in eslint-recommended…
JoshuaKGoldberg Oct 26, 2022
fff0e29
feat(utils): remove (ts-)eslint-scope types (#5256)
JoshuaKGoldberg Oct 26, 2022
3d85274
Merge branch 'main' into v6
JoshuaKGoldberg Oct 26, 2022
5b9c379
fix(eslint-plugin): [explicit-module-boundary-types] remove shouldTra…
JoshuaKGoldberg Oct 26, 2022
38478ef
Merge branch 'v6' into base-node-parent-non-optional
JoshuaKGoldberg Oct 26, 2022
d523f84
One more post-merge cleanup
JoshuaKGoldberg Oct 26, 2022
31a0fd7
Merge branch 'v6' into base-node-parent-non-optional
bradzacher Nov 25, 2022
3d65e74
fix lint errors in new files after merge
bradzacher Nov 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/ast-spec/src/index.ts
@@ -1,5 +1,6 @@
export * from './base/Accessibility';
export * from './base/BaseNode'; // this is exported so that the `types` package can merge the decl and add the `parent` property
export * from './base/NodeOrTokenData';
export * from './base/OptionalRangeAndLoc';
export * from './base/Position';
export * from './base/Range';
Expand Down
4 changes: 2 additions & 2 deletions packages/ast-spec/src/special/Program/spec.ts
@@ -1,10 +1,10 @@
import type { AST_NODE_TYPES } from '../../ast-node-types';
import type { BaseNode } from '../../base/BaseNode';
import type { NodeOrTokenData } from '../../base/NodeOrTokenData';
import type { Comment } from '../../unions/Comment';
import type { ProgramStatement } from '../../unions/Statement';
import type { Token } from '../../unions/Token';

export interface Program extends BaseNode {
export interface Program extends NodeOrTokenData {
type: AST_NODE_TYPES.Program;
body: ProgramStatement[];
sourceType: 'module' | 'script';
Expand Down
3 changes: 1 addition & 2 deletions packages/eslint-plugin/src/rules/array-type.ts
Expand Up @@ -154,7 +154,6 @@ export default util.createRule<Options, MessageIds>({
return {
TSArrayType(node): void {
const isReadonly =
node.parent &&
node.parent.type === AST_NODE_TYPES.TSTypeOperator &&
node.parent.operator === 'readonly';

Expand All @@ -171,7 +170,7 @@ export default util.createRule<Options, MessageIds>({
currentOption === 'generic'
? 'errorStringGeneric'
: 'errorStringGenericSimple';
const errorNode = isReadonly ? node.parent! : node;
const errorNode = isReadonly ? node.parent : node;

context.report({
node: errorNode,
Expand Down
Expand Up @@ -96,7 +96,7 @@ export default createRule<Options, MessageIds>({
const hasParens =
sourceCode.getTokenAfter(rhs.callee)?.value === '(';
const extraComments = new Set(
sourceCode.getCommentsInside(lhs.parent!),
sourceCode.getCommentsInside(lhs.parent),
);
sourceCode
.getCommentsInside(lhs.typeParameters)
Expand All @@ -105,7 +105,7 @@ export default createRule<Options, MessageIds>({
node,
messageId: 'preferConstructor',
*fix(fixer) {
yield fixer.remove(lhs.parent!);
yield fixer.remove(lhs.parent);
for (const comment of extraComments) {
yield fixer.insertTextAfter(
rhs.callee,
Expand Down
Expand Up @@ -134,7 +134,6 @@ export default util.createRule<Options, MessageIds>({

if (
options.objectLiteralTypeAssertions === 'allow-as-parameter' &&
node.parent &&
(node.parent.type === AST_NODE_TYPES.NewExpression ||
node.parent.type === AST_NODE_TYPES.CallExpression ||
node.parent.type === AST_NODE_TYPES.ThrowStatement ||
Expand Down
Expand Up @@ -269,7 +269,7 @@ export default util.createRule<Options, MessageIds>({
}

function isExportedHigherOrderFunction(node: FunctionNode): boolean {
let current = node.parent;
let current: TSESTree.Node | undefined = node.parent;
while (current) {
if (current.type === AST_NODE_TYPES.ReturnStatement) {
// the parent of a return will always be a block statement, so we can skip over it
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/rules/indent.ts
Expand Up @@ -210,6 +210,7 @@ export default util.createRule<Options, MessageIds>({
return rules.ConditionalExpression({
type: AST_NODE_TYPES.ConditionalExpression,
test: {
parent: node,
type: AST_NODE_TYPES.BinaryExpression,
operator: 'extends',
left: node.checkType as any,
Expand Down Expand Up @@ -371,6 +372,7 @@ export default util.createRule<Options, MessageIds>({
type: AST_NODE_TYPES.ObjectExpression,
properties: [
{
parent: node,
type: AST_NODE_TYPES.Property,
key: node.typeParameter as any,
value: node.typeAnnotation as any,
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/rules/init-declarations.ts
Expand Up @@ -49,7 +49,7 @@ export default createRule<Options, MessageIds>({
function isAncestorNamespaceDeclared(
node: TSESTree.VariableDeclaration,
): boolean {
let ancestor = node.parent;
let ancestor: TSESTree.Node | undefined = node.parent;

while (ancestor) {
if (
Expand Down
5 changes: 1 addition & 4 deletions packages/eslint-plugin/src/rules/no-base-to-string.ts
Expand Up @@ -178,10 +178,7 @@ export default util.createRule<Options, MessageIds>({
checkExpression(memberExpr.object);
},
TemplateLiteral(node: TSESTree.TemplateLiteral): void {
if (
node.parent &&
node.parent.type === AST_NODE_TYPES.TaggedTemplateExpression
) {
if (node.parent.type === AST_NODE_TYPES.TaggedTemplateExpression) {
return;
}
for (const expression of node.expressions) {
Expand Down
Expand Up @@ -186,7 +186,7 @@ export default util.createRule<Options, MessageId>({
// put a semicolon at the beginning of the line
newReturnStmtText = `;${newReturnStmtText}`;
}
if (returnStmt.parent?.type !== AST_NODE_TYPES.BlockStatement) {
if (returnStmt.parent.type !== AST_NODE_TYPES.BlockStatement) {
// e.g. `if (cond) return console.error();`
// add braces if not inside a block
newReturnStmtText = `{ ${newReturnStmtText} }`;
Expand Down
1 change: 0 additions & 1 deletion packages/eslint-plugin/src/rules/no-explicit-any.ts
Expand Up @@ -83,7 +83,6 @@ export default util.createRule<Options, MessageIds>({
function isNodeRestElementInFunction(node: TSESTree.Node): boolean {
return (
node.type === AST_NODE_TYPES.RestElement &&
typeof node.parent !== 'undefined' &&
isNodeValidFunction(node.parent)
);
}
Expand Down
5 changes: 2 additions & 3 deletions packages/eslint-plugin/src/rules/no-extraneous-class.ts
Expand Up @@ -82,10 +82,9 @@ export default util.createRule<Options, MessageIds>({
ClassBody(node): void {
const parent = node.parent as
| TSESTree.ClassDeclaration
| TSESTree.ClassExpression
| undefined;
| TSESTree.ClassExpression;

if (!parent || parent.superClass || isAllowWithDecorator(parent)) {
if (parent.superClass || isAllowWithDecorator(parent)) {
return;
}

Expand Down
9 changes: 2 additions & 7 deletions packages/eslint-plugin/src/rules/no-invalid-void-type.ts
Expand Up @@ -166,11 +166,6 @@ export default util.createRule<[Options], MessageIds>({

return {
TSVoidKeyword(node: TSESTree.TSVoidKeyword): void {
/* istanbul ignore next */
if (!node.parent?.parent) {
return;
}

// checks T<..., void, ...> against specification of allowInGenericArguments option
if (
node.parent.type === AST_NODE_TYPES.TSTypeParameterInstantiation &&
Expand Down Expand Up @@ -211,7 +206,7 @@ export default util.createRule<[Options], MessageIds>({
// default cases
if (
validParents.includes(node.parent.type) &&
!invalidGrandParents.includes(node.parent.parent.type)
!invalidGrandParents.includes(node.parent.parent!.type)
) {
return;
}
Expand All @@ -235,7 +230,7 @@ export default util.createRule<[Options], MessageIds>({
function getNotReturnOrGenericMessageId(
node: TSESTree.TSVoidKeyword,
): MessageIds {
return node.parent!.type === AST_NODE_TYPES.TSUnionType
return node.parent.type === AST_NODE_TYPES.TSUnionType
? 'invalidVoidUnionConstituent'
: 'invalidVoidNotReturnOrGeneric';
}
7 changes: 2 additions & 5 deletions packages/eslint-plugin/src/rules/no-misused-new.ts
Expand Up @@ -70,7 +70,7 @@ export default util.createRule({
): void {
if (
isMatchingParentType(
node.parent!.parent as TSESTree.TSInterfaceDeclaration,
node.parent.parent as TSESTree.TSInterfaceDeclaration,
node.returnType,
)
) {
Expand All @@ -93,10 +93,7 @@ export default util.createRule({
node: TSESTree.MethodDefinition,
): void {
if (node.value.type === AST_NODE_TYPES.TSEmptyBodyFunctionExpression) {
if (
node.parent &&
isMatchingParentType(node.parent.parent, node.value.returnType)
) {
if (isMatchingParentType(node.parent.parent, node.value.returnType)) {
context.report({
node,
messageId: 'errorMessageClass',
Expand Down
3 changes: 1 addition & 2 deletions packages/eslint-plugin/src/rules/no-namespace.ts
Expand Up @@ -67,8 +67,7 @@ export default util.createRule<Options, MessageIds>({
node: TSESTree.TSModuleDeclaration,
): void {
if (
(node.parent &&
node.parent.type === AST_NODE_TYPES.TSModuleDeclaration) ||
node.parent.type === AST_NODE_TYPES.TSModuleDeclaration ||
(allowDefinitionFiles && util.isDefinitionFile(filename)) ||
(allowDeclarations && isDeclaration(node))
) {
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/rules/no-redeclare.ts
Expand Up @@ -103,7 +103,7 @@ export default util.createRule<Options, MessageIds>({
const identifiers = variable.identifiers
.map(id => ({
identifier: id,
parent: id.parent!,
parent: id.parent,
}))
// ignore function declarations because TS will treat them as an overload
.filter(
Expand Down
Expand Up @@ -155,7 +155,6 @@ function describeLiteralTypeNode(typeNode: TSESTree.TypeNode): string {
function isNodeInsideReturnType(node: TSESTree.TSUnionType): boolean {
return !!(
node.parent?.type === AST_NODE_TYPES.TSTypeAnnotation &&
node.parent.parent &&
(util.isFunctionType(node.parent.parent) ||
util.isFunction(node.parent.parent))
);
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-plugin/src/rules/no-unused-vars.ts
Expand Up @@ -167,10 +167,10 @@ export default util.createRule<Options, MessageIds>({
): boolean {
if (options.ignoreRestSiblings) {
const hasRestSiblingDefinition = variable.defs.some(def =>
hasRestSibling(def.name.parent!),
hasRestSibling(def.name.parent),
);
const hasRestSiblingReference = variable.references.some(ref =>
hasRestSibling(ref.identifier.parent!),
hasRestSibling(ref.identifier.parent),
);

return hasRestSiblingDefinition || hasRestSiblingReference;
Expand Down
5 changes: 1 addition & 4 deletions packages/eslint-plugin/src/rules/no-use-before-define.ts
Expand Up @@ -116,9 +116,6 @@ function referenceContainsTypeQuery(node: TSESTree.Node): boolean {

case AST_NODE_TYPES.TSQualifiedName:
case AST_NODE_TYPES.Identifier:
if (!node.parent) {
return false;
}
return referenceContainsTypeQuery(node.parent);

default:
Expand Down Expand Up @@ -196,7 +193,7 @@ function isInInitializer(
return false;
}

let node = variable.identifiers[0].parent;
let node: TSESTree.Node | undefined = variable.identifiers[0].parent;
const location = reference.identifier.range[1];

while (node) {
Expand Down
2 changes: 0 additions & 2 deletions packages/eslint-plugin/src/rules/no-useless-constructor.ts
Expand Up @@ -19,9 +19,7 @@ function checkAccessibility(node: TSESTree.MethodDefinition): boolean {
return false;
case 'public':
if (
node.parent &&
node.parent.type === AST_NODE_TYPES.ClassBody &&
node.parent.parent &&
'superClass' in node.parent.parent &&
node.parent.parent.superClass
) {
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/rules/prefer-as-const.ts
Expand Up @@ -49,7 +49,7 @@ export default util.createRule({
{
messageId: 'variableSuggest',
fix: (fixer): TSESLint.RuleFix[] => [
fixer.remove(typeNode.parent!),
fixer.remove(typeNode.parent),
fixer.insertTextAfter(valueNode, ' as const'),
],
},
Expand Down
9 changes: 1 addition & 8 deletions packages/eslint-plugin/src/rules/prefer-function-type.ts
Expand Up @@ -99,7 +99,6 @@ export default util.createRule({
}

const fixable =
node.parent &&
node.parent.type === AST_NODE_TYPES.ExportDefaultDeclaration;

const fix = fixable
Expand Down Expand Up @@ -137,7 +136,6 @@ export default util.createRule({
}

const isParentExported =
node.parent &&
node.parent.type === AST_NODE_TYPES.ExportNamedDeclaration;

if (
Expand All @@ -154,12 +152,7 @@ export default util.createRule({
);
}, '');
// comments should move before export and not between export and interface declaration
fixes.push(
fixer.insertTextBefore(
node.parent as TSESTree.Node | TSESTree.Token,
commentsText,
),
);
fixes.push(fixer.insertTextBefore(node.parent, commentsText));
} else {
comments.forEach(comment => {
let commentText =
Expand Down
Expand Up @@ -111,7 +111,7 @@ export default util.createRule<Options, MessageIds>({
function* fix(
fixer: TSESLint.RuleFixer,
): IterableIterator<TSESLint.RuleFix> {
if (node.parent && util.isLogicalOrOperator(node.parent)) {
if (util.isLogicalOrOperator(node.parent)) {
// '&&' and '??' operations cannot be mixed without parentheses (e.g. a && b ?? c)
if (
node.left.type === AST_NODE_TYPES.LogicalExpression &&
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/src/rules/prefer-optional-chain.ts
Expand Up @@ -122,7 +122,7 @@ export default util.createRule({
): void {
// selector guarantees this cast
const initialExpression = (
initialIdentifierOrNotEqualsExpr.parent!.type ===
initialIdentifierOrNotEqualsExpr.parent.type ===
AST_NODE_TYPES.ChainExpression
? initialIdentifierOrNotEqualsExpr.parent.parent
: initialIdentifierOrNotEqualsExpr.parent
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-plugin/src/rules/prefer-return-this-type.ts
Expand Up @@ -151,7 +151,7 @@ export default createRule({

return {
'ClassBody > MethodDefinition'(node: TSESTree.MethodDefinition): void {
checkFunction(node.value, node.parent!.parent as ClassLikeDeclaration);
checkFunction(node.value, node.parent.parent as ClassLikeDeclaration);
},
'ClassBody > PropertyDefinition'(
node: TSESTree.PropertyDefinition,
Expand All @@ -165,7 +165,7 @@ export default createRule({
return;
}

checkFunction(node.value, node.parent!.parent as ClassLikeDeclaration);
checkFunction(node.value, node.parent.parent as ClassLikeDeclaration);
},
};
},
Expand Down
10 changes: 3 additions & 7 deletions packages/eslint-plugin/src/rules/promise-function-async.ts
Expand Up @@ -121,13 +121,12 @@ export default util.createRule<Options, MessageIds>({
return;
}

if (node.parent?.type === AST_NODE_TYPES.TSAbstractMethodDefinition) {
if (node.parent.type === AST_NODE_TYPES.TSAbstractMethodDefinition) {
// Abstract method can't be async
return;
}

if (
node.parent &&
(node.parent.type === AST_NODE_TYPES.Property ||
node.parent.type === AST_NODE_TYPES.MethodDefinition) &&
(node.parent.kind === 'get' || node.parent.kind === 'set')
Expand All @@ -153,10 +152,8 @@ export default util.createRule<Options, MessageIds>({
loc: util.getFunctionHeadLoc(node, sourceCode),
fix: fixer => {
if (
node.parent &&
(node.parent.type === AST_NODE_TYPES.MethodDefinition ||
(node.parent.type === AST_NODE_TYPES.Property &&
node.parent.method))
node.parent.type === AST_NODE_TYPES.MethodDefinition ||
(node.parent.type === AST_NODE_TYPES.Property && node.parent.method)
) {
// this function is a class method or object function property shorthand
const method = node.parent;
Expand Down Expand Up @@ -219,7 +216,6 @@ export default util.createRule<Options, MessageIds>({
node: TSESTree.FunctionExpression,
): void {
if (
node.parent &&
node.parent.type === AST_NODE_TYPES.MethodDefinition &&
node.parent.kind === 'method'
) {
Expand Down
Expand Up @@ -78,7 +78,7 @@ export default util.createRule<Options, MessageIds>({
}

if (util.isTypeArrayTypeOrUnionOfArrayTypes(calleeObjType, checker)) {
context.report({ node: callee.parent!, messageId: 'requireCompare' });
context.report({ node: callee.parent, messageId: 'requireCompare' });
}
},
};
Expand Down
Expand Up @@ -117,7 +117,7 @@ export default util.createRule<Options, MessageId>({
return {
TemplateLiteral(node: TSESTree.TemplateLiteral): void {
// don't check tagged template literals
if (node.parent!.type === AST_NODE_TYPES.TaggedTemplateExpression) {
if (node.parent.type === AST_NODE_TYPES.TaggedTemplateExpression) {
return;
}

Expand Down
Expand Up @@ -221,7 +221,7 @@ export default util.createRule<Options, MessageIds>({
? 'Intersection'
: 'Union',
};
if (node.parent?.type === AST_NODE_TYPES.TSTypeAliasDeclaration) {
if (node.parent.type === AST_NODE_TYPES.TSTypeAliasDeclaration) {
messageId = 'notSortedNamed';
data.name = node.parent.id.name;
}
Expand Down