CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-typescript-eslint--scope-manager

TypeScript scope analyser for ESLint that provides comprehensive scope analysis capabilities for JavaScript and TypeScript code

Pending
Overview
Eval results
Files

definition-system.mddocs/

Definition System

The definition tracking system categorizes how variables are defined and provides detailed context about their declarations across different language constructs.

Capabilities

Definition Union Type

The main Definition type that represents all possible definition types in the system.

type Definition = 
  | CatchClauseDefinition
  | ClassNameDefinition
  | FunctionNameDefinition
  | ImplicitGlobalVariableDefinition
  | ImportBindingDefinition
  | ParameterDefinition
  | TSEnumMemberDefinition
  | TSEnumNameDefinition
  | TSModuleNameDefinition
  | TypeDefinition
  | VariableDefinition;

Definition Type Enumeration

Enumeration of all definition type identifiers used throughout the system.

enum DefinitionType {
  CatchClause = "CatchClause",
  ClassName = "ClassName",
  FunctionName = "FunctionName", 
  ImplicitGlobalVariable = "ImplicitGlobalVariable",
  ImportBinding = "ImportBinding",
  Parameter = "Parameter",
  TSEnumMember = "TSEnumMemberName",
  TSEnumName = "TSEnumName",
  TSModuleName = "TSModuleName",
  Type = "Type",
  Variable = "Variable"
}

Base Definition Interface

All definitions extend from a common base that provides essential definition information.

interface DefinitionBase {
  /** Unique identifier for this definition instance */
  readonly $id: number;
  
  /** The type of this definition */
  readonly type: DefinitionType;
  
  /** The identifier node being defined */
  readonly name: TSESTree.BindingName;
  
  /** The AST node that creates this definition */
  readonly node: TSESTree.Node;
  
  /** The parent AST node containing the definition */
  readonly parent: TSESTree.Node | null;
  
  /** True if this definition creates a type binding */
  readonly isTypeDefinition: boolean;
  
  /** True if this definition creates a variable binding */
  readonly isVariableDefinition: boolean;
}

JavaScript Definition Types

Variable Definition

Definitions created by variable declarations (var, let, const).

class VariableDefinition extends DefinitionBase {
  readonly type: DefinitionType.Variable;
  readonly node: TSESTree.VariableDeclarator;
  readonly parent: TSESTree.VariableDeclaration;
  readonly isTypeDefinition: false;
  readonly isVariableDefinition: true;
}

Usage Examples:

// VariableDefinition examples:
var x = 1;        // VariableDefinition for 'x'
let y = 2;        // VariableDefinition for 'y'  
const z = 3;      // VariableDefinition for 'z'

const [a, b] = arr;     // VariableDefinition for 'a' and 'b'
const {name, age} = obj; // VariableDefinition for 'name' and 'age'

Function Name Definition

Definitions created by function declarations and named function expressions.

class FunctionNameDefinition extends DefinitionBase {
  readonly type: DefinitionType.FunctionName;
  readonly node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression;
  readonly parent: TSESTree.Node | null;
  readonly isTypeDefinition: false;
  readonly isVariableDefinition: true;
}

Parameter Definition

Definitions created by function parameters.

class ParameterDefinition extends DefinitionBase {
  readonly type: DefinitionType.Parameter;
  readonly node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression 
               | TSESTree.ArrowFunctionExpression;
  readonly parent: TSESTree.Node | null;
  readonly isTypeDefinition: false;
  readonly isVariableDefinition: true;
}

Class Name Definition

Definitions created by class declarations and expressions.

class ClassNameDefinition extends DefinitionBase {
  readonly type: DefinitionType.ClassName;
  readonly node: TSESTree.ClassDeclaration | TSESTree.ClassExpression;
  readonly parent: TSESTree.Node | null;
  readonly isTypeDefinition: true;
  readonly isVariableDefinition: true;
}

Catch Clause Definition

Definitions created by catch clause parameters.

class CatchClauseDefinition extends DefinitionBase {
  readonly type: DefinitionType.CatchClause;
  readonly node: TSESTree.CatchClause;
  readonly parent: TSESTree.TryStatement;
  readonly isTypeDefinition: false;
  readonly isVariableDefinition: true;
}

Import Binding Definition

Definitions created by import statements.

