Skip to content

Commit e0dc22a

Browse files
authored
Merge pull request #6081 from ethereum/accept-reject
Accept reject
2 parents 4ccf3fb + 4f726a2 commit e0dc22a

File tree

5 files changed

+552
-77
lines changed

5 files changed

+552
-77
lines changed

apps/remix-ide/src/app/tabs/locales/en/editor.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"editor.formatCode": "Format Code",
2222
"editor.generateDocumentation": "Generate documentation for this function",
2323
"editor.generateDocumentation2": "Generate documentation for the function \"{name}\"",
24-
"editor.generateDocumentationByAI": "```solidity\n {content}\n```\n You only generate the natspec documentation for the function {currentFunction} using the docstring style syntax. Only use docstring supported tags",
24+
"editor.generateDocumentationByAI": "```solidity\n {content}\n```\n Generate or improve the natspec documentation for the function {currentFunction} using the supported docstring style syntax and tags. Only return the comments and the function declaration, no other text.",
2525
"editor.explainFunction": "Explain this function",
2626
"editor.explainFunctionSol": "Explain this code",
2727
"editor.explainFunction2": "Explain the function \"{name}\"",

libs/remix-ui/editor/src/lib/actions/editor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export const reducerActions = (models = initialState, action: Action) => {
3838
const model = models[uri]?.model
3939
if (model) model.dispose()
4040
delete models[uri]
41-
return models
41+
return { ...models }
4242
}
4343
case 'ADD_DIFF': {
4444
if (!editors) return models

libs/remix-ui/editor/src/lib/helpers/retrieveNodesAtPosition.ts

Lines changed: 165 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,168 @@ export const retrieveNodesAtPosition = async (positionOffset: number, plugin: Pl
1111
}
1212
}
1313
return { nodesAtPosition, block }
14-
}
14+
}
15+
16+
export const extractFunctionComments = (code: string, indentSize: number = 0, isSolidity: boolean = false) => {
17+
// Different patterns for Solidity vs non-Solidity functions
18+
const functionPattern = isSolidity
19+
? /(?:function\s+(\w+)|constructor)\s*(?:\([^)]*\))?\s*(?:public|private|internal|external)?\s*(?:view|pure|payable)?\s*(?:returns\s*\([^)]*\))?\s*(?:is\w+)?\s*{/g
20+
: /(?:function\s+(\w+)|constructor|(\w+)\s*\([^)]*\)\s*(?::\s*\w+(?:<[^>]+>)?)?\s*{)/g
21+
22+
const functionPositions = new Map<string, { position: number, commentStart?: number, singleLineComments?: string[] }>()
23+
let functionMatch
24+
25+
// First pass: find all function positions
26+
while ((functionMatch = functionPattern.exec(code)) !== null) {
27+
const functionName = functionMatch[1] || functionMatch[2] || 'constructor'
28+
functionPositions.set(functionName, { position: functionMatch.index })
29+
}
30+
31+
// Initialize functionComments with null for all functions
32+
const functionComments = {}
33+
for (const [functionName] of functionPositions) {
34+
functionComments[functionName] = null
35+
}
36+
37+
const multiLineCommentPattern = /\/\*\*[\s\S]*?\*\//g
38+
let commentMatch
39+
40+
while ((commentMatch = multiLineCommentPattern.exec(code)) !== null) {
41+
const commentStart = commentMatch.index
42+
const commentEnd = commentStart + commentMatch[0].length
43+
let nextFunction = null
44+
let minDistance = Infinity
45+
46+
for (const [funcName, funcInfo] of functionPositions) {
47+
if (funcInfo.position > commentEnd && funcInfo.position - commentEnd < minDistance) {
48+
minDistance = funcInfo.position - commentEnd
49+
nextFunction = funcName
50+
}
51+
}
52+
53+
if (nextFunction && minDistance < Infinity) {
54+
const betweenCommentAndFunction = code.slice(commentEnd, functionPositions.get(nextFunction).position)
55+
const hasOtherFunction = betweenCommentAndFunction.match(functionPattern)
56+
57+
if (!hasOtherFunction) {
58+
functionPositions.get(nextFunction).commentStart = commentStart
59+
}
60+
}
61+
}
62+
63+
for (const [functionName, funcInfo] of functionPositions) {
64+
const functionStart = funcInfo.position
65+
const functionStartLine = code.slice(0, functionStart).split('\n').length
66+
const singleLineComments = []
67+
68+
let currentLine = functionStartLine - 1
69+
while (currentLine > 0) {
70+
const lineStart = code.split('\n').slice(0, currentLine - 1).join('\n').length + (currentLine > 1 ? 1 : 0)
71+
const lineEnd = code.split('\n').slice(0, currentLine).join('\n').length
72+
const line = code.slice(lineStart, lineEnd).trim()
73+
if (line.startsWith('//')) {
74+
singleLineComments.unshift(line.slice(2).trim())
75+
currentLine--
76+
} else if (line === '') {
77+
currentLine--
78+
} else {
79+
break
80+
}
81+
}
82+
if (singleLineComments.length > 0) {
83+
funcInfo.singleLineComments = singleLineComments
84+
}
85+
}
86+
87+
for (const [functionName, funcInfo] of functionPositions) {
88+
let processedComment = null
89+
90+
if (funcInfo.commentStart !== undefined) {
91+
const comment = code.slice(funcInfo.commentStart, funcInfo.position).trim()
92+
93+
if (isSolidity) {
94+
const betweenCommentAndFunction = code.slice(funcInfo.commentStart + comment.length, funcInfo.position)
95+
const contractKeywordPos = betweenCommentAndFunction.indexOf('contract')
96+
97+
if (contractKeywordPos === -1) {
98+
const contractCommentPattern = /\/\*\*[\s\S]*?\*\/\s*contract\s+\w+/g
99+
processedComment = comment
100+
.replace(contractCommentPattern, '')
101+
.trim()
102+
if (!processedComment.startsWith('/**')) {
103+
processedComment = '/**' + processedComment
104+
}
105+
if (!processedComment.endsWith('*/')) {
106+
processedComment = processedComment + '*/'
107+
}
108+
109+
processedComment = processedComment.split('\n')
110+
.filter(line => {
111+
const trimmed = line.trim()
112+
return trimmed.startsWith('*') || trimmed === '/*' || trimmed === '*/' || trimmed === '/**'
113+
})
114+
.join('\n')
115+
.trim()
116+
117+
if (indentSize > 0) {
118+
processedComment = applyIndentation(processedComment, indentSize)
119+
}
120+
121+
if (!processedComment.includes('@dev') && !processedComment.includes('@param') && !processedComment.includes('@return')) {
122+
processedComment = null
123+
}
124+
}
125+
} else {
126+
processedComment = comment.trim()
127+
if (!processedComment.startsWith('/**')) {
128+
processedComment = '/**' + processedComment
129+
}
130+
if (!processedComment.endsWith('*/')) {
131+
processedComment = processedComment + '*/'
132+
}
133+
processedComment = processedComment.split('\n')
134+
.filter(line => {
135+
const trimmed = line.trim()
136+
return trimmed.startsWith('*') || trimmed === '/*' || trimmed === '*/' || trimmed === '/**'
137+
})
138+
.join('\n')
139+
.trim()
140+
141+
if (indentSize > 0) {
142+
processedComment = applyIndentation(processedComment, indentSize)
143+
}
144+
}
145+
}
146+
147+
if (!processedComment && funcInfo.singleLineComments && funcInfo.singleLineComments.length > 0) {
148+
if (isSolidity) {
149+
processedComment = '/**\n * @dev ' + funcInfo.singleLineComments.join('\n * ') + '\n */'
150+
} else {
151+
processedComment = '/**\n * ' + funcInfo.singleLineComments.join('\n * ') + '\n */'
152+
}
153+
if (indentSize > 0) {
154+
processedComment = applyIndentation(processedComment, indentSize)
155+
}
156+
}
157+
158+
functionComments[functionName] = processedComment
159+
}
160+
161+
return functionComments
162+
}
163+
164+
// Helper function to apply indentation to comments
165+
const applyIndentation = (comment: string, indentSize: number): string => {
166+
const indent = '\t'.repeat(indentSize)
167+
return comment.split('\n').map(line => {
168+
if (line.trim() === '') return line
169+
if (line.trim() === '*/' || line.trim() === '/*') {
170+
return indent + line.trim()
171+
}
172+
if (line.trim().startsWith('*')) {
173+
const content = line.trim().slice(1).trim()
174+
return indent + '* ' + content
175+
}
176+
return indent + line
177+
}).join('\n')
178+
}

libs/remix-ui/editor/src/lib/remix-ui-editor.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,18 @@
2929

3030
div.monaco-list-row > span.title {
3131
margin-top: 12px;
32+
}
33+
34+
.modifiedChangesDecoration {
35+
background-color: var(--danger) !important;
36+
color: var(--white) !important;
37+
filter: opacity(0.1);
38+
font-weight: bolder;
39+
}
40+
41+
.newChangesDecoration {
42+
background-color: var(--ai) !important;
43+
color: var(--white) !important;
44+
filter: opacity(0.1);
45+
font-weight: bolder;
3246
}

0 commit comments

Comments
 (0)