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';
|
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);
|
||||||
})();
|
})();
|
@ -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);
|
||||||
|
@ -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)) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
};
|
};
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
@ -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>();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user