class ImportBindingDefinition extends DefinitionBase {
  readonly type: DefinitionType.ImportBinding;
  readonly node: TSESTree.ImportDefaultSpecifier | TSESTree.ImportNamespaceSpecifier 
               | TSESTree.ImportSpecifier;
  readonly parent: TSESTree.ImportDeclaration;
  readonly isTypeDefinition: boolean; // Depends on import type
  readonly isVariableDefinition: boolean; // Depends on import type
}

Implicit Global Variable Definition

Definitions for implicit global variables.

class ImplicitGlobalVariableDefinition extends DefinitionBase {
  readonly type: DefinitionType.ImplicitGlobalVariable;
  readonly node: TSESTree.Program;
  readonly parent: null;
  readonly isTypeDefinition: false;
  readonly isVariableDefinition: true;
}

TypeScript Definition Types

Type Definition

Definitions created by TypeScript type declarations.

class TypeDefinition extends DefinitionBase {
  readonly type: DefinitionType.Type;
  readonly node: TSESTree.TSTypeAliasDeclaration | TSESTree.TSInterfaceDeclaration;
  readonly parent: TSESTree.Node | null;
  readonly isTypeDefinition: true;
  readonly isVariableDefinition: false;
}

TypeScript Enum Definitions

Definitions for TypeScript enums and their members.

class TSEnumNameDefinition extends DefinitionBase {
  readonly type: DefinitionType.TSEnumName;
  readonly node: TSESTree.TSEnumDeclaration;
  readonly parent: TSESTree.Node | null;
  readonly isTypeDefinition: true;
  readonly isVariableDefinition: true;
}

class TSEnumMemberDefinition extends DefinitionBase {
  readonly type: DefinitionType.TSEnumMember;
  readonly node: TSESTree.TSEnumMember;
  readonly parent: TSESTree.TSEnumDeclaration;
  readonly isTypeDefinition: false;
  readonly isVariableDefinition: true;
}

TypeScript Module Definition

Definitions created by TypeScript module (namespace) declarations.

class TSModuleNameDefinition extends DefinitionBase {
  readonly type: DefinitionType.TSModuleName;
  readonly node: TSESTree.TSModuleDeclaration;
  readonly parent: TSESTree.Node | null;
  readonly isTypeDefinition: true;
  readonly isVariableDefinition: true;
}

Usage Examples:

import { analyze } from "@typescript-eslint/scope-manager";
import { parse } from "@typescript-eslint/parser";

const code = `
// Variable definitions
const message = "Hello";
let count = 0;

// Function definition
function greet(name: string) {  // Parameter definition for 'name'
  return message + ", " + name;
}

// Class definition
class User {
  constructor(public name: string) {}  // Parameter definition for 'name'
}

// Type definitions
interface Point {
  x: number;
  y: number;
}

type StringOrNumber = string | number;

// Enum definitions
enum Color {
  Red,    // TSEnumMemberDefinition
  Green,  // TSEnumMemberDefinition
  Blue    // TSEnumMemberDefinition
}

// Module definition
namespace Utils {
  export function helper() {}
}

// Import definitions
import { parse } from "@typescript-eslint/parser";

// Catch clause definition
try {
  // code
} catch (error) {  // CatchClauseDefinition for 'error'
  console.log(error);
}
`;

const ast = parse(code);
const scopeManager = analyze(ast, { sourceType: 'module' });

// Analyze all definitions
console.log('=== Definition Analysis ===');
scopeManager.variables.forEach(variable => {
  console.log(`\nVariable: ${variable.name}`);
  console.log(`Definitions: ${variable.defs.length}`);
  
  variable.defs.forEach((def, index) => {
    console.log(`  Definition ${index}:`);
    console.log(`    Type: ${def.type}`);
    console.log(`    Node: ${def.node.type}`);
    console.log(`    Is type definition: ${def.isTypeDefinition}`);
    console.log(`    Is variable definition: ${def.isVariableDefinition}`);
    
    if (def.parent) {
      console.log(`    Parent: ${def.parent.type}`);
    }
  });
});

Definition Categories

Analyze definitions by their characteristics:

// Categorize definitions
const allDefinitions: Definition[] = [];
scopeManager.variables.forEach(variable => {
  allDefinitions.push(...variable.defs);
});

// Group by definition type
const defsByType = new Map<DefinitionType, Definition[]>();
allDefinitions.forEach(def => {
  if (!defsByType.has(def.type)) {
    defsByType.set(def.type, []);
  }
  defsByType.get(def.type)!.push(def);
});

