@optave/codegraph 3.0.4 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +59 -52
  2. package/grammars/tree-sitter-go.wasm +0 -0
  3. package/package.json +9 -10
  4. package/src/ast-analysis/rules/csharp.js +201 -0
  5. package/src/ast-analysis/rules/go.js +182 -0
  6. package/src/ast-analysis/rules/index.js +82 -0
  7. package/src/ast-analysis/rules/java.js +175 -0
  8. package/src/ast-analysis/rules/javascript.js +246 -0
  9. package/src/ast-analysis/rules/php.js +219 -0
  10. package/src/ast-analysis/rules/python.js +196 -0
  11. package/src/ast-analysis/rules/ruby.js +204 -0
  12. package/src/ast-analysis/rules/rust.js +173 -0
  13. package/src/ast-analysis/shared.js +223 -0
  14. package/src/ast.js +15 -28
  15. package/src/audit.js +4 -5
  16. package/src/boundaries.js +1 -1
  17. package/src/branch-compare.js +84 -79
  18. package/src/builder.js +274 -159
  19. package/src/cfg.js +111 -341
  20. package/src/check.js +3 -3
  21. package/src/cli.js +122 -167
  22. package/src/cochange.js +1 -1
  23. package/src/communities.js +13 -16
  24. package/src/complexity.js +196 -1239
  25. package/src/cycles.js +1 -1
  26. package/src/dataflow.js +274 -697
  27. package/src/db/connection.js +88 -0
  28. package/src/db/migrations.js +312 -0
  29. package/src/db/query-builder.js +280 -0
  30. package/src/db/repository.js +134 -0
  31. package/src/db.js +19 -392
  32. package/src/embedder.js +145 -141
  33. package/src/export.js +1 -1
  34. package/src/flow.js +160 -228
  35. package/src/index.js +36 -2
  36. package/src/kinds.js +49 -0
  37. package/src/manifesto.js +3 -8
  38. package/src/mcp.js +97 -20
  39. package/src/owners.js +132 -132
  40. package/src/parser.js +58 -131
  41. package/src/queries-cli.js +866 -0
  42. package/src/queries.js +1356 -2261
  43. package/src/resolve.js +11 -2
  44. package/src/result-formatter.js +21 -0
  45. package/src/sequence.js +364 -0
  46. package/src/structure.js +200 -199
  47. package/src/test-filter.js +7 -0
  48. package/src/triage.js +120 -162
  49. package/src/viewer.js +1 -1
