Skip to content

Commit

Permalink
Merge pull request #214 from richzwart/master
Browse files Browse the repository at this point in the history
Fix auto-instantiation failing on extra parentheses
  • Loading branch information
joecrop authored Jan 9, 2024
2 parents 9d80c02 + 1271df3 commit 1258de5
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 23 deletions.
55 changes: 43 additions & 12 deletions src/providers/ModuleInstantiator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ function cleanUpContainer(container: string): string {
container = container.replace(/=/g, ' = ');
container = container.replace(/\(/g, ' ( ');
container = container.replace(/\)/g, ' ) ');
container = container.replace(/\[/g, ' [ ');
container = container.replace(/\]/g, ' ] ');
container = container.replace(/\/\//g, ' // ');
container = container.replace(/\/\*/g, ' /* ');

Expand Down Expand Up @@ -326,7 +328,7 @@ function findMaxLength(container: string, moduleIsParameterized: boolean): numbe
let lastPort: string = undefined; // eslint-disable-line no-undef-init
let lastParameter: string = undefined; // eslint-disable-line no-undef-init
let passedEqualSign = false;

let numBracketPast = 0;
let state = ProcessingState.INITIAL;

for (let i = 0; i < keys.length; i++) {
Expand All @@ -351,7 +353,13 @@ function findMaxLength(container: string, moduleIsParameterized: boolean): numbe
}
} else if (state === ProcessingState.PARAMETERS) {
if (keys[i] === ')') {
state = ProcessingState.PORTS;
if (numBracketPast === 0) {
state = ProcessingState.PORTS;
} else {
numBracketPast -= 1;
}
} else if (keys[i] === '(') {
numBracketPast += 1;
} else if (keys[i] === ',' && lastParameter) {
maxLength = Math.max(lastParameter.length, maxLength);
lastParameter = undefined;
Expand All @@ -369,13 +377,19 @@ function findMaxLength(container: string, moduleIsParameterized: boolean): numbe
lastParameter = undefined;
}

if (keys[i] === ')') {
if (keys[i] === ')' && numBracketPast == 0) {
state = ProcessingState.COMPLETE;
} else if (keys[i] === ',' && lastPort) {
maxLength = Math.max(lastPort.length, maxLength);
lastPort = undefined;
} else if (keys[i] === '[') {
numBracketPast += 1;
} else if (keys[i] === ']') {
numBracketPast -= 1;
} else if (!isPortSymbol(keys[i]) && !isEmptyKey(keys[i])) {
lastPort = keys[i].trim();
if (numBracketPast == 0) {
lastPort = keys[i].trim();
}
}
}

Expand Down Expand Up @@ -416,14 +430,16 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
}

const output = [];

const keys = container.split(' ');

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

let numBracketPast = 0;
let passedEqualSign = false;

let state = ProcessingState.INITIAL;
Expand All @@ -450,14 +466,19 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
}
} else if (state === ProcessingState.PARAMETERS) {
if (keys[i] === ')') {
state = ProcessingState.PORTS;
if (numBracketPast === 0) {
state = ProcessingState.PORTS;
} else {
numBracketPast -= 1;
parameterDefault.push(keys[i].trim());
}
} else if (keys[i] === ',' && lastParameter) {
// Set with default value if it exists
if (passedEqualSign) {
output.push(
`${padding}.${lastParameter}${' '.repeat(maxLength - lastParameter.length)}${' '.repeat(4)}(`
);
output.push(`${lastParameterDefault})`);
output.push(`${parameterDefault.join('')})`); // This will butcher default values for strings with spaces included, sorry.

passedEqualSign = false;
} else {
Expand All @@ -472,9 +493,13 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
lastParameter = undefined;
} else if (keys[i] === '=') {
passedEqualSign = true;
parameterDefault = [];
} else if (!isParameterSymbol(keys[i]) && !isEmptyKey(keys[i])) {
if (passedEqualSign) {
lastParameterDefault = keys[i].trim();
if (keys[i] === '(') {
numBracketPast += 1;
}
parameterDefault.push(keys[i].trim());
} else {
lastParameter = keys[i].trim();
}
Expand All @@ -486,7 +511,7 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
output.push(
`${padding}.${lastParameter}${' '.repeat(maxLength - lastParameter.length)}${' '.repeat(4)}(`
);
output.push(`${lastParameterDefault})\n`);
output.push(`${parameterDefault.join('')})\n`);

passedEqualSign = false;
} else {
Expand All @@ -500,7 +525,7 @@ function parseContainer(symbol: string, container: string, moduleIsParameterized
lastParameter = undefined;
}

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

lastPort = undefined;
} else if (!isPortSymbol(keys[i]) && !isEmptyKey(keys[i])) {
lastPort = keys[i].trim();
if (keys[i] === '[') {
numBracketPast += 1;
} else if (keys[i] === ']') {
numBracketPast -= 1;
} else if (numBracketPast == 0) {
lastPort = keys[i].trim();
}
}
}

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

passedEqualSign = false;
} else {
Expand Down
40 changes: 40 additions & 0 deletions src/test/ModuleInstantiator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,46 @@ suite('ModuleInstantiator Tests', () => {

compareInstantiation('golden', container, instance);
});

test('test #8: formatInstance with unpacked dimensions and brackets in ports', async () => {
let uri = vscode.Uri.file(path.join(__dirname, testFolderLocation, 'test-files', 'ModuleInstantiator.test.1.v')); // prettier-ignore
let document = await vscode.workspace.openTextDocument(uri);

let fullRange = null;
// Range of the module in the document
fullRange = new vscode.Range(new vscode.Position(300, 6), new vscode.Position(324, 0));

let container = document.getText(fullRange).replace(/^\s+|\s+$/g, '');

uri = vscode.Uri.file(path.join(__dirname, testFolderLocation, 'test-files', 'ModuleInstantiator.test.2.v'));
document = await vscode.workspace.openTextDocument(uri);

fullRange = new vscode.Range(new vscode.Position(137, 0), new vscode.Position(146, 0));

let instance = document.getText(fullRange);

compareInstantiation('arrer', container, instance);
});

test('test #9: formatInstance with brackets in parameter default value', async () => {
let uri = vscode.Uri.file(path.join(__dirname, testFolderLocation, 'test-files', 'ModuleInstantiator.test.1.v')); // prettier-ignore
let document = await vscode.workspace.openTextDocument(uri);

let fullRange = null;
// Range of the module in the document
fullRange = new vscode.Range(new vscode.Position(329, 6), new vscode.Position(354, 0));

let container = document.getText(fullRange).replace(/^\s+|\s+$/g, '');

uri = vscode.Uri.file(path.join(__dirname, testFolderLocation, 'test-files', 'ModuleInstantiator.test.2.v'));
document = await vscode.workspace.openTextDocument(uri);

fullRange = new vscode.Range(new vscode.Position(151, 0), new vscode.Position(163, 0));

let instance = document.getText(fullRange);

compareInstantiation('azzer', container, instance);
});
});