console.log('Definitions by type:');
defsByType.forEach((defs, type) => {
  console.log(`  ${type}: ${defs.length}`);
});

// Categorize by context
const typeDefs = allDefinitions.filter(def => def.isTypeDefinition);
const valueDefs = allDefinitions.filter(def => def.isVariableDefinition);
const dualDefs = allDefinitions.filter(def => 
  def.isTypeDefinition && def.isVariableDefinition
);

console.log('\nDefinitions by context:');
console.log(`  Type-only: ${typeDefs.length - dualDefs.length}`);
console.log(`  Value-only: ${valueDefs.length - dualDefs.length}`);
console.log(`  Dual context: ${dualDefs.length}`);

Definition Location Analysis

Analyze where definitions occur in the code:

// Analyze definition locations
console.log('=== Definition Location Analysis ===');

const defsByScope = new Map<string, Definition[]>();
scopeManager.scopes.forEach(scope => {
  scope.variables.forEach(variable => {
    variable.defs.forEach(def => {
      const scopeType = scope.type;
      if (!defsByScope.has(scopeType)) {
        defsByScope.set(scopeType, []);
      }
      defsByScope.get(scopeType)!.push(def);
    });
  });
});

defsByScope.forEach((defs, scopeType) => {
  console.log(`\n${scopeType} scope:`);
  console.log(`  Definitions: ${defs.length}`);
  
  const typeCount = new Map<DefinitionType, number>();
  defs.forEach(def => {
    typeCount.set(def.type, (typeCount.get(def.type) || 0) + 1);
  });
  
  typeCount.forEach((count, type) => {
    console.log(`    ${type}: ${count}`);
  });
});

Import Definition Analysis

Special analysis for import definitions:

// Analyze import definitions
const importDefs = allDefinitions.filter(def => 
  def.type === DefinitionType.ImportBinding
) as ImportBindingDefinition[];

console.log('=== Import Definition Analysis ===');
console.log(`Total imports: ${importDefs.length}`);

const importTypes = new Map<string, number>();
importDefs.forEach(def => {
  const nodeType = def.node.type;
  importTypes.set(nodeType, (importTypes.get(nodeType) || 0) + 1);
});

console.log('Import types:');
importTypes.forEach((count, type) => {
  console.log(`  ${type}: ${count}`);
});

// Examples:
// ImportDefaultSpecifier: import React from 'react'
// ImportNamespaceSpecifier: import * as React from 'react'  
// ImportSpecifier: import { useState } from 'react'

Parameter Definition Analysis

Analyze function parameters:

// Analyze parameter definitions
const paramDefs = allDefinitions.filter(def => 
  def.type === DefinitionType.Parameter
) as ParameterDefinition[];

console.log('=== Parameter Definition Analysis ===');
console.log(`Total parameters: ${paramDefs.length}`);

paramDefs.forEach(def => {
  const functionNode = def.node;
  console.log(`Parameter in ${functionNode.type}:`);
  console.log(`  Name: ${(def.name as TSESTree.Identifier).name}`);
  
  // Analyze parameter patterns
  if (def.name.type === 'ObjectPattern') {
    console.log(`  Destructured object parameter`);
  } else if (def.name.type === 'ArrayPattern') {
    console.log(`  Destructured array parameter`);
  } else if (def.name.type === 'RestElement') {
    console.log(`  Rest parameter`);
  }
});

Type Definition Analysis

Analyze TypeScript type definitions:

// Analyze type definitions
const typeDefs = allDefinitions.filter(def => 
  def.type === DefinitionType.Type
) as TypeDefinition[];

console.log('=== Type Definition Analysis ===');
console.log(`Total type definitions: ${typeDefs.length}`);

typeDefs.forEach(def => {
  console.log(`Type definition: ${(def.name as TSESTree.Identifier).name}`);
  console.log(`  Node type: ${def.node.type}`);
  
  if (def.node.type === 'TSInterfaceDeclaration') {
    console.log(`  Interface definition`);
  } else if (def.node.type === 'TSTypeAliasDeclaration') {
    console.log(`  Type alias definition`);
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-typescript-eslint--scope-manager

docs

analysis.md

definition-system.md

index.md

reference-system.md

scope-management.md

scope-types.md

variable-system.md

tile.json