gitlab-ai-review 3.1.1 → 3.2.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.
- package/lib/impact-analyzer.js +91 -32
- package/lib/prompt-tools.js +62 -21
- package/package.json +2 -2
package/lib/impact-analyzer.js
CHANGED
|
@@ -59,13 +59,14 @@ export function extractImportsExports(content, fileName) {
|
|
|
59
59
|
* 从 diff 中提取变更的函数/类/组件名称
|
|
60
60
|
* @param {string} diff - diff 内容
|
|
61
61
|
* @param {string} fileName - 文件名
|
|
62
|
-
* @returns {Object} 变更的符号列表 { added: [], deleted: [], modified: [] }
|
|
62
|
+
* @returns {Object} 变更的符号列表 { added: [], deleted: [], modified: [], commented: [] }
|
|
63
63
|
*/
|
|
64
64
|
export function extractChangedSymbols(diff, fileName) {
|
|
65
|
-
if (!diff) return { added: [], deleted: [], modified: [] };
|
|
65
|
+
if (!diff) return { added: [], deleted: [], modified: [], commented: [] };
|
|
66
66
|
|
|
67
67
|
const addedSymbols = [];
|
|
68
68
|
const deletedSymbols = [];
|
|
69
|
+
const commentedSymbols = []; // 新增:被注释掉的符号
|
|
69
70
|
const lines = diff.split('\n');
|
|
70
71
|
|
|
71
72
|
// 匹配函数、类、常量定义
|
|
@@ -84,55 +85,113 @@ export function extractChangedSymbols(diff, fileName) {
|
|
|
84
85
|
if (isAddition || isDeletion) {
|
|
85
86
|
const cleanLine = line.substring(1); // 移除 +/- 前缀
|
|
86
87
|
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
// 检查是否是"注释掉代码"的情况
|
|
89
|
+
if (isAddition && isDeletion) {
|
|
90
|
+
// 这种情况不会发生在单行中
|
|
91
|
+
} else if (isAddition) {
|
|
92
|
+
// 检查新增的行是否是注释掉的代码
|
|
93
|
+
const trimmedLine = cleanLine.trim();
|
|
94
|
+
|
|
95
|
+
// 判断是否是注释行
|
|
96
|
+
const isComment = trimmedLine.startsWith('//') ||
|
|
97
|
+
trimmedLine.startsWith('/*') ||
|
|
98
|
+
trimmedLine.startsWith('*');
|
|
99
|
+
|
|
100
|
+
if (isComment) {
|
|
101
|
+
// 提取注释后的代码
|
|
102
|
+
const codeAfterComment = trimmedLine.replace(/^\/\/\s*/, '')
|
|
103
|
+
.replace(/^\/\*\s*/, '')
|
|
104
|
+
.replace(/^[\*\s]*/, '');
|
|
96
105
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
106
|
+
// 检查注释后的内容是否包含定义
|
|
107
|
+
definitionPatterns.forEach(pattern => {
|
|
108
|
+
const match = codeAfterComment.match(pattern);
|
|
109
|
+
if (match) {
|
|
110
|
+
commentedSymbols.push({
|
|
111
|
+
name: match[1],
|
|
112
|
+
type: 'commented',
|
|
113
|
+
line: index + 1,
|
|
114
|
+
originalCode: codeAfterComment,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
} else {
|
|
119
|
+
// 正常的新增代码
|
|
120
|
+
definitionPatterns.forEach(pattern => {
|
|
121
|
+
const match = cleanLine.match(pattern);
|
|
122
|
+
if (match) {
|
|
123
|
+
addedSymbols.push({
|
|
124
|
+
name: match[1],
|
|
125
|
+
type: 'definition',
|
|
126
|
+
line: index + 1,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
114
129
|
});
|
|
130
|
+
|
|
131
|
+
// 匹配函数调用
|
|
132
|
+
const callPattern = /(\w+)\s*\(/g;
|
|
133
|
+
let callMatch;
|
|
134
|
+
while ((callMatch = callPattern.exec(cleanLine)) !== null) {
|
|
135
|
+
addedSymbols.push({
|
|
136
|
+
name: callMatch[1],
|
|
137
|
+
type: 'usage',
|
|
138
|
+
line: index + 1,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
115
141
|
}
|
|
142
|
+
} else if (isDeletion) {
|
|
143
|
+
// 删除的代码
|
|
144
|
+
definitionPatterns.forEach(pattern => {
|
|
145
|
+
const match = cleanLine.match(pattern);
|
|
146
|
+
if (match) {
|
|
147
|
+
deletedSymbols.push({
|
|
148
|
+
name: match[1],
|
|
149
|
+
type: 'definition',
|
|
150
|
+
line: index + 1,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
});
|
|
116
154
|
}
|
|
117
155
|
}
|
|
118
156
|
});
|
|
119
157
|
|
|
120
|
-
//
|
|
158
|
+
// 检测"注释掉"的模式:删除了代码,然后添加了注释版本
|
|
159
|
+
// 对于每个被注释的符号,检查是否有对应的删除
|
|
160
|
+
const commentedAsDeleted = [];
|
|
161
|
+
commentedSymbols.forEach(commented => {
|
|
162
|
+
const wasDeleted = deletedSymbols.find(del => del.name === commented.name);
|
|
163
|
+
if (wasDeleted) {
|
|
164
|
+
// 这个符号被注释掉了(相当于删除)
|
|
165
|
+
commentedAsDeleted.push({
|
|
166
|
+
name: commented.name,
|
|
167
|
+
type: 'commented-out',
|
|
168
|
+
line: commented.line,
|
|
169
|
+
wasDeleted: true,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// 将"被注释掉"的符号也算作删除
|
|
175
|
+
const allDeleted = [...deletedSymbols, ...commentedAsDeleted];
|
|
176
|
+
|
|
177
|
+
// 找出被修改的符号(既被删除又被添加,但不是注释掉)
|
|
121
178
|
const modifiedSymbols = [];
|
|
122
179
|
const deletedNames = new Set(deletedSymbols.map(s => s.name));
|
|
123
180
|
const addedNames = new Set(addedSymbols.map(s => s.name));
|
|
181
|
+
const commentedNames = new Set(commentedAsDeleted.map(s => s.name));
|
|
124
182
|
|
|
125
183
|
deletedNames.forEach(name => {
|
|
126
|
-
if (addedNames.has(name)) {
|
|
184
|
+
if (addedNames.has(name) && !commentedNames.has(name)) {
|
|
127
185
|
modifiedSymbols.push({ name, type: 'modified' });
|
|
128
186
|
}
|
|
129
187
|
});
|
|
130
188
|
|
|
131
189
|
return {
|
|
132
190
|
added: addedSymbols,
|
|
133
|
-
deleted:
|
|
191
|
+
deleted: allDeleted, // 包含注释掉的符号
|
|
134
192
|
modified: modifiedSymbols,
|
|
135
|
-
|
|
193
|
+
commented: commentedAsDeleted, // 单独记录被注释掉的符号
|
|
194
|
+
all: [...addedSymbols, ...allDeleted], // 所有变更的符号
|
|
136
195
|
};
|
|
137
196
|
}
|
|
138
197
|
|
package/lib/prompt-tools.js
CHANGED
|
@@ -67,12 +67,24 @@ export function buildFileReviewPrompt(fileName, meaningfulChanges) {
|
|
|
67
67
|
prompt += `\`\`\`\n`;
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
-
prompt += `\n##
|
|
70
|
+
prompt += `\n## ⚠️ 重要说明:如何区分删除和新增
|
|
71
|
+
|
|
72
|
+
**请务必注意以下标记:**
|
|
73
|
+
- 标记为 **"类型: 删除"** 且代码以 **"-"** 开头的,是**被删除的代码**(不再存在)
|
|
74
|
+
- 标记为 **"类型: 新增"** 且代码以 **"+"** 开头的,是**新增的代码**(新添加的)
|
|
75
|
+
|
|
76
|
+
**特别注意:**
|
|
77
|
+
- 如果看到 **"类型: 删除"** 和 **"-"**,这意味着该代码已被移除,不存在了
|
|
78
|
+
- 不要把"删除"理解成"存在"或"新增"
|
|
79
|
+
- 删除的代码需要重点关注是否仍被其他地方使用
|
|
80
|
+
|
|
81
|
+
## 审查要求
|
|
71
82
|
|
|
72
83
|
1. 仔细审查每一行变更,判断是否存在问题
|
|
73
|
-
2.
|
|
74
|
-
3.
|
|
75
|
-
4.
|
|
84
|
+
2. **优先检查"类型: 删除"的代码**,确认是否有其他地方仍在使用
|
|
85
|
+
3. **只对有问题的行提出审查意见**,没有问题的行不需要评论
|
|
86
|
+
4. **必须使用中文**返回审查意见
|
|
87
|
+
5. 返回 JSON 格式的结果,格式如下:
|
|
76
88
|
|
|
77
89
|
\`\`\`json
|
|
78
90
|
{
|
|
@@ -90,9 +102,14 @@ export function buildFileReviewPrompt(fileName, meaningfulChanges) {
|
|
|
90
102
|
}
|
|
91
103
|
\`\`\`
|
|
92
104
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
105
|
+
6. 如果所有代码都没有问题,返回空的 reviews 数组:\`{"reviews": []}\`
|
|
106
|
+
7. 只返回 JSON,不要包含其他文字说明
|
|
107
|
+
8. comment 字段必须使用中文,要简洁明了
|
|
108
|
+
|
|
109
|
+
**再次强调:**
|
|
110
|
+
- 看到 "类型: 删除" 和 "-" → 代码被移除了
|
|
111
|
+
- 看到 "类型: 新增" 和 "+" → 代码是新加的
|
|
112
|
+
- 不要混淆删除和新增!`;
|
|
96
113
|
|
|
97
114
|
return prompt;
|
|
98
115
|
}
|
|
@@ -132,15 +149,18 @@ export function buildFileReviewWithImpactPrompt(fileName, meaningfulChanges, imp
|
|
|
132
149
|
|
|
133
150
|
// 变更的符号统计
|
|
134
151
|
if (impactAnalysis.changedSymbols) {
|
|
135
|
-
const { added, deleted, modified } = impactAnalysis.changedSymbols;
|
|
152
|
+
const { added, deleted, modified, commented } = impactAnalysis.changedSymbols;
|
|
136
153
|
|
|
137
|
-
if (added.length > 0 || deleted.length > 0 || modified.length > 0) {
|
|
154
|
+
if (added.length > 0 || deleted.length > 0 || modified.length > 0 || (commented && commented.length > 0)) {
|
|
138
155
|
prompt += `**符号变更统计**:\n`;
|
|
139
156
|
if (added.length > 0) {
|
|
140
157
|
prompt += `- 新增: ${added.length} 个\n`;
|
|
141
158
|
}
|
|
142
159
|
if (deleted.length > 0) {
|
|
143
|
-
prompt += `-
|
|
160
|
+
prompt += `- 删除/注释掉: ${deleted.length} 个 ⚠️\n`;
|
|
161
|
+
}
|
|
162
|
+
if (commented && commented.length > 0) {
|
|
163
|
+
prompt += ` (其中 ${commented.length} 个是被注释掉的代码)\n`;
|
|
144
164
|
}
|
|
145
165
|
if (modified.length > 0) {
|
|
146
166
|
prompt += `- 修改: ${modified.length} 个 ⚠️\n`;
|
|
@@ -150,11 +170,12 @@ export function buildFileReviewWithImpactPrompt(fileName, meaningfulChanges, imp
|
|
|
150
170
|
|
|
151
171
|
// 被删除的符号详情
|
|
152
172
|
if (deleted.length > 0) {
|
|
153
|
-
const deletedDefs = deleted.filter(s => s.type === 'definition');
|
|
173
|
+
const deletedDefs = deleted.filter(s => s.type === 'definition' || s.type === 'commented-out');
|
|
154
174
|
if (deletedDefs.length > 0) {
|
|
155
|
-
prompt += `**⚠️
|
|
175
|
+
prompt += `**⚠️ 被删除/注释掉的函数/类/组件** (${deletedDefs.length} 个):\n`;
|
|
156
176
|
deletedDefs.slice(0, 10).forEach(symbol => {
|
|
157
|
-
|
|
177
|
+
const status = symbol.type === 'commented-out' ? ' (注释掉)' : '';
|
|
178
|
+
prompt += `- \`${symbol.name}\`${status}\n`;
|
|
158
179
|
});
|
|
159
180
|
prompt += `\n`;
|
|
160
181
|
}
|
|
@@ -251,18 +272,33 @@ export function buildFileReviewWithImpactPrompt(fileName, meaningfulChanges, imp
|
|
|
251
272
|
prompt += `\`\`\`\n`;
|
|
252
273
|
});
|
|
253
274
|
|
|
254
|
-
prompt += `\n##
|
|
275
|
+
prompt += `\n## ⚠️ 重要说明:如何区分删除和新增
|
|
255
276
|
|
|
256
|
-
|
|
257
|
-
|
|
277
|
+
**请务必正确理解以下标记:**
|
|
278
|
+
1. **"类型: 删除"** + 代码以 **"-"** 开头 = **代码已被移除**(不存在了)
|
|
279
|
+
2. **"类型: 新增"** + 代码以 **"+"** 开头 = **代码是新加的**(新存在的)
|
|
280
|
+
|
|
281
|
+
**错误示例(请避免):**
|
|
282
|
+
❌ 看到 "类型: 删除" 却说"新增了XXX"
|
|
283
|
+
❌ 看到 "-" 号却理解为"添加了"
|
|
284
|
+
❌ 把删除当成存在
|
|
285
|
+
|
|
286
|
+
**正确理解:**
|
|
287
|
+
✅ "类型: 删除" → 这段代码被删掉了 → 需要检查是否还有地方在用
|
|
288
|
+
✅ "类型: 新增" → 这段代码是新加的 → 检查新代码的质量
|
|
289
|
+
|
|
290
|
+
## 审查要求
|
|
291
|
+
|
|
292
|
+
1. **首先确认变更类型**:看清楚是"删除"还是"新增"
|
|
293
|
+
2. **🚨 最高优先级**:检查"类型: 删除"的符号是否仍被使用(文件内部或其他文件)
|
|
258
294
|
3. **特别关注**:
|
|
259
|
-
-
|
|
295
|
+
- **删除的函数/类/组件**是否在其他地方被调用(这会导致错误)
|
|
260
296
|
- 修改的函数签名是否会导致现有调用失效
|
|
261
|
-
-
|
|
297
|
+
- 新增的代码质量是否符合规范
|
|
262
298
|
4. 检查函数签名是否改变,所有调用方式是否需要更新
|
|
263
299
|
5. 检查是否有潜在的 API 不兼容问题
|
|
264
|
-
6.
|
|
265
|
-
7.
|
|
300
|
+
6. 如果发现文件内部使用了**被删除**的符号,这是**严重错误**
|
|
301
|
+
7. 如果发现其他文件使用了**被删除/修改**的符号,需要提醒可能的影响
|
|
266
302
|
8. **只对有问题的行提出审查意见**,没有问题的行不需要评论
|
|
267
303
|
9. **必须使用中文**返回审查意见
|
|
268
304
|
10. 返回 JSON 格式的结果,格式如下:
|
|
@@ -302,7 +338,12 @@ export function buildFileReviewWithImpactPrompt(fileName, meaningfulChanges, imp
|
|
|
302
338
|
|
|
303
339
|
11. 如果所有代码都没有问题,返回空的 reviews 数组:\`{"reviews": []}\`
|
|
304
340
|
12. 只返回 JSON,不要包含其他文字说明
|
|
305
|
-
13. comment
|
|
341
|
+
13. comment 字段必须使用中文,要简洁明了,重点指出影响范围
|
|
342
|
+
|
|
343
|
+
**最后再次确认:**
|
|
344
|
+
- 看到 **"类型: 删除"** 和 **"-"** → 代码**被移除了**,需要检查影响
|
|
345
|
+
- 看到 **"类型: 新增"** 和 **"+"** → 代码**是新的**,检查代码质量
|
|
346
|
+
- **千万不要把删除理解成新增!**`;
|
|
306
347
|
|
|
307
348
|
return prompt;
|
|
308
349
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gitlab-ai-review",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "GitLab AI Review SDK with Impact Analysis -
|
|
3
|
+
"version": "3.2.1",
|
|
4
|
+
"description": "GitLab AI Review SDK with Impact Analysis - 支持影响分析、删除符号检测、注释代码识别、文件内部冲突检查、智能文件过滤的智能代码审查工具",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|