# core/analyzers/drift.analyzer.ts

> 38 lines of code and 10 definitions.

Tree: GovLab Docs
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-analyzers-drift-analyzer-ts
Source text: https://banes-lab.com/source/docs/core/analyzers/drift.analyzer.ts.txt

Listed in [core/analyzers](https://banes-lab.com/api/source/docs/core/analyzers.md), after [core/analyzers/document.analyzer.ts](https://banes-lab.com/source/docs/core/analyzers/document.analyzer.ts.md) and before [core/analyzers/graph.analyzer.ts](https://banes-lab.com/source/docs/core/analyzers/graph.analyzer.ts.md).

## Definitions

- `symbolDriftIn` (lexical_declaration, line 33, exported)
- `parseSymbolRef` (lexical_declaration, line 11)
- `driftForRef` (lexical_declaration, line 21)
- `SYMBOL_SEPARATOR` (lexical_declaration, line 9)
- `hash` (lexical_declaration, line 12)
- `file` (lexical_declaration, line 16)
- `symbol` (lexical_declaration, line 17)
- `parsed` (lexical_declaration, line 22)
- `resolved` (lexical_declaration, line 26)
- `hit` (lexical_declaration, line 39, exported)

## Contained in

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

## Uses

- [core/parsers/export.parser.ts](https://banes-lab.com/source/docs/core/parsers/export.parser.ts.md)
- [core/parsers/location.parser.ts](https://banes-lab.com/source/docs/core/parsers/location.parser.ts.md)
- [core/predicates/reference.predicate.ts](https://banes-lab.com/source/docs/core/predicates/reference.predicate.ts.md)
- [core/predicates/source.predicate.ts](https://banes-lab.com/source/docs/core/predicates/source.predicate.ts.md)

## Used by

- [core/validators/manifest.prose.validator.ts](https://banes-lab.com/source/docs/core/validators/manifest.prose.validator.ts.md)

## Linked from

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

## Source

```typescript
import type { PathRef, SymbolRef } from "#types/reference.types";
import { exportedNames } from "#core/parsers/export.parser";
import { isCodeFile } from "#core/predicates/source.predicate";
import { isExternalTarget } from "#core/predicates/reference.predicate";
import { pathReferences } from "#core/parsers/location.parser";
import { resolveTargetFile } from "#core/resolvers/source.resolver";
import { unquote } from "#core/normalizers/reference.normalizer";

const SYMBOL_SEPARATOR = "#";

const parseSymbolRef = function parseSymbolRef(raw: string): SymbolRef | null {
    const hash = raw.indexOf(SYMBOL_SEPARATOR);
    if (hash <= 0) {
        return null;
    }
    const file = raw.slice(0, hash);
    const symbol = raw.slice(hash + 1);
    return symbol.length === 0 || isExternalTarget(file) || !isCodeFile(file) ? null : { file, symbol };
};

const driftForRef = function driftForRef(ref: PathRef, moduleDir: string, consumerRoot: string): string | null {
    const parsed = parseSymbolRef(unquote(ref.path));
    if (parsed === null) {
        return null;
    }
    const resolved = resolveTargetFile(parsed.file, moduleDir, consumerRoot);
    if (resolved === null || exportedNames(resolved).has(parsed.symbol)) {
        return null;
    }
    return `${parsed.file}${SYMBOL_SEPARATOR}${parsed.symbol}`;
};

export const symbolDriftIn = function symbolDriftIn(
    fragment: string,
    moduleDir: string,
    consumerRoot: string,
): string[] {
    return pathReferences(fragment).flatMap((ref) => {
        const hit = driftForRef(ref, moduleDir, consumerRoot);
        return hit === null ? [] : [hit];
    });
};
```
