Skip to content

Commit 5a15ced

Browse files
committed
first version commit for Solidity changes
1 parent c0139b2 commit 5a15ced

13 files changed

+1094
-364
lines changed

.vscode/tasks.json

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,34 @@
88

99
// A task runner that calls a custom npm script that compiles the extension.
1010
{
11-
"version": "0.1.0",
11+
"version": "2.0.0",
1212

1313
// we want to run npm
1414
"command": "npm",
1515

16-
// the command is a shell script
17-
"isShellCommand": true,
18-
19-
// show the output window only if unrecognized errors occur.
20-
"showOutput": "silent",
21-
2216
// we run the custom script "compile" as defined in package.json
2317
"args": ["run", "compile"],
2418

25-
// The tsc compiler is started in watching mode
26-
"isWatching": true,
19+
// The tsc compiler is started in background mode
20+
"isBackground": true,
2721

2822
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
29-
"problemMatcher": "$tsc-watch"
30-
}
23+
"problemMatcher": "$tsc-watch",
24+
"tasks": [
25+
{
26+
"label": "npm",
27+
"type": "shell",
28+
"command": "npm",
29+
"args": [
30+
"run",
31+
"compile"
32+
],
33+
"isBackground": true,
34+
"problemMatcher": "$tsc-watch",
35+
"group": {
36+
"_id": "build",
37+
"isDefault": false
38+
}
39+
}
40+
]
41+
}

README.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
# vscode-comment
2-
Adds simple jsdoc comments for the parameters of a selected function signature
1+
# VS Code Solidity Comments extension
2+
Adds NatSpec compliant @notice, @dev, @param and @return tags for function and modifier signatures in Solidity files.
33

4-
## Using
5-
In a typescript or javascript file, select a function signature, ideally one that contains one or more parameters. Select the whole function signature then invoke the Add Doc Comments extension (open the command palette (F1 on Windows) and look for the command 'Add doc comments'. Hit enter.)
6-
7-
![install and work](images/addDocComments.gif)
4+
## Installation
5+
Currently, the solidity-comments VS Code extension is installed from a VSIX file only.
86

7+
Go to `Extensions` tab and click the `...` at the top.
98

10-
The extension will parse the selected signature and add @param and @return tags for each parameter and any return type in the selected signature, directly above the signature.
9+
Select `Install from VSIX`.
1110

12-
## Limitations
13-
The extension does not support any other type of jsdoc tags. It only calculates @param and @return
11+
## Using
12+
In a Solidity file, move the cursor to a line with a function or modifier signature.
1413

15-
Parameter types are not inferred based on usage. If a type is not specified, empty braces {} are returned.
14+
Invoke the `Add Solidity Comments` extension
15+
- Open the command palette wit `F1` or `ctrl+shift+p` on Windows and find `Add Solidity Comments`. Hit enter.
16+
- Alternatively, you can use the keybindings `ctrl+alt+d` on Windows and `shift+cmd+d` on Mac.
1617

