📄 no-use-before-define.ts
¶
📊 Analysis Summary¶
Metric | Count |
---|---|
🔧 Functions | 15 |
📦 Imports | 6 |
📊 Variables & Constants | 11 |
📐 Interfaces | 1 |
📑 Type Aliases | 2 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/eslint-plugin/src/rules/no-use-before-define.ts
📦 Imports¶
Name | Source |
---|---|
TSESTree |
@typescript-eslint/utils |
DefinitionType |
@typescript-eslint/scope-manager |
AST_NODE_TYPES |
@typescript-eslint/utils |
TSESLint |
@typescript-eslint/utils |
createRule |
../util |
referenceContainsTypeQuery |
../util/referenceContainsTypeQuery |
Variables & Constants¶
Name | Type | Kind | Value | Exported |
---|---|---|---|---|
SENTINEL_TYPE |
RegExp |
const | /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/ |
✗ |
functions |
boolean |
let/var | true |
✗ |
classes |
boolean |
let/var | true |
✗ |
enums |
boolean |
let/var | true |
✗ |
variables |
boolean |
let/var | true |
✗ |
typedefs |
boolean |
let/var | true |
✗ |
ignoreTypeReferences |
boolean |
let/var | true |
✗ |
allowNamedExports |
boolean |
let/var | false |
✗ |
node |
TSESTree.Node | undefined |
let/var | variable.identifiers[0].parent |
✗ |
location |
any |
const | reference.identifier.range[1] |
✗ |
variable |
any |
const | reference.resolved |
✗ |
Functions¶
parseOptions(options: string | Config | null): Required<Config>
¶
Code
function parseOptions(options: string | Config | null): Required<Config> {
let functions = true;
let classes = true;
let enums = true;
let variables = true;
let typedefs = true;
let ignoreTypeReferences = true;
let allowNamedExports = false;
if (typeof options === 'string') {
functions = options !== 'nofunc';
} else if (typeof options === 'object' && options != null) {
functions = options.functions !== false;
classes = options.classes !== false;
enums = options.enums !== false;
variables = options.variables !== false;
typedefs = options.typedefs !== false;
ignoreTypeReferences = options.ignoreTypeReferences !== false;
allowNamedExports = options.allowNamedExports !== false;
}
return {
allowNamedExports,
classes,
enums,
functions,
ignoreTypeReferences,
typedefs,
variables,
};
}
-
JSDoc:
-
Parameters:
options: string | Config | null
- Return Type:
Required<Config>
isFunction(variable: TSESLint.Scope.Variable): boolean
¶
Code
-
JSDoc:
-
Parameters:
variable: TSESLint.Scope.Variable
- Return Type:
boolean
isTypedef(variable: TSESLint.Scope.Variable): boolean
¶
Code
-
JSDoc:
-
Parameters:
variable: TSESLint.Scope.Variable
- Return Type:
boolean
isOuterEnum(variable: TSESLint.Scope.Variable, reference: TSESLint.Scope.Reference): boolean
¶
Code
-
JSDoc:
-
Parameters:
variable: TSESLint.Scope.Variable
reference: TSESLint.Scope.Reference
- Return Type:
boolean
isOuterClass(variable: TSESLint.Scope.Variable, reference: TSESLint.Scope.Reference): boolean
¶
Code
-
JSDoc:
-
Parameters:
variable: TSESLint.Scope.Variable
reference: TSESLint.Scope.Reference
- Return Type:
boolean
isOuterVariable(variable: TSESLint.Scope.Variable, reference: TSESLint.Scope.Reference): boolean
¶
Code
-
JSDoc:
-
Parameters:
variable: TSESLint.Scope.Variable
reference: TSESLint.Scope.Reference
- Return Type:
boolean
isNamedExports(reference: TSESLint.Scope.Reference): boolean
¶
Code
-
JSDoc:
-
Parameters:
reference: TSESLint.Scope.Reference
- Return Type:
boolean
isTypeReference(reference: TSESLint.Scope.Reference): boolean
¶
Code
-
JSDoc:
-
Parameters:
reference: TSESLint.Scope.Reference
- Return Type:
boolean
- Calls:
referenceContainsTypeQuery (from ../util/referenceContainsTypeQuery)
isInRange(node: TSESTree.Expression | null | undefined, location: number): boolean
¶
Code
-
JSDoc:
-
Parameters:
node: TSESTree.Expression | null | undefined
location: number
- Return Type:
boolean
isClassRefInClassDecorator(variable: TSESLint.Scope.Variable, reference: TSESLint.Scope.Reference): boolean
¶
Code
function isClassRefInClassDecorator(
variable: TSESLint.Scope.Variable,
reference: TSESLint.Scope.Reference,
): boolean {
if (
variable.defs[0].type !== DefinitionType.ClassName ||
variable.defs[0].node.decorators.length === 0
) {
return false;
}
for (const deco of variable.defs[0].node.decorators) {
if (
reference.identifier.range[0] >= deco.range[0] &&
reference.identifier.range[1] <= deco.range[1]
) {
return true;
}
}
return false;
}
-
JSDoc:
-
Parameters:
variable: TSESLint.Scope.Variable
reference: TSESLint.Scope.Reference
- Return Type:
boolean
isInInitializer(variable: TSESLint.Scope.Variable, reference: TSESLint.Scope.Reference): boolean
¶
Code
function isInInitializer(
variable: TSESLint.Scope.Variable,
reference: TSESLint.Scope.Reference,
): boolean {
if (variable.scope !== reference.from) {
return false;
}
let node: TSESTree.Node | undefined = variable.identifiers[0].parent;
const location = reference.identifier.range[1];
while (node) {
if (node.type === AST_NODE_TYPES.VariableDeclarator) {
if (isInRange(node.init, location)) {
return true;
}
if (
(node.parent.parent.type === AST_NODE_TYPES.ForInStatement ||
node.parent.parent.type === AST_NODE_TYPES.ForOfStatement) &&
isInRange(node.parent.parent.right, location)
) {
return true;
}
break;
} else if (node.type === AST_NODE_TYPES.AssignmentPattern) {
if (isInRange(node.right, location)) {
return true;
}
} else if (SENTINEL_TYPE.test(node.type)) {
break;
}
node = node.parent;
}
return false;
}
-
JSDoc:
-
Parameters:
variable: TSESLint.Scope.Variable
reference: TSESLint.Scope.Reference
- Return Type:
boolean
- Calls:
isInRange
SENTINEL_TYPE.test
isForbidden(variable: TSESLint.Scope.Variable, reference: TSESLint.Scope.Reference): boolean
¶
Code
function isForbidden(
variable: TSESLint.Scope.Variable,
reference: TSESLint.Scope.Reference,
): boolean {
if (options.ignoreTypeReferences && isTypeReference(reference)) {
return false;
}
if (isFunction(variable)) {
return options.functions;
}
if (isOuterClass(variable, reference)) {
return options.classes;
}
if (isOuterVariable(variable, reference)) {
return options.variables;
}
if (isOuterEnum(variable, reference)) {
return options.enums;
}
if (isTypedef(variable)) {
return options.typedefs;
}
return true;
}
-
JSDoc:
-
Parameters:
variable: TSESLint.Scope.Variable
reference: TSESLint.Scope.Reference
- Return Type:
boolean
- Calls:
isTypeReference
isFunction
isOuterClass
isOuterVariable
isOuterEnum
isTypedef
isDefinedBeforeUse(variable: TSESLint.Scope.Variable, reference: TSESLint.Scope.Reference): boolean
¶
Code
- Parameters:
variable: TSESLint.Scope.Variable
reference: TSESLint.Scope.Reference
- Return Type:
boolean
- Calls:
isInInitializer
findVariablesInScope(scope: TSESLint.Scope.Scope): void
¶
Code
function findVariablesInScope(scope: TSESLint.Scope.Scope): void {
scope.references.forEach(reference => {
const variable = reference.resolved;
function report(): void {
context.report({
node: reference.identifier,
messageId: 'noUseBeforeDefine',
data: {
name: reference.identifier.name,
},
});
}
// Skips when the reference is:
// - initializations.
// - referring to an undefined variable.
// - referring to a global environment variable (there're no identifiers).
// - located preceded by the variable (except in initializers).
// - allowed by options.
if (reference.init) {
return;
}
if (!options.allowNamedExports && isNamedExports(reference)) {
if (!variable || !isDefinedBeforeUse(variable, reference)) {
report();
}
return;
}
if (!variable) {
return;
}
if (
variable.identifiers.length === 0 ||
isDefinedBeforeUse(variable, reference) ||
!isForbidden(variable, reference) ||
isClassRefInClassDecorator(variable, reference) ||
reference.from.type === TSESLint.Scope.ScopeType.functionType
) {
return;
}
// Reports.
report();
});
scope.childScopes.forEach(findVariablesInScope);
}
-
JSDoc:
-
Parameters:
scope: TSESLint.Scope.Scope
- Return Type:
void
- Calls:
scope.references.forEach
context.report
isNamedExports
isDefinedBeforeUse
report
isForbidden
isClassRefInClassDecorator
scope.childScopes.forEach
- Internal Comments:
report(): void
¶
Code
- Return Type:
void
- Calls:
context.report
Interfaces¶
Config
¶
Interface Code
Properties¶
Name | Type | Optional | Description |
---|---|---|---|
allowNamedExports |
boolean |
✓ | |
classes |
boolean |
✓ | |
enums |
boolean |
✓ | |
functions |
boolean |
✓ | |
ignoreTypeReferences |
boolean |
✓ | |
typedefs |
boolean |
✓ | |
variables |
boolean |
✓ |