MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / extract_decorators

Function extract_decorators

internal/cbm/extract_defs.c:1920–1985  ·  view source on GitHub ↗

Comments are NAMED nodes in tree-sitter, so a comment interleaved in a * decorator run would end the walk and silently drop every decorator above it: * * @Post('login') <-- lost * @HttpCode(HttpStatus.OK) <-- lost * // why this route is throttled <-- walk stopped here * @Throttle({ ... }) <-- kept * async login(...) * * Documenting a

Source from the content-addressed store, hash-verified

1918 * comments as transparent — like the anonymous tokens already skipped below.
1919 * (is_comment_node() is defined above, near the docstring helpers.) */
1920static const char **extract_decorators(CBMArena *a, TSNode node, const char *source,
1921 CBMLanguage lang, const CBMLangSpec *spec) {
1922 if (!spec->decorator_node_types || !spec->decorator_node_types[0]) {
1923 return NULL;
1924 }
1925
1926 int count = 0;
1927 TSNode prev = ts_node_prev_sibling(node);
1928 while (!ts_node_is_null(prev)) {
1929 if (cbm_kind_in_set(prev, spec->decorator_node_types)) {
1930 count++;
1931 } else if (ts_node_is_named(prev) && !is_comment_node(ts_node_type(prev))) {
1932 /* A real preceding construct ends the decorator run. Anonymous
1933 * tokens (e.g. TS `export` between `@Decorator` and the
1934 * `class_declaration`) and comments are skipped so the decorator
1935 * is still seen. */
1936 break;
1937 }
1938 prev = ts_node_prev_sibling(prev);
1939 }
1940
1941 TSNode modifiers = {0};
1942 int mod_count = 0;
1943 int child_count = 0;
1944 if (count == 0) {
1945 modifiers = find_jvm_modifiers(node, lang);
1946 if (!ts_node_is_null(modifiers)) {
1947 mod_count = count_modifier_annotations(modifiers, spec);
1948 }
1949 /* Languages like Scala attach the annotation directly as a child of the
1950 * definition node (no wrapper, no prev-sibling). */
1951 if (mod_count == 0) {
1952 child_count = count_child_decorators(node, spec);
1953 }
1954 }
1955
1956 int total = count + mod_count + child_count;
1957 if (total == 0) {
1958 return NULL;
1959 }
1960
1961 const char **result =
1962 (const char **)cbm_arena_alloc(a, sizeof(const char *) * (total + NULL_TERM));
1963 if (!result) {
1964 return NULL;
1965 }
1966
1967 int idx = 0;
1968 prev = ts_node_prev_sibling(node);
1969 while (!ts_node_is_null(prev) && idx < count) {
1970 if (cbm_kind_in_set(prev, spec->decorator_node_types)) {
1971 result[idx++] = cbm_node_text(a, prev, source);
1972 } else if (ts_node_is_named(prev) && !is_comment_node(ts_node_type(prev))) {
1973 break;
1974 }
1975 prev = ts_node_prev_sibling(prev);
1976 }
1977 if (!ts_node_is_null(modifiers)) {

Callers 3

extract_func_defFunction · 0.85
extract_class_defFunction · 0.85
push_method_defFunction · 0.85

Calls 9

cbm_kind_in_setFunction · 0.85
is_comment_nodeFunction · 0.85
find_jvm_modifiersFunction · 0.85
count_child_decoratorsFunction · 0.85
cbm_node_textFunction · 0.85
collect_child_decoratorsFunction · 0.85
cbm_arena_allocFunction · 0.70

Tested by

no test coverage detected