@@ -0,0 +1,219 @@
1
+ /**
2
+ * PHP — AST analysis rules.
3
+ */
4
+
5
+ import { makeCfgRules, makeDataflowRules } from '../shared.js';
6
+
7
+ // ─── Complexity ───────────────────────────────────────────────────────────
8
+
9
+ export const complexity = {
10
+ branchNodes: new Set([
11
+ 'if_statement',
12
+ 'else_if_clause',
13
+ 'else_clause',
14
+ 'for_statement',
15
+ 'foreach_statement',
16
+ 'while_statement',
17
+ 'do_statement',
18
+ 'catch_clause',
19
+ 'conditional_expression',
20
+ 'switch_statement',
21
+ ]),
22
+ caseNodes: new Set(['case_statement', 'default_statement']),
23
+ logicalOperators: new Set(['&&', '||', 'and', 'or', '??']),
24
+ logicalNodeType: 'binary_expression',
25
+ optionalChainType: 'nullsafe_member_access_expression',
26
+ nestingNodes: new Set([
27
+ 'if_statement',
28
+ 'for_statement',
29
+ 'foreach_statement',
30
+ 'while_statement',
31
+ 'do_statement',
32
+ 'catch_clause',
33
+ 'conditional_expression',
34
+ 'switch_statement',
35
+ ]),
36
+ functionNodes: new Set([
37
+ 'function_definition',
38
+ 'method_declaration',
39
+ 'anonymous_function_creation_expression',
40
+ 'arrow_function',
41
+ ]),
42
+ ifNodeType: 'if_statement',
43
+ elseNodeType: 'else_clause',
44
+ elifNodeType: 'else_if_clause',
45
+ elseViaAlternative: false,
46
+ switchLikeNodes: new Set(['switch_statement']),
47
+ };
48
+
49
+ // ─── Halstead ─────────────────────────────────────────────────────────────
50
+
51
+ export const halstead = {
52
+ operatorLeafTypes: new Set([
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
+ 'and',
85
+ 'or',
86
+ 'xor',
87
+ '??',
88
+ '&',
89
+ '|',
90
+ '^',
91
+ '~',
92
+ '<<',
93
+ '>>',
94
+ '++',
95
+ '--',
96
+ 'instanceof',
97
+ 'new',
98
+ 'clone',
99
+ 'if',
100
+ 'else',
101
+ 'elseif',
102
+ 'for',
103
+ 'foreach',
104
+ 'while',
105
+ 'do',
106
+ 'switch',
107
+ 'case',
108
+ 'return',
109
+ 'throw',
110
+ 'break',
111
+ 'continue',
112
+ 'try',
113
+ 'catch',
114
+ 'finally',
115
+ 'echo',
116
+ 'print',
117
+ 'yield',
118
+ '.',
119
+ '->',
120
+ '?->',
121
+ '::',
122
+ ',',
123
+ ';',
124
+ ':',
125
+ '?',
126
+ '=>',
127
+ ]),
128
+ operandLeafTypes: new Set([
129
+ 'name',
130
+ 'variable_name',
131
+ 'integer',
132
+ 'float',
133
+ 'string_content',
134
+ 'true',
135
+ 'false',
136
+ 'null',
137
+ ]),
138
+ compoundOperators: new Set([
139
+ 'function_call_expression',
140
+ 'member_call_expression',
141
+ 'scoped_call_expression',
142
+ 'subscript_expression',
143
+ 'object_creation_expression',
144
+ ]),
145
+ skipTypes: new Set([]),
146
+ };
147
+
148
+ // ─── CFG ──────────────────────────────────────────────────────────────────
149
+
150
+ export const cfg = makeCfgRules({
151
+ ifNode: 'if_statement',
152
+ elifNode: 'else_if_clause',
153
+ elseClause: 'else_clause',
154
+ ifConsequentField: 'body',
155
+ forNodes: new Set(['for_statement', 'foreach_statement']),
156
+ whileNode: 'while_statement',
157
+ doNode: 'do_statement',
158
+ switchNode: 'switch_statement',
159
+ caseNode: 'case_statement',
160
+ defaultNode: 'default_statement',
161
+ tryNode: 'try_statement',
162
+ catchNode: 'catch_clause',
163
+ finallyNode: 'finally_clause',
164
+ returnNode: 'return_statement',
165
+ throwNode: 'throw_expression',
166
+ breakNode: 'break_statement',
167
+ continueNode: 'continue_statement',
168
+ blockNode: 'compound_statement',
169
+ functionNodes: new Set([
170
+ 'function_definition',
171
+ 'method_declaration',
172
+ 'anonymous_function_creation_expression',
173
+ 'arrow_function',
174
+ ]),
175
+ });
176
+
177
+ // ─── Dataflow ─────────────────────────────────────────────────────────────
178
+
179
+ export const dataflow = makeDataflowRules({
180
+ functionNodes: new Set([
181
+ 'function_definition',
182
+ 'method_declaration',
183
+ 'anonymous_function_creation_expression',
184
+ 'arrow_function',
185
+ ]),
186
+ paramListField: 'parameters',
187
+ paramIdentifier: 'variable_name',
188
+ returnNode: 'return_statement',
189
+ varDeclaratorNode: null,
190
+ assignmentNode: 'assignment_expression',
191
+ assignLeftField: 'left',
192
+ assignRightField: 'right',
193
+ callNodes: new Set([
194
+ 'function_call_expression',
195
+ 'member_call_expression',
196
+ 'scoped_call_expression',
197
+ ]),
198
+ callFunctionField: 'function',
199
+ callArgsField: 'arguments',
200
+ spreadType: 'spread_expression',
201
+ memberNode: 'member_access_expression',
202
+ memberObjectField: 'object',
203
+ memberPropertyField: 'name',
204
+ argumentWrapperType: 'argument',
205
+ extraIdentifierTypes: new Set(['variable_name', 'name']),
206
+ mutatingMethods: new Set(['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse']),
207
+ extractParamName(node) {
208
+ if (node.type === 'simple_parameter' || node.type === 'variadic_parameter') {
209
+ const nameNode = node.childForFieldName('name');
210
+ return nameNode ? [nameNode.text] : null;
211
+ }
212
+ if (node.type === 'variable_name') return [node.text];
213
+ return null;
214
+ },
215
+ });
216
+
217
+ // ─── AST Node Types ───────────────────────────────────────────────────────
218
+
219
+ export const astTypes = null;
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Python — AST analysis rules.
3
+ */
4
+
5
+ import { makeCfgRules, makeDataflowRules } from '../shared.js';
6
+
7
+ // ─── Complexity ───────────────────────────────────────────────────────────
8
+
9
+ export const complexity = {
10
+ branchNodes: new Set([
11
+ 'if_statement',
12
+ 'elif_clause',
13
+ 'else_clause',
14
+ 'for_statement',
15
+ 'while_statement',
16
+ 'except_clause',
17
+ 'conditional_expression',
18
+ 'match_statement',
19
+ ]),
20
+ caseNodes: new Set(['case_clause']),
21
+ logicalOperators: new Set(['and', 'or']),
22
+ logicalNodeType: 'boolean_operator',
23
+ optionalChainType: null,
24
+ nestingNodes: new Set([
25
+ 'if_statement',
26
+ 'for_statement',
27
+ 'while_statement',
28
+ 'except_clause',
29
+ 'conditional_expression',
30
+ ]),
31
+ functionNodes: new Set(['function_definition', 'lambda']),
32
+ ifNodeType: 'if_statement',
33
+ elseNodeType: 'else_clause',
34
+ elifNodeType: 'elif_clause',
35
+ elseViaAlternative: false,
36
+ switchLikeNodes: new Set(['match_statement']),
37
+ };
38
+
39
+ // ─── Halstead ─────────────────────────────────────────────────────────────
40
+
41
+ export const halstead = {
42
+ operatorLeafTypes: new Set([
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
+ 'and',
70
+ 'or',
71
+ 'not',
72
+ '&',
73
+ '|',
74
+ '^',
75
+ '~',
76
+ '<<',
77
+ '>>',
78
+ 'if',
79
+ 'else',
80
+ 'elif',
81
+ 'for',
82
+ 'while',
83
+ 'with',
84
+ 'try',
85
+ 'except',
86
+ 'finally',
87
+ 'raise',
88
+ 'return',
89
+ 'yield',
90
+ 'await',
91
+ 'pass',
92
+ 'break',
93
+ 'continue',
94
+ 'import',
95
+ 'from',
96
+ 'as',
97
+ 'in',
98
+ 'is',
99
+ 'lambda',
100
+ 'del',
101
+ '.',
102
+ ',',
103
+ ':',
104
+ '@',
105
+ '->',
106
+ ]),
107
+ operandLeafTypes: new Set([
108
+ 'identifier',
109
+ 'integer',
110
+ 'float',
111
+ 'string_content',
112
+ 'true',
113
+ 'false',
114
+ 'none',
115
+ ]),
116
+ compoundOperators: new Set(['call', 'subscript', 'attribute']),
117
+ skipTypes: new Set([]),
118
+ };
119
+
120
+ // ─── CFG ──────────────────────────────────────────────────────────────────
121
+
122
+ export const cfg = makeCfgRules({
123
+ ifNode: 'if_statement',
124
+ elifNode: 'elif_clause',
125
+ elseClause: 'else_clause',
126
+ forNodes: new Set(['for_statement']),
127
+ whileNode: 'while_statement',
128
+ switchNode: 'match_statement',
129
+ caseNode: 'case_clause',
130
+ tryNode: 'try_statement',
131
+ catchNode: 'except_clause',
132
+ finallyNode: 'finally_clause',
133
+ returnNode: 'return_statement',
134
+ throwNode: 'raise_statement',
135
+ breakNode: 'break_statement',
136
+ continueNode: 'continue_statement',
137
+ blockNode: 'block',
138
+ functionNodes: new Set(['function_definition']),
139
+ });
140
+
141
+ // ─── Dataflow ─────────────────────────────────────────────────────────────
142
+
143
+ export const dataflow = makeDataflowRules({
144
+ functionNodes: new Set(['function_definition', 'lambda']),
145
+ defaultParamType: 'default_parameter',
146
+ restParamType: 'list_splat_pattern',
147
+ returnNode: 'return_statement',
148
+ varDeclaratorNode: null,
149
+ assignmentNode: 'assignment',
150
+ assignLeftField: 'left',
151
+ assignRightField: 'right',
152
+ callNode: 'call',
153
+ callFunctionField: 'function',
154
+ callArgsField: 'arguments',
155
+ spreadType: 'list_splat',
156
+ memberNode: 'attribute',
157
+ memberObjectField: 'object',
158
+ memberPropertyField: 'attribute',
159
+ awaitNode: 'await',
160
+ mutatingMethods: new Set([
161
+ 'append',
162
+ 'extend',
163
+ 'insert',
164
+ 'pop',
165
+ 'remove',
166
+ 'clear',
167
+ 'sort',
168
+ 'reverse',
169
+ 'add',
170
+ 'discard',
171
+ 'update',
172
+ ]),
173
+ extractParamName(node) {
174
+ if (node.type === 'typed_parameter' || node.type === 'typed_default_parameter') {
175
+ for (const c of node.namedChildren) {
176
+ if (c.type === 'identifier') return [c.text];
177
+ }
178
+ return null;
179
+ }
180
+ if (node.type === 'default_parameter') {
181
+ const nameNode = node.childForFieldName('name');
182
+ return nameNode ? [nameNode.text] : null;
183
+ }
184
+ if (node.type === 'list_splat_pattern' || node.type === 'dictionary_splat_pattern') {
185
+ for (const c of node.namedChildren) {
186
+ if (c.type === 'identifier') return [c.text];
187
+ }
188
+ return null;
189
+ }
190
+ return null;
191
+ },
192
+ });
193
+
194
+ // ─── AST Node Types ───────────────────────────────────────────────────────
195
+
196
+ export const astTypes = null;
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Ruby — AST analysis rules.
3
+ */
4
+
5
+ import { makeCfgRules, makeDataflowRules } from '../shared.js';
6
+
7
+ // ─── Complexity ───────────────────────────────────────────────────────────
8
+
9
+ export const complexity = {
10
+ branchNodes: new Set([
11
+ 'if',
12
+ 'elsif',
13
+ 'else',
14
+ 'unless',
15
+ 'case',
16
+ 'for',
17
+ 'while',
18
+ 'until',
19
+ 'rescue',
20
+ 'conditional',
21
+ ]),
22
+ caseNodes: new Set(['when']),
23
+ logicalOperators: new Set(['and', 'or', '&&', '||']),
24
+ logicalNodeType: 'binary',
25
+ optionalChainType: null,
26
+ nestingNodes: new Set(['if', 'unless', 'case', 'for', 'while', 'until', 'rescue', 'conditional']),
27
+ functionNodes: new Set(['method', 'singleton_method', 'lambda', 'do_block']),
28
+ ifNodeType: 'if',
29
+ elseNodeType: 'else',
30
+ elifNodeType: 'elsif',
31
+ elseViaAlternative: false,
32
+ switchLikeNodes: new Set(['case']),
33
+ };
34
+
35
+ // ─── Halstead ─────────────────────────────────────────────────────────────
36
+
37
+ export const halstead = {
38
+ operatorLeafTypes: new Set([
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
+ 'and',
71
+ 'or',
72
+ 'not',
73
+ '&',
74
+ '|',
75
+ '^',
76
+ '~',
77
+ '<<',
78
+ '>>',
79
+ 'if',
80
+ 'else',
81
+ 'elsif',
82
+ 'unless',
83
+ 'case',
84
+ 'when',
85
+ 'for',
86
+ 'while',
87
+ 'until',
88
+ 'do',
89
+ 'begin',
90
+ 'end',
91
+ 'return',
92
+ 'raise',
93
+ 'break',
94
+ 'next',
95
+ 'redo',
96
+ 'retry',
97
+ 'rescue',
98
+ 'ensure',
99
+ 'yield',
100
+ 'def',
101
+ 'class',
102
+ 'module',
103
+ '.',
104
+ ',',
105
+ ':',
106
+ '::',
107
+ '=>',
108
+ '->',
109
+ ]),
110
+ operandLeafTypes: new Set([
111
+ 'identifier',
112
+ 'constant',
113
+ 'instance_variable',
114
+ 'class_variable',
115
+ 'global_variable',
116
+ 'integer',
117
+ 'float',
118
+ 'string_content',
119
+ 'symbol',
120
+ 'true',
121
+ 'false',
122
+ 'nil',
123
+ 'self',
124
+ ]),
125
+ compoundOperators: new Set(['call', 'element_reference']),
126
+ skipTypes: new Set([]),
127
+ };
128
+
129
+ // ─── CFG ──────────────────────────────────────────────────────────────────
130
+
131
+ export const cfg = makeCfgRules({
132
+ ifNode: 'if',
133
+ elifNode: 'elsif',
134
+ elseClause: 'else',
135
+ forNodes: new Set(['for']),
136
+ whileNode: 'while',
137
+ unlessNode: 'unless',
138
+ untilNode: 'until',
139
+ switchNode: 'case',
140
+ caseNode: 'when',
141
+ defaultNode: 'else',
142
+ tryNode: 'begin',
143
+ catchNode: 'rescue',
144
+ finallyNode: 'ensure',
145
+ returnNode: 'return',
146
+ breakNode: 'break',
147
+ continueNode: 'next',
148
+ blockNodes: new Set(['then', 'do', 'body_statement']),
149
+ functionNodes: new Set(['method', 'singleton_method']),
150
+ });
151
+
152
+ // ─── Dataflow ─────────────────────────────────────────────────────────────
153
+
154
+ export const dataflow = makeDataflowRules({
155
+ functionNodes: new Set(['method', 'singleton_method', 'lambda']),
156
+ paramListField: 'parameters',
157
+ returnNode: 'return',
158
+ varDeclaratorNode: null,
159
+ assignmentNode: 'assignment',
160
+ assignLeftField: 'left',
161
+ assignRightField: 'right',
162
+ callNode: 'call',
163
+ callFunctionField: 'method',
164
+ callArgsField: 'arguments',
165
+ spreadType: 'splat_parameter',
166
+ memberNode: 'call',
167
+ memberObjectField: 'receiver',
168
+ memberPropertyField: 'method',
169
+ mutatingMethods: new Set([
170
+ 'push',
171
+ 'pop',
172
+ 'shift',
173
+ 'unshift',
174
+ 'delete',
175
+ 'clear',
176
+ 'sort!',
177
+ 'reverse!',
178
+ 'map!',
179
+ 'select!',
180
+ 'reject!',
181
+ 'compact!',
182
+ 'flatten!',
183
+ 'concat',
184
+ 'replace',
185
+ 'insert',
186
+ ]),
187
+ extractParamName(node) {
188
+ if (node.type === 'identifier') return [node.text];
189
+ if (
190
+ node.type === 'optional_parameter' ||
191
+ node.type === 'keyword_parameter' ||
192
+ node.type === 'splat_parameter' ||
193
+ node.type === 'hash_splat_parameter'
194
+ ) {
195
+ const nameNode = node.childForFieldName('name');
196
+ return nameNode ? [nameNode.text] : null;
197
+ }
198
+ return null;
199
+ },
200
+ });
201
+
202
+ // ─── AST Node Types ───────────────────────────────────────────────────────
203
+
204
+ export const astTypes = null;