diff --git a/resources/hdlParser/parser.wasm b/resources/hdlParser/parser.wasm index d964683..9626ef7 100644 Binary files a/resources/hdlParser/parser.wasm and b/resources/hdlParser/parser.wasm differ diff --git a/script/test/vhdlAll.js b/script/test/vhdlAll.js index b2514fa..74e4aef 100644 --- a/script/test/vhdlAll.js +++ b/script/test/vhdlAll.js @@ -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); })(); \ No newline at end of file diff --git a/script/test/vlogAll.js b/script/test/vlogAll.js index 282d9da..6538f7b 100644 --- a/script/test/vlogAll.js +++ b/script/test/vlogAll.js @@ -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); diff --git a/src/function/lsp/completion/vlog.ts b/src/function/lsp/completion/vlog.ts index a40a817..c14ad2b 100644 --- a/src/function/lsp/completion/vlog.ts +++ b/src/function/lsp/completion/vlog.ts @@ -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)) { diff --git a/src/function/lsp/definition/vhdl.ts b/src/function/lsp/definition/vhdl.ts index 62576e5..93d8e02 100644 --- a/src/function/lsp/definition/vhdl.ts +++ b/src/function/lsp/definition/vhdl.ts @@ -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 { // 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 { + 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 { + 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; } } diff --git a/src/function/lsp/definition/vlog.ts b/src/function/lsp/definition/vlog.ts index b97b827..54b51de 100644 --- a/src/function/lsp/definition/vlog.ts +++ b/src/function/lsp/definition/vlog.ts @@ -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; } diff --git a/src/function/lsp/docSymbol/vhdl.ts b/src/function/lsp/docSymbol/vhdl.ts index 5aae9ba..a117492 100644 --- a/src/function/lsp/docSymbol/vhdl.ts +++ b/src/function/lsp/docSymbol/vhdl.ts @@ -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, range: AllowNull }; +const vhdlSymbolKind: Record = { + 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 { @@ -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); + } } } diff --git a/src/function/lsp/hover/vhdl.ts b/src/function/lsp/hover/vhdl.ts index 6326c5a..38358bc 100644 --- a/src/function/lsp/hover/vhdl.ts +++ b/src/function/lsp/hover/vhdl.ts @@ -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 { + 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 { + 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; } } diff --git a/src/function/lsp/hover/vlog.ts b/src/function/lsp/hover/vlog.ts index 6986650..51dd730 100644 --- a/src/function/lsp/hover/vlog.ts +++ b/src/function/lsp/hover/vlog.ts @@ -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); diff --git a/src/function/lsp/util/index.ts b/src/function/lsp/util/index.ts index 9d8bda2..5a27b97 100644 --- a/src/function/lsp/util/index.ts +++ b/src/function/lsp/util/index.ts @@ -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 { +function locateVlogSymbol(position: vscode.Position, rawSymbols: RawSymbol[]): AllowNull { if (!rawSymbols) { return null; } @@ -87,6 +87,34 @@ function filterSymbolScope(position: vscode.Position, rawSymbols: RawSymbol[]): }; } +function locateVhdlSymbol(position: vscode.Position, rawSymbols: RawSymbol[]): AllowNull { + 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 { const targetRange = transformRange(range, -1, 0); @@ -400,7 +467,8 @@ async function searchCommentAround(path: AbsPath, range: Range): Promise; - private compilerKeywords: string[]; // start with ` - private systemKeywords: string[]; // start with $ + private compilerKeywords: Set; // start with ` + private systemKeywords: Set; // 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 { return this.keywords; } - public compilerKeys(): string[] { + public compilerKeys(): Set { return this.compilerKeywords; } - public systemKeys(): string[] { + public systemKeys(): Set { return this.systemKeywords; } diff --git a/src/hdlParser/common.ts b/src/hdlParser/common.ts index 2dd78ed..339aef0 100644 --- a/src/hdlParser/common.ts +++ b/src/hdlParser/common.ts @@ -170,6 +170,7 @@ interface RawSymbol { range: Range width?: string init?: string + parent?: string signed: number netType: string }; diff --git a/src/hdlParser/core.ts b/src/hdlParser/core.ts index 65344b3..9f1d522 100644 --- a/src/hdlParser/core.ts +++ b/src/hdlParser/core.ts @@ -427,7 +427,7 @@ class HdlModule { this.range = range; this.params = params ? params : []; this.ports = ports ? ports : []; - + this.rawInstances = instances; this.nameToInstances = new Map(); diff --git a/src/monitor/event.ts b/src/monitor/event.ts index 545053f..e4019f5 100644 --- a/src/monitor/event.ts +++ b/src/monitor/event.ts @@ -91,11 +91,10 @@ class HdlAction extends BaseAction { console.log('HdlAction unlink', path); // operation to process unlink of hdl files can be deleted in - 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);