From 84437a7aa84c498c3fe2b87bce4fea21eb4a34b7 Mon Sep 17 00:00:00 2001 From: yuling Date: Sun, 26 Mar 2017 21:48:23 +0800 Subject: [PATCH 1/8] cnange import style --- src/extension.ts | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 31a07e2..eba5858 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,19 +1,19 @@ // The module 'vscode' contains the VS Code extensibility API // Import the necessary extensibility types to use in your code below -import {ExtensionContext, Position, TextDocument, CancellationToken, languages, Hover, HoverProvider} from 'vscode'; +import * as vscode from 'vscode'; // This method is called when your extension is activated. Activation is // controlled by the activation events defined in package.json. -export function activate(context: ExtensionContext) { +export function activate(context: vscode.ExtensionContext) { // System Verilog Hover Provider context.subscriptions.push( - languages.registerHoverProvider('systemverilog', + vscode.languages.registerHoverProvider('systemverilog', new SystemVerilogHoverProvider() ) ); } -class SystemVerilogHoverProvider implements HoverProvider { +class SystemVerilogHoverProvider implements vscode.HoverProvider { private _excludedText: RegExp; @@ -22,31 +22,27 @@ class SystemVerilogHoverProvider implements HoverProvider { } public provideHover( - document: TextDocument, position: Position, token: CancellationToken): - Hover { - // text at current line - let textLine = document.lineAt(position).text; - + document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): + vscode.Hover { // get word start and end let textRange = document.getWordRangeAtPosition(position); // hover word - let targetText = textLine.substring(textRange.start.character, textRange.end.character); + let targetText = document.getText(textRange); if (targetText.search(this._excludedText) !== -1) { // systemverilog keywords return; } else { // find declaration let declarationText = this._findDeclaration(document, position, targetText); if (declarationText !== undefined) { - let renderedText = '```systemverilog\n' + declarationText + '\n```'; - return new Hover(renderedText); + return new vscode.Hover({language: 'systemverilog', value: declarationText}); } else { return; } } } - private _findDeclaration(document: TextDocument, position: Position, target: string): string { + private _findDeclaration(document: vscode.TextDocument, position: vscode.Position, target: string): string { // check target is valid variable name if (target.search(/[A-Za-z_][A-Za-z0-9_]*/g) === -1) { return; From baa00afec8134513eeb1a0d5feb7661173c06b84 Mon Sep 17 00:00:00 2001 From: yuling Date: Sun, 26 Mar 2017 21:48:59 +0800 Subject: [PATCH 2/8] add instantiate module command --- package.json | 4 ++ src/extension.ts | 133 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/package.json b/package.json index fa78d5a..93df75e 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,10 @@ "snippets": [{ "language": "systemverilog", "path": "./snippets/snippets.json" + }], + "commands": [{ + "command": "extension.systemverilog.instantiateModule", + "title": "Instantiate system verilog module" }] }, "activationEvents": [ diff --git a/src/extension.ts b/src/extension.ts index eba5858..c1f34eb 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,6 +1,8 @@ // The module 'vscode' contains the VS Code extensibility API // Import the necessary extensibility types to use in your code below import * as vscode from 'vscode'; +import * as fs from 'fs'; +import * as path from 'path'; // This method is called when your extension is activated. Activation is // controlled by the activation events defined in package.json. @@ -11,6 +13,13 @@ export function activate(context: vscode.ExtensionContext) { new SystemVerilogHoverProvider() ) ); + + // instantiate system verilog module + context.subscriptions.push( + vscode.commands.registerCommand('extension.systemverilog.instantiateModule', + instantiateModuleInteract + ) + ); } class SystemVerilogHoverProvider implements vscode.HoverProvider { @@ -81,3 +90,127 @@ class SystemVerilogHoverProvider implements vscode.HoverProvider { } } } + +function getDirectories (srcpath: string): string[] { + return fs.readdirSync(srcpath) + .filter(file => fs.statSync(path.join(srcpath, file)).isDirectory()); +} + +function getFiles (srcpath: string): string[] { + return fs.readdirSync(srcpath) + .filter(file => fs.statSync(path.join(srcpath, file)).isFile()); +} + +function selectFile(currentDir?: string): Thenable { + currentDir = currentDir || vscode.workspace.rootPath; + + let dirs = getDirectories(currentDir); + // if is subdirectory, add '../' + if (currentDir !== vscode.workspace.rootPath) { + dirs.unshift('..') + } + // all files ends with '.sv' + let files = getFiles(currentDir) + .filter(file => file.endsWith('.v') || file.endsWith('.sv')); + + // available quick pick items + let items = dirs.concat(files); + + return vscode.window.showQuickPick(items) + .then(selected => { + if (!selected) { + return; + } + + let location = path.join(currentDir, selected); + if (fs.statSync(location).isDirectory()) { + return selectFile(location); + } + return location; + }); +} + +function instantiatePort(ports: string[]): string { + let options = vscode.window.activeTextEditor.options; + let useTab = !options.insertSpaces; + let spacesSize = options.tabSize; + let port = '' + for (let i = 0; i < ports.length; i++) { + let element = ports[i]; + if (useTab) { + port += `\t.${element}(${element})`; + } else { + port += ' '.repeat(spacesSize); + port += `.${element}(${element})`; + } + + if (i !== ports.length - 1) { + port += ','; + } + + port += '\n'; + } + + return port; +} + +function instantiateModule(srcpath: string) { + if (!srcpath || !fs.statSync(srcpath).isFile) { + return; + } + + // remove comment + let content = fs.readFileSync(srcpath, 'utf8').replace(/\/\/.*/g, '').replace(/\/\*[\s\S]*?\*\//g, ''); + if (content.indexOf('module') === -1) { + return; + } + let moduleIO = content.substring(content.indexOf('module'), content.indexOf(';')); + let moduleName = moduleIO.match(/module\s+\b([A-Za-z_][A-Za-z0-9_]*)\b/)[1]; + let parametersName = []; + let portsName = []; + let lines = moduleIO.split('\n'); + lines.forEach(line => { + line = line.trim(); + let matched = line.match(/parameter\s+\b([A-Za-z_][A-Za-z0-9_]*)\b/); + if (matched !== null) { + parametersName.push(matched[1]); + } + + if (line.search(/^\b(input|output|inout)\b/) !== -1) { + let variables = line.replace(/\b(input|output|inout|reg|wire|logic|integer|bit|byte|shortint|int|longint|time|shortreal|real|double|realtime)\b/g, '') + .replace(/(\[.+?\])?/g, '').replace(/\s+/g, '').split(',').forEach(variable => { + if (variable) { + portsName.push(variable); + } + }); + } + }); + + if (portsName.length === 0) { + return; + } + let inst = moduleName + '\n'; + if (parametersName.length > 0) { + inst += '#(\n'; + inst += instantiatePort(parametersName); + inst += ')\n'; + } + inst += `u_${moduleName}(\n`; + inst += instantiatePort(portsName); + inst += ');\n'; + return inst; +} + +function instantiateModuleInteract() { + let filePath = path.dirname(vscode.window.activeTextEditor.document.fileName); + selectFile(filePath).then(srcpath => { + let inst = instantiateModule(srcpath); + let editor = vscode.window.activeTextEditor; + let sel = editor.selection; + + editor.edit(editBuilder => { + editBuilder.insert(sel.start, inst); + editBuilder.insert + }); + }); +} From 381ceb8fb1334e43e1ffa1d40dae4cc06578371e Mon Sep 17 00:00:00 2001 From: yuling Date: Sun, 26 Mar 2017 21:53:23 +0800 Subject: [PATCH 3/8] exclude all systemverilog keywords --- src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extension.ts b/src/extension.ts index c1f34eb..0e61540 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -27,7 +27,7 @@ class SystemVerilogHoverProvider implements vscode.HoverProvider { private _excludedText: RegExp; constructor() { - this._excludedText = RegExp(/(reg|wire|input|output|logic|parameter|localparam|always|begin|end)/); + this._excludedText = RegExp(/\b(alias|always|always_comb|always_ff|always_latch|and|assert|assign|assume|automatic|before|begin|bind|bins|binsof|bit|break|buf|bufif0|bufif1|byte|case|casex|casez|cell|chandle|class|clocking|cmos|config|const|constraint|context|continue|cover|covergroup|coverpoint|cross|deassign|default|defparam|design|disable|dist|do|edge|else|end|endcase|endclass|endclocking|endconfig|endfunction|endgenerate|endgroup|endinterface|endmodule|endpackage|endprimitive|endprogram|endproperty|endspecify|endsequence|endtable|endtask|enum|event|expect|export|extends|extern|final|first_match|for|force|foreach|forever|fork|forkjoin|function|generate|genvar|highz0|highz1|if|iff|ifnone|ignore_bins|illegal_bins|import|incdir|include|initial|inout|input|inside|instance|int|integer|interface|intersect|join|join_any|join_none|large|liblist|library|local|localparam|logic|longint|macromodule|matches|medium|modport|module|nand|negedge|new|nmos|nor|noshowcancelled|not|notif0|notif1|null|or|output|package|packed|parameter|pmos|posedge|primitive|priority|program|property|protected|pull0|pull1|pulldown|pullup|pulsestyle_onevent|pulsestyle_ondetect|pure|rand|randc|randcase|randsequence|rcmos|real|realtime|ref|reg|release|repeat|return|rnmos|rpmos|rtran|rtranif0|rtranif1|scalared|sequence|shortint|shortreal|showcancelled|signed|small|solve|specify|specparam|static|string|strong0|strong1|struct|super|supply0|supply1|table|tagged|task|this|throughout|time|timeprecision|timeunit|tran|tranif0|tranif1|tri|tri0|tri1|triand|trior|trireg|type|typedef|union|unique|unsigned|use|uwire|var|vectored|virtual|void|wait|wait_order|wand|weak0|weak1|while|wildcard|wire|with|within|wor|xnor|xor)\b/); } public provideHover( From 914eb4408f1bf8185c1230e0ac517f3d585bb34a Mon Sep 17 00:00:00 2001 From: yuling Date: Sun, 26 Mar 2017 22:30:51 +0800 Subject: [PATCH 4/8] add comments --- src/extension.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 0e61540..7746b91 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -122,10 +122,13 @@ function selectFile(currentDir?: string): Thenable { return; } + // if is a directory let location = path.join(currentDir, selected); if (fs.statSync(location).isDirectory()) { return selectFile(location); } + + // return file path return location; }); } @@ -135,6 +138,7 @@ function instantiatePort(ports: string[]): string { let useTab = !options.insertSpaces; let spacesSize = options.tabSize; let port = '' + // .NAME(NAME) for (let i = 0; i < ports.length; i++) { let element = ports[i]; if (useTab) { @@ -147,10 +151,8 @@ function instantiatePort(ports: string[]): string { if (i !== ports.length - 1) { port += ','; } - port += '\n'; } - return port; } @@ -164,11 +166,14 @@ function instantiateModule(srcpath: string) { if (content.indexOf('module') === -1) { return; } + // module 2001 style let moduleIO = content.substring(content.indexOf('module'), content.indexOf(';')); let moduleName = moduleIO.match(/module\s+\b([A-Za-z_][A-Za-z0-9_]*)\b/)[1]; let parametersName = []; let portsName = []; let lines = moduleIO.split('\n'); + + // find all parameters and ports lines.forEach(line => { line = line.trim(); let matched = line.match(/parameter\s+\b([A-Za-z_][A-Za-z0-9_]*)\b/); @@ -205,12 +210,11 @@ function instantiateModuleInteract() { let filePath = path.dirname(vscode.window.activeTextEditor.document.fileName); selectFile(filePath).then(srcpath => { let inst = instantiateModule(srcpath); + let editor = vscode.window.activeTextEditor; let sel = editor.selection; - editor.edit(editBuilder => { editBuilder.insert(sel.start, inst); - editBuilder.insert }); }); } From 016fa86387113271ba549a3a97672a99bdd99577 Mon Sep 17 00:00:00 2001 From: yuling Date: Sun, 26 Mar 2017 22:31:19 +0800 Subject: [PATCH 5/8] hover will not show last ',' or ';' --- src/extension.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/extension.ts b/src/extension.ts index 7746b91..42b1fd3 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -70,6 +70,10 @@ class SystemVerilogHoverProvider implements vscode.HoverProvider { for (let i = position.line-1; i >= 0; i--) { // text at current line let element = document.lineAt(i).text.replace(/\/\/.*/, '').trim().replace(/\s+/g, ' '); + let lastChar = element.charAt(element.length - 1); + if (lastChar === ',' || lastChar === ';') { // remove last ',' or ';' + element = element.substring(0, element.length - 1); + } // find variable declaration type if (element.search(regexVariableTypeStart) !== -1) { From 6030aeba763098a0528655c69eb634dded9554d4 Mon Sep 17 00:00:00 2001 From: yuling Date: Sun, 26 Mar 2017 22:57:30 +0800 Subject: [PATCH 6/8] update command name --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 93df75e..626605f 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ }], "commands": [{ "command": "extension.systemverilog.instantiateModule", - "title": "Instantiate system verilog module" + "title": "System Verilog: Instantiate Module" }] }, "activationEvents": [ From 65354fa4ab6efe20ea655c25434a2dadb04f56dd Mon Sep 17 00:00:00 2001 From: yuling Date: Mon, 27 Mar 2017 00:37:41 +0800 Subject: [PATCH 7/8] update vscode engines --- package.json | 5 +++-- src/extension.ts | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 626605f..da46fb4 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "url": "https://github.com/mshr-h/vscode-systemverilog-support.git" }, "engines": { - "vscode": "^0.10.1" + "vscode": "^1.10.0" }, "categories": [ "Languages" @@ -45,6 +45,7 @@ }, "devDependencies": { "typescript": "^2.0.3", - "vscode": "^1.0.0" + "vscode": "^1.0.0", + "@types/node": "*" } } diff --git a/src/extension.ts b/src/extension.ts index 42b1fd3..570875b 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -140,7 +140,10 @@ function selectFile(currentDir?: string): Thenable { function instantiatePort(ports: string[]): string { let options = vscode.window.activeTextEditor.options; let useTab = !options.insertSpaces; - let spacesSize = options.tabSize; + let spacesSize = 4; + if (typeof options.tabSize === 'number') { + spacesSize = options.tabSize; + } let port = '' // .NAME(NAME) for (let i = 0; i < ports.length; i++) { From e568f03041de119af87636fbce993c76bf75cf12 Mon Sep 17 00:00:00 2001 From: yuling Date: Mon, 27 Mar 2017 00:49:41 +0800 Subject: [PATCH 8/8] use node as default --- .travis.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 077db43..a18965b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,17 +2,21 @@ sudo: false os: - linux - + +language: node_js +node_js: + - "7" + before_install: - if [ $TRAVIS_OS_NAME == "linux" ]; then export CXX="g++-4.9" CC="gcc-4.9" DISPLAY=:99.0; sh -e /etc/init.d/xvfb start; sleep 3; fi - + install: - npm install - npm run vscode:prepublish - + script: - npm test --silent