#fix optimise LSP

This commit is contained in:
锦恢 2023-07-30 16:35:06 +08:00
parent d6c80a919a
commit 77f743e1a3
13 changed files with 167 additions and 62 deletions

View File

@ -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,9 +78,10 @@ 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
}

View File

@ -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;
}

View File

@ -0,0 +1,5 @@
import { vlogSymbolStorage } from './vlog';
export {
vlogSymbolStorage
};

View 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
};

View File

@ -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 {

View File

@ -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;
}
}

View File

@ -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 [];

View File

@ -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 {

View File

@ -1,6 +1,5 @@
import { registerVlogLinterServer, firstLinter } from './vlog';
import { vlogLinter } from './vlog';
export {
registerVlogLinterServer,
firstLinter
vlogLinter
};

View File

@ -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);
@ -29,9 +31,7 @@ class VlogLinter {
diag.source = hdlError.source;
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
};

View File

@ -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();
}
}

View 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

View File

@ -7,10 +7,7 @@ module mux2to1(
output wire outp
);
assign outp = sel == 1'b0 ? a : b;
endmodule