finish 0.3.2

This commit is contained in:
锦恢 2023-11-29 21:08:52 +08:00
parent ea1a70e8aa
commit 5c2763f379
14 changed files with 327 additions and 245 deletions

Binary file not shown.

View File

@ -3,6 +3,7 @@ const { vhdlAll } = require('../../resources/hdlParser');
const testFile = '../Digital-Test/Verilog/dependence_test/test.vhd'; const testFile = '../Digital-Test/Verilog/dependence_test/test.vhd';
(async () => { (async () => {
const fast = await vhdlAll(testFile); const all = await vhdlAll(testFile);
console.log(JSON.stringify(fast, null, ' ')); console.log(JSON.stringify(all, null, ' '));
console.log('number of symbols:', all.content.length);
})(); })();

View File

@ -1,6 +1,6 @@
const { vlogAll } = require('../../resources/hdlParser'); const { vlogAll } = require('../../resources/hdlParser');
const testFile = '../Digital-Test/user/src/netlist_test.v'; const testFile = '../Digital-Test/user/src/child_2.v';
(async () => { (async () => {
const all = await vlogAll(testFile); const all = await vlogAll(testFile);

View File

@ -122,7 +122,7 @@ class VlogPositionPortProvider implements vscode.CompletionItemProvider {
return null; return null;
} }
const scopeSymbols = util.filterSymbolScope(position, symbolResult.content); const scopeSymbols = util.locateVlogSymbol(position, symbolResult.content);
if (!scopeSymbols || if (!scopeSymbols ||
!scopeSymbols.module || !scopeSymbols.module ||
!scopeSymbols.symbols || !scopeSymbols.symbols ||
@ -202,7 +202,7 @@ class VlogCompletionProvider implements vscode.CompletionItemProvider {
} }
// locate at one module // locate at one module
const scopeSymbols = util.filterSymbolScope(position, symbolResult.content); const scopeSymbols = util.locateVlogSymbol(position, symbolResult.content);
if (!scopeSymbols || if (!scopeSymbols ||
!scopeSymbols.module || !scopeSymbols.module ||
!hdlParam.hasHdlModule(filePath, scopeSymbols.module.name)) { !hdlParam.hasHdlModule(filePath, scopeSymbols.module.name)) {

View File

@ -7,12 +7,13 @@ import { vlogKeyword } from '../util/keyword';
import * as util from '../util'; import * as util from '../util';
import { MainOutput, ReportType } from '../../../global'; import { MainOutput, ReportType } from '../../../global';
import { hdlSymbolStorage } from '../core'; import { hdlSymbolStorage } from '../core';
import { RawSymbol } from '../../../hdlParser/common';
class VhdlDefinitionProvider implements vscode.DefinitionProvider { class VhdlDefinitionProvider implements vscode.DefinitionProvider {
public async provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Location | vscode.LocationLink[] | null> { public async provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Location | vscode.LocationLink[] | null> {
// console.log('VhdlDefinitionProvider'); // console.log('VhdlDefinitionProvider');
// get current words // get current words
const wordRange = document.getWordRangeAtPosition(position, /[`_0-9A-Za-z]+/); const wordRange = document.getWordRangeAtPosition(position, /[`_0-9A-Za-z]+/);
if (!wordRange) { if (!wordRange) {
@ -51,106 +52,115 @@ class VhdlDefinitionProvider implements vscode.DefinitionProvider {
const filePath = hdlPath.toSlash(document.fileName); const filePath = hdlPath.toSlash(document.fileName);
const lineText = document.lineAt(position).text; const lineText = document.lineAt(position).text;
// match `include // locate at one entity or architecture
const includeResult = util.matchInclude(document, position, all.macro.includes); // TODO: remove it after adjust of backend
const rawSymbols = [];
if (includeResult) { for (const symbol of all.content) {
const absPath = hdlPath.rel2abs(filePath, includeResult.name); const rawSymbol: RawSymbol = {
const targetFile = vscode.Uri.file(absPath); name: symbol.name,
const targetPosition = new vscode.Position(0, 0); type: symbol.type,
const targetRange = new vscode.Range(targetPosition, targetPosition); parent: symbol.parent,
const originSelectionRange = document.getWordRangeAtPosition(position, /["\.\\\/_0-9A-Za-z]+/); range: util.transformRange(symbol.range, -1),
const link: vscode.LocationLink = { targetUri: targetFile, targetRange, originSelectionRange }; signed: symbol.signed,
return [link]; netType: symbol.netType
};
rawSymbols.push(rawSymbol);
} }
const moduleScope = util.locateVhdlSymbol(position, rawSymbols);
// match macro if (!moduleScope) {
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; return null;
} }
// match instance const scopeType = moduleScope.module.type;
const instResult = util.matchInstance(targetWord, currentModule); if (scopeType === 'architecture') {
if (instResult) { return await this.makeArchitectureDefinition(filePath, targetWord, targetWordRange, moduleScope);
const instModule = instResult.module; } else if (scopeType === 'entity') {
if (!instModule || !instResult.instModPath) { return await this.makeEntityDefinition(filePath, targetWord, targetWordRange, moduleScope);
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) return null;
if (util.isPositionInput(lineText, position.character)) { }
const currentInstResult = util.filterInstanceByPosition(position, scopeSymbols.symbols, currentModule);
if (!currentInstResult || !currentInstResult.instModPath) { private async makeArchitectureDefinition(filePath: string, targetWord: string, targetWordRange: vscode.Range, moduleScope: util.ModuleScope): Promise<vscode.Location | vscode.LocationLink[] | null> {
return null; const architecture = moduleScope.module;
// point to the entity of the architecture
if (architecture.parent && architecture.parent === targetWord) {
const entity = hdlParam.getHdlModule(filePath, architecture.parent);
if (entity) {
const targetUri = vscode.Uri.file(entity.path);
const targetRange = util.transformRange(entity.range, -1, 0);
const link: vscode.LocationLink = { targetUri, targetRange, originSelectionRange: targetWordRange };
return [ link ];
} }
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 // filter defined signal
const portResult = util.matchPorts(targetWord, currentModule); for (const symbol of moduleScope.symbols) {
if (symbol.name === targetWord) {
if (portResult) { const targetUri = vscode.Uri.file(filePath);
const targetRange = util.transformRange(portResult.range, -1, 0); const targetRange = util.transformRange(symbol.range, 0, 0);
const link: vscode.LocationLink = { targetUri: document.uri, targetRange }; const link: vscode.LocationLink = { targetUri, targetRange, originSelectionRange: targetWordRange };
return [link]; return [ link ];
}
} }
// match others // inner variable mapping to entity
const normalResult = util.matchNormalSymbol(targetWord, scopeSymbols.symbols); if (architecture.parent) {
if (normalResult) { const entity = hdlParam.getHdlModule(filePath, architecture.parent);
const targetRange = util.transformRange(normalResult.range, -1, 0); if (entity) {
const link: vscode.LocationLink = { targetUri: document.uri, targetRange }; // find params definitio
return [link]; for (const param of entity.params) {
if (param.name === targetWord) {
const targetUri = vscode.Uri.file(entity.path);
const targetRange = util.transformRange(param.range, -1, 0);
const link: vscode.LocationLink = { targetUri, targetRange, originSelectionRange: targetWordRange };
return [ link ];
}
}
// find ports definition
for (const port of entity.ports) {
if (port.name === targetWord) {
const targetUri = vscode.Uri.file(entity.path);
const targetRange = util.transformRange(port.range, -1, 0);
const link: vscode.LocationLink = { targetUri, targetRange, originSelectionRange: targetWordRange };
return [ link ];
}
}
}
} }
return null;
}
private async makeEntityDefinition(filePath: string, targetWord: string, targetWordRange: vscode.Range, moduleScope: util.ModuleScope): Promise<vscode.Location | vscode.LocationLink[] | null> {
const entity = hdlParam.getHdlModule(filePath, moduleScope.module.name);
if (entity) {
if (targetWord === entity.name) {
const targetUri = vscode.Uri.file(entity.path);
const targetRange = util.transformRange(entity.range, -1, 0);
const link: vscode.LocationLink = { targetUri, targetRange, originSelectionRange: targetWordRange };
return [ link ];
}
// find params definitio
for (const param of entity.params) {
if (param.name === targetWord) {
const targetUri = vscode.Uri.file(entity.path);
const targetRange = util.transformRange(param.range, -1, 0);
const link: vscode.LocationLink = { targetUri, targetRange, originSelectionRange: targetWordRange };
return [ link ];
}
}
// find ports definition
for (const port of entity.ports) {
if (port.name === targetWord) {
const targetUri = vscode.Uri.file(entity.path);
const targetRange = util.transformRange(port.range, -1, 0);
const link: vscode.LocationLink = { targetUri, targetRange, originSelectionRange: targetWordRange };
return [ link ];
}
}
}
return null; return null;
} }
} }

View File

@ -74,7 +74,7 @@ class VlogDefinitionProvider implements vscode.DefinitionProvider {
} }
// locate at one module // locate at one module
const scopeSymbols = util.filterSymbolScope(position, all.content); const scopeSymbols = util.locateVlogSymbol(position, all.content);
if (!scopeSymbols || !scopeSymbols.module) { if (!scopeSymbols || !scopeSymbols.module) {
return null; return null;
} }

View File

@ -4,13 +4,18 @@ import { AllowNull } from '../../../global';
import { RawSymbol, Range } from '../../../hdlParser/common'; import { RawSymbol, Range } from '../../../hdlParser/common';
import { hdlSymbolStorage } from '../core'; import { hdlSymbolStorage } from '../core';
import { positionAfterEqual } from '../util';
interface DocSymbolContainer { interface DocSymbolContainer {
docSymbol: AllowNull<vscode.DocumentSymbol>, docSymbol: AllowNull<vscode.DocumentSymbol>,
range: AllowNull<Range> range: AllowNull<Range>
}; };
const vhdlSymbolKind: Record<string, vscode.SymbolKind> = {
entity: vscode.SymbolKind.Interface,
port: vscode.SymbolKind.Property,
architecture: vscode.SymbolKind.Variable,
signal: vscode.SymbolKind.Property
};
class VhdlDocSymbolProvider implements vscode.DocumentSymbolProvider { class VhdlDocSymbolProvider implements vscode.DocumentSymbolProvider {
public async provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentSymbol[]> { public async provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentSymbol[]> {
@ -38,7 +43,7 @@ class VhdlDocSymbolProvider implements vscode.DocumentSymbolProvider {
if (symbol.type === 'entity') { if (symbol.type === 'entity') {
const docSymbol = new vscode.DocumentSymbol(symbol.name, const docSymbol = new vscode.DocumentSymbol(symbol.name,
symbol.name, symbol.name,
vscode.SymbolKind.Interface, vhdlSymbolKind[symbol.type],
symbolRange, symbolRange,
symbolRange); symbolRange);
docSymbols.push(docSymbol); docSymbols.push(docSymbol);
@ -46,10 +51,27 @@ class VhdlDocSymbolProvider implements vscode.DocumentSymbolProvider {
const parentEntity = docSymbols[docSymbols.length - 1]; const parentEntity = docSymbols[docSymbols.length - 1];
const docSymbol = new vscode.DocumentSymbol(symbol.name, const docSymbol = new vscode.DocumentSymbol(symbol.name,
symbol.name, symbol.name,
vscode.SymbolKind.Method, vhdlSymbolKind[symbol.type],
symbolRange, symbolRange,
symbolRange); symbolRange);
parentEntity.children.push(docSymbol); parentEntity.children.push(docSymbol);
} else if (symbol.type === 'architecture') {
const docSymbol = new vscode.DocumentSymbol(symbol.name,
symbol.name,
vhdlSymbolKind[symbol.type],
symbolRange,
symbolRange);
docSymbols.push(docSymbol);
} else if (symbol.type === 'signal') {
const parentArchitecture = docSymbols[docSymbols.length - 1];
if (parentArchitecture.kind === vhdlSymbolKind['architecture']) {
const docSymbol = new vscode.DocumentSymbol(symbol.name,
symbol.name,
vhdlSymbolKind[symbol.type],
symbolRange,
symbolRange);
parentArchitecture.children.push(docSymbol);
}
} }
} }

View File

@ -3,11 +3,12 @@ import * as vscode from 'vscode';
import { hdlPath } from '../../../hdlFs'; import { hdlPath } from '../../../hdlFs';
import { hdlParam } from '../../../hdlParser'; import { hdlParam } from '../../../hdlParser';
import { All } from '../../../../resources/hdlParser'; import { All } from '../../../../resources/hdlParser';
import { vlogKeyword } from '../util/keyword'; import { vhdlKeyword } from '../util/keyword';
import * as util from '../util'; import * as util from '../util';
import { MainOutput, ReportType } from '../../../global'; import { MainOutput, ReportType } from '../../../global';
import { HdlLangID } from '../../../global/enum'; import { HdlLangID } from '../../../global/enum';
import { hdlSymbolStorage } from '../core'; import { hdlSymbolStorage } from '../core';
import { RawSymbol } from '../../../hdlParser/common';
class VhdlHoverProvider implements vscode.HoverProvider { class VhdlHoverProvider implements vscode.HoverProvider {
@ -26,19 +27,33 @@ class VhdlHoverProvider implements vscode.HoverProvider {
return null; return null;
} }
const keywordHover = this.getKeywordHover(targetWord);
if (keywordHover) {
return keywordHover;
}
const filePath = document.fileName; const filePath = document.fileName;
const vlogAll = await hdlSymbolStorage.getSymbol(filePath); const vhdlAll = await hdlSymbolStorage.getSymbol(filePath);
if (!vlogAll) { if (!vhdlAll) {
return null; return null;
} else { } else {
const hover = await this.makeHover(document, position, vlogAll, targetWord, wordRange); const hover = await this.makeHover(document, position, vhdlAll, targetWord, wordRange);
return hover; return hover;
} }
} }
private getKeywordHover(words: string): vscode.Hover | undefined {
const content = new vscode.MarkdownString('', true);
if (vhdlKeyword.compilerKeys().has(words)) {
content.appendMarkdown('IEEE Library data type');
return new vscode.Hover(content);
}
return undefined;
}
private needSkip(document: vscode.TextDocument, position: vscode.Position, targetWord: string): boolean { private needSkip(document: vscode.TextDocument, position: vscode.Position, targetWord: string): boolean {
// check keyword // check keyword
if (vlogKeyword.isKeyword(targetWord)) { if (vhdlKeyword.isKeyword(targetWord)) {
return true; return true;
} }
@ -52,147 +67,110 @@ class VhdlHoverProvider implements vscode.HoverProvider {
const lineText = document.lineAt(position).text; const lineText = document.lineAt(position).text;
const filePath = hdlPath.toSlash(document.fileName); const filePath = hdlPath.toSlash(document.fileName);
// total content rendered on the hover box // locate at one entity or architecture
// TODO: remove it after adjust of backend
const rawSymbols = [];
for (const symbol of all.content) {
const rawSymbol: RawSymbol = {
name: symbol.name,
type: symbol.type,
parent: symbol.parent,
range: util.transformRange(symbol.range, -1),
signed: symbol.signed,
netType: symbol.netType
};
rawSymbols.push(rawSymbol);
}
const moduleScope = util.locateVhdlSymbol(position, rawSymbols);
if (!moduleScope) {
return null;
}
const scopeType = moduleScope.module.type;
if (scopeType === 'architecture') {
return await this.makeArchitectureHover(filePath, targetWord, targetWordRange, moduleScope);
} else if (scopeType === 'entity') {
return await this.makeEntityHover(filePath, targetWord, targetWordRange, moduleScope);
}
return null;
}
private async makeArchitectureHover(filePath: string, targetWord: string, targetWordRange: vscode.Range, moduleScope: util.ModuleScope): Promise<vscode.Hover | null> {
const architecture = moduleScope.module;
const content = new vscode.MarkdownString('', true); const content = new vscode.MarkdownString('', true);
// match `include // point to the entity of the architecture
const includeResult = util.matchInclude(document, position, all.macro.includes); if (architecture.parent && architecture.parent === targetWord) {
if (includeResult) { const entity = hdlParam.getHdlModule(filePath, architecture.parent);
const absPath = hdlPath.rel2abs(filePath, includeResult.name); if (entity) {
content.appendCodeblock(`"${absPath}"`, HdlLangID.Verilog); await util.makeVhdlHoverContent(content, entity);
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); return new vscode.Hover(content);
} }
await util.makeVlogHoverContent(content, instModule);
return new vscode.Hover(content);
} }
// filter defined signal
// match port or param definition (position input) for (const symbol of moduleScope.symbols) {
/** for example, when you hover the ".clk" below, the branch will be entered if (symbol.name === targetWord) {
template u_template( content.appendCodeblock(symbol.type, 'vhdl');
//input return new vscode.Hover(content);
.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) { // inner variable mapping to entity
const paramComment = await util.searchCommentAround(currentInstResult.instModPath, instParam.range); if (architecture.parent) {
const paramDesc = util.makeParamDesc(instParam); const entity = hdlParam.getHdlModule(filePath, architecture.parent);
content.appendCodeblock(paramDesc, HdlLangID.Verilog); if (entity) {
if (paramComment) { // find params definitio
content.appendCodeblock(paramComment, HdlLangID.Verilog); for (const param of entity.params) {
if (param.name === targetWord) {
const desc = util.makeParamDesc(param);
content.appendCodeblock(desc, 'vhdl');
return new vscode.Hover(content);
}
} }
return new vscode.Hover(content); // find ports definition
} for (const port of entity.ports) {
if (instPort) { if (port.name === targetWord) {
const portComment = await util.searchCommentAround(currentInstResult.instModPath, instPort.range); const desc = util.makePortDesc(port);
const portDesc = util.makePortDesc(instPort); content.appendCodeblock(desc, 'vhdl');
content.appendCodeblock(portDesc, HdlLangID.Verilog); return new vscode.Hover(content);
if (portComment) { }
content.appendCodeblock(portComment, HdlLangID.Verilog);
} }
}
}
return null;
}
private async makeEntityHover(filePath: string, targetWord: string, targetWordRange: vscode.Range, moduleScope: util.ModuleScope): Promise<vscode.Hover | null> {
const entity = hdlParam.getHdlModule(filePath, moduleScope.module.name);
const content = new vscode.MarkdownString('', true);
if (entity) {
if (targetWord === entity.name) {
await util.makeVhdlHoverContent(content, entity);
return new vscode.Hover(content); return new vscode.Hover(content);
} }
// find params definitio
return null; for (const param of entity.params) {
} if (param.name === targetWord) {
const desc = util.makeParamDesc(param);
content.appendCodeblock(desc, 'vhdl');
// match params return new vscode.Hover(content);
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); // find ports definition
} for (const port of entity.ports) {
if (port.name === targetWord) {
// match ports const desc = util.makePortDesc(port);
const portResult = util.matchPorts(targetWord, currentModule); content.appendCodeblock(desc, 'vhdl');
if (portResult) { return new vscode.Hover(content);
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);
} }
return null;
// 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);
} }
} }

View File

@ -27,7 +27,7 @@ class VlogHoverProvider implements vscode.HoverProvider {
} }
const filePath = document.fileName; const filePath = document.fileName;
const vlogAll = await hdlSymbolStorage.getSymbol(filePath); const vlogAll = await hdlSymbolStorage.getSymbol(filePath);
if (!vlogAll) { if (!vlogAll) {
return null; return null;
} else { } else {
@ -75,11 +75,13 @@ class VlogHoverProvider implements vscode.HoverProvider {
return new vscode.Hover(content, targetWordRange); return new vscode.Hover(content, targetWordRange);
} }
// locate at one module // locate at one module
const scopeSymbols = util.filterSymbolScope(position, all.content); const scopeSymbols = util.locateVlogSymbol(position, all.content);
if (!scopeSymbols || !scopeSymbols.module || !hdlParam.hasHdlModule(filePath, scopeSymbols.module.name)) { if (!scopeSymbols || !scopeSymbols.module || !hdlParam.hasHdlModule(filePath, scopeSymbols.module.name)) {
return null; return null;
} }
const currentModule = hdlParam.getHdlModule(filePath, scopeSymbols.module.name); const currentModule = hdlParam.getHdlModule(filePath, scopeSymbols.module.name);
if (!currentModule) { if (!currentModule) {
MainOutput.report('Fail to get HdlModule ' + filePath + ' ' + scopeSymbols.module.name, ReportType.Debug); MainOutput.report('Fail to get HdlModule ' + filePath + ' ' + scopeSymbols.module.name, ReportType.Debug);

View File

@ -60,7 +60,7 @@ function positionAfterEqual(positionA: Position, positionB: Position): boolean {
/** /**
* @description filter the symbol result item that exceed the scope * @description filter the symbol result item that exceed the scope
*/ */
function filterSymbolScope(position: vscode.Position, rawSymbols: RawSymbol[]): AllowNull<ModuleScope> { function locateVlogSymbol(position: vscode.Position, rawSymbols: RawSymbol[]): AllowNull<ModuleScope> {
if (!rawSymbols) { if (!rawSymbols) {
return null; return null;
} }
@ -87,6 +87,34 @@ function filterSymbolScope(position: vscode.Position, rawSymbols: RawSymbol[]):
}; };
} }
function locateVhdlSymbol(position: vscode.Position, rawSymbols: RawSymbol[]): AllowNull<ModuleScope> {
if (!rawSymbols) {
return null;
}
const parentModules = rawSymbols.filter(item =>
(item.type === 'entity' || item.type === 'architecture') &&
positionAfterEqual(position, item.range.start) &&
positionAfterEqual(item.range.end, position)
);
if (parentModules.length === 0) {
// TODO : macro
return null;
}
const parentModule = parentModules[0];
const symbols = rawSymbols.filter(item =>
item !== parentModule &&
positionAfterEqual(item.range.start, parentModule.range.start) &&
positionAfterEqual(parentModule.range.end, item.range.end));
return {
module : parentModule,
symbols : symbols
};
}
function isInComment(document: vscode.TextDocument, position: Position, comments: CommentResult[]): boolean { function isInComment(document: vscode.TextDocument, position: Position, comments: CommentResult[]): boolean {
if (!comments) { if (!comments) {
@ -391,6 +419,45 @@ async function makeVlogHoverContent(content: vscode.MarkdownString, module: HdlM
content.appendCodeblock(moduleDefinitionCode, 'verilog'); content.appendCodeblock(moduleDefinitionCode, 'verilog');
} }
async function makeVhdlHoverContent(content: vscode.MarkdownString, module: HdlModule) {
const portNum = module.ports.length;
const paramNum = module.params.length;
const instNum = module.getInstanceNum();
const moduleUri = vscode.Uri.file(module.path);
const thenableFileDocument = vscode.workspace.openTextDocument(moduleUri);
const portDesc = ' $(instance-param) ' + paramNum +
' $(instance-port) ' + portNum +
' $(instance-module)' + instNum;
content.appendMarkdown(portDesc);
content.appendText(' | ');
const count = {
input: 0,
output: 0,
inout: 0
};
for (const port of module.ports) {
count[port.type as keyof typeof count] += 1;
}
const ioDesc = ' $(instance-input) ' + count.input +
' $(instance-output) ' + count.output +
' $(instance-inout)' + count.inout;
content.appendMarkdown(ioDesc);
content.appendText('\n');
content.appendMarkdown('---');
// make document
const fileDocument = await thenableFileDocument;
const range = transformRange(module.range, -1, 0, 1);
const moduleDefinitionCode = fileDocument.getText(range);
content.appendCodeblock(moduleDefinitionCode, 'vhdl');
}
async function searchCommentAround(path: AbsPath, range: Range): Promise<string | null> { async function searchCommentAround(path: AbsPath, range: Range): Promise<string | null> {
const targetRange = transformRange(range, -1, 0); const targetRange = transformRange(range, -1, 0);
@ -400,7 +467,8 @@ async function searchCommentAround(path: AbsPath, range: Range): Promise<string
export { export {
transformRange, transformRange,
filterSymbolScope, locateVlogSymbol,
locateVhdlSymbol,
filterInstanceByPosition, filterInstanceByPosition,
isPositionInput, isPositionInput,
isInComment, isInComment,
@ -412,6 +480,7 @@ export {
matchParams, matchParams,
matchNormalSymbol, matchNormalSymbol,
makeVlogHoverContent, makeVlogHoverContent,
makeVhdlHoverContent,
positionAfterEqual, positionAfterEqual,
getInstPortByPosition, getInstPortByPosition,
getInstParamByPosition, getInstParamByPosition,
@ -420,4 +489,5 @@ export {
makeNormalDesc, makeNormalDesc,
transferVlogNumber, transferVlogNumber,
searchCommentAround, searchCommentAround,
ModuleScope
}; };

View File

@ -2,24 +2,23 @@ import * as vscode from 'vscode';
class Keywords { class Keywords {
private keywords: Set<string>; private keywords: Set<string>;
private compilerKeywords: string[]; // start with ` private compilerKeywords: Set<string>; // start with `
private systemKeywords: string[]; // start with $ private systemKeywords: Set<string>; // start with $
constructor(keywords: string[], compilerKeywords: string[], systemKeywords: string[]) { constructor(keywords: string[], compilerKeywords: string[], systemKeywords: string[]) {
this.keywords = new Set(keywords); this.keywords = new Set(keywords);
const keywordItems = []; this.compilerKeywords = new Set(compilerKeywords);
this.compilerKeywords = compilerKeywords; this.systemKeywords = new Set(systemKeywords);
this.systemKeywords = systemKeywords;
} }
public keys(): Set<string> { public keys(): Set<string> {
return this.keywords; return this.keywords;
} }
public compilerKeys(): string[] { public compilerKeys(): Set<string> {
return this.compilerKeywords; return this.compilerKeywords;
} }
public systemKeys(): string[] { public systemKeys(): Set<string> {
return this.systemKeywords; return this.systemKeywords;
} }

View File

@ -170,6 +170,7 @@ interface RawSymbol {
range: Range range: Range
width?: string width?: string
init?: string init?: string
parent?: string
signed: number signed: number
netType: string netType: string
}; };

View File

@ -427,7 +427,7 @@ class HdlModule {
this.range = range; this.range = range;
this.params = params ? params : []; this.params = params ? params : [];
this.ports = ports ? ports : []; this.ports = ports ? ports : [];
this.rawInstances = instances; this.rawInstances = instances;
this.nameToInstances = new Map<string, HdlInstance>(); this.nameToInstances = new Map<string, HdlInstance>();

View File

@ -91,11 +91,10 @@ class HdlAction extends BaseAction {
console.log('HdlAction unlink', path); console.log('HdlAction unlink', path);
// operation to process unlink of hdl files can be deleted in <processLibFiles> // operation to process unlink of hdl files can be deleted in <processLibFiles>
if (fs.existsSync(path)) { path = hdlPath.toSlash(path);
path = hdlPath.toSlash(path); hdlParam.deleteHdlFile(path);
hdlParam.deleteHdlFile(path); console.log(hdlParam);
refreshArchTree(); refreshArchTree();
}
const uri = vscode.Uri.file(path); const uri = vscode.Uri.file(path);
const langID = hdlFile.getLanguageId(path); const langID = hdlFile.getLanguageId(path);