MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / parseObjcRNExports

Function parseObjcRNExports

src/resolution/frameworks/react-native.ts:99–143  ·  view source on GitHub ↗

* Parse an ObjC `.m`/`.mm` file's source for `RCT_EXPORT_MODULE` and * `RCT_EXPORT_METHOD` / `RCT_REMAP_METHOD` declarations, returning the * inferred (moduleName, jsMethodName) pairs. * * The macro forms (a single `RCT_EXPORT_MODULE` per file conventionally * matched to a single `@implementati

(
  source: string,
  className: string | null
)

Source from the content-addressed store, hash-verified

97 * macro-aware ObjC parse the tree-sitter grammar doesn't provide.
98 */
99function parseObjcRNExports(
100 source: string,
101 className: string | null
102): Array<{ moduleName: string; jsName: string; nativeSelectorFirstKw: string; line: number }> {
103 const results: Array<{ moduleName: string; jsName: string; nativeSelectorFirstKw: string; line: number }> = [];
104
105 // RCT_EXPORT_MODULE — one per file by convention. Capture the optional arg.
106 const moduleMatch = source.match(/RCT_EXPORT_MODULE\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)?\s*\)/);
107 // Need a module name to attribute methods. Prefer the explicit macro arg,
108 // then the class name, then bail (no module = nothing useful to register).
109 const moduleName =
110 moduleMatch?.[1] ??
111 (className ? defaultObjcModuleName(className) : null);
112 if (!moduleName) return results;
113
114 const lineOf = (idx: number): number => {
115 let line = 1;
116 for (let i = 0; i < idx && i < source.length; i++) if (source.charCodeAt(i) === 10) line++;
117 return line;
118 };
119
120 // RCT_EXPORT_METHOD(selectorFirstKw:(args)…)
121 // The first keyword (everything up to the first `:` or open paren) is the
122 // JS-visible name. We don't try to parse full multi-keyword selectors —
123 // RN's JS view of the method uses only the first keyword.
124 const exportRegex = /RCT_EXPORT_METHOD\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)/g;
125 let m: RegExpExecArray | null;
126 while ((m = exportRegex.exec(source)) !== null) {
127 const kw = m[1];
128 if (kw) results.push({ moduleName, jsName: kw, nativeSelectorFirstKw: kw, line: lineOf(m.index) });
129 }
130
131 // RCT_REMAP_METHOD(jsName, nativeSelectorFirstKw:(args)…)
132 const remapRegex =
133 /RCT_REMAP_METHOD\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*,\s*([A-Za-z_][A-Za-z0-9_]*)/g;
134 while ((m = remapRegex.exec(source)) !== null) {
135 const jsName = m[1];
136 const nativeKw = m[2];
137 if (jsName && nativeKw) {
138 results.push({ moduleName, jsName, nativeSelectorFirstKw: nativeKw, line: lineOf(m.index) });
139 }
140 }
141
142 return results;
143}
144
145/**
146 * Find the `@implementation` class name in an ObjC file — used as the

Callers 2

buildRNMapsFunction · 0.85
extractFunction · 0.85

Calls 3

defaultObjcModuleNameFunction · 0.85
lineOfFunction · 0.85
execMethod · 0.65

Tested by

no test coverage detected