finish 0.3.2
This commit is contained in:
parent
ea1a70e8aa
commit
5c2763f379
Binary file not shown.
@ -3,6 +3,7 @@ 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, ' '));
|
||||
const all = await vhdlAll(testFile);
|
||||
console.log(JSON.stringify(all, null, ' '));
|
||||
console.log('number of symbols:', all.content.length);
|
||||
})();
|
@ -1,6 +1,6 @@
|
||||
const { vlogAll } = require('../../resources/hdlParser');
|
||||
|
||||
const testFile = '../Digital-Test/user/src/netlist_test.v';
|
||||
const testFile = '../Digital-Test/user/src/child_2.v';
|
||||
|
||||
(async () => {
|
||||
const all = await vlogAll(testFile);
|
||||
|
@ -122,7 +122,7 @@ class VlogPositionPortProvider implements vscode.CompletionItemProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
const scopeSymbols = util.filterSymbolScope(position, symbolResult.content);
|
||||
const scopeSymbols = util.locateVlogSymbol(position, symbolResult.content);
|
||||
if (!scopeSymbols ||
|
||||
!scopeSymbols.module ||
|
||||
!scopeSymbols.symbols ||
|
||||
@ -202,7 +202,7 @@ class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
||||
}
|
||||
|
||||
// locate at one module
|
||||
const scopeSymbols = util.filterSymbolScope(position, symbolResult.content);
|
||||
const scopeSymbols = util.locateVlogSymbol(position, symbolResult.content);
|
||||
if (!scopeSymbols ||
|
||||
!scopeSymbols.module ||
|
||||
!hdlParam.hasHdlModule(filePath, scopeSymbols.module.name)) {
|
||||
|
@ -7,12 +7,13 @@ import { vlogKeyword } from '../util/keyword';
|
||||
import * as util from '../util';
|
||||
import { MainOutput, ReportType } from '../../../global';
|
||||
import { hdlSymbolStorage } from '../core';
|
||||
import { RawSymbol } from '../../../hdlParser/common';
|
||||
|
||||
|
||||
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) {
|
||||
@ -51,106 +52,115 @@ class VhdlDefinitionProvider implements vscode.DefinitionProvider {
|
||||
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];
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
if (!moduleScope) {
|
||||
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];
|
||||
const scopeType = moduleScope.module.type;
|
||||
if (scopeType === 'architecture') {
|
||||
return await this.makeArchitectureDefinition(filePath, targetWord, targetWordRange, moduleScope);
|
||||
} else if (scopeType === 'entity') {
|
||||
return await this.makeEntityDefinition(filePath, targetWord, targetWordRange, moduleScope);
|
||||
}
|
||||
|
||||
// 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;
|
||||
return null;
|
||||
}
|
||||
|
||||
private async makeArchitectureDefinition(filePath: string, targetWord: string, targetWordRange: vscode.Range, moduleScope: util.ModuleScope): Promise<vscode.Location | vscode.LocationLink[] | 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
|
||||
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];
|
||||
// filter defined signal
|
||||
for (const symbol of moduleScope.symbols) {
|
||||
if (symbol.name === targetWord) {
|
||||
const targetUri = vscode.Uri.file(filePath);
|
||||
const targetRange = util.transformRange(symbol.range, 0, 0);
|
||||
const link: vscode.LocationLink = { targetUri, targetRange, originSelectionRange: targetWordRange };
|
||||
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];
|
||||
// inner variable mapping to entity
|
||||
if (architecture.parent) {
|
||||
const entity = hdlParam.getHdlModule(filePath, architecture.parent);
|
||||
if (entity) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ class VlogDefinitionProvider implements vscode.DefinitionProvider {
|
||||
}
|
||||
|
||||
// locate at one module
|
||||
const scopeSymbols = util.filterSymbolScope(position, all.content);
|
||||
const scopeSymbols = util.locateVlogSymbol(position, all.content);
|
||||
if (!scopeSymbols || !scopeSymbols.module) {
|
||||
return null;
|
||||
}
|
||||
|
@ -4,13 +4,18 @@ 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>
|
||||
};
|
||||
|
||||
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 {
|
||||
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') {
|
||||
const docSymbol = new vscode.DocumentSymbol(symbol.name,
|
||||
symbol.name,
|
||||
vscode.SymbolKind.Interface,
|
||||
vhdlSymbolKind[symbol.type],
|
||||
symbolRange,
|
||||
symbolRange);
|
||||
docSymbols.push(docSymbol);
|
||||
@ -46,10 +51,27 @@ class VhdlDocSymbolProvider implements vscode.DocumentSymbolProvider {
|
||||
const parentEntity = docSymbols[docSymbols.length - 1];
|
||||
const docSymbol = new vscode.DocumentSymbol(symbol.name,
|
||||
symbol.name,
|
||||
vscode.SymbolKind.Method,
|
||||
vhdlSymbolKind[symbol.type],
|
||||
symbolRange,
|
||||
symbolRange);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,12 @@ import * as vscode from 'vscode';
|
||||
import { hdlPath } from '../../../hdlFs';
|
||||
import { hdlParam } from '../../../hdlParser';
|
||||
import { All } from '../../../../resources/hdlParser';
|
||||
import { vlogKeyword } from '../util/keyword';
|
||||
import { vhdlKeyword } from '../util/keyword';
|
||||
import * as util from '../util';
|
||||
import { MainOutput, ReportType } from '../../../global';
|
||||
import { HdlLangID } from '../../../global/enum';
|
||||
import { hdlSymbolStorage } from '../core';
|
||||
import { RawSymbol } from '../../../hdlParser/common';
|
||||
|
||||
|
||||
class VhdlHoverProvider implements vscode.HoverProvider {
|
||||
@ -26,19 +27,33 @@ class VhdlHoverProvider implements vscode.HoverProvider {
|
||||
return null;
|
||||
}
|
||||
|
||||
const keywordHover = this.getKeywordHover(targetWord);
|
||||
if (keywordHover) {
|
||||
return keywordHover;
|
||||
}
|
||||
|
||||
const filePath = document.fileName;
|
||||
const vlogAll = await hdlSymbolStorage.getSymbol(filePath);
|
||||
if (!vlogAll) {
|
||||
const vhdlAll = await hdlSymbolStorage.getSymbol(filePath);
|
||||
if (!vhdlAll) {
|
||||
return null;
|
||||
} else {
|
||||
const hover = await this.makeHover(document, position, vlogAll, targetWord, wordRange);
|
||||
const hover = await this.makeHover(document, position, vhdlAll, targetWord, wordRange);
|
||||
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 {
|
||||
// check keyword
|
||||
if (vlogKeyword.isKeyword(targetWord)) {
|
||||
if (vhdlKeyword.isKeyword(targetWord)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -52,147 +67,110 @@ class VhdlHoverProvider implements vscode.HoverProvider {
|
||||
const lineText = document.lineAt(position).text;
|
||||
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);
|
||||
|
||||
// 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');
|
||||
// point to the entity of the architecture
|
||||
if (architecture.parent && architecture.parent === targetWord) {
|
||||
const entity = hdlParam.getHdlModule(filePath, architecture.parent);
|
||||
if (entity) {
|
||||
await util.makeVhdlHoverContent(content, entity);
|
||||
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;
|
||||
// filter defined signal
|
||||
for (const symbol of moduleScope.symbols) {
|
||||
if (symbol.name === targetWord) {
|
||||
content.appendCodeblock(symbol.type, 'vhdl');
|
||||
return new vscode.Hover(content);
|
||||
}
|
||||
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);
|
||||
// inner variable mapping to entity
|
||||
if (architecture.parent) {
|
||||
const entity = hdlParam.getHdlModule(filePath, architecture.parent);
|
||||
if (entity) {
|
||||
// find params definitio
|
||||
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);
|
||||
}
|
||||
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);
|
||||
// find ports definition
|
||||
for (const port of entity.ports) {
|
||||
if (port.name === targetWord) {
|
||||
const desc = util.makePortDesc(port);
|
||||
content.appendCodeblock(desc, 'vhdl');
|
||||
return new vscode.Hover(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 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);
|
||||
// find params definitio
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
// find ports definition
|
||||
for (const port of entity.ports) {
|
||||
if (port.name === targetWord) {
|
||||
const desc = util.makePortDesc(port);
|
||||
content.appendCodeblock(desc, 'vhdl');
|
||||
return new vscode.Hover(content);
|
||||
}
|
||||
}
|
||||
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);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ class VlogHoverProvider implements vscode.HoverProvider {
|
||||
}
|
||||
|
||||
const filePath = document.fileName;
|
||||
const vlogAll = await hdlSymbolStorage.getSymbol(filePath);
|
||||
const vlogAll = await hdlSymbolStorage.getSymbol(filePath);
|
||||
if (!vlogAll) {
|
||||
return null;
|
||||
} else {
|
||||
@ -75,11 +75,13 @@ class VlogHoverProvider implements vscode.HoverProvider {
|
||||
return new vscode.Hover(content, targetWordRange);
|
||||
}
|
||||
|
||||
// locate at one module
|
||||
const scopeSymbols = util.filterSymbolScope(position, all.content);
|
||||
// locate at one module
|
||||
const scopeSymbols = util.locateVlogSymbol(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);
|
||||
|
@ -60,7 +60,7 @@ function positionAfterEqual(positionA: Position, positionB: Position): boolean {
|
||||
/**
|
||||
* @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) {
|
||||
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 {
|
||||
if (!comments) {
|
||||
@ -391,6 +419,45 @@ async function makeVlogHoverContent(content: vscode.MarkdownString, module: HdlM
|
||||
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> {
|
||||
const targetRange = transformRange(range, -1, 0);
|
||||
@ -400,7 +467,8 @@ async function searchCommentAround(path: AbsPath, range: Range): Promise<string
|
||||
|
||||
export {
|
||||
transformRange,
|
||||
filterSymbolScope,
|
||||
locateVlogSymbol,
|
||||
locateVhdlSymbol,
|
||||
filterInstanceByPosition,
|
||||
isPositionInput,
|
||||
isInComment,
|
||||
@ -412,6 +480,7 @@ export {
|
||||
matchParams,
|
||||
matchNormalSymbol,
|
||||
makeVlogHoverContent,
|
||||
makeVhdlHoverContent,
|
||||
positionAfterEqual,
|
||||
getInstPortByPosition,
|
||||
getInstParamByPosition,
|
||||
@ -420,4 +489,5 @@ export {
|
||||
makeNormalDesc,
|
||||
transferVlogNumber,
|
||||
searchCommentAround,
|
||||
ModuleScope
|
||||
};
|
@ -2,24 +2,23 @@ import * as vscode from 'vscode';
|
||||
|
||||
class Keywords {
|
||||
private keywords: Set<string>;
|
||||
private compilerKeywords: string[]; // start with `
|
||||
private systemKeywords: string[]; // start with $
|
||||
private compilerKeywords: Set<string>; // start with `
|
||||
private systemKeywords: Set<string>; // start with $
|
||||
constructor(keywords: string[], compilerKeywords: string[], systemKeywords: string[]) {
|
||||
this.keywords = new Set(keywords);
|
||||
const keywordItems = [];
|
||||
this.compilerKeywords = compilerKeywords;
|
||||
this.systemKeywords = systemKeywords;
|
||||
this.compilerKeywords = new Set(compilerKeywords);
|
||||
this.systemKeywords = new Set(systemKeywords);
|
||||
}
|
||||
|
||||
public keys(): Set<string> {
|
||||
return this.keywords;
|
||||
}
|
||||
|
||||
public compilerKeys(): string[] {
|
||||
public compilerKeys(): Set<string> {
|
||||
return this.compilerKeywords;
|
||||
}
|
||||
|
||||
public systemKeys(): string[] {
|
||||
public systemKeys(): Set<string> {
|
||||
return this.systemKeywords;
|
||||
}
|
||||
|
||||
|
@ -170,6 +170,7 @@ interface RawSymbol {
|
||||
range: Range
|
||||
width?: string
|
||||
init?: string
|
||||
parent?: string
|
||||
signed: number
|
||||
netType: string
|
||||
};
|
||||
|
@ -427,7 +427,7 @@ class HdlModule {
|
||||
this.range = range;
|
||||
this.params = params ? params : [];
|
||||
this.ports = ports ? ports : [];
|
||||
|
||||
|
||||
this.rawInstances = instances;
|
||||
this.nameToInstances = new Map<string, HdlInstance>();
|
||||
|
||||
|
@ -91,11 +91,10 @@ class HdlAction extends BaseAction {
|
||||
console.log('HdlAction unlink', path);
|
||||
|
||||
// operation to process unlink of hdl files can be deleted in <processLibFiles>
|
||||
if (fs.existsSync(path)) {
|
||||
path = hdlPath.toSlash(path);
|
||||
hdlParam.deleteHdlFile(path);
|
||||
refreshArchTree();
|
||||
}
|
||||
path = hdlPath.toSlash(path);
|
||||
hdlParam.deleteHdlFile(path);
|
||||
console.log(hdlParam);
|
||||
refreshArchTree();
|
||||
|
||||
const uri = vscode.Uri.file(path);
|
||||
const langID = hdlFile.getLanguageId(path);
|
||||
|
Loading…
x
Reference in New Issue
Block a user