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

Function extract_decorators

internal/cbm/extract_defs.c:1962–2028  ·  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

1960 * comments as transparent — like the anonymous tokens already skipped below.
1961 * (is_comment_node() is defined above, near the docstring helpers.) */
1962static const char **extract_decorators(CBMArena *a, TSNode node, const char *source,
1963 CBMLanguage lang, const CBMLangSpec *spec) {
1964 if (!spec->decorator_node_types || !spec->decorator_node_types[0]) {
1965 return NULL;
1966 }
1967
1968 int count = 0;
1969 TSNode prev = ts_node_prev_sibling(node);
1970 while (!ts_node_is_null(prev)) {
1971 if (cbm_kind_in_set(prev, spec->decorator_node_types)) {
1972 count++;
1973 } else if (ts_node_is_named(prev) && !is_comment_node(ts_node_type(prev))) {
1974 /* A real preceding construct ends the decorator run. Anonymous
1975 * tokens (e.g. TS `export` between `@Decorator` and the
1976 * `class_declaration`) and comments are skipped so the decorator
1977 * is still seen. */
1978 break;
1979 }
1980 prev = ts_node_prev_sibling(prev);
1981 }
1982
1983 TSNode wrappers[MAX_ATTR_WRAPPERS];
1984 int wn = 0;
1985 int mod_count = 0;
1986 int child_count = 0;
1987 if (count == 0) {
1988 wn = find_jvm_modifiers(node, lang, wrappers, MAX_ATTR_WRAPPERS);
1989 for (int w = 0; w < wn; w++) {
1990 mod_count += count_modifier_annotations(wrappers[w], spec);
1991 }
1992 /* Languages like Scala attach the annotation directly as a child of the
1993 * definition node (no wrapper, no prev-sibling). */
1994 if (mod_count == 0) {
1995 child_count = count_child_decorators(node, spec);
1996 }
1997 }
1998
1999 int total = count + mod_count + child_count;
2000 if (total == 0) {
2001 return NULL;
2002 }
2003
2004 const char **result =
2005 (const char **)cbm_arena_alloc(a, sizeof(const char *) * (total + NULL_TERM));
2006 if (!result) {
2007 return NULL;
2008 }
2009
2010 int idx = 0;
2011 prev = ts_node_prev_sibling(node);
2012 while (!ts_node_is_null(prev) && idx < count) {
2013 if (cbm_kind_in_set(prev, spec->decorator_node_types)) {
2014 result[idx++] = cbm_node_text(a, prev, source);
2015 } else if (ts_node_is_named(prev) && !is_comment_node(ts_node_type(prev))) {
2016 break;
2017 }
2018 prev = ts_node_prev_sibling(prev);
2019 }

Callers 4

extract_func_defFunction · 0.85
extract_class_defFunction · 0.85
push_method_defFunction · 0.85
extract_class_fieldsFunction · 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