Skip to content

Commit

Permalink
Document code: Add tree-sitter query for C (#4391)
Browse files Browse the repository at this point in the history
  • Loading branch information
abeatrix authored May 30, 2024
1 parent 82066df commit 8f85eeb
Show file tree
Hide file tree
Showing 5 changed files with 370 additions and 0 deletions.
2 changes: 2 additions & 0 deletions vscode/src/tree-sitter/queries.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { SupportedLanguage } from './grammars'
import { cQueries } from './queries/c'
import { goQueries } from './queries/go'
import { javaQueries } from './queries/java'
import { javascriptQueries } from './queries/javascript'
Expand Down Expand Up @@ -51,4 +52,5 @@ export const languages: Partial<Record<SupportedLanguage, Record<QueryName, stri
...kotlinQueries,
...phpQueries,
...rustQueries,
...cQueries,
} as const
48 changes: 48 additions & 0 deletions vscode/src/tree-sitter/queries/c.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import dedent from 'dedent'

import { SupportedLanguage } from '../grammars'
import type { QueryName } from '../queries'

const DOCUMENTABLE_NODES = dedent`
; Function definitions
;--------------------------------
(function_definition
type: (primitive_type)
declarator: (function_declarator)
body: (compound_statement) @symbol.function) @range.function
; Class definitions
;--------------------------------
(struct_specifier
name: (type_identifier)
body: (_)) @range.function
(declaration
type: (union_specifier
name: (type_identifier) @symbol.function)) @range.function
; Variables
;--------------------------------
(declaration) @symbol.identifier @range.identifier
; Types
;--------------------------------
(type_definition
type: (type_identifier) @symbol.identifier) @range.identifier
(enum_specifier
name: (type_identifier) @symbol.identifier) @range.identifier
`

const ENCLOSING_FUNCTION_QUERY = dedent`
(function_declarator declarator: (identifier) @symbol.function) @range.function
`

export const cQueries = {
[SupportedLanguage.c]: {
singlelineTriggers: '',
intents: '',
documentableNodes: DOCUMENTABLE_NODES,
identifiers: '',
graphContextIdentifiers: '',
enclosingFunction: ENCLOSING_FUNCTION_QUERY,
},
} satisfies Partial<Record<SupportedLanguage, Record<QueryName, string>>>
11 changes: 11 additions & 0 deletions vscode/src/tree-sitter/query-tests/documentable-nodes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,15 @@ describe('getDocumentableNode', () => {
sourcesPath: 'test-data/documentable-node.php',
})
})

it('c', async () => {
const { language, parser, queries } = await initTreeSitterSDK(SupportedLanguage.c)

await annotateAndMatchSnapshot({
parser,
language,
captures: queryWrapper(queries.getDocumentableNode),
sourcesPath: 'test-data/documentable-node.c',
})
})
})
117 changes: 117 additions & 0 deletions vscode/src/tree-sitter/query-tests/test-data/documentable-node.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* wrapper */
void wrapper() {
printf("wrapper\n");
void test() {
// |
}
}

// ------------------------------------

void test() {
// |
}

// ------------------------------------

static void twoSum(int* nums, int numsSize, int target, int* returnSize) {
if (numsSize < 2) {
return;
} else {
for (int i = 0; i < numsSize; i++) {
for (int j = i + 1; j < numsSize; j++) {
if (nums[i] + nums[j] == target) {
// |
returnSize[0] = i;
returnSize[1] = j;
return;
}
}
}
}
}

// ------------------------------------

void test_multiline_func_declaration(
// |
int val,
int val2
) {
wrapper();
}


// ------------------------------------

void test_parameter(int val) {
// |
wrapper();
}


// ------------------------------------

typedef struct Agent {
// |
} Agent;


// ------------------------------------

typedef struct AgentMultiLine {
// |
void (*__init__)(struct AgentMultiLine* self, char* name);
} AgentMultiLine;


// ------------------------------------

void AgentMultiLine__init__(struct AgentMultiLine* self, char* name) {
// |
self->name = name;
}


