New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

exfoliate

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

exfoliate

Function inliner for reducing code complexity

latest
npmnpm
Version
0.0.8
Version published
Maintainers
1
Created
Source

exfoliate - JavaScript Function Inliner

A comprehensive AST-based function inliner for reducing code complexity and flattening nested function calls.

Features

Smart Inlining Strategy

  • Single-use functions are inlined: Functions called exactly once are automatically inlined
  • Multi-use functions are preserved: Functions called multiple times remain as reusable methods
  • Predictable and reliable: Uses topological sorting to inline dependencies in the correct order

Complete Scope Management

  • Variable conflict resolution: Automatically renames variables that would conflict
  • Parameter substitution: Replaces function parameters with actual arguments
  • Shadowing prevention: Handles variable shadowing correctly

Early Return Handling

  • Semantic preservation: Correctly handles early returns using control flow flags
  • Nested returns: Properly transforms returns inside if statements and blocks
  • Control flow integrity: Ensures code after early returns doesn't execute

Example

Before:

export class D {
  constructor() {
    this._super_C_constructor();
    console.log('d');
  }
  _super_A_constructor() {
    console.log('a');
  }
  _super_B_constructor() {
    this._super_A_constructor();
    console.log('b');
  }
  _super_C_constructor() {
    this._super_B_constructor();
    console.log('c');
  }
}

After:

export class D {
  constructor() {
    console.log('a');
    console.log('b');
    console.log('c');
    console.log('d');
  }
}

Usage

import { inline } from './inliner.js';
import { readFileSync } from 'fs';

const code = readFileSync('./your-file.js', 'utf-8');
const inlinedCode = await inline(code);

console.log(inlinedCode);

How It Works

1. Call Graph Analysis

Analyzes which functions call which, and counts how many times each function is called.

2. Candidate Selection

Identifies functions called exactly once as candidates for inlining.

3. Topological Ordering

Sorts functions so that dependencies are inlined first (leaves to root).

4. AST Transformation

For each inlined function:

  • Clone the function body
  • Rename local variables to avoid conflicts
  • Substitute parameters with arguments
  • Handle return statements with control flow flags if needed
  • Replace the call site with the transformed body

5. Code Generation

Generates clean, formatted code using astring and prettier.

Advanced Features

Early Return Transformation

Original:

function validate(value) {
  if (value < 0) {
    return false;
  }
  if (value > 100) {
    return false;
  }
  return true;
}

Inlined:

let result$1;
let returned_result$1 = false;
if (!returned_result$1) {
  if (num < 0) {
    result$1 = false;
    returned_result$1 = true;
  }
}
if (!returned_result$1) {
  if (num > 100) {
    result$1 = false;
    returned_result$1 = true;
  }
}
if (!returned_result$1) {
  result$1 = true;
}

Variable Shadowing Resolution

Original:

function shadowTest() {
  const temp = 5;
  const result = helper(temp);
  return result;
}

function helper(x) {
  const temp = x + 10; // Shadows outer temp
  return temp;
}

Inlined:

function shadowTest() {
  const temp = 5;
  const temp$1 = temp + 10; // Renamed to avoid conflict
  const result = temp$1;
  return result;
}

Multi-use Function Preservation

// _reusable_log is called 3 times, so it's NOT inlined
_reusable_log(message) {
  console.log('[LOG]', message);
}

method1() {
  this._reusable_log('From method1');
  return 1;
}

method2() {
  this._reusable_log('From method2');
  return 2;
}

Test Results

From the test module:

  • Original code: 3,848 characters
  • Inlined code: 2,923 characters
  • Reduction: ~24%
  • Functions analyzed: 32
  • Inline candidates: 15
  • Functions inlined: 15
  • Preserved (multi-use): 2 (_reusable_log, _multiple_a)

Use Cases

  • Flattening inheritance chains: Inline super constructor calls
  • Removing helper abstraction overhead: Inline single-use helper methods
  • Simplifying code flow: Make code more linear and easier to understand
  • Improving AI collaboration: Reduce indirection for better AI code analysis

Architecture

  • ScopeTracker: Manages variable bindings and generates unique names
  • CallGraphAnalyzer: Builds call graph and counts function usage
  • SimpleVariableRenamer: Renames variables to avoid conflicts
  • ParameterSubstituter: Replaces parameter references with arguments
  • ReturnHandler: Transforms return statements for inlining
  • Inliner: Main orchestrator that coordinates the inlining process

Limitations

  • Recursive functions cannot be inlined (detected and rejected)
  • External function calls are not analyzed
  • Dynamic calls (e.g., via call, apply) are not tracked
  • Requires valid JavaScript that parses with acorn

Dependencies

  • acorn: JavaScript parser
  • astring: AST to code generator
  • prettier: Code formatter

License

MIT

Keywords

inline

FAQs

Package last updated on 25 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts