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/
|
||||
*.vsix
|
||||
parser_stuck.v
|
||||
**/*.wasm
|
||||
out-js/
|
||||
*.pyc
|
||||
*.pyd
|
||||
|
@ -16,6 +16,7 @@ Change
|
||||
- 将插件的工作状态显示在 vscode 下侧的状态栏上,利于用户了解目前的设置状态
|
||||
- 状态栏右下角现在可以看到目前选择的linter以及是否正常工作了
|
||||
- 优化项目配置目录
|
||||
- 优化自动补全的性能
|
||||
|
||||
Feature
|
||||
- 增加对 XDC,TCL 等脚本的 LSP 支持
|
||||
|
@ -44,6 +44,11 @@
|
||||
"default": true,
|
||||
"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": {
|
||||
"type": "string",
|
||||
"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[]
|
||||
}
|
||||
|
||||
export function callParser(path: AbsPath, func: number): Promise<any | undefined>;
|
||||
export function vlogFast(path: AbsPath): Promise<Fast | undefined>;
|
||||
export function vlogAll(path: AbsPath): Promise<All | undefined>;
|
||||
export function vhdlFast(path: AbsPath): Promise<Fast | undefined>;
|
||||
|
@ -1,4 +1,5 @@
|
||||
const vscode = require('vscode');
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
const hdlParser = require('./parser');
|
||||
@ -49,14 +50,21 @@ async function callParser(path, func) {
|
||||
console.log(path, debug);
|
||||
return JSON.parse(res);
|
||||
} 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(
|
||||
'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: '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));
|
||||
} else if (res && res.value === false) {
|
||||
dsaSetting.update('propose.issue', true);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@ -95,5 +103,6 @@ module.exports = {
|
||||
vhdlAll,
|
||||
svFast,
|
||||
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 () => {
|
||||
const fast = await vlogFast(testFile);
|
||||
|
@ -19,8 +19,7 @@ async function registerCommand(context: vscode.ExtensionContext) {
|
||||
|
||||
|
||||
async function launch(context: vscode.ExtensionContext) {
|
||||
|
||||
vscode.window.withProgress({
|
||||
await vscode.window.withProgress({
|
||||
location: vscode.ProgressLocation.Window,
|
||||
title: 'Initialization (Digtial-IDE)'
|
||||
}, async () => {
|
||||
@ -29,10 +28,10 @@ async function launch(context: vscode.ExtensionContext) {
|
||||
hdlMonitor.start();
|
||||
});
|
||||
|
||||
MainOutput.report('Digital-IDE has launched, Version: 0.3.2');
|
||||
MainOutput.report('OS: ' + opeParam.os);
|
||||
MainOutput.report('Digital-IDE has launched, Version: 0.3.2', ReportType.Launch);
|
||||
MainOutput.report('OS: ' + opeParam.os, ReportType.Launch);
|
||||
|
||||
// console.log(hdlParam);
|
||||
console.log(hdlParam);
|
||||
|
||||
// show welcome information (if first install)
|
||||
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);
|
||||
|
||||
|
||||
|
@ -11,53 +11,27 @@ import { hdlPath } from '../../../hdlFs';
|
||||
import { hdlSymbolStorage } from '../core';
|
||||
|
||||
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> {
|
||||
// console.log('VhdlCompletionProvider');
|
||||
|
||||
try {
|
||||
const filePath = hdlPath.toSlash(document.fileName);
|
||||
|
||||
// 1. provide keyword
|
||||
const completions = this.makeKeywordItems(document, position);
|
||||
completions.push(...this.makeCompilerKeywordItems(document, position));
|
||||
completions.push(...this.makeSystemKeywordItems(document, position));
|
||||
|
||||
const symbolResult = await hdlSymbolStorage.getSymbol(filePath);
|
||||
|
||||
if (!symbolResult) {
|
||||
return completions;
|
||||
}
|
||||
|
||||
console.log('vhdl symbol result');
|
||||
|
||||
|
||||
// locate at one module
|
||||
const scopeSymbols = util.filterSymbolScope(position, symbolResult.content);
|
||||
if (!scopeSymbols ||
|
||||
!scopeSymbols.module ||
|
||||
!hdlParam.hasHdlModule(filePath, scopeSymbols.module.name)) {
|
||||
// MainOutput.report('Fail to get HdlModule ' + filePath + ' ' + scopeSymbols?.module.name, ReportType.Debug);
|
||||
return completions;
|
||||
const symbols = symbolResult.content;
|
||||
for (const symbol of symbols) {
|
||||
const kind = this.getCompletionItemKind(symbol.type);
|
||||
const clItem = new vscode.CompletionItem(symbol.name, kind);
|
||||
completions.push(clItem);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@ -66,49 +40,43 @@ class VhdlCompletionProvider implements vscode.CompletionItemProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private makeKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
||||
const vhdlKeywordItem = [];
|
||||
private getCompletionItemKind(type: string): vscode.CompletionItemKind {
|
||||
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()) {
|
||||
const clItem = this.makekeywordCompletionItem(keyword);
|
||||
vhdlKeywordItem.push(clItem);
|
||||
const clItem = this.makekeywordCompletionItem(keyword, 'vhdl keyword');
|
||||
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()) {
|
||||
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword);
|
||||
clItem.insertText = new vscode.SnippetString(prefix + keyword);
|
||||
clItem.detail = 'compiler directive';
|
||||
items.push(clItem);
|
||||
const clItem = this.makekeywordCompletionItem(keyword, 'IEEE lib function');
|
||||
vhdlKeywordItems.push(clItem);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private makeSystemKeywordItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
||||
const items = [];
|
||||
for (const keyword of vhdlKeyword.systemKeys()) {
|
||||
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Method);
|
||||
clItem.insertText = new vscode.SnippetString('\\$' + keyword + '($1);');
|
||||
clItem.detail = 'system task';
|
||||
items.push(clItem);
|
||||
const clItem = this.makekeywordCompletionItem(keyword, 'vhdl keyword');
|
||||
vhdlKeywordItems.push(clItem);
|
||||
}
|
||||
return items;
|
||||
this.keywordItems = vhdlKeywordItems;
|
||||
return vhdlKeywordItems;
|
||||
}
|
||||
|
||||
|
||||
private makekeywordCompletionItem(keyword: string): vscode.CompletionItem {
|
||||
private makekeywordCompletionItem(keyword: string, detail: string): vscode.CompletionItem {
|
||||
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword);
|
||||
clItem.detail = 'keyword';
|
||||
clItem.detail = detail;
|
||||
|
||||
switch (keyword) {
|
||||
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;
|
||||
}
|
||||
return clItem;
|
||||
|
@ -184,6 +184,7 @@ class VlogPositionPortProvider 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> {
|
||||
// console.log('VlogCompletionProvider');
|
||||
|
||||
@ -237,13 +238,16 @@ class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
||||
}
|
||||
|
||||
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()) {
|
||||
const clItem = this.makekeywordCompletionItem(keyword);
|
||||
vlogKeywordItem.push(clItem);
|
||||
vlogKeywordItems.push(clItem);
|
||||
}
|
||||
|
||||
return vlogKeywordItem;
|
||||
this.keywordItems = vlogKeywordItems;
|
||||
return vlogKeywordItems;
|
||||
}
|
||||
|
||||
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 {
|
||||
const clItem = new vscode.CompletionItem(keyword, vscode.CompletionItemKind.Keyword);
|
||||
clItem.detail = 'keyword';
|
||||
clItem.detail = 'verilog keyword';
|
||||
|
||||
switch (keyword) {
|
||||
case 'begin': clItem.insertText = new vscode.SnippetString("begin$1\nend"); break;
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { vlogDefinitionProvider } from './vlog';
|
||||
import { vhdlDefinitionProvider } from './vhdl';
|
||||
|
||||
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 { vhdlDocSymbolProvider } from './vhdl';
|
||||
|
||||
|
||||
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) {
|
||||
return vscode.SymbolKind.Array;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { vlogHoverProvider } from './vlog';
|
||||
import { vhdlHoverProvider } from './vhdl';
|
||||
|
||||
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 { vhdlLinterManager } from './vhdl';
|
||||
import { easyExec } from '../../../global/util';
|
||||
import { LspOutput } from '../../../global';
|
||||
|
||||
let _selectVlogLinter: string | null = null;
|
||||
let _selectVhdlLinter: string | null = null;
|
||||
@ -76,13 +77,20 @@ async function makeModelsimPickItem(langID: HdlLangID): Promise<LinterItem> {
|
||||
|
||||
async function pickVlogLinter() {
|
||||
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.items = [
|
||||
await makeDefaultPickItem(),
|
||||
await makeVivadoPickItem(HdlLangID.Verilog),
|
||||
await makeModelsimPickItem(HdlLangID.Verilog)
|
||||
];
|
||||
|
||||
await vscode.window.withProgress({
|
||||
location: vscode.ProgressLocation.Notification,
|
||||
title: 'Parsing local environment ...',
|
||||
cancellable: true
|
||||
}, async () => {
|
||||
pickWidget.items = [
|
||||
await makeDefaultPickItem(),
|
||||
await makeVivadoPickItem(HdlLangID.Verilog),
|
||||
await makeModelsimPickItem(HdlLangID.Verilog)
|
||||
];
|
||||
});
|
||||
|
||||
pickWidget.onDidChangeSelection(items => {
|
||||
const selectedItem = items[0];
|
||||
@ -101,7 +109,36 @@ async function pickVlogLinter() {
|
||||
}
|
||||
|
||||
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 {
|
||||
diagnostic: vscode.DiagnosticCollection;
|
||||
constructor() {
|
||||
this.diagnostic = vscode.languages.createDiagnosticCollection();
|
||||
this.diagnostic = vscode.languages.createDiagnosticCollection('Digital-IDE Default Linter');
|
||||
}
|
||||
|
||||
async lint(document: vscode.TextDocument): Promise<void> {
|
||||
@ -22,14 +22,16 @@ class DefaultVlogLinter implements BaseLinter {
|
||||
const diagnostics = this.provideDiagnostics(document, vlogAll);
|
||||
this.diagnostic.set(document.uri, diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private provideDiagnostics(document: vscode.TextDocument, all: All): vscode.Diagnostic[] {
|
||||
const diagnostics: vscode.Diagnostic[] = [];
|
||||
if (all.error && all.error.length > 0) {
|
||||
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 diag = new vscode.Diagnostic(range, hdlError.message, hdlError.severity);
|
||||
const diag = new vscode.Diagnostic(range, syntaxInfo, hdlError.severity);
|
||||
diag.source = hdlError.source;
|
||||
diagnostics.push(diag);
|
||||
}
|
||||
@ -78,7 +80,7 @@ class DefaultVlogLinter implements BaseLinter {
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultVHDLLinter implements BaseLinter {
|
||||
class DefaultVhdlLinter implements BaseLinter {
|
||||
diagnostic: vscode.DiagnosticCollection;
|
||||
constructor() {
|
||||
this.diagnostic = vscode.languages.createDiagnosticCollection();
|
||||
@ -99,6 +101,8 @@ class DefaultVHDLLinter implements BaseLinter {
|
||||
const diagnostics: vscode.Diagnostic[] = [];
|
||||
if (all.error && all.error.length > 0) {
|
||||
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 diag = new vscode.Diagnostic(range, hdlError.message, hdlError.severity);
|
||||
diag.source = hdlError.source;
|
||||
@ -150,11 +154,11 @@ class DefaultVHDLLinter implements BaseLinter {
|
||||
}
|
||||
|
||||
const defaultVlogLinter = new DefaultVlogLinter();
|
||||
const defaultVHDLLinter = new DefaultVHDLLinter();
|
||||
const defaultVhdlLinter = new DefaultVhdlLinter();
|
||||
|
||||
export {
|
||||
defaultVlogLinter,
|
||||
defaultVHDLLinter,
|
||||
defaultVhdlLinter,
|
||||
DefaultVlogLinter,
|
||||
DefaultVHDLLinter
|
||||
DefaultVhdlLinter
|
||||
};
|
||||
|
@ -43,7 +43,7 @@ class ModelsimLinter implements BaseLinter {
|
||||
}
|
||||
|
||||
const args = [filePath, ...linterArgs];
|
||||
const executor = this.executableInvokeNameMap.get(langID);
|
||||
const executor = this.executableInvokeNameMap.get(langID);
|
||||
if (executor !== undefined) {
|
||||
const { stdout } = await easyExec(executor, args);
|
||||
if (stdout.length > 0) {
|
||||
|
@ -2,38 +2,54 @@ import * as vscode from 'vscode';
|
||||
import { LspOutput, ReportType } from '../../../global';
|
||||
import { HdlLangID } from '../../../global/enum';
|
||||
import { BaseLinter, BaseManager } from './base';
|
||||
import { defaultVlogLinter } from './default';
|
||||
import { defaultVhdlLinter } from './default';
|
||||
import { modelsimLinter } from './modelsim';
|
||||
import { vivadoLinter } from './vivado';
|
||||
import { hdlFile, hdlPath } from '../../../hdlFs';
|
||||
|
||||
class VhdlLinterManager implements BaseManager {
|
||||
currentLinter: BaseLinter | undefined;
|
||||
activateList: Map<string, boolean> = new Map<string, boolean>();
|
||||
activateLinterName: string;
|
||||
statusBarItem: vscode.StatusBarItem;
|
||||
initialized: boolean;
|
||||
|
||||
constructor() {
|
||||
this.activateList.set('vivado', false);
|
||||
this.activateList.set('modelsim', false);
|
||||
this.activateList.set('default', false);
|
||||
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
|
||||
vscode.workspace.onDidChangeConfiguration(() => {
|
||||
const diagnostor = this.getUserDiagnostorSelection();
|
||||
const lastDiagnostor = this.activateLinterName;
|
||||
if (diagnostor !== lastDiagnostor) {
|
||||
LspOutput.report(`<vhdl lsp manager> detect linter setting changes, switch ${lastDiagnostor} to ${diagnostor}.`, );
|
||||
this.updateLinter();
|
||||
}
|
||||
this.updateLinter();
|
||||
});
|
||||
}
|
||||
|
||||
async initialise(): Promise<void> {
|
||||
const success = await this.updateLinter();
|
||||
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
for (const doc of vscode.workspace.textDocuments) {
|
||||
const fileName = hdlPath.toSlash(doc.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);
|
||||
|
||||
// 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) {
|
||||
this.currentLinter?.remove(document.uri);
|
||||
await this.currentLinter?.lint(document);
|
||||
}
|
||||
|
||||
|
||||
async remove(uri: vscode.Uri): Promise<void> {
|
||||
this.currentLinter?.remove(uri);
|
||||
}
|
||||
|
||||
public getUserDiagnostorSelection() {
|
||||
const vlogLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vlog');
|
||||
const diagnostor = vlogLspConfig.get('diagnostor', 'default');
|
||||
const vhdlLspConfig = vscode.workspace.getConfiguration('digital-ide.function.lsp.linter.vhdl');
|
||||
const diagnostor = vhdlLspConfig.get('diagnostor', 'xxx');
|
||||
return diagnostor;
|
||||
}
|
||||
|
||||
public async updateLinter(): Promise<boolean> {
|
||||
const diagnostor = this.getUserDiagnostorSelection();
|
||||
switch (diagnostor) {
|
||||
case 'vivado': return this.activateVivado();
|
||||
case 'modelsim': return this.activateModelsim();
|
||||
case 'default': return this.activateDefault();
|
||||
default: return this.activateDefault();
|
||||
}
|
||||
public async updateLinter(): Promise<boolean> {
|
||||
const diagnostorName = this.getUserDiagnostorSelection();
|
||||
|
||||
const lastDiagnostorName = this.activateLinterName;
|
||||
const lastDiagnostor = this.currentLinter;
|
||||
|
||||
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> {
|
||||
const selectedLinter = vivadoLinter;
|
||||
let launch = true;
|
||||
|
||||
if (this.activateList.get('vivado') === false) {
|
||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
||||
this.activateList.set('vivado', true);
|
||||
launch = await selectedLinter.initialise(HdlLangID.Vhdl);
|
||||
if (launch) {
|
||||
this.statusBarItem.text = '$(getting-started-beginner) Linter(vivado)';
|
||||
|
||||
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.activateLinterName = 'vivado';
|
||||
this.statusBarItem.show();
|
||||
|
||||
return launch;
|
||||
}
|
||||
|
||||
@ -86,29 +141,46 @@ class VhdlLinterManager implements BaseManager {
|
||||
const selectedLinter = modelsimLinter;
|
||||
let launch = true;
|
||||
|
||||
if (this.activateList.get('modelsim') === false) {
|
||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
||||
this.activateList.set('modelsim', true);
|
||||
LspOutput.report('<vhdl lsp manager> modelsim linter has been activated', ReportType.Info);
|
||||
launch = await selectedLinter.initialise(HdlLangID.Vhdl);
|
||||
if (launch) {
|
||||
this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)';
|
||||
|
||||
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.activateLinterName = 'modelsim';
|
||||
this.statusBarItem.show();
|
||||
|
||||
return launch;
|
||||
}
|
||||
|
||||
public async activateDefault(): Promise<boolean> {
|
||||
const selectedLinter = defaultVlogLinter;
|
||||
const selectedLinter = defaultVhdlLinter;
|
||||
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);
|
||||
} 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.activateLinterName = 'default';
|
||||
this.statusBarItem.show();
|
||||
|
||||
return launch;
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ class VivadoLinter implements BaseLinter {
|
||||
|
||||
public async initialise(langID: HdlLangID): Promise<boolean> {
|
||||
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 { vivadoLinter } from './vivado';
|
||||
import { hdlFile, hdlPath } from '../../../hdlFs';
|
||||
import { isVerilogFile } from '../../../hdlFs/file';
|
||||
|
||||
class VlogLinterManager implements BaseManager {
|
||||
currentLinter: BaseLinter | undefined;
|
||||
activateList: Map<string, boolean> = new Map<string, boolean>();
|
||||
activateLinterName: string;
|
||||
statusBarItem: vscode.StatusBarItem;
|
||||
initialized: boolean;
|
||||
|
||||
constructor() {
|
||||
this.activateList.set('vivado', false);
|
||||
this.activateList.set('modelsim', false);
|
||||
this.activateList.set('default', false);
|
||||
this.activateLinterName = 'default';
|
||||
this.initialized = false;
|
||||
|
||||
// make a status bar for rendering
|
||||
this.statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
|
||||
@ -31,7 +28,7 @@ class VlogLinterManager implements BaseManager {
|
||||
}
|
||||
const currentFileName = hdlPath.toSlash(editor.document.fileName);
|
||||
|
||||
if (isVerilogFile(currentFileName)) {
|
||||
if (hdlFile.isVerilogFile(currentFileName)) {
|
||||
this.statusBarItem.show();
|
||||
} else {
|
||||
this.statusBarItem.hide();
|
||||
@ -40,21 +37,19 @@ class VlogLinterManager implements BaseManager {
|
||||
|
||||
// update when user's config is changed
|
||||
vscode.workspace.onDidChangeConfiguration(() => {
|
||||
const diagnostor = this.getUserDiagnostorSelection();
|
||||
const lastDiagnostor = this.activateLinterName;
|
||||
if (diagnostor !== lastDiagnostor) {
|
||||
LspOutput.report(`<vlog lsp manager> detect linter setting changes, switch ${lastDiagnostor} to ${diagnostor}.`, );
|
||||
this.updateLinter();
|
||||
}
|
||||
this.updateLinter();
|
||||
});
|
||||
}
|
||||
|
||||
async initialise(): Promise<void> {
|
||||
const success = await this.updateLinter();
|
||||
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
|
||||
for (const doc of vscode.workspace.textDocuments) {
|
||||
const fileName = hdlPath.toSlash(doc.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);
|
||||
|
||||
// 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) {
|
||||
this.currentLinter?.remove(document.uri);
|
||||
await this.currentLinter?.lint(document);
|
||||
}
|
||||
|
||||
@ -74,44 +78,62 @@ class VlogLinterManager implements BaseManager {
|
||||
|
||||
public getUserDiagnostorSelection() {
|
||||
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;
|
||||
}
|
||||
|
||||
public async updateLinter() {
|
||||
const diagnostor = this.getUserDiagnostorSelection();
|
||||
switch (diagnostor) {
|
||||
case 'vivado': return this.activateVivado();
|
||||
case 'modelsim': return this.activateModelsim();
|
||||
case 'default': return this.activateDefault();
|
||||
default: return this.activateDefault();
|
||||
public async updateLinter(): Promise<boolean> {
|
||||
const diagnostorName = this.getUserDiagnostorSelection();
|
||||
|
||||
const lastDiagnostorName = this.activateLinterName;
|
||||
const lastDiagnostor = this.currentLinter;
|
||||
|
||||
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> {
|
||||
const selectedLinter = vivadoLinter;
|
||||
let launch = true;
|
||||
|
||||
if (this.activateList.get('vivado') === false) {
|
||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
||||
if (launch) {
|
||||
this.statusBarItem.text = '$(getting-started-beginner) Linter(Vivado)';
|
||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
||||
if (launch) {
|
||||
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);
|
||||
} 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('<vlog 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('<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.activateLinterName = 'vivado';
|
||||
this.statusBarItem.show();
|
||||
|
||||
|
||||
return launch;
|
||||
}
|
||||
|
||||
@ -119,22 +141,17 @@ class VlogLinterManager implements BaseManager {
|
||||
const selectedLinter = modelsimLinter;
|
||||
let launch = true;
|
||||
|
||||
if (this.activateList.get('modelsim') === false) {
|
||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
||||
if (launch) {
|
||||
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);
|
||||
}
|
||||
launch = await selectedLinter.initialise(HdlLangID.Verilog);
|
||||
if (launch) {
|
||||
this.statusBarItem.text = '$(getting-started-beginner) Linter(modelsim)';
|
||||
|
||||
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;
|
||||
@ -148,23 +165,22 @@ class VlogLinterManager implements BaseManager {
|
||||
const selectedLinter = defaultVlogLinter;
|
||||
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('<vlog 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)';
|
||||
if (launch) {
|
||||
this.statusBarItem.text = '$(getting-started-beginner) Linter(default)';
|
||||
|
||||
LspOutput.report('<vlog 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('<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.activateLinterName = 'default';
|
||||
this.statusBarItem.show();
|
||||
|
||||
return launch;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
|
||||
class Keywords {
|
||||
private keywords: Set<string>;
|
||||
private compilerKeywords: string[]; // start with `
|
||||
@ -76,7 +75,24 @@ const vlogKeyword = new Keywords([
|
||||
);
|
||||
|
||||
// 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([
|
||||
"above", "disable", "idt", "notif1", "supply0", "abs", "discipline", "idtmod",
|
||||
|
@ -12,7 +12,7 @@ interface CommandDataItem {
|
||||
cmd: string,
|
||||
icon: string,
|
||||
tip: string,
|
||||
children: any[]
|
||||
children: CommandDataItem[]
|
||||
}
|
||||
|
||||
type CommandConfig = Record<string, {
|
||||
|
@ -14,6 +14,10 @@ async function openFileAtPosition(uri: vscode.Uri, line: number, character: numb
|
||||
}
|
||||
|
||||
function openFileByUri(path: string, range: Range) {
|
||||
if (range === undefined) {
|
||||
vscode.window.showErrorMessage(`${path} not support jump yet`);
|
||||
return;
|
||||
}
|
||||
if (hdlPath.exist(path)) {
|
||||
const uri = vscode.Uri.file(path);
|
||||
const start = range.start;
|
||||
|
@ -120,7 +120,7 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
|
||||
|
||||
// set iconPath
|
||||
treeItem.iconPath = getIconConfig(element.icon);
|
||||
|
||||
|
||||
// set command
|
||||
treeItem.command = {
|
||||
title: "Open this HDL File",
|
||||
@ -225,8 +225,8 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
|
||||
icon: 'file',
|
||||
type: instance.name,
|
||||
name: instance.type,
|
||||
range: instance.module ? instance.module.range : null,
|
||||
path: instance.instModPath,
|
||||
range: instance.range,
|
||||
path: instance.parentMod.path,
|
||||
parent: element
|
||||
};
|
||||
|
||||
@ -257,6 +257,10 @@ class ModuleTreeProvider implements vscode.TreeDataProvider<ModuleDataItem> {
|
||||
|
||||
private judgeIcon(item: ModuleDataItem, instance: HdlInstance): string {
|
||||
const workspacePath = opeParam.workspacePath;
|
||||
if (instance.module === undefined) {
|
||||
return 'File Error';
|
||||
}
|
||||
|
||||
if (hdlPath.exist(item.path)) {
|
||||
if (!item.path?.includes(workspacePath)) {
|
||||
return 'remote';
|
||||
|
@ -1,3 +1,5 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { AbsPath, opeParam } from '../global';
|
||||
import { HdlLangID } from '../global/enum';
|
||||
import { MainOutput, ReportType } from '../global/outputChannel';
|
||||
@ -240,7 +242,7 @@ class HdlParam {
|
||||
}
|
||||
|
||||
public async initHdlFiles(hdlFiles: AbsPath[] | Generator<AbsPath>) {
|
||||
for (const path of hdlFiles) {
|
||||
for (const path of hdlFiles) {
|
||||
await this.doHdlFast(path);
|
||||
}
|
||||
}
|
||||
@ -475,23 +477,52 @@ class HdlModule {
|
||||
public createHdlInstance(rawHdlInstance: common.RawHdlInstance): HdlInstance {
|
||||
const instModName = rawHdlInstance.type;
|
||||
|
||||
const searchResult = this.searchInstModPath(instModName);
|
||||
const hdlInstance = new HdlInstance(rawHdlInstance.name,
|
||||
rawHdlInstance.type,
|
||||
searchResult.path,
|
||||
searchResult.status,
|
||||
rawHdlInstance.instparams,
|
||||
rawHdlInstance.instports,
|
||||
rawHdlInstance.range,
|
||||
this);
|
||||
if (!searchResult.path) {
|
||||
hdlParam.addUnhandleInstance(hdlInstance);
|
||||
this.addUnhandleInstance(hdlInstance);
|
||||
|
||||
if (this.languageId === HdlLangID.Verilog || this.languageId === HdlLangID.SystemVerilog) {
|
||||
const searchResult = this.searchInstModPath(instModName);
|
||||
const hdlInstance = new HdlInstance(rawHdlInstance.name,
|
||||
rawHdlInstance.type,
|
||||
searchResult.path,
|
||||
searchResult.status,
|
||||
rawHdlInstance.instparams,
|
||||
rawHdlInstance.instports,
|
||||
rawHdlInstance.range,
|
||||
this);
|
||||
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() {
|
||||
@ -707,7 +738,7 @@ class HdlFile {
|
||||
hdlParam.setHdlFile(this);
|
||||
|
||||
// make nameToModule
|
||||
this.nameToModule = new Map<string, HdlModule>();
|
||||
this.nameToModule = new Map<string, HdlModule>();
|
||||
for (const rawHdlModule of modules) {
|
||||
this.createHdlModule(rawHdlModule);
|
||||
}
|
||||
@ -776,7 +807,7 @@ class HdlFile {
|
||||
}
|
||||
|
||||
public makeInstance() {
|
||||
for (const module of this.getAllHdlModules()) {
|
||||
for (const module of this.getAllHdlModules()) {
|
||||
module.makeNameToInstances();
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ class HdlAction extends BaseAction {
|
||||
|
||||
const fast = await HdlSymbol.fast(path);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1220,23 +1220,23 @@
|
||||
"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",
|
||||
"name": "support.type.std.standard.vhdl"
|
||||
"name": "support.function.type.std.standard.vhdl"
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"name": "support.type.ieee.std_logic_1164.vhdl"
|
||||
"name": "support.function.type.ieee.std_logic_1164.vhdl"
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"name": "support.type.ieee.math_complex.vhdl"
|
||||
"name": "support.function.type.ieee.math_complex.vhdl"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user