Skip to content

Commit 1258de5

Browse files
authored
Merge pull request #214 from richzwart/master
Fix auto-instantiation failing on extra parentheses
2 parents 9d80c02 + 1271df3 commit 1258de5

File tree

5 files changed

+182
-23
lines changed

5 files changed

+182
-23
lines changed

src/providers/ModuleInstantiator.ts

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ function cleanUpContainer(container: string): string {
285285
container = container.replace(/=/g, ' = ');
286286
container = container.replace(/\(/g, ' ( ');
287287
container = container.replace(/\)/g, ' ) ');
288+
container = container.replace(/\[/g, ' [ ');
289+
container = container.replace(/\]/g, ' ] ');
288290
container = container.replace(/\/\//g, ' // ');
289291
container = container.replace(/\/\*/g, ' /* ');
290292

@@ -326,7 +328,7 @@ function findMaxLength(container: string, moduleIsParameterized: boolean): numbe
326328
let lastPort: string = undefined; // eslint-disable-line no-undef-init
327329
let lastParameter: string = undefined; // eslint-disable-line no-undef-init
328330
let passedEqualSign = false;
329-
331+
let numBracketPast = 0;
330332
let state = ProcessingState.INITIAL;
331333

332334
for (let i = 0; i < keys.length; i++) {
@@ -351,7 +353,13 @@ function findMaxLength(container: string, moduleIsParameterized: boolean): numbe
351353
}
352354
} else if (state === ProcessingState.PARAMETERS) {
353355
if (keys[i] === ')') {
354-
state = ProcessingState.PORTS;
356+
if (numBracketPast === 0) {
357+
state = ProcessingState.PORTS;
358+
} else {
359+
numBracketPast -= 1;
360+
}
361+
} else if (keys[i] === '(') {
362+
numBracketPast += 1;
355363
} else if (keys[i] === ',' && lastParameter) {
356364
maxLength = Math.max(lastParameter.length, maxLength);
357365
lastParameter = undefined;
@@ -369,13 +377,19 @@ function findMaxLength(container: string, moduleIsParameterized: boolean): numbe
369377
lastParameter = undefined;
370378
}
371379

372-
if (keys[i] === ')') {
380+
if (keys[i] === ')' && numBracketPast == 0) {
373381
state = ProcessingState.COMPLETE;
374382
} else if (keys[i] === ',' && lastPort) {
375383
maxLength = Math.max(lastPort.length, maxLength);
376384
lastPort = undefined;
385+
} else if (keys[i] === '[') {
386+
numBracketPast += 1;
387+
} else if (keys[i] === ']') {
388+
numBracketPast -= 1;
377389
} else if (!isPortSymbol(keys[i]) && !isEmptyKey(keys[i])) {
378-
lastPort = keys[i].trim();
390+
if (numBracketPast == 0) {
391+
lastPort = keys[i].trim();
392+
}
379393
}
380394
}
381395

@@ -416,14 +430,16 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
416430
}
417431

418432
const output = [];
433+
419434
const keys = container.split(' ');
420435

421436
// This is a bit funky, but the for loop below actually checks if these varaibles
422437
// are undefined so it is important that they are initialized as such
423438
let lastPort: string = undefined; // eslint-disable-line no-undef-init
424439
let lastParameter: string = undefined; // eslint-disable-line no-undef-init
425-
let lastParameterDefault: string = undefined; // eslint-disable-line no-undef-init
440+
let parameterDefault = [];
426441

442+
let numBracketPast = 0;
427443
let passedEqualSign = false;
428444

429445
let state = ProcessingState.INITIAL;
@@ -450,14 +466,19 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
450466
}
451467
} else if (state === ProcessingState.PARAMETERS) {
452468
if (keys[i] === ')') {
453-
state = ProcessingState.PORTS;
469+
if (numBracketPast === 0) {
470+
state = ProcessingState.PORTS;
471+
} else {
472+
numBracketPast -= 1;
473+
parameterDefault.push(keys[i].trim());
474+
}
454475
} else if (keys[i] === ',' && lastParameter) {
455476
// Set with default value if it exists
456477
if (passedEqualSign) {
457478
output.push(
458479
`${padding}.${lastParameter}${' '.repeat(maxLength - lastParameter.length)}${' '.repeat(4)}(`
459480
);
460-
output.push(`${lastParameterDefault})`);
481+
output.push(`${parameterDefault.join('')})`); // This will butcher default values for strings with spaces included, sorry.
461482

462483
passedEqualSign = false;
463484
} else {
@@ -472,9 +493,13 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
472493
lastParameter = undefined;
473494
} else if (keys[i] === '=') {
474495
passedEqualSign = true;
496+
parameterDefault = [];
475497
} else if (!isParameterSymbol(keys[i]) && !isEmptyKey(keys[i])) {
476498
if (passedEqualSign) {
477-
lastParameterDefault = keys[i].trim();
499+
if (keys[i] === '(') {
500+
numBracketPast += 1;
501+
}
502+
parameterDefault.push(keys[i].trim());
478503
} else {
479504
lastParameter = keys[i].trim();
480505
}
@@ -486,7 +511,7 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
486511
output.push(
487512
`${padding}.${lastParameter}${' '.repeat(maxLength - lastParameter.length)}${' '.repeat(4)}(`
488513
);
489-
output.push(`${lastParameterDefault})\n`);
514+
output.push(`${parameterDefault.join('')})\n`);
490515

491516
passedEqualSign = false;
492517
} else {
@@ -500,7 +525,7 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
500525
lastParameter = undefined;
501526
}
502527

503-
if (keys[i] === ')') {
528+
if (keys[i] === ')' && numBracketPast == 0) {
504529
state = ProcessingState.COMPLETE;
505530
} else if (keys[i] === ',' && lastPort) {
506531
output.push(
@@ -510,7 +535,13 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
510535

511536
lastPort = undefined;
512537
} else if (!isPortSymbol(keys[i]) && !isEmptyKey(keys[i])) {
513-
lastPort = keys[i].trim();
538+
if (keys[i] === '[') {
539+
numBracketPast += 1;
540+
} else if (keys[i] === ']') {
541+
numBracketPast -= 1;
542+
} else if (numBracketPast == 0) {
543+
lastPort = keys[i].trim();
544+
}
514545
}
515546
}
516547

@@ -522,7 +553,7 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
522553
output.push(
523554
`${padding}.${lastParameter}${' '.repeat(maxLength - lastParameter.length)}${' '.repeat(4)}(`
524555
);
525-
output.push(`${lastParameterDefault})\n`);
556+
output.push(`${parameterDefault.join('')})\n`);
526557

527558
passedEqualSign = false;
528559
} else {

src/test/ModuleInstantiator.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,46 @@ suite('ModuleInstantiator Tests', () => {
199199

200200
compareInstantiation('golden', container, instance);
201201
});
202+
203+
test('test #8: formatInstance with unpacked dimensions and brackets in ports', async () => {
204+
let uri = vscode.Uri.file(path.join(__dirname, testFolderLocation, 'test-files', 'ModuleInstantiator.test.1.v')); // prettier-ignore
205+
let document = await vscode.workspace.openTextDocument(uri);
206+
207+
let fullRange = null;
208+
// Range of the module in the document
209+
fullRange = new vscode.Range(new vscode.Position(300, 6), new vscode.Position(324, 0));
210+
211+
let container = document.getText(fullRange).replace(/^\s+|\s+$/g, '');
212+
213+
uri = vscode.Uri.file(path.join(__dirname, testFolderLocation, 'test-files', 'ModuleInstantiator.test.2.v'));
214+
document = await vscode.workspace.openTextDocument(uri);
215+
216+
fullRange = new vscode.Range(new vscode.Position(137, 0), new vscode.Position(146, 0));
217+
218+
let instance = document.getText(fullRange);
219+
220+
compareInstantiation('arrer', container, instance);
221+
});
222+
223+
test('test #9: formatInstance with brackets in parameter default value', async () => {
224+
let uri = vscode.Uri.file(path.join(__dirname, testFolderLocation, 'test-files', 'ModuleInstantiator.test.1.v')); // prettier-ignore
225+
let document = await vscode.workspace.openTextDocument(uri);
226+
227+
let fullRange = null;
228+
// Range of the module in the document
229+
fullRange = new vscode.Range(new vscode.Position(329, 6), new vscode.Position(354, 0));
230+
231+
let container = document.getText(fullRange).replace(/^\s+|\s+$/g, '');
232+
233+
uri = vscode.Uri.file(path.join(__dirname, testFolderLocation, 'test-files', 'ModuleInstantiator.test.2.v'));
234+
document = await vscode.workspace.openTextDocument(uri);
235+
236+
fullRange = new vscode.Range(new vscode.Position(151, 0), new vscode.Position(163, 0));
237+
238+
let instance = document.getText(fullRange);
239+
240+
compareInstantiation('azzer', container, instance);
241+
});
202242
});
203243

204244
function compareInstantiation(instance_name, container_name, expected): void {

src/test/indexer_map.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ suite('indexer_map Tests', () => {
3131
assert.strictEqual(symbols.size, 4);
3232
let count = await indexer.addDocumentSymbols(sVDocument, symbols);
3333

34-
assert.strictEqual(count, 8);
34+
assert.strictEqual(count, 10);
3535
assert.strictEqual(symbols.size, 5);
36-
assert.strictEqual(symbols.get(uri.fsPath).length, 8);
37-
assert.strictEqual(getSymbolsCount(), 21);
36+
assert.strictEqual(symbols.get(uri.fsPath).length, 10);
37+
assert.strictEqual(getSymbolsCount(), 23);
3838

3939
documentSymbols.forEach((symbolName) => {
4040
if (!symbolExists(symbolName)) {
@@ -47,28 +47,28 @@ suite('indexer_map Tests', () => {
4747
assert.strictEqual(count, 0);
4848
assert.strictEqual(symbols.size, 5);
4949
assert.strictEqual(symbols.get(nonSVUri.fsPath), undefined);
50-
assert.strictEqual(getSymbolsCount(), 21);
50+
assert.strictEqual(getSymbolsCount(), 23);
5151

5252
// undefined/null document
5353
count = await indexer.addDocumentSymbols(undefined, symbols);
5454
assert.strictEqual(count, 0);
5555
assert.strictEqual(symbols.size, 5);
56-
assert.strictEqual(getSymbolsCount(), 21);
56+
assert.strictEqual(getSymbolsCount(), 23);
5757

5858
count = await indexer.addDocumentSymbols(sVDocument, undefined);
5959
assert.strictEqual(count, 0);
6060
assert.strictEqual(symbols.size, 5);
61-
assert.strictEqual(getSymbolsCount(), 21);
61+
assert.strictEqual(getSymbolsCount(), 23);
6262

6363
count = await indexer.addDocumentSymbols(undefined, undefined);
6464
assert.strictEqual(count, 0);
6565
assert.strictEqual(symbols.size, 5);
66-
assert.strictEqual(getSymbolsCount(), 21);
66+
assert.strictEqual(getSymbolsCount(), 23);
6767

6868
count = await indexer.addDocumentSymbols(null, symbols);
6969
assert.strictEqual(count, 0);
7070
assert.strictEqual(symbols.size, 5);
71-
assert.strictEqual(getSymbolsCount(), 21);
71+
assert.strictEqual(getSymbolsCount(), 23);
7272
});
7373

7474
test('test #2: removeDocumentSymbols', async () => {
@@ -80,9 +80,9 @@ suite('indexer_map Tests', () => {
8080
assert.strictEqual(symbols.size, 4);
8181
let count = await indexer.addDocumentSymbols(sVDocument, symbols);
8282

83-
assert.strictEqual(count, 8);
83+
assert.strictEqual(count, 10);
8484
assert.strictEqual(symbols.size, 5);
85-
assert.strictEqual(getSymbolsCount(), 21);
85+
assert.strictEqual(getSymbolsCount(), 23);
8686

8787
count = indexer.removeDocumentSymbols(sVDocument.uri.fsPath, symbols);
8888

@@ -92,7 +92,7 @@ suite('indexer_map Tests', () => {
9292
}
9393
});
9494

95-
assert.strictEqual(count, -8);
95+
assert.strictEqual(count, -10);
9696
assert.strictEqual(symbols.size, 4);
9797
assert.strictEqual(getSymbolsCount(), 13);
9898

src/test/test-files/ModuleInstantiator.test.1.v

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,61 @@ module golden(
293293
assign c = tmp_c;
294294

295295
endmodule
296+
297+
298+
// ---------------------------------------------------------------
299+
// -- Example of ports with unpacked dimensions and brackets
300+
// ---------------------------------------------------------------
301+
302+
module arrer (
303+
input clk,
304+
input reset,
305+
input [(2+2)-1:0] a [2:0],
306+
input [3:0] b [(3-1):0] ,
307+
input valid,
308+
output [6:0] c
309+
);
310+
311+
input clk;
312+
input reset;
313+
input [3:0] a;
314+
// keep this single comment
315+
input [3:0] b;
316+
/* multiline comment should
317+
be kept*/
318+
input valid;
319+
output [6:0] c;
320+
321+
reg [6:0] tmp_c;
322+
assign c = tmp_c;
323+
324+
endmodule
325+
326+
// ---------------------------------------------------------------
327+
// -- Example of parameters with brackets
328+
// ---------------------------------------------------------------
329+
330+
module azzer #(parameter SIZE = (2*1)+1,
331+
parameter SIZE_TWO = 2*(1+1)) (
332+
input clk,
333+
input reset,
334+
input [3:0] a,
335+
input [3:0] b,
336+
input valid,
337+
output [6:0] c
338+
);
339+
340+
input clk;
341+
input reset;
342+
input [3:0] a;
343+
// keep this single comment
344+
input [3:0] b;
345+
/* multiline comment should
346+
be kept*/
347+
input valid;
348+
output [6:0] c;
349+
350+
reg [6:0] tmp_c;
351+
assign c = tmp_c;
352+
353+
endmodule

src/test/test-files/ModuleInstantiator.test.2.v

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,36 @@ golden u_golden (
132132
.c (c)
133133
);
134134

135+
// ---------------------------------------------------------------
136+
// -- Example of ports with unpacked dimensions and brackets
137+
// ---------------------------------------------------------------
138+
139+
arrer u_arrer (
140+
.clk (clk),
141+
.reset (reset),
142+
.a (a),
143+
.b (b),
144+
.valid (valid),
145+
.c (c)
146+
);
147+
148+
149+
// ---------------------------------------------------------------
150+
// -- Example of parameters with brackets
151+
// ---------------------------------------------------------------
152+
153+
azzer #(
154+
.SIZE ((2*1)+1),
155+
.SIZE_TWO (2*(1+1))
156+
) u_azzer (
157+
.clk (clk),
158+
.reset (reset),
159+
.a (a),
160+
.b (b),
161+
.valid (valid),
162+
.c (c)
163+
);
164+
135165
// -------------------------------------------------------
136166
// -- End file
137167
// -------------------------------------------------------

0 commit comments

Comments
 (0)