// ------------------------------------

typedef struct Agent {
char* name;
// |
} Agent;


// ------------------------------------

void Agent_test(struct Agent* self) {
// |
}


// ------------------------------------

void return_statement() {
return;
// |
}


// ------------------------------------

return_statement('value');
// |


// ------------------------------------

char* user_name = "Tom";
// |

// ------------------------------------

enum Level {
// |
LOW,
MEDIUM,
HIGH
};
192 changes: 192 additions & 0 deletions vscode/src/tree-sitter/query-tests/test-data/documentable-node.snap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
//
// | - query start position in the source file.
// █ – query start position in the annotated file.
// ^ – characters matching the last query result.
//
// ------------------------------------

/* wrapper */
void wrapper() {
printf("wrapper\n");
void test() {
// ^ start range.function[1]
// █
}
// ^ end range.function[1]
}

// Nodes types:
// range.function[1]: function_definition

// ------------------------------------

void test() {
//^ start range.function[1]
// █
}
//^ end range.function[1]

// Nodes types:
// range.function[1]: function_definition

// ------------------------------------

static void twoSum(int* nums, int numsSize, int target, int* returnSize) {
//^ start range.function[1]
if (numsSize < 2) {
return;
} else {
for (int i = 0; i < numsSize; i++) {
for (int j = i + 1; j < numsSize; j++) {
if (nums[i] + nums[j] == target) {
// █
returnSize[0] = i;
returnSize[1] = j;
return;
}
}
}
}
}
//^ end range.function[1]

// Nodes types:
// range.function[1]: function_definition

// ------------------------------------

void test_multiline_func_declaration(
//^ start range.function[1]
// █
int val,
int val2
) {
wrapper();
}
//^ end range.function[1]


// Nodes types:
// range.function[1]: function_definition

// ------------------------------------

void test_parameter(int val) {
//^ start range.function[1]
// █
wrapper();
}
//^ end range.function[1]


// Nodes types:
// range.function[1]: function_definition

// ------------------------------------

typedef struct Agent {
// ^ start range.function[1]
// █
} Agent;
//^ end range.function[1]


// Nodes types:
// range.function[1]: struct_specifier

// ------------------------------------

typedef struct AgentMultiLine {
// ^ start range.function[1]
// █
void (*__init__)(struct AgentMultiLine* self, char* name);
} AgentMultiLine;
//^ end range.function[1]


// Nodes types:
// range.function[1]: struct_specifier

// ------------------------------------

void AgentMultiLine__init__(struct AgentMultiLine* self, char* name) {
//^ start range.function[1]
// █
self->name = name;
}
//^ end range.function[1]


// Nodes types:
// range.function[1]: function_definition

// ------------------------------------

typedef struct Agent {
// ^ start range.function[1]
char* name;
// █
} Agent;
//^ end range.function[1]


// Nodes types:
// range.function[1]: struct_specifier

// ------------------------------------

void Agent_test(struct Agent* self) {
//^ start range.function[1]
// █
}
//^ end range.function[1]


// Nodes types:
// range.function[1]: function_definition

// ------------------------------------

void return_statement() {
//^ start range.function[1]
return;
// █
}
//^ end range.function[1]


// Nodes types:
// range.function[1]: function_definition

// ------------------------------------

return_statement('value');
// |


// ------------------------------------

char* user_name = "Tom";
//^^^^^^^^^^^^^^^^^^^^^^^^ symbol.identifier[1], range.identifier[1]
// █

// Nodes types:
// symbol.identifier[1]: declaration
// range.identifier[1]: declaration

// ------------------------------------

enum Level {
//^ start range.identifier[1]
// ^^^^^ symbol.identifier[1]
// █
LOW,
MEDIUM,
HIGH
};
//^ end range.identifier[1]

// Nodes types:
// symbol.identifier[1]: type_identifier
// range.identifier[1]: enum_specifier

0 comments on commit 8f85eeb

Please sign in to comment.