17-
## Other extensions
18-
[Document This](https://marketplace.visualstudio.com/items?itemName=joelday.docthis) provides the same functionality but supports many more tags
18+
The extension will parse the signature on the line of the cursor. A stub with @notice, @dev, @param and @return tags for each parameter and return variables will be added directly above the line.
1919

20-
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
20+
## Limitations
21+
The extension does not support any other type of NatSpec tags. It only uses @notice, @dev, @param and @return

argParser.ts

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
2+
export class paramDef {
3+
constructor(public paramName: string, public paramType: string) {
4+
this.paramName = paramName;
5+
this.paramType = paramType;
6+
}
7+
}
8+
9+
export function getParameterText(functionParams: paramDef[], returnParams: paramDef[]): string {
10+
var textToInsert: string = "";
11+
textToInsert = textToInsert + '/**\n * @notice .\n * @dev .\n';
12+
functionParams.forEach(element => {
13+
if (element.paramName != '') {
14+
textToInsert = textToInsert + ' * @param ';
15+
// textToInsert = textToInsert + '{' + element.paramType + '}' + ' '; // for type insertion
16+
textToInsert = textToInsert + element.paramName + ' .' + '\n';
17+
}
18+
});
19+
returnParams.forEach(element => {
20+
if (element.paramType != '') {
21+
textToInsert = textToInsert + ' * @return ';
22+
// textToInsert = textToInsert + '{' + element.paramType + '}' + ' '; // for type insertion
23+
if (element.paramName != '') {
24+
textToInsert = textToInsert + element.paramName + ' .' + '\n';
25+
} else {
26+
// textToInsert = textToInsert + 'UNNAMED' + '\n'; // for type insertion
27+
textToInsert = textToInsert + element.paramType + ' .' + '\n';
28+
}
29+
}
30+
});
31+
textToInsert = textToInsert + ' */';
32+
return textToInsert;
33+
}
34+
35+
// split a given line by a keyword
36+
// for Solidity keyword is expected to be used with 'returns'
37+
// everything before 'returns' will be used to build lines[0] for function parameters
38+
// everything after 'returns' will be used to build lines[1] for the return parameters
39+
export function splitTextByKeyword(text: string, keyword: string): string[] {
40+
const result = text.trim().split(/\s+/);
41+
const index = result.indexOf("{", 0);
42+
if (index > -1) {
43+
result.splice(index, 1);
44+
}
45+
let lines: string[] = [];
46+
const rPos = result.indexOf(keyword);
47+
if (rPos != -1) {
48+
lines[0] = result.slice(0, rPos).join(" ");
49+
lines[1] = result.slice(rPos + 1, result.length).join(" ");
50+
} else {
51+
lines[0] = result.slice(0, result.length).join(" ");
52+
lines[1] = "";
53+
}
54+
return lines;
55+
}
56+
57+
//Assumes that the string passed in starts with ( and continues to ) and does not contain any comments
58+
export function getFunctionParams(text: string): paramDef[] {
59+
var params: paramDef[] = [];
60+
//Start by looking for the function name declaration
61+
var index = 0;
62+
text = text.trim(); // delete the leading and trailing spaces
63+
//if there is no '(' then this is not a valid function declaration
64+
if (text.charAt(index) == '(') {
65+
//count the number of matching opening and closing braces. Keep parsing until 0
66+
var numBraces = 1;
67+
index++;
68+
while ((numBraces != 0) && (index != text.length)) {
69+
var name_type: string = '';
70+
while ((text.charAt(index) != ',') && (text.charAt(index) != ')') && (index < text.length)) {
71+
name_type = name_type + text.charAt(index);
72+
index++;
73+
}
74+
if (text.charAt(index) == ')') {
75+
numBraces--;
76+
}
77+
name_type = name_type.trim() // trim leading and trailing whitespace
78+
let parts = name_type.split(" "); // spitting a returns element (bool b, uint256 u, ...)
79+
let idx = parts.indexOf("memory", 0); // remove memory from parts
80+
if (idx > -1) {
81+
parts.splice(idx, 1);
82+
}
83+
idx = parts.indexOf("calldata", 0); // remove calldata from parts
84+
if (idx > -1) {
85+
parts.splice(idx, 1);
86+
}
87+
idx = parts.indexOf("storage", 0); // remove storage from parts
88+
if (idx > -1) {
89+
parts.splice(idx, 1);
90+
}
91+
if (parts.length == 1) {
92+
params.push(new paramDef("", ""));
93+
} else if (parts.length == 2) {
94+
params.push(new paramDef(parts[1], parts[0]));
95+
} else {
96+
const errorMessage = "Arguments are malformed in the selected code";
97+
throw new Error(errorMessage);
98+
}
99+
if (index < text.length) {
100+
index++;
101+
while (text.charAt(index) == ' ') index++; // consume whitespace
102+
}
103+
}
104+
}
105+
return params;
106+
}
107+
108+
//Assumes that the string passed in starts with ( and continues to ) and does not contain any comments
109+
export function getReturnParams(text: string): paramDef[] {
110+
var params: paramDef[] = [];
111+
//Start by looking for the function name declaration
112+
var index = 0;
113+
text = text.trim(); // delete the leading and trailing spaces
114+
//if there is no '(' then this is not a valid function declaration
115+
if (text.charAt(index) == '(') {
116+
//count the number of matching opening and closing braces. Keep parsing until 0
117+
var numBraces = 1;
118+
index++;
119+
while ((numBraces != 0) && (index != text.length)) {
120+
var name_type: string = '';
121+
while ((text.charAt(index) != ',') && (text.charAt(index) != ')') && (index < text.length)) {
122+
name_type = name_type + text.charAt(index);
123+
index++;
124+
}
125+
if (text.charAt(index) == ')') {
126+
numBraces--;
127+
}
128+
name_type = name_type.trim() // trim leading and trailing whitespace
129+
const parts = name_type.split(" "); // spitting a returns element (bool b, uint256 u, ...) or (bool, uint256, ...)
130+
let idx = parts.indexOf("memory", 0); // remove memory from parts
131+
if (idx > -1) {
132+
parts.splice(idx, 1);
133+
}
134+
idx = parts.indexOf("calldata", 0); // remove calldata from parts
135+
if (idx > -1) {
136+
parts.splice(idx, 1);
137+
}
138+
idx = parts.indexOf("storage", 0); // remove storage from parts
139+
if (idx > -1) {
140+
parts.splice(idx, 1);
141+
}
142+
if (parts.length == 0) {
143+
params.push(new paramDef("", ""));
144+
} else if (parts.length == 2) {
145+
params.push(new paramDef(parts[1], parts[0]));
146+
} else if (parts.length == 1) {
147+
params.push(new paramDef("", parts[0]));
148+
} else {
149+
const errorMessage = "Elements of returns are malformed in the selected code";
150+
throw new Error(errorMessage);
151+
}
152+
if (index < text.length) {
153+
index++;
154+
while (text.charAt(index) == ' ') index++; // consume whitespace
155+
}
156+
}
157+
}
158+
return params;
159+
}
160+
161+
export function stripComments(text: string): string {
162+
var uncommentedText: string = '';
163+
var index = 0;
164+
while (index != text.length) {
165+
if ((text.charAt(index) == '/') && (text.charAt(index + 1) == '*')) {
166+
//parse comment
167+
if ((index + 2) != text.length) { //Check for the corner case that the selected text contains a /* right at the end
168+
index = index + 2;
169+
while ((text.charAt(index) != '*') && (text.charAt(index + 1) != '/')) {
170+
index++;
171+
}
172+
}
173+
index = index + 2;
174+
}
175+
else if ((text.charAt(index) == '/') && (text.charAt(index + 1) == '/')) {
176+
//read to end of line
177+
while ((text.charAt(index) != '\n') && (index < text.length)) {
178+
index++;
179+
}
180+
}
181+
else {
182+
uncommentedText = uncommentedText + text.charAt(index);
183+
index++;
184+
}
185+
}
186+
return uncommentedText;
187+
}
26.3 KB
Binary file not shown.

0 commit comments

Comments
 (0)