finish left parts 1
This commit is contained in:
parent
e504d0450e
commit
ea1a70e8aa
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,7 +5,6 @@ script/__pycache__
|
|||||||
.vscode-test/
|
.vscode-test/
|
||||||
*.vsix
|
*.vsix
|
||||||
parser_stuck.v
|
parser_stuck.v
|
||||||
**/*.wasm
|
|
||||||
out-js/
|
out-js/
|
||||||
*.pyc
|
*.pyc
|
||||||
*.pyd
|
*.pyd
|
||||||
|
@ -16,6 +16,7 @@ Change
|
|||||||
- 将插件的工作状态显示在 vscode 下侧的状态栏上,利于用户了解目前的设置状态
|
- 将插件的工作状态显示在 vscode 下侧的状态栏上,利于用户了解目前的设置状态
|
||||||
- 状态栏右下角现在可以看到目前选择的linter以及是否正常工作了
|
- 状态栏右下角现在可以看到目前选择的linter以及是否正常工作了
|
||||||
- 优化项目配置目录
|
- 优化项目配置目录
|
||||||
|
- 优化自动补全的性能
|
||||||
|
|
||||||
Feature
|
Feature
|
||||||
- 增加对 XDC,TCL 等脚本的 LSP 支持
|
- 增加对 XDC,TCL 等脚本的 LSP 支持
|
||||||
|
@ -44,6 +44,11 @@
|
|||||||
"default": true,
|
"default": true,
|
||||||
"description": "show the welcome text in Digital-IDE"
|
"description": "show the welcome text in Digital-IDE"
|
||||||
},
|
},
|
||||||
|
"digital-ide.dont-show-again.propose.issue": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "show the welcome text in Digital-IDE"
|
||||||
|
},
|
||||||
"digital-ide.lib.custom.path": {
|
"digital-ide.lib.custom.path": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "",
|
"default": "",
|
||||||
|
BIN
resources/fsm/resources/tree-sitter/tree-sitter-verilog.wasm
Normal file
BIN
resources/fsm/resources/tree-sitter/tree-sitter-verilog.wasm
Normal file
Binary file not shown.
BIN
resources/fsm/resources/tree-sitter/tree-sitter-vhdl.wasm
Normal file
BIN
resources/fsm/resources/tree-sitter/tree-sitter-vhdl.wasm
Normal file
Binary file not shown.
BIN
resources/fsm/resources/tree-sitter/tree-sitter.wasm
Normal file
BIN
resources/fsm/resources/tree-sitter/tree-sitter.wasm
Normal file
Binary file not shown.
1
resources/hdlParser/index.d.ts
vendored
1
resources/hdlParser/index.d.ts
vendored
@ -21,6 +21,7 @@ interface All {
|
|||||||
error: Error[]
|
error: Error[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function callParser(path: AbsPath, func: number): Promise<any | undefined>;
|
||||||
export function vlogFast(path: AbsPath): Promise<Fast | undefined>;
|
export function vlogFast(path: AbsPath): Promise<Fast | undefined>;
|
||||||
export function vlogAll(path: AbsPath): Promise<All | undefined>;
|
export function vlogAll(path: AbsPath): Promise<All | undefined>;
|
||||||
export function vhdlFast(path: AbsPath): Promise<Fast | undefined>;
|
export function vhdlFast(path: AbsPath): Promise<Fast | undefined>;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
const vscode = require('vscode');
|
const vscode = require('vscode');
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
const hdlParser = require('./parser');
|
const hdlParser = require('./parser');
|
||||||
@ -49,14 +50,21 @@ async function callParser(path, func) {
|
|||||||
console.log(path, debug);
|
console.log(path, debug);
|
||||||
return JSON.parse(res);
|
return JSON.parse(res);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`errors happen when call wasm, path: ${path}, errors: ${error}`);
|
console.log(`errors happen when call wasm, path: ${path}, errors: ${error}, input params: (${path}, ${func})`);
|
||||||
|
|
||||||
|
const dsaSetting = vscode.workspace.getConfiguration('digital-ide.dont-show-again');
|
||||||
|
if (dsaSetting.get('propose.issue', false) === true) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
const res = await vscode.window.showErrorMessage(
|
const res = await vscode.window.showErrorMessage(
|
||||||
'Errors happen when parsing ' + path + '. Just propose a valuable issue in our github repo 😊',
|
`Errors happen when parsing ${path}. Error: "${error}". Just propose a valuable issue in our github repo 😊`,
|
||||||
{ title: 'Go and Propose!', value: true },
|
{ title: 'Go and Propose!', value: true },
|
||||||
{ title: 'Refuse', value: false }
|
{ title: "Don't Show Again", value: false }
|
||||||
);
|
);
|
||||||
if (res && res.value) {
|
if (res && res.value === true) {
|
||||||
vscode.env.openExternal(vscode.Uri.parse(githubIssueUrl));
|
vscode.env.openExternal(vscode.Uri.parse(githubIssueUrl));
|
||||||
|
} else if (res && res.value === false) {
|
||||||
|
dsaSetting.update('propose.issue', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -95,5 +103,6 @@ module.exports = {
|
|||||||
vhdlAll,
|
vhdlAll,
|
||||||
svFast,
|
svFast,
|
||||||
svAll,
|
svAll,
|
||||||
extensionUrl
|
extensionUrl,
|
||||||
|
callParser
|
||||||
};
|
};
|
File diff suppressed because one or more lines are too long
Binary file not shown.
BIN
resources/netlist/resources/kernel/kernel.wasm
Normal file
BIN
resources/netlist/resources/kernel/kernel.wasm
Normal file
Binary file not shown.
10
script/test/callParser.js
Normal file
10
script/test/callParser.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const { vlogFast, callParser } = require('../../resources/hdlParser');
|
||||||
|
|
||||||
|
const testFile = 'c:/Users/11934/Project/Digital-IDE/Digital-Test/user/src/netlist_test.v';
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const fast = await callParser(testFile, 5);
|
||||||
|
console.log(fast);
|
||||||
|
const all = await callParser(testFile, 6);
|
||||||
|
console.log(all);
|
||||||
|
})();
|
8
script/test/vhdlAll.js
Normal file
8
script/test/vhdlAll.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
const { vhdlAll } = require('../../resources/hdlParser');
|
||||||
|
|
||||||
|
const testFile = '../Digital-Test/Verilog/dependence_test/test.vhd';
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const fast = await vhdlAll(testFile);
|
||||||
|
console.log(JSON.stringify(fast, null, ' '));
|
||||||
|
})();
|
8
script/test/vhdlFast.js
Normal file
8
script/test/vhdlFast.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
const { vhdlFast } = require('../../resources/hdlParser');
|
||||||
|
|
||||||
|
const testFile = '../Digital-Test/Verilog/dependence_test/test.vhd';
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const fast = await vhdlFast(testFile);
|
||||||
|
console.log(JSON.stringify(fast, null, ' '));
|
||||||
|
})();
|
8
script/test/vlogAll.js
Normal file
8
script/test/vlogAll.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
const { vlogAll } = require('../../resources/hdlParser');
|
||||||
|
|
||||||
|
const testFile = '../Digital-Test/user/src/netlist_test.v';
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const all = await vlogAll(testFile);
|
||||||
|
console.log(JSON.stringify(all, null, ' '));
|
||||||
|
})();
|
@ -1,6 +1,6 @@
|
|||||||
const { vlogFast } = require('../../resources/hdlParser');
|
const { vlogFast, callParser } = require('../../resources/hdlParser');
|
||||||
|
|
||||||
const testFile = '../Digital-Test/Verilog/dependence_test/head_1.v';
|
const testFile = '../Digital-Test/user/src/netlist_test.v';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const fast = await vlogFast(testFile);
|
const fast = await vlogFast(testFile);
|
||||||
|
@ -19,8 +19,7 @@ async function registerCommand(context: vscode.ExtensionContext) {
|
|||||||
|
|
||||||
|
|
||||||
async function launch(context: vscode.ExtensionContext) {
|
async function launch(context: vscode.ExtensionContext) {
|
||||||
|
await vscode.window.withProgress({
|
||||||
vscode.window.withProgress({
|
|
||||||
location: vscode.ProgressLocation.Window,
|
location: vscode.ProgressLocation.Window,
|
||||||
title: 'Initialization (Digtial-IDE)'
|
title: 'Initialization (Digtial-IDE)'
|
||||||
}, async () => {
|
}, async () => {
|
||||||
@ -29,10 +28,10 @@ async function launch(context: vscode.ExtensionContext) {
|
|||||||
hdlMonitor.start();
|
hdlMonitor.start();
|
||||||
});
|
});
|
||||||
|
|
||||||
MainOutput.report('Digital-IDE has launched, Version: 0.3.2');
|
MainOutput.report('Digital-IDE has launched, Version: 0.3.2', ReportType.Launch);
|
||||||
MainOutput.report('OS: ' + opeParam.os);
|
MainOutput.report('OS: ' + opeParam.os, ReportType.Launch);
|
||||||
|
|
||||||
// console.log(hdlParam);
|
console.log(hdlParam);
|
||||||
|
|
||||||
// show welcome information (if first install)
|
// show welcome information (if first install)
|
||||||
const welcomeSetting = vscode.workspace.getConfiguration('digital-ide.welcome');
|
const welcomeSetting = vscode.workspace.getConfiguration('digital-ide.welcome');
|
||||||
|
@ -82,8 +82,10 @@ function registerLsp(context: vscode.ExtensionContext) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// vhdl lsp
|
// vhdl lsp
|
||||||
|
vscode.languages.registerDocumentSymbolProvider(vhdlSelector, lspDocSymbol.vhdlDocSymbolProvider);
|
||||||
|
vscode.languages.registerDefinitionProvider(vhdlSelector, lspDefinition.vhdlDefinitionProvider);
|
||||||
|
vscode.languages.registerHoverProvider(vhdlSelector, lspHover.vhdlHoverProvider);
|
||||||
vscode.languages.registerCompletionItemProvider(vhdlSelector, lspCompletion.vhdlCompletionProvider);
|
vscode.languages.registerCompletionItemProvider(vhdlSelector, lspCompletion.vhdlCompletionProvider);
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,53 +11,27 @@ import { hdlPath } from '../../../hdlFs';
|
|||||||
import { hdlSymbolStorage } from '../core';
|
import { hdlSymbolStorage } from '../core';
|
||||||
|
|
||||||
class VhdlCompletionProvider implements vscode.CompletionItemProvider {
|
class VhdlCompletionProvider implements vscode.CompletionItemProvider {
|
||||||
|
keywordItems: vscode.CompletionItem[] | undefined;
|
||||||
public async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Promise<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem> | null | undefined> {
|
public async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Promise<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem> | null | undefined> {
|
||||||
// console.log('VhdlCompletionProvider');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const filePath = hdlPath.toSlash(document.fileName);
|
const filePath = hdlPath.toSlash(document.fileName);
|
||||||
|
|
||||||
// 1. provide keyword
|
// 1. provide keyword
|
||||||
const completions = this.makeKeywordItems(document, position);
|
const completions = this.makeKeywordItems(document, position);
|
||||||
completions.push(...this.makeCompilerKeywordItems(document, position));
|
|
||||||
completions.push(...this.makeSystemKeywordItems(document, position));
|
|
||||||
|
|
||||||
const symbolResult = await hdlSymbolStorage.getSymbol(filePath);
|
const symbolResult = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
|
|
||||||
if (!symbolResult) {
|
if (!symbolResult) {
|
||||||
return completions;
|
return completions;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('vhdl symbol result');
|
|
||||||
|
|
||||||
|
const symbols = symbolResult.content;
|
||||||
// locate at one module
|
for (const symbol of symbols) {
|
||||||
const scopeSymbols = util.filterSymbolScope(position, symbolResult.content);
|
const kind = this.getCompletionItemKind(symbol.type);
|
||||||
if (!scopeSymbols ||
|
const clItem = new vscode.CompletionItem(symbol.name, kind);
|
||||||
!scopeSymbols.module ||
|
completions.push(clItem);
|
||||||
!hdlParam.hasHdlModule(filePath, scopeSymbols.module.name)) {
|
|
||||||
// MainOutput.report('Fail to get HdlModule ' + filePath + ' ' + scopeSymbols?.module.name, ReportType.Debug);
|
|
||||||
return completions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// find wrapper module
|
|
||||||
const currentModule = hdlParam.getHdlModule(filePath, scopeSymbols.module.name);
|
|
||||||
if (!currentModule) {
|
|
||||||
return completions;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. provide modules
|
|
||||||
const suggestModulesPromise = this.provideModules(document, position, filePath, symbolResult.macro.includes);
|
|
||||||
|
|
||||||
// 4. provide params and ports of wrapper module
|
|
||||||
const suggestParamsPortsPromise = this.provideParamsPorts(currentModule);
|
|
||||||
|
|
||||||
// 5. provide nets
|
|
||||||
const suggestNetsPromise = this.provideNets(scopeSymbols.symbols);
|
|
||||||
|
|
||||||
// collect
|
|
||||||
completions.push(...await suggestModulesPromise);
|
|
||||||
completions.push(...await suggestParamsPortsPromise);
|
|
||||||
completions.push(...await suggestNetsPromise);
|
|
||||||
|
|
||||||
return completions;
|
return completions;
|
||||||
|
|
||||||
@ -66,49 +40,43 @@ class VhdlCompletionProvider implements vscode.CompletionItemProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private makeKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
private getCompletionItemKind(type: string): vscode.CompletionItemKind {
|
||||||
const vhdlKeywordItem = [];
|
switch (type) {
|
||||||
|
case 'entity': return vscode.CompletionItemKind.Class; break;
|
||||||
|
case 'port': return vscode.CompletionItemKind.Variable; break;
|
||||||
|
default: return vscode.CompletionItemKind.Value; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private makeKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
||||||
|
if (this.keywordItems !== undefined && this.keywordItems.length > 0) {
|
||||||
|
return this.keywordItems;
|
||||||
|
}
|
||||||
|
const vhdlKeywordItems: vscode.CompletionItem[] = [];
|
||||||
for (const keyword of vhdlKeyword.keys()) {
|
for (const keyword of vhdlKeyword.keys()) {
|
||||||
const clItem = this.makekeywordCompletionItem(keyword);
|
const clItem = this.makekeywordCompletionItem(keyword, 'vhdl keyword');
|
||||||
vhdlKeywordItem.push(clItem);
|
vhdlKeywordItems.push(clItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vhdlKeywordItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
private makeCompilerKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
|
||||||
const items = [];
|
|
||||||
const targetRange = document.getWordRangeAtPosition(position, /[`_0-9a-zA-Z]+/);
|
|
||||||
const targetWord = document.getText(targetRange);
|
|
||||||
const prefix = targetWord.startsWith('`') ? '' : '`';
|
|
||||||
for (const keyword of vhdlKeyword.compilerKeys()) {
|
for (const keyword of vhdlKeyword.compilerKeys()) {
|
||||||
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword);
|
const clItem = this.makekeywordCompletionItem(keyword, 'IEEE lib function');
|
||||||
clItem.insertText = new vscode.SnippetString(prefix + keyword);
|
vhdlKeywordItems.push(clItem);
|
||||||
clItem.detail = 'compiler directive';
|
|
||||||
items.push(clItem);
|
|
||||||
}
|
}
|
||||||
return items;
|
|
||||||
}
|
|
||||||
|
|
||||||
private makeSystemKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
|
||||||
const items = [];
|
|
||||||
for (const keyword of vhdlKeyword.systemKeys()) {
|
for (const keyword of vhdlKeyword.systemKeys()) {
|
||||||
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Method);
|
const clItem = this.makekeywordCompletionItem(keyword, 'vhdl keyword');
|
||||||
clItem.insertText = new vscode.SnippetString('\\$' + keyword + '($1);');
|
vhdlKeywordItems.push(clItem);
|
||||||
clItem.detail = 'system task';
|
|
||||||
items.push(clItem);
|
|
||||||
}
|
}
|
||||||
return items;
|
this.keywordItems = vhdlKeywordItems;
|
||||||
|
return vhdlKeywordItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private makekeywordCompletionItem(keyword: string, detail: string): vscode.CompletionItem {
|
||||||
private makekeywordCompletionItem(keyword: string): vscode.CompletionItem {
|
|
||||||
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword);
|
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword);
|
||||||
clItem.detail = 'keyword';
|
clItem.detail = detail;
|
||||||
|
|
||||||
switch (keyword) {
|
switch (keyword) {
|
||||||
case 'begin': clItem.insertText = new vscode.SnippetString("begin$1\nend"); break;
|
case 'begin': clItem.insertText = new vscode.SnippetString("begin$1\nend"); break;
|
||||||
case 'function': clItem.insertText = new vscode.SnippetString("function ${1:name}\n\nendfunction"); break;
|
case 'entity': clItem.insertText = new vscode.SnippetString("entity ${1:name} is\n\t${2:content}\nend entity;"); break;
|
||||||
|
case 'architecture': clItem.insertText = new vscode.SnippetString("architecture ${1:name} of ${2:entity} is\n\t${3:definition}\nbegin\n\t${4:content}\nend architecture;"); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return clItem;
|
return clItem;
|
||||||
|
@ -184,6 +184,7 @@ class VlogPositionPortProvider implements vscode.CompletionItemProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
||||||
|
keywordItems: vscode.CompletionItem[] | undefined;
|
||||||
public async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Promise<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem> | null | undefined> {
|
public async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Promise<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem> | null | undefined> {
|
||||||
// console.log('VlogCompletionProvider');
|
// console.log('VlogCompletionProvider');
|
||||||
|
|
||||||
@ -237,13 +238,16 @@ class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private makeKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
private makeKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
||||||
const vlogKeywordItem = [];
|
if (this.keywordItems !== undefined && this.keywordItems.length > 0) {
|
||||||
|
return this.keywordItems;
|
||||||
|
}
|
||||||
|
const vlogKeywordItems: vscode.CompletionItem[] = [];
|
||||||
for (const keyword of vlogKeyword.keys()) {
|
for (const keyword of vlogKeyword.keys()) {
|
||||||
const clItem = this.makekeywordCompletionItem(keyword);
|
const clItem = this.makekeywordCompletionItem(keyword);
|
||||||
vlogKeywordItem.push(clItem);
|
vlogKeywordItems.push(clItem);
|
||||||
}
|
}
|
||||||
|
this.keywordItems = vlogKeywordItems;
|
||||||
return vlogKeywordItem;
|
return vlogKeywordItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
private makeCompilerKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
private makeCompilerKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
||||||
@ -274,7 +278,7 @@ class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
|||||||
|
|
||||||
private makekeywordCompletionItem(keyword: string): vscode.CompletionItem {
|
private makekeywordCompletionItem(keyword: string): vscode.CompletionItem {
|
||||||
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword);
|
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword);
|
||||||
clItem.detail = 'keyword';
|
clItem.detail = 'verilog keyword';
|
||||||
|
|
||||||
switch (keyword) {
|
switch (keyword) {
|
||||||
case 'begin': clItem.insertText = new vscode.SnippetString("begin$1\nend"); break;
|
case 'begin': clItem.insertText = new vscode.SnippetString("begin$1\nend"); break;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { vlogDefinitionProvider } from './vlog';
|
import { vlogDefinitionProvider } from './vlog';
|
||||||
|
import { vhdlDefinitionProvider } from './vhdl';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
vlogDefinitionProvider
|
vlogDefinitionProvider,
|
||||||
|
vhdlDefinitionProvider
|
||||||
};
|
};
|
162
src/function/lsp/definition/vhdl.ts
Normal file
162
src/function/lsp/definition/vhdl.ts
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
|
import { hdlPath } from '../../../hdlFs';
|
||||||
|
import { hdlParam } from '../../../hdlParser';
|
||||||
|
import { All } from '../../../../resources/hdlParser';
|
||||||
|
import { vlogKeyword } from '../util/keyword';
|
||||||
|
import * as util from '../util';
|
||||||
|
import { MainOutput, ReportType } from '../../../global';
|
||||||
|
import { hdlSymbolStorage } from '../core';
|
||||||
|
|
||||||
|
|
||||||
|
class VhdlDefinitionProvider implements vscode.DefinitionProvider {
|
||||||
|
public async provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Location | vscode.LocationLink[] | null> {
|
||||||
|
// console.log('VhdlDefinitionProvider');
|
||||||
|
|
||||||
|
// get current words
|
||||||
|
const wordRange = document.getWordRangeAtPosition(position, /[`_0-9A-Za-z]+/);
|
||||||
|
if (!wordRange) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const targetWord = document.getText(wordRange);
|
||||||
|
|
||||||
|
// check if need skip
|
||||||
|
if (this.needSkip(document, position, targetWord)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = document.fileName;
|
||||||
|
const vlogAll = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
|
if (!vlogAll) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
const location = await this.makeDefinition(document, position, vlogAll, targetWord, wordRange);
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private needSkip(document: vscode.TextDocument, position: vscode.Position, targetWord: string): boolean {
|
||||||
|
// check keyword
|
||||||
|
if (vlogKeyword.isKeyword(targetWord)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check comment
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async makeDefinition(document: vscode.TextDocument, position: vscode.Position, all: All, targetWord: string, targetWordRange: vscode.Range): Promise<vscode.Location | vscode.LocationLink[] | null> {
|
||||||
|
const filePath = hdlPath.toSlash(document.fileName);
|
||||||
|
const lineText = document.lineAt(position).text;
|
||||||
|
|
||||||
|
// match `include
|
||||||
|
const includeResult = util.matchInclude(document, position, all.macro.includes);
|
||||||
|
|
||||||
|
if (includeResult) {
|
||||||
|
const absPath = hdlPath.rel2abs(filePath, includeResult.name);
|
||||||
|
const targetFile = vscode.Uri.file(absPath);
|
||||||
|
const targetPosition = new vscode.Position(0, 0);
|
||||||
|
const targetRange = new vscode.Range(targetPosition, targetPosition);
|
||||||
|
const originSelectionRange = document.getWordRangeAtPosition(position, /["\.\\\/_0-9A-Za-z]+/);
|
||||||
|
const link: vscode.LocationLink = { targetUri: targetFile, targetRange, originSelectionRange };
|
||||||
|
return [link];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// match macro
|
||||||
|
const macroResult = util.matchDefineMacro(position, targetWord, all.macro.defines);
|
||||||
|
if (macroResult) {
|
||||||
|
const targetRange = util.transformRange(macroResult.range, -1, -1);
|
||||||
|
const link: vscode.LocationLink = { targetUri: document.uri, targetRange: targetRange, originSelectionRange: targetWordRange };
|
||||||
|
return [link];
|
||||||
|
}
|
||||||
|
|
||||||
|
// locate at one module
|
||||||
|
const scopeSymbols = util.filterSymbolScope(position, all.content);
|
||||||
|
if (!scopeSymbols || !scopeSymbols.module) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const currentModule = hdlParam.getHdlModule(filePath, scopeSymbols.module.name);
|
||||||
|
if (!currentModule) {
|
||||||
|
MainOutput.report('Fail to get HdlModule ' + filePath + ' ' + scopeSymbols.module.name, ReportType.Debug);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// match instance
|
||||||
|
const instResult = util.matchInstance(targetWord, currentModule);
|
||||||
|
if (instResult) {
|
||||||
|
const instModule = instResult.module;
|
||||||
|
if (!instModule || !instResult.instModPath) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const targetFile = vscode.Uri.file(instResult.instModPath);
|
||||||
|
const targetRange = util.transformRange(instModule.range, -1, 0, 1);
|
||||||
|
const link: vscode.LocationLink = { targetUri: targetFile, targetRange };
|
||||||
|
return [link];
|
||||||
|
}
|
||||||
|
|
||||||
|
// match port or param definition (position input)
|
||||||
|
if (util.isPositionInput(lineText, position.character)) {
|
||||||
|
const currentInstResult = util.filterInstanceByPosition(position, scopeSymbols.symbols, currentModule);
|
||||||
|
if (!currentInstResult || !currentInstResult.instModPath) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const instParamPromise = util.getInstParamByPosition(currentInstResult, position, targetWord);
|
||||||
|
const instPortPromise = util.getInstPortByPosition(currentInstResult, position, targetWord);
|
||||||
|
|
||||||
|
const instParam = await instParamPromise;
|
||||||
|
const instPort = await instPortPromise;
|
||||||
|
const instModPathUri = vscode.Uri.file(currentInstResult.instModPath);
|
||||||
|
|
||||||
|
if (instParam) {
|
||||||
|
const targetRange = util.transformRange(instParam.range, -1, 0);
|
||||||
|
const link: vscode.LocationLink = { targetUri: instModPathUri, targetRange };
|
||||||
|
return [link];
|
||||||
|
}
|
||||||
|
if (instPort) {
|
||||||
|
const targetRange = util.transformRange(instPort.range, -1, 0);
|
||||||
|
const link: vscode.LocationLink = { targetUri: instModPathUri, targetRange };
|
||||||
|
return [link];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// match params
|
||||||
|
const paramResult = util.matchParams(targetWord, currentModule);
|
||||||
|
|
||||||
|
if (paramResult) {
|
||||||
|
const targetRange = util.transformRange(paramResult.range, -1, 0);
|
||||||
|
const link: vscode.LocationLink = { targetUri: document.uri, targetRange };
|
||||||
|
return [link];
|
||||||
|
}
|
||||||
|
|
||||||
|
// match ports
|
||||||
|
const portResult = util.matchPorts(targetWord, currentModule);
|
||||||
|
|
||||||
|
if (portResult) {
|
||||||
|
const targetRange = util.transformRange(portResult.range, -1, 0);
|
||||||
|
const link: vscode.LocationLink = { targetUri: document.uri, targetRange };
|
||||||
|
return [link];
|
||||||
|
}
|
||||||
|
|
||||||
|
// match others
|
||||||
|
const normalResult = util.matchNormalSymbol(targetWord, scopeSymbols.symbols);
|
||||||
|
if (normalResult) {
|
||||||
|
const targetRange = util.transformRange(normalResult.range, -1, 0);
|
||||||
|
const link: vscode.LocationLink = { targetUri: document.uri, targetRange };
|
||||||
|
return [link];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const vhdlDefinitionProvider = new VhdlDefinitionProvider();
|
||||||
|
|
||||||
|
export {
|
||||||
|
vhdlDefinitionProvider
|
||||||
|
};
|
@ -1,6 +1,8 @@
|
|||||||
import { vlogDocSymbolProvider } from './vlog';
|
import { vlogDocSymbolProvider } from './vlog';
|
||||||
|
import { vhdlDocSymbolProvider } from './vhdl';
|
||||||
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
vlogDocSymbolProvider
|
vlogDocSymbolProvider,
|
||||||
|
vhdlDocSymbolProvider
|
||||||
};
|
};
|
64
src/function/lsp/docSymbol/vhdl.ts
Normal file
64
src/function/lsp/docSymbol/vhdl.ts
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
|
import { AllowNull } from '../../../global';
|
||||||
|
import { RawSymbol, Range } from '../../../hdlParser/common';
|
||||||
|
import { hdlSymbolStorage } from '../core';
|
||||||
|
|
||||||
|
import { positionAfterEqual } from '../util';
|
||||||
|
|
||||||
|
interface DocSymbolContainer {
|
||||||
|
docSymbol: AllowNull<vscode.DocumentSymbol>,
|
||||||
|
range: AllowNull<Range>
|
||||||
|
};
|
||||||
|
|
||||||
|
class VhdlDocSymbolProvider implements vscode.DocumentSymbolProvider {
|
||||||
|
public async provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentSymbol[]> {
|
||||||
|
|
||||||
|
const path = document.fileName;
|
||||||
|
const vhdlAll = await hdlSymbolStorage.getSymbol(path);
|
||||||
|
|
||||||
|
if (!vhdlAll || !vhdlAll.content) {
|
||||||
|
return [];
|
||||||
|
} else {
|
||||||
|
const symbols = vhdlAll.content;
|
||||||
|
const symbolInfos = this.makeDocumentSymbols(document, symbols);
|
||||||
|
return symbolInfos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private makeDocumentSymbols(document: vscode.TextDocument, symbols: RawSymbol[]): vscode.DocumentSymbol[] {
|
||||||
|
const docSymbols: vscode.DocumentSymbol[] = [];
|
||||||
|
|
||||||
|
for (const symbol of symbols) {
|
||||||
|
const symbolStart = new vscode.Position(symbol.range.start.line - 1, symbol.range.start.character);
|
||||||
|
const symbolEnd = new vscode.Position(symbol.range.end.line - 1, symbol.range.end.character);
|
||||||
|
const symbolRange = new vscode.Range(symbolStart, symbolEnd);
|
||||||
|
|
||||||
|
if (symbol.type === 'entity') {
|
||||||
|
const docSymbol = new vscode.DocumentSymbol(symbol.name,
|
||||||
|
symbol.name,
|
||||||
|
vscode.SymbolKind.Interface,
|
||||||
|
symbolRange,
|
||||||
|
symbolRange);
|
||||||
|
docSymbols.push(docSymbol);
|
||||||
|
} else if (symbol.type === 'port') {
|
||||||
|
const parentEntity = docSymbols[docSymbols.length - 1];
|
||||||
|
const docSymbol = new vscode.DocumentSymbol(symbol.name,
|
||||||
|
symbol.name,
|
||||||
|
vscode.SymbolKind.Method,
|
||||||
|
symbolRange,
|
||||||
|
symbolRange);
|
||||||
|
parentEntity.children.push(docSymbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return docSymbols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const vhdlDocSymbolProvider = new VhdlDocSymbolProvider();
|
||||||
|
|
||||||
|
export {
|
||||||
|
vhdlDocSymbolProvider
|
||||||
|
};
|
@ -128,7 +128,7 @@ class VlogDocSymbolProvider implements vscode.DocumentSymbolProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getSymbolKind(name: string): vscode.SymbolKind {
|
private getSymbolKind(name: string): vscode.SymbolKind {
|
||||||
if (name.indexOf('[') !== -1) {
|
if (name.indexOf('[') !== -1) {
|
||||||
return vscode.SymbolKind.Array;
|
return vscode.SymbolKind.Array;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import { vlogHoverProvider } from './vlog';
|
import { vlogHoverProvider } from './vlog';
|
||||||
|
import { vhdlHoverProvider } from './vhdl';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
vlogHoverProvider
|
vlogHoverProvider,
|
||||||
|
vhdlHoverProvider
|
||||||
};
|
};
|
204
src/function/lsp/hover/vhdl.ts
Normal file
204
src/function/lsp/hover/vhdl.ts
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
|
import { hdlPath } from '../../../hdlFs';
|
||||||
|
import { hdlParam } from '../../../hdlParser';
|
||||||
|
import { All } from '../../../../resources/hdlParser';
|
||||||
|
import { vlogKeyword } from '../util/keyword';
|
||||||
|
import * as util from '../util';
|
||||||
|
import { MainOutput, ReportType } from '../../../global';
|
||||||
|
import { HdlLangID } from '../../../global/enum';
|
||||||
|
import { hdlSymbolStorage } from '../core';
|
||||||
|
|
||||||
|
|
||||||
|
class VhdlHoverProvider implements vscode.HoverProvider {
|
||||||
|
public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Hover | null> {
|
||||||
|
// console.log('VhdlHoverProvider');
|
||||||
|
|
||||||
|
// get current words
|
||||||
|
const wordRange = document.getWordRangeAtPosition(position, /[`_0-9A-Za-z]+/);
|
||||||
|
if (!wordRange) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const targetWord = document.getText(wordRange);
|
||||||
|
|
||||||
|
// check if need skip
|
||||||
|
if (this.needSkip(document, position, targetWord)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = document.fileName;
|
||||||
|
const vlogAll = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
|
if (!vlogAll) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
const hover = await this.makeHover(document, position, vlogAll, targetWord, wordRange);
|
||||||
|
return hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private needSkip(document: vscode.TextDocument, position: vscode.Position, targetWord: string): boolean {
|
||||||
|
// check keyword
|
||||||
|
if (vlogKeyword.isKeyword(targetWord)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check comment
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async makeHover(document: vscode.TextDocument, position: vscode.Position, all: All, targetWord: string, targetWordRange: vscode.Range): Promise<vscode.Hover | null> {
|
||||||
|
const lineText = document.lineAt(position).text;
|
||||||
|
const filePath = hdlPath.toSlash(document.fileName);
|
||||||
|
|
||||||
|
// total content rendered on the hover box
|
||||||
|
const content = new vscode.MarkdownString('', true);
|
||||||
|
|
||||||
|
// match `include
|
||||||
|
const includeResult = util.matchInclude(document, position, all.macro.includes);
|
||||||
|
if (includeResult) {
|
||||||
|
const absPath = hdlPath.rel2abs(filePath, includeResult.name);
|
||||||
|
content.appendCodeblock(`"${absPath}"`, HdlLangID.Verilog);
|
||||||
|
const targetRange = document.getWordRangeAtPosition(position, /[1-9a-zA-Z_\.]+/);
|
||||||
|
return new vscode.Hover(content, targetRange);
|
||||||
|
} else if (lineText.trim().startsWith('`include')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// match macro
|
||||||
|
const macroResult = util.matchDefineMacro(position, targetWord, all.macro.defines);
|
||||||
|
if (macroResult) {
|
||||||
|
const name = macroResult.name;
|
||||||
|
const value = macroResult.value;
|
||||||
|
content.appendCodeblock(`\`define ${name} ${value}`, HdlLangID.Verilog);
|
||||||
|
return new vscode.Hover(content, targetWordRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
// locate at one module
|
||||||
|
const scopeSymbols = util.filterSymbolScope(position, all.content);
|
||||||
|
if (!scopeSymbols || !scopeSymbols.module || !hdlParam.hasHdlModule(filePath, scopeSymbols.module.name)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const currentModule = hdlParam.getHdlModule(filePath, scopeSymbols.module.name);
|
||||||
|
if (!currentModule) {
|
||||||
|
MainOutput.report('Fail to get HdlModule ' + filePath + ' ' + scopeSymbols.module.name, ReportType.Debug);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// match instance
|
||||||
|
const instResult = util.matchInstance(targetWord, currentModule);
|
||||||
|
if (instResult) {
|
||||||
|
const instModule = instResult.module;
|
||||||
|
if (!instModule || !instResult.instModPath) {
|
||||||
|
content.appendMarkdown('cannot find the definition of the module');
|
||||||
|
return new vscode.Hover(content);
|
||||||
|
}
|
||||||
|
await util.makeVlogHoverContent(content, instModule);
|
||||||
|
return new vscode.Hover(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// match port or param definition (position input)
|
||||||
|
/** for example, when you hover the ".clk" below, the branch will be entered
|
||||||
|
template u_template(
|
||||||
|
//input
|
||||||
|
.clk ( clk ),
|
||||||
|
);
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if (util.isPositionInput(lineText, position.character)) {
|
||||||
|
console.log('enter position input');
|
||||||
|
const currentInstResult = util.filterInstanceByPosition(position, scopeSymbols.symbols, currentModule);
|
||||||
|
if (!currentInstResult || !currentInstResult.instModPath) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
console.log(currentInstResult);
|
||||||
|
|
||||||
|
const instParamPromise = util.getInstParamByPosition(currentInstResult, position, targetWord);
|
||||||
|
const instPortPromise = util.getInstPortByPosition(currentInstResult, position, targetWord);
|
||||||
|
|
||||||
|
const instParam = await instParamPromise;
|
||||||
|
const instPort = await instPortPromise;
|
||||||
|
|
||||||
|
if (instParam) {
|
||||||
|
const paramComment = await util.searchCommentAround(currentInstResult.instModPath, instParam.range);
|
||||||
|
const paramDesc = util.makeParamDesc(instParam);
|
||||||
|
content.appendCodeblock(paramDesc, HdlLangID.Verilog);
|
||||||
|
if (paramComment) {
|
||||||
|
content.appendCodeblock(paramComment, HdlLangID.Verilog);
|
||||||
|
}
|
||||||
|
return new vscode.Hover(content);
|
||||||
|
}
|
||||||
|
if (instPort) {
|
||||||
|
const portComment = await util.searchCommentAround(currentInstResult.instModPath, instPort.range);
|
||||||
|
const portDesc = util.makePortDesc(instPort);
|
||||||
|
content.appendCodeblock(portDesc, HdlLangID.Verilog);
|
||||||
|
if (portComment) {
|
||||||
|
content.appendCodeblock(portComment, HdlLangID.Verilog);
|
||||||
|
}
|
||||||
|
return new vscode.Hover(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// match params
|
||||||
|
const paramResult = util.matchParams(targetWord, currentModule);
|
||||||
|
if (paramResult) {
|
||||||
|
const paramComment = await util.searchCommentAround(filePath, paramResult.range);
|
||||||
|
const paramDesc = util.makeParamDesc(paramResult);
|
||||||
|
content.appendCodeblock(paramDesc, HdlLangID.Verilog);
|
||||||
|
if (paramComment) {
|
||||||
|
content.appendCodeblock(paramComment, HdlLangID.Verilog);
|
||||||
|
}
|
||||||
|
return new vscode.Hover(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// match ports
|
||||||
|
const portResult = util.matchPorts(targetWord, currentModule);
|
||||||
|
if (portResult) {
|
||||||
|
const portComment = await util.searchCommentAround(filePath, portResult.range);
|
||||||
|
const portDesc = util.makePortDesc(portResult);
|
||||||
|
content.appendCodeblock(portDesc, HdlLangID.Verilog);
|
||||||
|
if (portComment) {
|
||||||
|
content.appendCodeblock(portComment, HdlLangID.Verilog);
|
||||||
|
}
|
||||||
|
return new vscode.Hover(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// match others
|
||||||
|
const normalResult = util.matchNormalSymbol(targetWord, scopeSymbols.symbols);
|
||||||
|
if (normalResult) {
|
||||||
|
const normalComment = await util.searchCommentAround(filePath, normalResult.range);
|
||||||
|
const normalDesc = util.makeNormalDesc(normalResult);
|
||||||
|
|
||||||
|
content.appendCodeblock(normalDesc, HdlLangID.Verilog);
|
||||||
|
if (normalComment) {
|
||||||
|
content.appendCodeblock(normalComment, HdlLangID.Verilog);
|
||||||
|
}
|
||||||
|
return new vscode.Hover(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// feature 1. number signed and unsigned number display
|
||||||
|
const numberResult = util.transferVlogNumber(lineText, position.character);
|
||||||
|
if (numberResult) {
|
||||||
|
const bits = targetWord.length - 1;
|
||||||
|
content.appendCodeblock(bits + "'" + targetWord, HdlLangID.Verilog);
|
||||||
|
content.appendMarkdown("`unsigned` " + numberResult.unsigned);
|
||||||
|
content.appendText('\n');
|
||||||
|
content.appendMarkdown("`signed` " + numberResult.signed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new vscode.Hover(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const vhdlHoverProvider = new VhdlHoverProvider();
|
||||||
|
|
||||||
|
export {
|
||||||
|
vhdlHoverProvider
|
||||||
|
};
|
@ -7,6 +7,7 @@ import { HdlLangID } from '../../../global/enum';
|
|||||||
import { vlogLinterManager } from './vlog';
|
import { vlogLinterManager } from './vlog';
|
||||||
import { vhdlLinterManager } from './vhdl';
|
import { vhdlLinterManager } from './vhdl';
|
||||||
import { easyExec } from '../../../global/util';
|
import { easyExec } from '../../../global/util';
|
||||||
|
import { LspOutput } from '../../../global';
|
||||||
|
|
||||||
let _selectVlogLinter: string | null = null;
|
let _selectVlogLinter: string | null = null;
|
||||||
let _selectVhdlLinter: string | null = null;
|
let _selectVhdlLinter: string | null = null;
|
||||||
@ -76,13 +77,20 @@ async function makeModelsimPickItem(langID: HdlLangID): Promise<LinterItem> {
|
|||||||
|
|
||||||
async function pickVlogLinter() {
|
async function pickVlogLinter() {
|
||||||
const pickWidget = vscode.window.createQuickPick<LinterItem>();
|
const pickWidget = vscode.window.createQuickPick<LinterItem>();
|
||||||
pickWidget.placeholder = 'select a linter for code diagnostic';
|
pickWidget.placeholder = 'select a linter for verilog code diagnostic';
|
||||||
pickWidget.canSelectMany = false;
|
pickWidget.canSelectMany = false;
|
||||||
pickWidget.items = [
|
|
||||||
await makeDefaultPickItem(),
|
await vscode.window.withProgress({
|
||||||
await makeVivadoPickItem(HdlLangID.Verilog),
|
location: vscode.ProgressLocation.Notification,
|
||||||
await makeModelsimPickItem(HdlLangID.Verilog)
|
title: 'Parsing local environment ...',
|
||||||
];
|
cancellable: true
|
||||||
|
}, async () => {
|
||||||
|
pickWidget.items = [
|
||||||
|
await makeDefaultPickItem(),
|
||||||
|
await makeVivadoPickItem(HdlLangID.Verilog),
|
||||||
|
await makeModelsimPickItem(HdlLangID.Verilog)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
pickWidget.onDidChangeSelection(items => {
|
pickWidget.onDidChangeSelection(items => {
|
||||||
const selectedItem = items[0];
|
const selectedItem = items[0];
|
||||||
@ -101,7 +109,36 @@ async function pickVlogLinter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function pickVhdlLinter() {
|
async function pickVhdlLinter() {
|
||||||
|
const pickWidget = vscode.window.createQuickPick<LinterItem>();
|
||||||
|
pickWidget.placeholder = 'select a linter for code diagnostic';
|
||||||
|
pickWidget.canSelectMany = false;
|
||||||
|
|
||||||
|
await vscode.window.withProgress({
|
||||||
|
location: vscode.ProgressLocation.Notification,
|
||||||
|
title: 'Parsing local environment ...',
|
||||||
|
cancellable: true
|
||||||
|
}, async () => {
|
||||||
|
pickWidget.items = [
|
||||||
|
await makeDefaultPickItem(),
|
||||||
|
await makeVivadoPickItem(HdlLangID.Vhdl),
|
||||||
|
await makeModelsimPickItem(HdlLangID.Vhdl)
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
pickWidget.onDidChangeSelection(items => {
|
||||||
|
const selectedItem = items[0];
|
||||||
|
_selectVlogLinter = selectedItem.name;
|
||||||
|
});
|
||||||
|
|
||||||
|
pickWidget.onDidAccept(() => {
|
||||||
|
if (_selectVlogLinter) {
|
||||||
|
const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vhdl');
|
||||||
|
vlogLspConfig.update('diagnostor', _selectVlogLinter);
|
||||||
|
pickWidget.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pickWidget.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import { LspOutput, ReportType } from '../../../global';
|
|||||||
class DefaultVlogLinter implements BaseLinter {
|
class DefaultVlogLinter implements BaseLinter {
|
||||||
diagnostic: vscode.DiagnosticCollection;
|
diagnostic: vscode.DiagnosticCollection;
|
||||||
constructor() {
|
constructor() {
|
||||||
this.diagnostic = vscode.languages.createDiagnosticCollection();
|
this.diagnostic = vscode.languages.createDiagnosticCollection('Digital-IDE Default Linter');
|
||||||
}
|
}
|
||||||
|
|
||||||
async lint(document: vscode.TextDocument): Promise<void> {
|
async lint(document: vscode.TextDocument): Promise<void> {
|
||||||
@ -22,14 +22,16 @@ class DefaultVlogLinter implements BaseLinter {
|
|||||||
const diagnostics = this.provideDiagnostics(document, vlogAll);
|
const diagnostics = this.provideDiagnostics(document, vlogAll);
|
||||||
this.diagnostic.set(document.uri, diagnostics);
|
this.diagnostic.set(document.uri, diagnostics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private provideDiagnostics(document: vscode.TextDocument, all: All): vscode.Diagnostic[] {
|
private provideDiagnostics(document: vscode.TextDocument, all: All): vscode.Diagnostic[] {
|
||||||
const diagnostics: vscode.Diagnostic[] = [];
|
const diagnostics: vscode.Diagnostic[] = [];
|
||||||
if (all.error && all.error.length > 0) {
|
if (all.error && all.error.length > 0) {
|
||||||
for (const hdlError of all.error) {
|
for (const hdlError of all.error) {
|
||||||
|
LspOutput.report(`<default linter> line: ${hdlError.range.line}, info: ${hdlError.message}`, ReportType.Run);
|
||||||
|
const syntaxInfo = hdlError.message.replace(/\\r\\n/g, '\n');
|
||||||
const range = this.makeCorrectRange(document, hdlError.range);
|
const range = this.makeCorrectRange(document, hdlError.range);
|
||||||
const diag = new vscode.Diagnostic(range, hdlError.message, hdlError.severity);
|
const diag = new vscode.Diagnostic(range, syntaxInfo, hdlError.severity);
|
||||||
diag.source = hdlError.source;
|
diag.source = hdlError.source;
|
||||||
diagnostics.push(diag);
|
diagnostics.push(diag);
|
||||||
}
|
}
|
||||||
@ -78,7 +80,7 @@ class DefaultVlogLinter implements BaseLinter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class DefaultVHDLLinter implements BaseLinter {
|
class DefaultVhdlLinter implements BaseLinter {
|
||||||
diagnostic: vscode.DiagnosticCollection;
|
diagnostic: vscode.DiagnosticCollection;
|
||||||
constructor() {
|
constructor() {
|
||||||
this.diagnostic = vscode.languages.createDiagnosticCollection();
|
this.diagnostic = vscode.languages.createDiagnosticCollection();
|
||||||
@ -99,6 +101,8 @@ class DefaultVHDLLinter implements BaseLinter {
|
|||||||
const diagnostics: vscode.Diagnostic[] = [];
|
const diagnostics: vscode.Diagnostic[] = [];
|
||||||
if (all.error && all.error.length > 0) {
|
if (all.error && all.error.length > 0) {
|
||||||
for (const hdlError of all.error) {
|
for (const hdlError of all.error) {
|
||||||
|
LspOutput.report(`<default linter> line: ${hdlError.range.line}, info: ${hdlError.message}`, ReportType.Run);
|
||||||
|
|
||||||
const range = this.makeCorrectRange(document, hdlError.range);
|
const range = this.makeCorrectRange(document, hdlError.range);
|
||||||
const diag = new vscode.Diagnostic(range, hdlError.message, hdlError.severity);
|
const diag = new vscode.Diagnostic(range, hdlError.message, hdlError.severity);
|
||||||
diag.source = hdlError.source;
|
diag.source = hdlError.source;
|
||||||
@ -150,11 +154,11 @@ class DefaultVHDLLinter implements BaseLinter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const defaultVlogLinter = new DefaultVlogLinter();
|
const defaultVlogLinter = new DefaultVlogLinter();
|
||||||
const defaultVHDLLinter = new DefaultVHDLLinter();
|
const defaultVhdlLinter = new DefaultVhdlLinter();
|
||||||
|
|
||||||
export {
|
export {
|
||||||
defaultVlogLinter,
|
defaultVlogLinter,
|
||||||
defaultVHDLLinter,
|
defaultVhdlLinter,
|
||||||
DefaultVlogLinter,
|
DefaultVlogLinter,
|
||||||
DefaultVHDLLinter
|
DefaultVhdlLinter
|
||||||
};
|
};
|
||||||
|
@ -43,7 +43,7 @@ class ModelsimLinter implements BaseLinter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const args = [filePath, ...linterArgs];
|
const args = [filePath, ...linterArgs];
|
||||||
const executor = this.executableInvokeNameMap.get(langID);
|
const executor = this.executableInvokeNameMap.get(langID);
|
||||||
if (executor !== undefined) {
|
if (executor !== undefined) {
|
||||||
const { stdout } = await easyExec(executor, args);
|
const { stdout } = await easyExec(executor, args);
|
||||||
if (stdout.length > 0) {
|
if (stdout.length > 0) {
|
||||||
|
@ -2,38 +2,54 @@ import * as vscode from 'vscode';
|
|||||||
import { LspOutput, ReportType } from '../../../global';
|
import { LspOutput, ReportType } from '../../../global';
|
||||||
import { HdlLangID } from '../../../global/enum';
|
import { HdlLangID } from '../../../global/enum';
|
||||||
import { BaseLinter, BaseManager } from './base';
|
import { BaseLinter, BaseManager } from './base';
|
||||||
import { defaultVlogLinter } from './default';
|
import { defaultVhdlLinter } from './default';
|
||||||
import { modelsimLinter } from './modelsim';
|
import { modelsimLinter } from './modelsim';
|
||||||
import { vivadoLinter } from './vivado';
|
import { vivadoLinter } from './vivado';
|
||||||
import { hdlFile, hdlPath } from '../../../hdlFs';
|
import { hdlFile, hdlPath } from '../../../hdlFs';
|
||||||
|
|
||||||
class VhdlLinterManager implements BaseManager {
|
class VhdlLinterManager implements BaseManager {
|
||||||
currentLinter: BaseLinter | undefined;
|
currentLinter: BaseLinter | undefined;
|
||||||
activateList: Map<string, boolean> = new Map<string, boolean>();
|
|
||||||
activateLinterName: string;
|
activateLinterName: string;
|
||||||
|
statusBarItem: vscode.StatusBarItem;
|
||||||
|
initialized: boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.activateList.set('vivado', false);
|
|
||||||
this.activateList.set('modelsim', false);
|
|
||||||
this.activateList.set('default', false);
|
|
||||||
this.activateLinterName = 'default';
|
this.activateLinterName = 'default';
|
||||||
|
this.initialized = false;
|
||||||
|
|
||||||
|
// make a status bar for rendering
|
||||||
|
this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
|
||||||
|
this.statusBarItem.command = 'digital-ide.lsp.vhdl.linter.pick';
|
||||||
|
|
||||||
|
// when changing file, hide if langID is not vhdl
|
||||||
|
vscode.window.onDidChangeActiveTextEditor(editor => {
|
||||||
|
if (!editor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const currentFileName = hdlPath.toSlash(editor.document.fileName);
|
||||||
|
|
||||||
|
if (hdlFile.isVhdlFile(currentFileName)) {
|
||||||
|
this.statusBarItem.show();
|
||||||
|
} else {
|
||||||
|
this.statusBarItem.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// update when user's config is changed
|
// update when user's config is changed
|
||||||
vscode.workspace.onDidChangeConfiguration(() => {
|
vscode.workspace.onDidChangeConfiguration(() => {
|
||||||
const diagnostor = this.getUserDiagnostorSelection();
|
this.updateLinter();
|
||||||
const lastDiagnostor = this.activateLinterName;
|
|
||||||
if (diagnostor !== lastDiagnostor) {
|
|
||||||
LspOutput.report(`<vhdl lsp manager> detect linter setting changes, switch ${lastDiagnostor} to ${diagnostor}.`, );
|
|
||||||
this.updateLinter();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialise(): Promise<void> {
|
async initialise(): Promise<void> {
|
||||||
const success = await this.updateLinter();
|
const success = await this.updateLinter();
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.initialized = true;
|
||||||
|
|
||||||
for (const doc of vscode.workspace.textDocuments) {
|
for (const doc of vscode.workspace.textDocuments) {
|
||||||
const fileName = hdlPath.toSlash(doc.fileName);
|
const fileName = hdlPath.toSlash(doc.fileName);
|
||||||
if (hdlFile.isVhdlFile(fileName)) {
|
if (hdlFile.isVhdlFile(fileName)) {
|
||||||
@ -41,44 +57,83 @@ class VhdlLinterManager implements BaseManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LspOutput.report('<vhdl lsp manager> finish initialization of vhdl linter. Linter name: ' + this.activateLinterName, ReportType.Launch);
|
LspOutput.report('<vhdl lsp manager> finish initialization of vhdl linter. Linter name: ' + this.activateLinterName, ReportType.Launch);
|
||||||
|
|
||||||
|
// hide it if current window is not vhdl
|
||||||
|
const editor = vscode.window.activeTextEditor;
|
||||||
|
if (editor && hdlFile.isVhdlFile(editor.document.fileName)) {
|
||||||
|
this.statusBarItem.show();
|
||||||
|
} else {
|
||||||
|
this.statusBarItem.hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async lint(document: vscode.TextDocument) {
|
async lint(document: vscode.TextDocument) {
|
||||||
|
this.currentLinter?.remove(document.uri);
|
||||||
await this.currentLinter?.lint(document);
|
await this.currentLinter?.lint(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove(uri: vscode.Uri): Promise<void> {
|
async remove(uri: vscode.Uri): Promise<void> {
|
||||||
this.currentLinter?.remove(uri);
|
this.currentLinter?.remove(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUserDiagnostorSelection() {
|
public getUserDiagnostorSelection() {
|
||||||
const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vlog');
|
const vhdlLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vhdl');
|
||||||
const diagnostor = vlogLspConfig.get('diagnostor', 'default');
|
const diagnostor = vhdlLspConfig.get('diagnostor', 'xxx');
|
||||||
return diagnostor;
|
return diagnostor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateLinter(): Promise<boolean> {
|
public async updateLinter(): Promise<boolean> {
|
||||||
const diagnostor = this.getUserDiagnostorSelection();
|
const diagnostorName = this.getUserDiagnostorSelection();
|
||||||
switch (diagnostor) {
|
|
||||||
case 'vivado': return this.activateVivado();
|
const lastDiagnostorName = this.activateLinterName;
|
||||||
case 'modelsim': return this.activateModelsim();
|
const lastDiagnostor = this.currentLinter;
|
||||||
case 'default': return this.activateDefault();
|
|
||||||
default: return this.activateDefault();
|
if (this.initialized && diagnostorName === lastDiagnostorName) {
|
||||||
}
|
// no need for update
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
LspOutput.report(`<vhdl lsp manager> detect linter setting changes, switch from ${lastDiagnostorName} to ${diagnostorName}.`, ReportType.Launch);
|
||||||
|
|
||||||
|
let launch = false;
|
||||||
|
switch (diagnostorName) {
|
||||||
|
case 'vivado': launch = await this.activateVivado(); break;
|
||||||
|
case 'modelsim': launch = await this.activateModelsim(); break;
|
||||||
|
case 'default': launch = await this.activateDefault(); break;
|
||||||
|
default: launch = await this.activateDefault(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const doc of vscode.workspace.textDocuments) {
|
||||||
|
const fileName = hdlPath.toSlash(doc.fileName);
|
||||||
|
if (hdlFile.isVhdlFile(fileName)) {
|
||||||
|
lastDiagnostor?.remove(doc.uri);
|
||||||
|
await this.lint(doc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return launch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async activateVivado(): Promise<boolean> {
|
public async activateVivado(): Promise<boolean> {
|
||||||
const selectedLinter = vivadoLinter;
|
const selectedLinter = vivadoLinter;
|
||||||
let launch = true;
|
let launch = true;
|
||||||
|
|
||||||
if (this.activateList.get('vivado') === false) {
|
launch = await selectedLinter.initialise(HdlLangID.Vhdl);
|
||||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
if (launch) {
|
||||||
this.activateList.set('vivado', true);
|
this.statusBarItem.text = '$(getting-started-beginner) Linter(vivado)';
|
||||||
|
|
||||||
LspOutput.report('<vhdl lsp manager> vivado linter has been activated', ReportType.Info);
|
LspOutput.report('<vhdl lsp manager> vivado linter has been activated', ReportType.Info);
|
||||||
|
} else {
|
||||||
|
this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
||||||
|
this.statusBarItem.tooltip = 'Fail to launch vivado linter';
|
||||||
|
this.statusBarItem.text = '$(extensions-warning-message) Linter(vivado)';
|
||||||
|
|
||||||
|
LspOutput.report('<vhdl lsp manager> Fail to launch vivado linter', ReportType.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentLinter = selectedLinter;
|
this.currentLinter = selectedLinter;
|
||||||
this.activateLinterName = 'vivado';
|
this.activateLinterName = 'vivado';
|
||||||
|
this.statusBarItem.show();
|
||||||
|
|
||||||
return launch;
|
return launch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,29 +141,46 @@ class VhdlLinterManager implements BaseManager {
|
|||||||
const selectedLinter = modelsimLinter;
|
const selectedLinter = modelsimLinter;
|
||||||
let launch = true;
|
let launch = true;
|
||||||
|
|
||||||
if (this.activateList.get('modelsim') === false) {
|
launch = await selectedLinter.initialise(HdlLangID.Vhdl);
|
||||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
if (launch) {
|
||||||
this.activateList.set('modelsim', true);
|
this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)';
|
||||||
LspOutput.report('<vhdl lsp manager> modelsim linter has been activated', ReportType.Info);
|
|
||||||
|
LspOutput.report('<vhdl lsp manager> modelsim linter has been activated', ReportType.Info);
|
||||||
|
} else {
|
||||||
|
this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
||||||
|
this.statusBarItem.tooltip = 'Fail to launch modelsim linter';
|
||||||
|
this.statusBarItem.text = '$(extensions-warning-message) Linter(modelsim)';
|
||||||
|
|
||||||
|
LspOutput.report('<vhdl lsp manager> Fail to launch modelsim linter', ReportType.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentLinter = selectedLinter;
|
this.currentLinter = selectedLinter;
|
||||||
this.activateLinterName = 'modelsim';
|
this.activateLinterName = 'modelsim';
|
||||||
|
this.statusBarItem.show();
|
||||||
|
|
||||||
return launch;
|
return launch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async activateDefault(): Promise<boolean> {
|
public async activateDefault(): Promise<boolean> {
|
||||||
const selectedLinter = defaultVlogLinter;
|
const selectedLinter = defaultVhdlLinter;
|
||||||
let launch = true;
|
let launch = true;
|
||||||
|
|
||||||
if (this.activateList.get('default') === false) {
|
if (launch) {
|
||||||
|
this.statusBarItem.text = '$(getting-started-beginner) Linter(default)';
|
||||||
|
|
||||||
this.activateList.set('default', true);
|
|
||||||
LspOutput.report('<vhdl lsp manager> default build-in linter has been activated', ReportType.Info);
|
LspOutput.report('<vhdl lsp manager> default build-in linter has been activated', ReportType.Info);
|
||||||
|
} else {
|
||||||
|
this.statusBarItem.backgroundColor = undefined;
|
||||||
|
this.statusBarItem.tooltip = 'Fail to launch default linter';
|
||||||
|
this.statusBarItem.text = '$(extensions-warning-message) Linter(default)';
|
||||||
|
|
||||||
|
LspOutput.report('<vhdl lsp manager> Fail to launch default linter', ReportType.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentLinter = selectedLinter;
|
this.currentLinter = selectedLinter;
|
||||||
this.activateLinterName = 'default';
|
this.activateLinterName = 'default';
|
||||||
|
this.statusBarItem.show();
|
||||||
|
|
||||||
return launch;
|
return launch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ class VivadoLinter implements BaseLinter {
|
|||||||
|
|
||||||
public async initialise(langID: HdlLangID): Promise<boolean> {
|
public async initialise(langID: HdlLangID): Promise<boolean> {
|
||||||
const executorPath = this.getExecutableFilePath(langID);
|
const executorPath = this.getExecutableFilePath(langID);
|
||||||
return this.setExecutableFilePath(executorPath, langID);
|
return await this.setExecutableFilePath(executorPath, langID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,19 +6,16 @@ import { defaultVlogLinter } from './default';
|
|||||||
import { modelsimLinter } from './modelsim';
|
import { modelsimLinter } from './modelsim';
|
||||||
import { vivadoLinter } from './vivado';
|
import { vivadoLinter } from './vivado';
|
||||||
import { hdlFile, hdlPath } from '../../../hdlFs';
|
import { hdlFile, hdlPath } from '../../../hdlFs';
|
||||||
import { isVerilogFile } from '../../../hdlFs/file';
|
|
||||||
|
|
||||||
class VlogLinterManager implements BaseManager {
|
class VlogLinterManager implements BaseManager {
|
||||||
currentLinter: BaseLinter | undefined;
|
currentLinter: BaseLinter | undefined;
|
||||||
activateList: Map<string, boolean> = new Map<string, boolean>();
|
|
||||||
activateLinterName: string;
|
activateLinterName: string;
|
||||||
statusBarItem: vscode.StatusBarItem;
|
statusBarItem: vscode.StatusBarItem;
|
||||||
|
initialized: boolean;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.activateList.set('vivado', false);
|
|
||||||
this.activateList.set('modelsim', false);
|
|
||||||
this.activateList.set('default', false);
|
|
||||||
this.activateLinterName = 'default';
|
this.activateLinterName = 'default';
|
||||||
|
this.initialized = false;
|
||||||
|
|
||||||
// make a status bar for rendering
|
// make a status bar for rendering
|
||||||
this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
|
this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
|
||||||
@ -31,7 +28,7 @@ class VlogLinterManager implements BaseManager {
|
|||||||
}
|
}
|
||||||
const currentFileName = hdlPath.toSlash(editor.document.fileName);
|
const currentFileName = hdlPath.toSlash(editor.document.fileName);
|
||||||
|
|
||||||
if (isVerilogFile(currentFileName)) {
|
if (hdlFile.isVerilogFile(currentFileName)) {
|
||||||
this.statusBarItem.show();
|
this.statusBarItem.show();
|
||||||
} else {
|
} else {
|
||||||
this.statusBarItem.hide();
|
this.statusBarItem.hide();
|
||||||
@ -40,21 +37,19 @@ class VlogLinterManager implements BaseManager {
|
|||||||
|
|
||||||
// update when user's config is changed
|
// update when user's config is changed
|
||||||
vscode.workspace.onDidChangeConfiguration(() => {
|
vscode.workspace.onDidChangeConfiguration(() => {
|
||||||
const diagnostor = this.getUserDiagnostorSelection();
|
this.updateLinter();
|
||||||
const lastDiagnostor = this.activateLinterName;
|
|
||||||
if (diagnostor !== lastDiagnostor) {
|
|
||||||
LspOutput.report(`<vlog lsp manager> detect linter setting changes, switch ${lastDiagnostor} to ${diagnostor}.`, );
|
|
||||||
this.updateLinter();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialise(): Promise<void> {
|
async initialise(): Promise<void> {
|
||||||
const success = await this.updateLinter();
|
const success = await this.updateLinter();
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.initialized = true;
|
||||||
|
|
||||||
for (const doc of vscode.workspace.textDocuments) {
|
for (const doc of vscode.workspace.textDocuments) {
|
||||||
const fileName = hdlPath.toSlash(doc.fileName);
|
const fileName = hdlPath.toSlash(doc.fileName);
|
||||||
if (hdlFile.isVerilogFile(fileName)) {
|
if (hdlFile.isVerilogFile(fileName)) {
|
||||||
@ -62,9 +57,18 @@ class VlogLinterManager implements BaseManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LspOutput.report('<vlog lsp manager> finish initialization of vlog linter. Linter name: ' + this.activateLinterName, ReportType.Launch);
|
LspOutput.report('<vlog lsp manager> finish initialization of vlog linter. Linter name: ' + this.activateLinterName, ReportType.Launch);
|
||||||
|
|
||||||
|
// hide it if current window is not verilog
|
||||||
|
const editor = vscode.window.activeTextEditor;
|
||||||
|
if (editor && hdlFile.isVerilogFile(editor.document.fileName)) {
|
||||||
|
this.statusBarItem.show();
|
||||||
|
} else {
|
||||||
|
this.statusBarItem.hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async lint(document: vscode.TextDocument) {
|
async lint(document: vscode.TextDocument) {
|
||||||
|
this.currentLinter?.remove(document.uri);
|
||||||
await this.currentLinter?.lint(document);
|
await this.currentLinter?.lint(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,44 +78,62 @@ class VlogLinterManager implements BaseManager {
|
|||||||
|
|
||||||
public getUserDiagnostorSelection() {
|
public getUserDiagnostorSelection() {
|
||||||
const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vlog');
|
const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vlog');
|
||||||
const diagnostor = vlogLspConfig.get('diagnostor', 'default');
|
const diagnostor = vlogLspConfig.get('diagnostor', 'xxx');
|
||||||
return diagnostor;
|
return diagnostor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateLinter() {
|
public async updateLinter(): Promise<boolean> {
|
||||||
const diagnostor = this.getUserDiagnostorSelection();
|
const diagnostorName = this.getUserDiagnostorSelection();
|
||||||
switch (diagnostor) {
|
|
||||||
case 'vivado': return this.activateVivado();
|
const lastDiagnostorName = this.activateLinterName;
|
||||||
case 'modelsim': return this.activateModelsim();
|
const lastDiagnostor = this.currentLinter;
|
||||||
case 'default': return this.activateDefault();
|
|
||||||
default: return this.activateDefault();
|
if (this.initialized && diagnostorName === lastDiagnostorName) {
|
||||||
|
// no need for update
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
LspOutput.report(`<vlog lsp manager> detect linter setting changes, switch from ${lastDiagnostorName} to ${diagnostorName}.`, ReportType.Launch);
|
||||||
|
|
||||||
|
let launch = false;
|
||||||
|
switch (diagnostorName) {
|
||||||
|
case 'vivado': launch = await this.activateVivado(); break;
|
||||||
|
case 'modelsim': launch = await this.activateModelsim(); break;
|
||||||
|
case 'default': launch = await this.activateDefault(); break;
|
||||||
|
default: launch = await this.activateDefault(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const doc of vscode.workspace.textDocuments) {
|
||||||
|
const fileName = hdlPath.toSlash(doc.fileName);
|
||||||
|
if (hdlFile.isVerilogFile(fileName)) {
|
||||||
|
lastDiagnostor?.remove(doc.uri);
|
||||||
|
await this.lint(doc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return launch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async activateVivado(): Promise<boolean> {
|
public async activateVivado(): Promise<boolean> {
|
||||||
const selectedLinter = vivadoLinter;
|
const selectedLinter = vivadoLinter;
|
||||||
let launch = true;
|
let launch = true;
|
||||||
|
|
||||||
if (this.activateList.get('vivado') === false) {
|
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
||||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
if (launch) {
|
||||||
if (launch) {
|
this.statusBarItem.text = '$(getting-started-beginner) Linter(vivado)';
|
||||||
this.statusBarItem.text = '$(getting-started-beginner) Linter(Vivado)';
|
|
||||||
|
|
||||||
this.activateList.set('vivado', true);
|
LspOutput.report('<vlog lsp manager> vivado linter has been activated', ReportType.Info);
|
||||||
LspOutput.report('<vlog lsp manager> vivado linter has been activated', ReportType.Info);
|
} else {
|
||||||
} else {
|
this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
||||||
this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
this.statusBarItem.tooltip = 'Fail to launch vivado linter';
|
||||||
this.statusBarItem.tooltip = 'Fail to launch vivado linter';
|
this.statusBarItem.text = '$(extensions-warning-message) Linter(vivado)';
|
||||||
this.statusBarItem.text = '$(extensions-warning-message) Linter(vivado)';
|
|
||||||
|
|
||||||
LspOutput.report('<vlog lsp manager> Fail to launch vivado linter', ReportType.Error);
|
LspOutput.report('<vlog lsp manager> Fail to launch vivado linter', ReportType.Error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentLinter = selectedLinter;
|
this.currentLinter = selectedLinter;
|
||||||
this.activateLinterName = 'vivado';
|
this.activateLinterName = 'vivado';
|
||||||
this.statusBarItem.show();
|
this.statusBarItem.show();
|
||||||
|
|
||||||
return launch;
|
return launch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,22 +141,17 @@ class VlogLinterManager implements BaseManager {
|
|||||||
const selectedLinter = modelsimLinter;
|
const selectedLinter = modelsimLinter;
|
||||||
let launch = true;
|
let launch = true;
|
||||||
|
|
||||||
if (this.activateList.get('modelsim') === false) {
|
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
||||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
if (launch) {
|
||||||
if (launch) {
|
this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)';
|
||||||
this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)';
|
|
||||||
|
|
||||||
this.activateList.set('modelsim', true);
|
|
||||||
LspOutput.report('<vlog lsp manager> modelsim linter has been activated', ReportType.Info);
|
|
||||||
} else {
|
|
||||||
this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
|
||||||
this.statusBarItem.tooltip = 'Fail to launch modelsim linter';
|
|
||||||
this.statusBarItem.text = '$(extensions-warning-message) Linter(modelsim)';
|
|
||||||
|
|
||||||
LspOutput.report('<vlog lsp manager> Fail to launch modelsim linter', ReportType.Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
LspOutput.report('<vlog lsp manager> modelsim linter has been activated', ReportType.Info);
|
||||||
|
} else {
|
||||||
|
this.statusBarItem.backgroundColor = new vscode.ThemeColor('statusBarItem.warningBackground');
|
||||||
|
this.statusBarItem.tooltip = 'Fail to launch modelsim linter';
|
||||||
|
this.statusBarItem.text = '$(extensions-warning-message) Linter(modelsim)';
|
||||||
|
|
||||||
|
LspOutput.report('<vlog lsp manager> Fail to launch modelsim linter', ReportType.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentLinter = selectedLinter;
|
this.currentLinter = selectedLinter;
|
||||||
@ -148,23 +165,22 @@ class VlogLinterManager implements BaseManager {
|
|||||||
const selectedLinter = defaultVlogLinter;
|
const selectedLinter = defaultVlogLinter;
|
||||||
let launch = true;
|
let launch = true;
|
||||||
|
|
||||||
if (this.activateList.get('default') === false) {
|
if (launch) {
|
||||||
if (launch) {
|
this.statusBarItem.text = '$(getting-started-beginner) Linter(default)';
|
||||||
this.statusBarItem.text = '$(getting-started-beginner) Linter(default)';
|
|
||||||
|
LspOutput.report('<vlog lsp manager> default build-in linter has been activated', ReportType.Info);
|
||||||
this.activateList.set('default', true);
|
} else {
|
||||||
LspOutput.report('<vlog lsp manager> default build-in linter has been activated', ReportType.Info);
|
this.statusBarItem.backgroundColor = undefined;
|
||||||
} else {
|
this.statusBarItem.tooltip = 'Fail to launch default linter';
|
||||||
this.statusBarItem.backgroundColor = undefined;
|
this.statusBarItem.text = '$(extensions-warning-message) Linter(default)';
|
||||||
this.statusBarItem.tooltip = 'Fail to launch default linter';
|
|
||||||
this.statusBarItem.text = '$(extensions-warning-message) Linter(default)';
|
|
||||||
|
|
||||||
LspOutput.report('<vlog lsp manager> Fail to launch default linter', ReportType.Error);
|
LspOutput.report('<vlog lsp manager> Fail to launch default linter', ReportType.Error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentLinter = selectedLinter;
|
this.currentLinter = selectedLinter;
|
||||||
this.activateLinterName = 'default';
|
this.activateLinterName = 'default';
|
||||||
|
this.statusBarItem.show();
|
||||||
|
|
||||||
return launch;
|
return launch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
|
|
||||||
class Keywords {
|
class Keywords {
|
||||||
private keywords: Set<string>;
|
private keywords: Set<string>;
|
||||||
private compilerKeywords: string[]; // start with `
|
private compilerKeywords: string[]; // start with `
|
||||||
@ -76,7 +75,24 @@ const vlogKeyword = new Keywords([
|
|||||||
);
|
);
|
||||||
|
|
||||||
// TODO : do vhdl and sv version
|
// TODO : do vhdl and sv version
|
||||||
const vhdlKeyword = new Keywords([], [], []);
|
const vhdlKeyword = new Keywords(["abs", "configuration", "impure", "null", "rem", "type",
|
||||||
|
"access", "constant", "in", "of", "report", "unaffected", "after", "disconnect",
|
||||||
|
"inertial", "on", "return", "units", "alias", "downto", "inout", "open", "rol",
|
||||||
|
"until", "all", "else", "is", "or", "ror", "use", "and", "elsif", "label", "others",
|
||||||
|
"select", "variable", "architecture", "end", "library", "out", "severity", "wait", "array",
|
||||||
|
"entity", "linkage", "package", "signal", "when", "assert", "exit", "literal", "port", "shared",
|
||||||
|
"while", "attribute", "file", "loop", "postponed", "sla", "with", "begin", "for", "map", "procedure",
|
||||||
|
"sll", "xnor", "block", "function", "mod", "process", "sra", "xor", "body", "generate", "nand", "pure",
|
||||||
|
"srl", "buffer", "generic", "new", "range", "subtype", "bus", "group", "next", "record", "then", "case",
|
||||||
|
"guarded", "nor", "register", "to",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"std_logic", "std_ulogic", "std_logic_vector", "std_ulogic_vector", "signed", "unsigned", "complex", "complex_polar",
|
||||||
|
"boolean", "bit", "character", "severity_level", "integer", "real", "time", "delay_length", "now", "natural", "positive",
|
||||||
|
"string", "bit_vector", "file_open_kind", "file_open_status", "fs", "ps", "ns", "us", "ms", "sec", "min", "hr",
|
||||||
|
"severity_level", "note", "warning", "error", "failure", "line", "text", "side", "width", "input", "output"
|
||||||
|
],
|
||||||
|
[]);
|
||||||
|
|
||||||
const systemverilogKeyword = new Keywords([
|
const systemverilogKeyword = new Keywords([
|
||||||
"above", "disable", "idt", "notif1", "supply0", "abs", "discipline", "idtmod",
|
"above", "disable", "idt", "notif1", "supply0", "abs", "discipline", "idtmod",
|
||||||
|
@ -12,7 +12,7 @@ interface CommandDataItem {
|
|||||||
cmd: string,
|
cmd: string,
|
||||||
icon: string,
|
icon: string,
|
||||||
tip: string,
|
tip: string,
|
||||||
children: any[]
|
children: CommandDataItem[]
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommandConfig = Record<string, {
|
type CommandConfig = Record<string, {
|
||||||
|
@ -14,6 +14,10 @@ async function openFileAtPosition(uri: vscode.Uri, line: number, character: numb
|
|||||||
}
|
}
|
||||||
|
|
||||||
function openFileByUri(path: string, range: Range) {
|
function openFileByUri(path: string, range: Range) {
|
||||||
|
if (range === undefined) {
|
||||||
|
vscode.window.showErrorMessage(`${path} not support jump yet`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (hdlPath.exist(path)) {
|
if (hdlPath.exist(path)) {
|
||||||
const uri = vscode.Uri.file(path);
|
const uri = vscode.Uri.file(path);
|
||||||
const start = range.start;
|
const start = range.start;
|
||||||
|
@ -120,7 +120,7 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
|
|||||||
|
|
||||||
// set iconPath
|
// set iconPath
|
||||||
treeItem.iconPath = getIconConfig(element.icon);
|
treeItem.iconPath = getIconConfig(element.icon);
|
||||||
|
|
||||||
// set command
|
// set command
|
||||||
treeItem.command = {
|
treeItem.command = {
|
||||||
title: "Open this HDL File",
|
title: "Open this HDL File",
|
||||||
@ -225,8 +225,8 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
|
|||||||
icon: 'file',
|
icon: 'file',
|
||||||
type: instance.name,
|
type: instance.name,
|
||||||
name: instance.type,
|
name: instance.type,
|
||||||
range: instance.module ? instance.module.range : null,
|
range: instance.range,
|
||||||
path: instance.instModPath,
|
path: instance.parentMod.path,
|
||||||
parent: element
|
parent: element
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -257,6 +257,10 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
|
|||||||
|
|
||||||
private judgeIcon(item: ModuleDataItem, instance: HdlInstance): string {
|
private judgeIcon(item: ModuleDataItem, instance: HdlInstance): string {
|
||||||
const workspacePath = opeParam.workspacePath;
|
const workspacePath = opeParam.workspacePath;
|
||||||
|
if (instance.module === undefined) {
|
||||||
|
return 'File Error';
|
||||||
|
}
|
||||||
|
|
||||||
if (hdlPath.exist(item.path)) {
|
if (hdlPath.exist(item.path)) {
|
||||||
if (!item.path?.includes(workspacePath)) {
|
if (!item.path?.includes(workspacePath)) {
|
||||||
return 'remote';
|
return 'remote';
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
import { AbsPath, opeParam } from '../global';
|
import { AbsPath, opeParam } from '../global';
|
||||||
import { HdlLangID } from '../global/enum';
|
import { HdlLangID } from '../global/enum';
|
||||||
import { MainOutput, ReportType } from '../global/outputChannel';
|
import { MainOutput, ReportType } from '../global/outputChannel';
|
||||||
@ -240,7 +242,7 @@ class HdlParam {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async initHdlFiles(hdlFiles: AbsPath[] | Generator<AbsPath>) {
|
public async initHdlFiles(hdlFiles: AbsPath[] | Generator<AbsPath>) {
|
||||||
for (const path of hdlFiles) {
|
for (const path of hdlFiles) {
|
||||||
await this.doHdlFast(path);
|
await this.doHdlFast(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -475,23 +477,52 @@ class HdlModule {
|
|||||||
public createHdlInstance(rawHdlInstance: common.RawHdlInstance): HdlInstance {
|
public createHdlInstance(rawHdlInstance: common.RawHdlInstance): HdlInstance {
|
||||||
const instModName = rawHdlInstance.type;
|
const instModName = rawHdlInstance.type;
|
||||||
|
|
||||||
const searchResult = this.searchInstModPath(instModName);
|
|
||||||
const hdlInstance = new HdlInstance(rawHdlInstance.name,
|
if (this.languageId === HdlLangID.Verilog || this.languageId === HdlLangID.SystemVerilog) {
|
||||||
rawHdlInstance.type,
|
const searchResult = this.searchInstModPath(instModName);
|
||||||
searchResult.path,
|
const hdlInstance = new HdlInstance(rawHdlInstance.name,
|
||||||
searchResult.status,
|
rawHdlInstance.type,
|
||||||
rawHdlInstance.instparams,
|
searchResult.path,
|
||||||
rawHdlInstance.instports,
|
searchResult.status,
|
||||||
rawHdlInstance.range,
|
rawHdlInstance.instparams,
|
||||||
this);
|
rawHdlInstance.instports,
|
||||||
if (!searchResult.path) {
|
rawHdlInstance.range,
|
||||||
hdlParam.addUnhandleInstance(hdlInstance);
|
this);
|
||||||
this.addUnhandleInstance(hdlInstance);
|
if (!searchResult.path) {
|
||||||
|
hdlParam.addUnhandleInstance(hdlInstance);
|
||||||
|
this.addUnhandleInstance(hdlInstance);
|
||||||
|
}
|
||||||
|
if (this.nameToInstances) {
|
||||||
|
this.nameToInstances.set(rawHdlInstance.name, hdlInstance);
|
||||||
|
}
|
||||||
|
return hdlInstance;
|
||||||
|
} else if (this.languageId === HdlLangID.Vhdl) {
|
||||||
|
const hdlInstance = new HdlInstance(rawHdlInstance.name,
|
||||||
|
rawHdlInstance.type,
|
||||||
|
this.path,
|
||||||
|
common.InstModPathStatus.Current,
|
||||||
|
rawHdlInstance.instparams,
|
||||||
|
this.ports[0].range,
|
||||||
|
rawHdlInstance.range,
|
||||||
|
this);
|
||||||
|
hdlInstance.module = this;
|
||||||
|
if (this.nameToInstances) {
|
||||||
|
this.nameToInstances.set(rawHdlInstance.name, hdlInstance);
|
||||||
|
}
|
||||||
|
return hdlInstance;
|
||||||
|
} else {
|
||||||
|
vscode.window.showErrorMessage(`Unknown Language :${this.languageId} exist in our core program`);
|
||||||
|
const hdlInstance = new HdlInstance(rawHdlInstance.name,
|
||||||
|
rawHdlInstance.type,
|
||||||
|
this.path,
|
||||||
|
common.InstModPathStatus.Unknown,
|
||||||
|
rawHdlInstance.instparams,
|
||||||
|
this.ports[0].range,
|
||||||
|
rawHdlInstance.range,
|
||||||
|
this);
|
||||||
|
|
||||||
|
return hdlInstance;
|
||||||
}
|
}
|
||||||
if (this.nameToInstances) {
|
|
||||||
this.nameToInstances.set(rawHdlInstance.name, hdlInstance);
|
|
||||||
}
|
|
||||||
return hdlInstance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public makeNameToInstances() {
|
public makeNameToInstances() {
|
||||||
@ -707,7 +738,7 @@ class HdlFile {
|
|||||||
hdlParam.setHdlFile(this);
|
hdlParam.setHdlFile(this);
|
||||||
|
|
||||||
// make nameToModule
|
// make nameToModule
|
||||||
this.nameToModule = new Map<string, HdlModule>();
|
this.nameToModule = new Map<string, HdlModule>();
|
||||||
for (const rawHdlModule of modules) {
|
for (const rawHdlModule of modules) {
|
||||||
this.createHdlModule(rawHdlModule);
|
this.createHdlModule(rawHdlModule);
|
||||||
}
|
}
|
||||||
@ -776,7 +807,7 @@ class HdlFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public makeInstance() {
|
public makeInstance() {
|
||||||
for (const module of this.getAllHdlModules()) {
|
for (const module of this.getAllHdlModules()) {
|
||||||
module.makeNameToInstances();
|
module.makeNameToInstances();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ class HdlAction extends BaseAction {
|
|||||||
|
|
||||||
const fast = await HdlSymbol.fast(path);
|
const fast = await HdlSymbol.fast(path);
|
||||||
if (!fast) {
|
if (!fast) {
|
||||||
vscode.window.showErrorMessage('error happen when parse ' + path + '\nFail to update');
|
// vscode.window.showErrorMessage('error happen when parse ' + path + '\nFail to update');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1220,23 +1220,23 @@
|
|||||||
"patterns": [
|
"patterns": [
|
||||||
{
|
{
|
||||||
"match": "\\b(?i:boolean|bit|character|severity_level|integer|real|time|delay_length|now|natural|positive|string|bit_vector|file_open_kind|file_open_status|fs|ps|ns|us|ms|sec|min|hr|severity_level|note|warning|error|failure)\\b",
|
"match": "\\b(?i:boolean|bit|character|severity_level|integer|real|time|delay_length|now|natural|positive|string|bit_vector|file_open_kind|file_open_status|fs|ps|ns|us|ms|sec|min|hr|severity_level|note|warning|error|failure)\\b",
|
||||||
"name": "support.type.std.standard.vhdl"
|
"name": "support.function.type.std.standard.vhdl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"match": "\\b(?i:line|text|side|width|input|output)\\b",
|
"match": "\\b(?i:line|text|side|width|input|output)\\b",
|
||||||
"name": "support.type.std.textio.vhdl"
|
"name": "support.function.type.std.textio.vhdl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"match": "\\b(?i:std_logic|std_ulogic|std_logic_vector|std_ulogic_vector)\\b",
|
"match": "\\b(?i:std_logic|std_ulogic|std_logic_vector|std_ulogic_vector)\\b",
|
||||||
"name": "support.type.ieee.std_logic_1164.vhdl"
|
"name": "support.function.type.ieee.std_logic_1164.vhdl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"match": "\\b(?i:signed|unsigned)\\b",
|
"match": "\\b(?i:signed|unsigned)\\b",
|
||||||
"name": "support.type.ieee.numeric_std.vhdl"
|
"name": "support.function.type.ieee.numeric_std.vhdl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"match": "\\b(?i:complex|complex_polar)\\b",
|
"match": "\\b(?i:complex|complex_polar)\\b",
|
||||||
"name": "support.type.ieee.math_complex.vhdl"
|
"name": "support.function.type.ieee.math_complex.vhdl"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user