# Inline Method

> Replace calls to a function whose body is as clear as its name with the body itself, then delete the function.

- kind: technique
- category: composing-methods
- aliases: Inline Function
- canonical: https://aipatterns.dev/refactoring/techniques/inline-method
- inspired-by: https://refactoring.guru/inline-method

## Problem

A function adds a name but no meaning. Its body is one obvious line, or it only forwards to another call. Readers jump to the definition and find nothing they could not have read in place.

## Solution

**Put the body at each call site and delete the function.** Do this also as a reset: inline a tangle of badly split helpers back into one function, then extract them again along better lines.

## Before

```ts
class SessionPolicy {
  constructor(private readonly maxIdleMinutes: number) {}

  isExpired(session: Session, now: Date): boolean {
    return this.idleMinutes(session, now) > this.limit();
  }

  private idleMinutes(session: Session, now: Date): number {
    return minutesBetween(session.lastSeenAt, now);
  }

  private limit(): number {
    return this.maxIdleMinutes;
  }
}
```

## After

```ts
class SessionPolicy {
  constructor(private readonly maxIdleMinutes: number) {}

  isExpired(session: Session, now: Date): boolean {
    return minutesBetween(session.lastSeenAt, now) > this.maxIdleMinutes;
  }
}
```

## Why

- Fewer hops to understand the code. The condition is visible in one line.
- Removes indirection left over from earlier refactorings or from speculative "maybe we'll override this" hooks.
- Inlining a cluster of small, poorly named helpers is often the fastest route to re-extracting good ones.

## Steps

1. Confirm the function is not polymorphic: no subclass overrides it and no interface requires it. If one does, stop.
2. Find every call site. Include reflection, string-based dispatch, templates and tests.
3. Replace one call with the body, substituting arguments for parameters. Run the tests.
4. Repeat for each remaining call site.
5. Delete the function. Run the tests again.

## Watch out

- Don't inline a method that subclasses override or that is part of a public API. Callers outside your codebase break.
- Don't inline when the body is long or used in many places. You trade one name for duplicated code; that is the [Duplicate Code](https://aipatterns.dev/refactoring/smells/duplicate-code.md) smell.
- If arguments have side effects or are expensive, substituting them into the body more than once changes behavior. Assign them to a local first.
- Recursive functions and those with several `return` statements need care; turning them into inline code may require restructuring.
- The inverse is [Extract Method](https://aipatterns.dev/refactoring/techniques/extract-method.md). Extract when the body is less clear than a name would be.

## Related

- Fixes [Speculative Generality](https://aipatterns.dev/refactoring/smells/speculative-generality.md), [Middle Man](https://aipatterns.dev/refactoring/smells/middle-man.md) and [Lazy Class](https://aipatterns.dev/refactoring/smells/lazy-class.md) when the class shrinks to forwarding methods.
- Inverse: [Extract Method](https://aipatterns.dev/refactoring/techniques/extract-method.md).
- [Remove Middle Man](https://aipatterns.dev/refactoring/techniques/remove-middle-man.md) and [Inline Class](https://aipatterns.dev/refactoring/techniques/inline-class.md) apply the same idea at class level.
- [Inline Temp](https://aipatterns.dev/refactoring/techniques/inline-temp.md) is the variable-level counterpart.

## Agent checklist

- [ ] No override, interface contract or external caller depends on the method.
- [ ] All call sites were found, including dynamic and test references.
- [ ] Arguments with side effects are evaluated exactly once after inlining.
- [ ] The inlined code is no harder to read than the call was.
- [ ] The method is deleted and tests pass.
