# core/plugins/syntax.release.plugin.ts

> 28 lines of code and 10 definitions.

Tree: GovLab Docs
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-plugins-syntax-release-plugin-ts
Source text: https://banes-lab.com/source/docs/core/plugins/syntax.release.plugin.ts.txt

Listed in [core/plugins](https://banes-lab.com/api/source/docs/core/plugins.md), after [core/plugins/syntax.registrar.plugin.ts](https://banes-lab.com/source/docs/core/plugins/syntax.registrar.plugin.ts.md).

## Definitions

- `isTeardownMethod` (lexical_declaration, line 7)
- `classify` (method_definition, line 13, exported)
- `TEARDOWN_NAMES` (lexical_declaration, line 4)
- `TEARDOWN_PREFIXES` (lexical_declaration, line 5)
- `lower` (lexical_declaration, line 8)
- `recognizer` (lexical_declaration, line 12, exported)
- `method` (lexical_declaration, line 17, exported)
- `target` (lexical_declaration, line 21, exported)
- `owner` (lexical_declaration, line 22, exported)
- `id` (lexical_declaration, line 23, exported)

## Contained in

- [core/plugins](https://banes-lab.com/anatomy/docs/folder-docs-core-plugins.md)

## Linked from

- [core/plugins](https://banes-lab.com/anatomy/docs/folder-docs-core-plugins.md)

## Source

```typescript
import type { Recognizer } from "#types/code.types";
import ts from "typescript";

const TEARDOWN_NAMES: ReadonlySet<string> = new Set(["remove", "off", "unsubscribe", "destroy"]);
const TEARDOWN_PREFIXES: readonly string[] = ["cleanup", "teardown", "dispose"];

const isTeardownMethod = function isTeardownMethod(name: string): boolean {
    const lower = name.toLowerCase();
    return TEARDOWN_NAMES.has(lower) || TEARDOWN_PREFIXES.some((prefix) => lower.startsWith(prefix));
};

export const recognizer: Recognizer = {
    classify(node, context) {
        if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression)) {
            return null;
        }
        const method = node.expression.name.text;
        if (!isTeardownMethod(method)) {
            return null;
        }
        const target = node.expression.expression;
        const owner = ts.isIdentifier(target) ? target.text : method;
        const id = context.mkNodeId(node);
        return {
            edges: [{ from: context.currentId, kind: "teardown", label: method, to: id }],
            nodes: [{ id, kind: "collaborator", label: owner, source: context.sourceOf(node) }],
        };
    },
    emits: { edges: ["teardown"], nodes: ["collaborator"] },
    name: "teardown",
};
```
