-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuiltin.ts
More file actions
135 lines (127 loc) · 3.64 KB
/
Copy pathbuiltin.ts
File metadata and controls
135 lines (127 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { extractCssData } from "../css-parser";
import { extractMarkers, extractSuppressions } from "../markers";
import { extractFileData } from "../parser";
import type { LanguageAdapter, ParsedFilePayload, ParseContext } from "./types";
const TS_JS_EXT = new Set([
".ts",
".tsx",
".mts",
".cts",
".js",
".jsx",
".mjs",
".cjs",
]);
function parseTsJs(ctx: ParseContext): ParsedFilePayload {
const data = extractFileData(ctx.absPath, ctx.source, ctx.relPath);
return {
category: "ts",
symbols: data.symbols,
imports: data.imports,
exports: data.exports,
components: data.components,
markers: data.markers,
suppressions: extractSuppressions(ctx.source, ctx.relPath),
typeMembers: data.typeMembers,
typeHeritage: data.typeHeritage,
calls: data.calls,
importSpecifiers: data.importSpecifiers,
scopes: data.scopes,
references: data.references,
fileMetrics: data.fileMetrics,
functionParams: data.functionParams,
runtimeMarkers: data.runtimeMarkers,
testSuites: data.testSuites,
dynamicImports: data.dynamicImports,
jsxElements: data.jsxElements,
jsxAttributes: data.jsxAttributes,
asyncCalls: data.asyncCalls,
tryCatchRows: data.tryCatchRows,
decorators: data.decorators,
jsdocTags: data.jsdocTags,
hasSideEffects: data.hasSideEffects,
};
}
function parseCss(ctx: ParseContext): ParsedFilePayload {
const cssData = extractCssData(ctx.absPath, ctx.source, ctx.relPath);
return {
category: "css",
cssVariables: cssData.variables,
cssClasses: cssData.classes,
cssKeyframes: cssData.keyframes,
markers: cssData.markers,
suppressions: extractSuppressions(ctx.source, ctx.relPath),
cssImportSources: cssData.importSources,
};
}
function parseText(ctx: ParseContext): ParsedFilePayload {
return {
category: "text",
markers: extractMarkers(ctx.source, ctx.relPath),
suppressions: extractSuppressions(ctx.source, ctx.relPath),
};
}
/**
* Built-in adapters (oxc TS/JS, Lightning CSS, text/markers). Order matters for the first match.
*/
export const BUILTIN_ADAPTERS: readonly LanguageAdapter[] = [
{
id: "builtin.ts-js",
extensions: [...TS_JS_EXT],
parse: parseTsJs,
},
{
id: "builtin.css",
extensions: [".css"],
parse: parseCss,
},
{
id: "builtin.text",
extensions: [
".md",
".mdx",
".mdc",
".yml",
".yaml",
".txt",
".json",
".sh",
],
parse: parseText,
},
];
// WeakMap-keyed so future plugin-registered adapter arrays (c9-plugin-layer.md)
// also memoise without leaking refs to GC'd arrays.
const adapterIndexCache = new WeakMap<
readonly LanguageAdapter[],
Map<string, LanguageAdapter>
>();
function buildAdapterIndex(
adapters: readonly LanguageAdapter[],
): Map<string, LanguageAdapter> {
const index = new Map<string, LanguageAdapter>();
// First-match-wins: skip ext if an earlier adapter already claimed it.
for (const a of adapters) {
for (const ext of a.extensions) {
const key = ext.toLowerCase();
if (!index.has(key)) index.set(key, a);
}
}
return index;
}
/**
* First-match adapter lookup by file extension. `ext` must include the
* leading dot (`.tsx`); returns `undefined` when nothing matches (the
* indexer then falls back to markers-only text).
*/
export function getAdapterForExtension(
ext: string,
adapters: readonly LanguageAdapter[] = BUILTIN_ADAPTERS,
): LanguageAdapter | undefined {
let index = adapterIndexCache.get(adapters);
if (index === undefined) {
index = buildAdapterIndex(adapters);
adapterIndexCache.set(adapters, index);
}
return index.get(ext.toLowerCase());
}