#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 lspLinter from './lsp/linter';
import * as tool from './tool'; import * as tool from './tool';
import * as lspCore from './lsp/core';
// special function // special function
import * as FSM from './fsm'; 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.vlogPositionPortProvider, '.');
vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogCompletionProvider); vscode.languages.registerCompletionItemProvider(vlogSelector, lspCompletion.vlogCompletionProvider);
vscode.languages.registerDocumentSemanticTokensProvider(vlogSelector, lspDocSemantic.vlogDocSenmanticProvider, lspDocSemantic.vlogLegend); vscode.languages.registerDocumentSemanticTokensProvider(vlogSelector, lspDocSemantic.vlogDocSenmanticProvider, lspDocSemantic.vlogLegend);
const vlogLinter = lspLinter.registerVlogLinterServer();
lspLinter.firstLinter(vlogLinter); lspLinter.vlogLinter.initialise();
lspCore.vlogSymbolStorage.initialise();
// vhdl lsp // vhdl lsp
} }

View File

@ -3,15 +3,18 @@ import * as fs from 'fs';
import * as util from '../util'; import * as util from '../util';
import { hdlFile, hdlPath } from '../../../hdlFs'; import { hdlFile, hdlPath } from '../../../hdlFs';
import { hdlParam, HdlSymbol } from '../../../hdlParser'; import { hdlParam } from '../../../hdlParser';
import { AbsPath, MainOutput, RelPath, ReportType } from '../../../global'; import { AbsPath, MainOutput, RelPath, ReportType } from '../../../global';
import { Define, Include, RawSymbol } from '../../../hdlParser/common'; import { Define, Include, RawSymbol } from '../../../hdlParser/common';
import { HdlInstance, HdlModule } from '../../../hdlParser/core'; import { HdlInstance, HdlModule } from '../../../hdlParser/core';
import { vlogKeyword } from '../util/keyword'; import { vlogKeyword } from '../util/keyword';
import { instanceVlogCode } from '../../sim/instance'; import { instanceVlogCode } from '../../sim/instance';
import { vlogSymbolStorage } from '../core';
class VlogIncludeCompletionProvider implements vscode.CompletionItemProvider { 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>> { 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 { try {
const items = this.provideIncludeFiles(document, position); const items = this.provideIncludeFiles(document, position);
return items; return items;
@ -67,11 +70,14 @@ class VlogIncludeCompletionProvider implements vscode.CompletionItemProvider {
class VlogMacroCompletionProvider 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> { 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 { try {
const targetWordRange = document.getWordRangeAtPosition(position, /[`_0-9a-zA-Z]+/); const targetWordRange = document.getWordRangeAtPosition(position, /[`_0-9a-zA-Z]+/);
const targetWord = document.getText(targetWordRange); const targetWord = document.getText(targetWordRange);
const filePath = document.fileName; const filePath = document.fileName;
const symbolResult = await HdlSymbol.all(filePath);
const symbolResult = await vlogSymbolStorage.getSymbol(filePath);
if (!symbolResult) { if (!symbolResult) {
return null; return null;
} }
@ -102,10 +108,12 @@ class VlogMacroCompletionProvider implements vscode.CompletionItemProvider {
class VlogPositionPortProvider 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> { 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 { try {
const suggestPositionPorts: vscode.CompletionItem[] = []; const suggestPositionPorts: vscode.CompletionItem[] = [];
const filePath = hdlPath.toSlash(document.fileName); const filePath = hdlPath.toSlash(document.fileName);
const symbolResult = await HdlSymbol.all(filePath); const symbolResult = await vlogSymbolStorage.getSymbol(filePath);
if (!symbolResult) { if (!symbolResult) {
return null; return null;
} }
@ -173,6 +181,8 @@ class VlogPositionPortProvider implements vscode.CompletionItemProvider {
class VlogCompletionProvider 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> { 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 { try {
const filePath = hdlPath.toSlash(document.fileName); const filePath = hdlPath.toSlash(document.fileName);
@ -181,7 +191,7 @@ class VlogCompletionProvider implements vscode.CompletionItemProvider {
completions.push(...this.makeCompilerKeywordItems(document, position)); completions.push(...this.makeCompilerKeywordItems(document, position));
completions.push(...this.makeSystemKeywordItems(document, position)); completions.push(...this.makeSystemKeywordItems(document, position));
const symbolResult = await HdlSymbol.all(filePath); const symbolResult = await vlogSymbolStorage.getSymbol(filePath);
if (!symbolResult) { if (!symbolResult) {
return completions; 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 * as vsctm from 'vscode-textmate';
import { hdlPath } from '../../../hdlFs'; import { hdlPath } from '../../../hdlFs';
import { hdlParam, HdlSymbol } from '../../../hdlParser'; import { hdlParam } from '../../../hdlParser';
import { All } from '../../../../resources/hdlParser'; import { All } from '../../../../resources/hdlParser';
import { vlogKeyword } from '../util/keyword'; 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 { vlogSymbolStorage } from '../core';
class VlogDefinitionProvider implements vscode.DefinitionProvider { class VlogDefinitionProvider 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('VlogDefinitionProvider');
// 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) {
@ -25,7 +27,7 @@ class VlogDefinitionProvider implements vscode.DefinitionProvider {
} }
const filePath = document.fileName; const filePath = document.fileName;
const vlogAll = await HdlSymbol.all(filePath); const vlogAll = await vlogSymbolStorage.getSymbol(filePath);
if (!vlogAll) { if (!vlogAll) {
return null; return null;
} else { } else {

View File

@ -1,15 +1,14 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { HdlSymbol } from '../../../hdlParser';
const tokenTypes = ['class', 'interface', 'enum', 'function', 'variable']; const tokenTypes = ['class', 'interface', 'enum', 'function', 'variable'];
const tokenModifiers = ['declaration', 'documentation']; const tokenModifiers = ['declaration', 'documentation'];
const vlogLegend = new vscode.SemanticTokensLegend(tokenTypes, tokenModifiers); const vlogLegend = new vscode.SemanticTokensLegend(tokenTypes, tokenModifiers);
class VlogDocSenmanticProvider implements vscode.DocumentSemanticTokensProvider { class VlogDocSenmanticProvider implements vscode.DocumentSemanticTokensProvider {
public async provideDocumentSemanticTokens(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.SemanticTokens | null | undefined> { public async provideDocumentSemanticTokens(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.SemanticTokens | null | undefined> {
const tokensBuilder = new vscode.SemanticTokensBuilder(vlogLegend); // TODO : finish this
return tokensBuilder.build(); // const tokensBuilder = new vscode.SemanticTokensBuilder(vlogLegend);
return null;
} }
} }

View File

@ -1,8 +1,8 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { AllowNull } from '../../../global'; import { AllowNull } from '../../../global';
import { HdlSymbol } from '../../../hdlParser';
import { RawSymbol, Range } from '../../../hdlParser/common'; import { RawSymbol, Range } from '../../../hdlParser/common';
import { vlogSymbolStorage } from '../core';
import { positionAfterEqual } from '../util'; import { positionAfterEqual } from '../util';
@ -13,8 +13,10 @@ interface DocSymbolContainer {
class VlogDocSymbolProvider implements vscode.DocumentSymbolProvider { class VlogDocSymbolProvider 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[]> {
// console.log('VlogDocSymbolProvider');
const path = document.fileName; const path = document.fileName;
const vlogAll = await HdlSymbol.all(path); const vlogAll = await vlogSymbolStorage.getSymbol(path);
if (!vlogAll || !vlogAll.content) { if (!vlogAll || !vlogAll.content) {
return []; return [];

View File

@ -1,16 +1,19 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { hdlDir, hdlPath } from '../../../hdlFs'; import { hdlPath } from '../../../hdlFs';
import { hdlParam, HdlSymbol } from '../../../hdlParser'; import { hdlParam } from '../../../hdlParser';
import { All } from '../../../../resources/hdlParser'; import { All } from '../../../../resources/hdlParser';
import { vlogKeyword } from '../util/keyword'; 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 { HdlLangID } from '../../../global/enum'; import { HdlLangID } from '../../../global/enum';
import { vlogSymbolStorage } from '../core';
class VlogHoverProvider implements vscode.HoverProvider { class VlogHoverProvider implements vscode.HoverProvider {
public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Hover | null> { public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise<vscode.Hover | null> {
// console.log('VlogHoverProvider');
// 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) {
@ -24,7 +27,7 @@ class VlogHoverProvider implements vscode.HoverProvider {
} }
const filePath = document.fileName; const filePath = document.fileName;
const vlogAll = await HdlSymbol.all(filePath); const vlogAll = await vlogSymbolStorage.getSymbol(filePath);
if (!vlogAll) { if (!vlogAll) {
return null; return null;
} else { } else {

View File

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

View File

@ -1,8 +1,8 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { All } from '../../../../resources/hdlParser'; import { All } from '../../../../resources/hdlParser';
import { getLanguageId, isVerilogFile } from '../../../hdlFs/file'; import { isVerilogFile } from '../../../hdlFs/file';
import { hdlParam, HdlSymbol } from '../../../hdlParser';
import { Position, Range } from '../../../hdlParser/common'; import { Position, Range } from '../../../hdlParser/common';
import { vlogSymbolStorage } from '../core';
class VlogLinter { class VlogLinter {
@ -13,7 +13,9 @@ class VlogLinter {
async lint(document: vscode.TextDocument) { async lint(document: vscode.TextDocument) {
const filePath = document.fileName; const filePath = document.fileName;
const vlogAll = await HdlSymbol.all(filePath); const vlogAll = await vlogSymbolStorage.getSymbol(filePath);
console.log('lint all finish');
if (vlogAll) { if (vlogAll) {
const diagnostics = this.provideDiagnostics(document, vlogAll); const diagnostics = this.provideDiagnostics(document, vlogAll);
this.diagnostic.set(document.uri, diagnostics); this.diagnostic.set(document.uri, diagnostics);
@ -30,8 +32,6 @@ class VlogLinter {
diagnostics.push(diag); diagnostics.push(diag);
} }
} }
console.log(diagnostics);
return diagnostics; return diagnostics;
} }
@ -54,7 +54,6 @@ class VlogLinter {
if (range.character === 0 && currentLine.trim().length > 0) { if (range.character === 0 && currentLine.trim().length > 0) {
range.character = currentLine.trimEnd().length; range.character = currentLine.trimEnd().length;
} }
console.log(range);
const position = new vscode.Position(range.line, range.character); const position = new vscode.Position(range.line, range.character);
const wordRange = document.getWordRangeAtPosition(position, /[`_0-9a-zA-Z]+/); const wordRange = document.getWordRangeAtPosition(position, /[`_0-9a-zA-Z]+/);
@ -70,37 +69,19 @@ class VlogLinter {
async remove(document: vscode.TextDocument) { async remove(document: vscode.TextDocument) {
this.diagnostic.delete(document.uri); this.diagnostic.delete(document.uri);
} }
}
function registerVlogLinterServer(): VlogLinter { public async initialise() {
const linter = new VlogLinter(); for (const doc of vscode.workspace.textDocuments) {
vscode.workspace.onDidOpenTextDocument(doc => { if (isVerilogFile(doc.fileName)) {
if (isVerilogFile(doc.fileName)) { // TODO : check performance
linter.lint(doc); await this.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);
} }
} }
} }
const vlogLinter = new VlogLinter();
export { export {
registerVlogLinterServer, vlogLinter
firstLinter
}; };

View File

@ -13,6 +13,9 @@ import { prjManage } from '../manager';
import { libManage } from '../manager/lib'; import { libManage } from '../manager/lib';
import type { HdlMonitor } from './index'; import type { HdlMonitor } from './index';
import { ToolChainType } from '../global/enum'; import { ToolChainType } from '../global/enum';
import { vlogSymbolStorage } from '../function/lsp/core';
import { vlogLinter } from '../function/lsp/linter';
import { isVerilogFile } from '../hdlFs/file';
enum Event { enum Event {
Add = 'add', // emit when add file Add = 'add', // emit when add file
@ -70,6 +73,8 @@ class HdlAction extends BaseAction {
path = hdlPath.toSlash(path); path = hdlPath.toSlash(path);
this.updateLinter(path);
// check if it has been created // check if it has been created
if (hdlParam.hasHdlFile(path)) { if (hdlParam.hasHdlFile(path)) {
MainOutput.report('<HdlAction Add Event> HdlFile ' + path + ' has been created', ReportType.Warn); MainOutput.report('<HdlAction Add Event> HdlFile ' + path + ' has been created', ReportType.Warn);
@ -91,6 +96,10 @@ class HdlAction extends BaseAction {
hdlParam.deleteHdlFile(path); hdlParam.deleteHdlFile(path);
refreshArchTree(); 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> { async unlinkDir(path: string, m: HdlMonitor): Promise<void> {
@ -105,8 +114,29 @@ class HdlAction extends BaseAction {
async change(path: string, m: HdlMonitor): Promise<void> { async change(path: string, m: HdlMonitor): Promise<void> {
console.log('HdlAction change'); console.log('HdlAction change');
path = hdlPath.toSlash(path); 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); const moduleFile = hdlParam.getHdlFile(path);
if (!moduleFile) { if (!moduleFile) {
@ -147,8 +177,6 @@ class HdlAction extends BaseAction {
for (const moduleName of uncheckedModuleNames) { for (const moduleName of uncheckedModuleNames) {
moduleFile.deleteHdlModule(moduleName); 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

@ -8,9 +8,6 @@ module mux2to1(
); );
assign outp = sel == 1'b0 ? a : b; assign outp = sel == 1'b0 ? a : b;
endmodule endmodule