function compareInstantiation(instance_name, container_name, expected): void {
Expand Down
22 changes: 11 additions & 11 deletions src/test/indexer_map.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ suite('indexer_map Tests', () => {
assert.strictEqual(symbols.size, 4);
let count = await indexer.addDocumentSymbols(sVDocument, symbols);

assert.strictEqual(count, 8);
assert.strictEqual(count, 10);
assert.strictEqual(symbols.size, 5);
assert.strictEqual(symbols.get(uri.fsPath).length, 8);
assert.strictEqual(getSymbolsCount(), 21);
assert.strictEqual(symbols.get(uri.fsPath).length, 10);
assert.strictEqual(getSymbolsCount(), 23);

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

// undefined/null document
count = await indexer.addDocumentSymbols(undefined, symbols);
assert.strictEqual(count, 0);
assert.strictEqual(symbols.size, 5);
assert.strictEqual(getSymbolsCount(), 21);
assert.strictEqual(getSymbolsCount(), 23);

count = await indexer.addDocumentSymbols(sVDocument, undefined);
assert.strictEqual(count, 0);
assert.strictEqual(symbols.size, 5);
assert.strictEqual(getSymbolsCount(), 21);
assert.strictEqual(getSymbolsCount(), 23);

count = await indexer.addDocumentSymbols(undefined, undefined);
assert.strictEqual(count, 0);
assert.strictEqual(symbols.size, 5);
assert.strictEqual(getSymbolsCount(), 21);
assert.strictEqual(getSymbolsCount(), 23);

count = await indexer.addDocumentSymbols(null, symbols);
assert.strictEqual(count, 0);
assert.strictEqual(symbols.size, 5);
assert.strictEqual(getSymbolsCount(), 21);
assert.strictEqual(getSymbolsCount(), 23);
});

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

assert.strictEqual(count, 8);
assert.strictEqual(count, 10);
assert.strictEqual(symbols.size, 5);
assert.strictEqual(getSymbolsCount(), 21);
assert.strictEqual(getSymbolsCount(), 23);

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

Expand All @@ -92,7 +92,7 @@ suite('indexer_map Tests', () => {
}
});

assert.strictEqual(count, -8);
assert.strictEqual(count, -10);
assert.strictEqual(symbols.size, 4);
assert.strictEqual(getSymbolsCount(), 13);

Expand Down
58 changes: 58 additions & 0 deletions src/test/test-files/ModuleInstantiator.test.1.v
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,61 @@ module golden(
assign c = tmp_c;

endmodule


// ---------------------------------------------------------------
// -- Example of ports with unpacked dimensions and brackets
// ---------------------------------------------------------------

module arrer (
input clk,
input reset,
input [(2+2)-1:0] a [2:0],
input [3:0] b [(3-1):0] ,
input valid,
output [6:0] c
);

input clk;
input reset;
input [3:0] a;
// keep this single comment
input [3:0] b;
/* multiline comment should
be kept*/
input valid;
output [6:0] c;

reg [6:0] tmp_c;
assign c = tmp_c;

endmodule

// ---------------------------------------------------------------
// -- Example of parameters with brackets
// ---------------------------------------------------------------

module azzer #(parameter SIZE = (2*1)+1,
parameter SIZE_TWO = 2*(1+1)) (
input clk,
input reset,
input [3:0] a,
input [3:0] b,
input valid,
output [6:0] c
);

input clk;
input reset;
input [3:0] a;
// keep this single comment
input [3:0] b;
/* multiline comment should
be kept*/
input valid;
output [6:0] c;

reg [6:0] tmp_c;
assign c = tmp_c;

endmodule
30 changes: 30 additions & 0 deletions src/test/test-files/ModuleInstantiator.test.2.v
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,36 @@ golden u_golden (
.c (c)
);

// ---------------------------------------------------------------
// -- Example of ports with unpacked dimensions and brackets
// ---------------------------------------------------------------

arrer u_arrer (
.clk (clk),
.reset (reset),
.a (a),
.b (b),
.valid (valid),
.c (c)
);


// ---------------------------------------------------------------
// -- Example of parameters with brackets
// ---------------------------------------------------------------

azzer #(
.SIZE ((2*1)+1),
.SIZE_TWO (2*(1+1))
) u_azzer (
.clk (clk),
.reset (reset),
.a (a),
.b (b),
.valid (valid),
.c (c)
);

// -------------------------------------------------------
// -- End file
// -------------------------------------------------------

0 comments on commit 1258de5

Please sign in to comment.