#fix optimise LSP
This commit is contained in:
parent
d6c80a919a
commit
77f743e1a3
@ -14,6 +14,7 @@ import * as lspDocSemantic from './lsp/docSemantic';
|
||||
import * as lspLinter from './lsp/linter';
|
||||
|
||||
import * as tool from './tool';
|
||||
import * as lspCore from './lsp/core';
|
||||
|
||||
// special function
|
||||
import * as FSM from './fsm';
|
||||
@ -77,8 +78,9 @@ function registerLsp(context: vscode.ExtensionContext) {
|
||||
vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogPositionPortProvider, '.');
|
||||
vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogCompletionProvider);
|
||||
vscode.languages.registerDocumentSemanticTokensProvider(vlogSelector, lspDocSemantic.vlogDocSenmanticProvider, lspDocSemantic.vlogLegend);
|
||||
const vlogLinter = lspLinter.registerVlogLinterServer();
|
||||
lspLinter.firstLinter(vlogLinter);
|
||||
|
||||
lspLinter.vlogLinter.initialise();
|
||||
lspCore.vlogSymbolStorage.initialise();
|
||||
|
||||
// vhdl lsp
|
||||
}
|
||||
|
@ -3,15 +3,18 @@ import * as fs from 'fs';
|
||||
|
||||
import * as util from '../util';
|
||||
import { hdlFile, hdlPath } from '../../../hdlFs';
|
||||
import { hdlParam, HdlSymbol } from '../../../hdlParser';
|
||||
import { hdlParam } from '../../../hdlParser';
|
||||
import { AbsPath, MainOutput, RelPath, ReportType } from '../../../global';
|
||||
import { Define, Include, RawSymbol } from '../../../hdlParser/common';
|
||||
import { HdlInstance, HdlModule } from '../../../hdlParser/core';
|
||||
import { vlogKeyword } from '../util/keyword';
|
||||
import { instanceVlogCode } from '../../sim/instance';
|
||||
import { vlogSymbolStorage } from '../core';
|
||||
|
||||
class VlogIncludeCompletionProvider implements vscode.CompletionItemProvider {
|
||||
public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): vscode.ProviderResult<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem>> {
|
||||
// console.log('VlogIncludeCompletionProvider');
|
||||
|
||||
try {
|
||||
const items = this.provideIncludeFiles(document, position);
|
||||
return items;
|
||||
@ -67,11 +70,14 @@ class VlogIncludeCompletionProvider implements vscode.CompletionItemProvider {
|
||||
|
||||
class VlogMacroCompletionProvider implements vscode.CompletionItemProvider {
|
||||
public async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Promise<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem> | null | undefined> {
|
||||
// console.log('VlogMacroCompletionProvider');
|
||||
|
||||
try {
|
||||
const targetWordRange = document.getWordRangeAtPosition(position, /[`_0-9a-zA-Z]+/);
|
||||
const targetWord = document.getText(targetWordRange);
|
||||
const filePath = document.fileName;
|
||||
const symbolResult = await HdlSymbol.all(filePath);
|
||||
|
||||
const symbolResult = await vlogSymbolStorage.getSymbol(filePath);
|
||||
if (!symbolResult) {
|
||||
return null;
|
||||
}
|
||||
@ -102,10 +108,12 @@ class VlogMacroCompletionProvider implements vscode.CompletionItemProvider {
|
||||
|
||||
class VlogPositionPortProvider implements vscode.CompletionItemProvider {
|
||||
public async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Promise<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem> | null | undefined> {
|
||||
// console.log('VlogPositionPortProvider');
|
||||
|
||||
try {
|
||||
const suggestPositionPorts: vscode.CompletionItem[] = [];
|
||||
const filePath = hdlPath.toSlash(document.fileName);
|
||||
const symbolResult = await HdlSymbol.all(filePath);
|
||||
const symbolResult = await vlogSymbolStorage.getSymbol(filePath);
|
||||
if (!symbolResult) {
|
||||
return null;
|
||||
}
|
||||
@ -173,6 +181,8 @@ class VlogPositionPortProvider implements vscode.CompletionItemProvider {
|
||||
|
||||
class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
||||
public async provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, context: vscode.CompletionContext): Promise<vscode.CompletionItem[] | vscode.CompletionList<vscode.CompletionItem> | null | undefined> {
|
||||
// console.log('VlogCompletionProvider');
|
||||
|
||||
try {
|
||||
const filePath = hdlPath.toSlash(document.fileName);
|
||||
|
||||
@ -181,7 +191,7 @@ class VlogCompletionProvider implements vscode.CompletionItemProvider {
|
||||
completions.push(...this.makeCompilerKeywordItems(document, position));
|
||||
completions.push(...this.makeSystemKeywordItems(document, position));
|
||||
|
||||
const symbolResult = await HdlSymbol.all(filePath);
|
||||
const symbolResult = await vlogSymbolStorage.getSymbol(filePath);
|
||||
if (!symbolResult) {
|
||||
return completions;
|
||||
}
|
||||
|
5
src/function/lsp/core/index.ts
Normal file
5
src/function/lsp/core/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { vlogSymbolStorage } from './vlog';
|
||||
|
||||
export {
|
||||
vlogSymbolStorage
|
||||
};
|
48
src/function/lsp/core/vlog.ts
Normal file
48
src/function/lsp/core/vlog.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { All } from '../../../../resources/hdlParser';
|
||||
import { AbsPath } from '../../../global';
|
||||
import { hdlPath } from '../../../hdlFs';
|
||||
import { isVerilogFile } from '../../../hdlFs/file';
|
||||
import { HdlSymbol } from '../../../hdlParser';
|
||||
|
||||
type ThenableAll = Promise<All | undefined>;
|
||||
|
||||
class VlogSymbolStorage {
|
||||
private symbolMap: Map<AbsPath, ThenableAll>;
|
||||
constructor() {
|
||||
this.symbolMap = new Map<AbsPath, ThenableAll>();
|
||||
}
|
||||
|
||||
public async getSymbol(path: AbsPath): ThenableAll {
|
||||
path = hdlPath.toSlash(path);
|
||||
const all = await this.symbolMap.get(path);
|
||||
return all;
|
||||
}
|
||||
|
||||
public async updateSymbol(path: AbsPath) {
|
||||
path = hdlPath.toSlash(path);
|
||||
const vlogAllPromise = HdlSymbol.all(path);
|
||||
this.symbolMap.set(path, vlogAllPromise);
|
||||
}
|
||||
|
||||
public async deleteSymbol(path: AbsPath) {
|
||||
path = hdlPath.toSlash(path);
|
||||
this.symbolMap.delete(path);
|
||||
}
|
||||
|
||||
|
||||
public async initialise() {
|
||||
for (const doc of vscode.workspace.textDocuments) {
|
||||
if (isVerilogFile(doc.fileName)) {
|
||||
// TODO : check performance
|
||||
await this.updateSymbol(doc.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const vlogSymbolStorage = new VlogSymbolStorage();
|
||||
|
||||
export {
|
||||
vlogSymbolStorage
|
||||
};
|
@ -2,16 +2,18 @@ import * as vscode from 'vscode';
|
||||
import * as vsctm from 'vscode-textmate';
|
||||
|
||||
import { hdlPath } from '../../../hdlFs';
|
||||
import { hdlParam, HdlSymbol } from '../../../hdlParser';
|
||||
import { hdlParam } from '../../../hdlParser';
|
||||
import { All } from '../../../../resources/hdlParser';
|
||||
import { vlogKeyword } from '../util/keyword';
|
||||
import * as util from '../util';
|
||||
import { MainOutput, ReportType } from '../../../global';
|
||||
import { vlogSymbolStorage } from '../core';
|
||||
|
||||
|
||||
class VlogDefinitionProvider implements vscode.DefinitionProvider {
|
||||
|
||||
public async provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Location | vscode.LocationLink[] | null> {
|
||||
// console.log('VlogDefinitionProvider');
|
||||
|
||||
// get current words
|
||||
const wordRange = document.getWordRangeAtPosition(position, /[`_0-9A-Za-z]+/);
|
||||
if (!wordRange) {
|
||||
@ -25,7 +27,7 @@ class VlogDefinitionProvider implements vscode.DefinitionProvider {
|
||||
}
|
||||
|
||||
const filePath = document.fileName;
|
||||
const vlogAll = await HdlSymbol.all(filePath);
|
||||
const vlogAll = await vlogSymbolStorage.getSymbol(filePath);
|
||||
if (!vlogAll) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -1,15 +1,14 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { HdlSymbol } from '../../../hdlParser';
|
||||
|
||||
const tokenTypes = ['class', 'interface', 'enum', 'function', 'variable'];
|
||||
const tokenModifiers = ['declaration', 'documentation'];
|
||||
const vlogLegend = new vscode.SemanticTokensLegend(tokenTypes, tokenModifiers);
|
||||
|
||||
class VlogDocSenmanticProvider implements vscode.DocumentSemanticTokensProvider {
|
||||
public async provideDocumentSemanticTokens(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.SemanticTokens | null | undefined> {
|
||||
const tokensBuilder = new vscode.SemanticTokensBuilder(vlogLegend);
|
||||
return tokensBuilder.build();
|
||||
// TODO : finish this
|
||||
// const tokensBuilder = new vscode.SemanticTokensBuilder(vlogLegend);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { AllowNull } from '../../../global';
|
||||
import { HdlSymbol } from '../../../hdlParser';
|
||||
import { RawSymbol, Range } from '../../../hdlParser/common';
|
||||
import { vlogSymbolStorage } from '../core';
|
||||
|
||||
import { positionAfterEqual } from '../util';
|
||||
|
||||
@ -13,8 +13,10 @@ interface DocSymbolContainer {
|
||||
|
||||
class VlogDocSymbolProvider implements vscode.DocumentSymbolProvider {
|
||||
public async provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentSymbol[]> {
|
||||
// console.log('VlogDocSymbolProvider');
|
||||
|
||||
const path = document.fileName;
|
||||
const vlogAll = await HdlSymbol.all(path);
|
||||
const vlogAll = await vlogSymbolStorage.getSymbol(path);
|
||||
|
||||
if (!vlogAll || !vlogAll.content) {
|
||||
return [];
|
||||
|
@ -1,16 +1,19 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { hdlDir, hdlPath } from '../../../hdlFs';
|
||||
import { hdlParam, HdlSymbol } from '../../../hdlParser';
|
||||
import { hdlPath } from '../../../hdlFs';
|
||||
import { hdlParam } from '../../../hdlParser';
|
||||
import { All } from '../../../../resources/hdlParser';
|
||||
import { vlogKeyword } from '../util/keyword';
|
||||
import * as util from '../util';
|
||||
import { MainOutput, ReportType } from '../../../global';
|
||||
import { HdlLangID } from '../../../global/enum';
|
||||
import { vlogSymbolStorage } from '../core';
|
||||
|
||||
|
||||
class VlogHoverProvider implements vscode.HoverProvider {
|
||||
public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Hover | null> {
|
||||
// console.log('VlogHoverProvider');
|
||||
|
||||
// get current words
|
||||
const wordRange = document.getWordRangeAtPosition(position, /[`_0-9A-Za-z]+/);
|
||||
if (!wordRange) {
|
||||
@ -24,7 +27,7 @@ class VlogHoverProvider implements vscode.HoverProvider {
|
||||
}
|
||||
|
||||
const filePath = document.fileName;
|
||||
const vlogAll = await HdlSymbol.all(filePath);
|
||||
const vlogAll = await vlogSymbolStorage.getSymbol(filePath);
|
||||
if (!vlogAll) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { registerVlogLinterServer, firstLinter } from './vlog';
|
||||
import { vlogLinter } from './vlog';
|
||||
|
||||
export {
|
||||
registerVlogLinterServer,
|
||||
firstLinter
|
||||
vlogLinter
|
||||
};
|
@ -1,8 +1,8 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { All } from '../../../../resources/hdlParser';
|
||||
import { getLanguageId, isVerilogFile } from '../../../hdlFs/file';
|
||||
import { hdlParam, HdlSymbol } from '../../../hdlParser';
|
||||
import { isVerilogFile } from '../../../hdlFs/file';
|
||||
import { Position, Range } from '../../../hdlParser/common';
|
||||
import { vlogSymbolStorage } from '../core';
|
||||
|
||||
|
||||
class VlogLinter {
|
||||
@ -13,7 +13,9 @@ class VlogLinter {
|
||||
|
||||
async lint(document: vscode.TextDocument) {
|
||||
const filePath = document.fileName;
|
||||
const vlogAll = await HdlSymbol.all(filePath);
|
||||
const vlogAll = await vlogSymbolStorage.getSymbol(filePath);
|
||||
console.log('lint all finish');
|
||||
|
||||
if (vlogAll) {
|
||||
const diagnostics = this.provideDiagnostics(document, vlogAll);
|
||||
this.diagnostic.set(document.uri, diagnostics);
|
||||
@ -30,8 +32,6 @@ class VlogLinter {
|
||||
diagnostics.push(diag);
|
||||
}
|
||||
}
|
||||
console.log(diagnostics);
|
||||
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
@ -54,7 +54,6 @@ class VlogLinter {
|
||||
if (range.character === 0 && currentLine.trim().length > 0) {
|
||||
range.character = currentLine.trimEnd().length;
|
||||
}
|
||||
console.log(range);
|
||||
|
||||
const position = new vscode.Position(range.line, range.character);
|
||||
const wordRange = document.getWordRangeAtPosition(position, /[`_0-9a-zA-Z]+/);
|
||||
@ -70,37 +69,19 @@ class VlogLinter {
|
||||
async remove(document: vscode.TextDocument) {
|
||||
this.diagnostic.delete(document.uri);
|
||||
}
|
||||
}
|
||||
|
||||
function registerVlogLinterServer(): VlogLinter {
|
||||
const linter = new VlogLinter();
|
||||
vscode.workspace.onDidOpenTextDocument(doc => {
|
||||
if (isVerilogFile(doc.fileName)) {
|
||||
linter.lint(doc);
|
||||
}
|
||||
});
|
||||
vscode.workspace.onDidSaveTextDocument(doc => {
|
||||
if (isVerilogFile(doc.fileName)) {
|
||||
linter.lint(doc);
|
||||
}
|
||||
});
|
||||
vscode.workspace.onDidCloseTextDocument(doc => {
|
||||
if (isVerilogFile(doc.fileName)) {
|
||||
linter.remove(doc);
|
||||
}
|
||||
});
|
||||
return linter;
|
||||
}
|
||||
|
||||
async function firstLinter(linter: VlogLinter) {
|
||||
for (const doc of vscode.workspace.textDocuments) {
|
||||
if (isVerilogFile(doc.fileName)) {
|
||||
linter.lint(doc);
|
||||
public async initialise() {
|
||||
for (const doc of vscode.workspace.textDocuments) {
|
||||
if (isVerilogFile(doc.fileName)) {
|
||||
// TODO : check performance
|
||||
await this.lint(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const vlogLinter = new VlogLinter();
|
||||
|
||||
export {
|
||||
registerVlogLinterServer,
|
||||
firstLinter
|
||||
vlogLinter
|
||||
};
|
@ -13,6 +13,9 @@ import { prjManage } from '../manager';
|
||||
import { libManage } from '../manager/lib';
|
||||
import type { HdlMonitor } from './index';
|
||||
import { ToolChainType } from '../global/enum';
|
||||
import { vlogSymbolStorage } from '../function/lsp/core';
|
||||
import { vlogLinter } from '../function/lsp/linter';
|
||||
import { isVerilogFile } from '../hdlFs/file';
|
||||
|
||||
enum Event {
|
||||
Add = 'add', // emit when add file
|
||||
@ -70,6 +73,8 @@ class HdlAction extends BaseAction {
|
||||
|
||||
path = hdlPath.toSlash(path);
|
||||
|
||||
this.updateLinter(path);
|
||||
|
||||
// check if it has been created
|
||||
if (hdlParam.hasHdlFile(path)) {
|
||||
MainOutput.report('<HdlAction Add Event> HdlFile ' + path + ' has been created', ReportType.Warn);
|
||||
@ -91,6 +96,10 @@ class HdlAction extends BaseAction {
|
||||
hdlParam.deleteHdlFile(path);
|
||||
refreshArchTree();
|
||||
}
|
||||
|
||||
const uri = vscode.Uri.file(path);
|
||||
const document = await vscode.workspace.openTextDocument(uri);
|
||||
vlogLinter.remove(document);
|
||||
}
|
||||
|
||||
async unlinkDir(path: string, m: HdlMonitor): Promise<void> {
|
||||
@ -105,8 +114,29 @@ class HdlAction extends BaseAction {
|
||||
|
||||
async change(path: string, m: HdlMonitor): Promise<void> {
|
||||
console.log('HdlAction change');
|
||||
|
||||
path = hdlPath.toSlash(path);
|
||||
|
||||
// TODO : check performance
|
||||
await this.updateSymbolStorage(path);
|
||||
await this.updateLinter(path);
|
||||
|
||||
await this.updateHdlParam(path);
|
||||
refreshArchTree();
|
||||
}
|
||||
|
||||
async updateSymbolStorage(path: string) {
|
||||
vlogSymbolStorage.updateSymbol(path);
|
||||
}
|
||||
|
||||
async updateLinter(path: string) {
|
||||
if (isVerilogFile(path)) {
|
||||
const uri = vscode.Uri.file(path);
|
||||
const document = await vscode.workspace.openTextDocument(uri);
|
||||
vlogLinter.lint(document);
|
||||
}
|
||||
}
|
||||
|
||||
async updateHdlParam(path: string) {
|
||||
const moduleFile = hdlParam.getHdlFile(path);
|
||||
|
||||
if (!moduleFile) {
|
||||
@ -147,8 +177,6 @@ class HdlAction extends BaseAction {
|
||||
for (const moduleName of uncheckedModuleNames) {
|
||||
moduleFile.deleteHdlModule(moduleName);
|
||||
}
|
||||
|
||||
refreshArchTree();
|
||||
}
|
||||
}
|
||||
|
||||
|
29
src/test/user/Hardware/src/clkdiv.v
Normal file
29
src/test/user/Hardware/src/clkdiv.v
Normal file
@ -0,0 +1,29 @@
|
||||
module clkdiv(
|
||||
input clk50,
|
||||
input rst_n,
|
||||
output reg clkout
|
||||
);
|
||||
reg [15:0] cnt;
|
||||
always @(posedge clk50 or negedge rst_n)
|
||||
begin
|
||||
if(!rst_n)
|
||||
begin
|
||||
cnt <= 16'b0;
|
||||
clkout <= 1'b0;
|
||||
end
|
||||
else if(cnt == 16'd162)
|
||||
begin
|
||||
clkout <= 1'b1;
|
||||
cnt <= cnt + 16'd1;
|
||||
end
|
||||
else if(cnt == 16'd325)
|
||||
begin
|
||||
clkout <= 1'b0;
|
||||
cnt <= 16'd0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cnt <= cnt + 16'd1;
|
||||
end
|
||||
end
|
||||
endmodule
|
@ -8,9 +8,6 @@ module mux2to1(
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
assign outp = sel == 1'b0 ? a : b;
|
||||
|
||||
endmodule
|
||||
|
Loading…
x
Reference in New Issue
Block a user