#fix issue 8
This commit is contained in:
parent
cf722bfbee
commit
c86d6e57db
@ -80,7 +80,7 @@ function registerLsp(context: vscode.ExtensionContext) {
|
|||||||
vscode.languages.registerDocumentSemanticTokensProvider(vlogSelector, lspDocSemantic.vlogDocSenmanticProvider, lspDocSemantic.vlogLegend);
|
vscode.languages.registerDocumentSemanticTokensProvider(vlogSelector, lspDocSemantic.vlogDocSenmanticProvider, lspDocSemantic.vlogLegend);
|
||||||
|
|
||||||
lspLinter.vlogLinter.initialise();
|
lspLinter.vlogLinter.initialise();
|
||||||
lspCore.vlogSymbolStorage.initialise();
|
lspCore.hdlSymbolStorage.initialise();
|
||||||
|
|
||||||
// vhdl lsp
|
// vhdl lsp
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ 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';
|
import { hdlSymbolStorage } 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>> {
|
||||||
@ -77,7 +77,7 @@ class VlogMacroCompletionProvider implements vscode.CompletionItemProvider {
|
|||||||
const targetWord = document.getText(targetWordRange);
|
const targetWord = document.getText(targetWordRange);
|
||||||
const filePath = document.fileName;
|
const filePath = document.fileName;
|
||||||
|
|
||||||
const symbolResult = await vlogSymbolStorage.getSymbol(filePath);
|
const symbolResult = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
if (!symbolResult) {
|
if (!symbolResult) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ class VlogPositionPortProvider implements vscode.CompletionItemProvider {
|
|||||||
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 vlogSymbolStorage.getSymbol(filePath);
|
const symbolResult = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
|
|
||||||
// console.log(symbolResult?.content);
|
// console.log(symbolResult?.content);
|
||||||
// console.log(position.character, position.line);
|
// console.log(position.character, position.line);
|
||||||
@ -195,7 +195,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 vlogSymbolStorage.getSymbol(filePath);
|
const symbolResult = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
if (!symbolResult) {
|
if (!symbolResult) {
|
||||||
return completions;
|
return completions;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,55 @@
|
|||||||
import { vlogSymbolStorage } from './vlog';
|
import * as vscode from 'vscode';
|
||||||
|
import { All } from '../../../../resources/hdlParser';
|
||||||
|
import { AbsPath } from '../../../global';
|
||||||
|
import { hdlPath } from '../../../hdlFs';
|
||||||
|
import { isHDLFile, isVerilogFile, isVhdlFile } from '../../../hdlFs/file';
|
||||||
|
import { HdlSymbol } from '../../../hdlParser';
|
||||||
|
|
||||||
|
type ThenableAll = Promise<All | undefined>;
|
||||||
|
|
||||||
|
class SymbolStorage {
|
||||||
|
private symbolMap: Map<AbsPath, ThenableAll>;
|
||||||
|
private isHdlFile: (file: AbsPath) => boolean;
|
||||||
|
constructor(isHdlFile: (file: AbsPath) => boolean) {
|
||||||
|
this.symbolMap = new Map<AbsPath, ThenableAll>();
|
||||||
|
this.isHdlFile = isHdlFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getSymbol(path: AbsPath): ThenableAll {
|
||||||
|
path = hdlPath.toSlash(path);
|
||||||
|
const allP = this.symbolMap.get(path);
|
||||||
|
if (allP) {
|
||||||
|
return await allP;
|
||||||
|
}
|
||||||
|
this.updateSymbol(path);
|
||||||
|
const all = await this.symbolMap.get(path);
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async updateSymbol(path: AbsPath) {
|
||||||
|
path = hdlPath.toSlash(path);
|
||||||
|
const allPromise = HdlSymbol.all(path);
|
||||||
|
this.symbolMap.set(path, allPromise);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async deleteSymbol(path: AbsPath) {
|
||||||
|
path = hdlPath.toSlash(path);
|
||||||
|
this.symbolMap.delete(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async initialise() {
|
||||||
|
for (const doc of vscode.workspace.textDocuments) {
|
||||||
|
// TODO : check support for sv
|
||||||
|
// TODO : check performance
|
||||||
|
if (isHDLFile(doc.fileName)) {
|
||||||
|
await this.updateSymbol(doc.fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const hdlSymbolStorage = new SymbolStorage(isVerilogFile);
|
||||||
|
|
||||||
export {
|
export {
|
||||||
vlogSymbolStorage
|
hdlSymbolStorage
|
||||||
};
|
};
|
@ -1,53 +0,0 @@
|
|||||||
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 allP = this.symbolMap.get(path);
|
|
||||||
if (allP) {
|
|
||||||
return await allP;
|
|
||||||
}
|
|
||||||
this.updateSymbol(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
|
|
||||||
};
|
|
@ -6,7 +6,7 @@ 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';
|
import { hdlSymbolStorage } from '../core';
|
||||||
|
|
||||||
|
|
||||||
class VlogDefinitionProvider implements vscode.DefinitionProvider {
|
class VlogDefinitionProvider implements vscode.DefinitionProvider {
|
||||||
@ -26,7 +26,7 @@ class VlogDefinitionProvider implements vscode.DefinitionProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const filePath = document.fileName;
|
const filePath = document.fileName;
|
||||||
const vlogAll = await vlogSymbolStorage.getSymbol(filePath);
|
const vlogAll = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
if (!vlogAll) {
|
if (!vlogAll) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@ -120,6 +120,8 @@ class VlogDefinitionProvider implements vscode.DefinitionProvider {
|
|||||||
const link: vscode.LocationLink = { targetUri: instModPathUri, targetRange };
|
const link: vscode.LocationLink = { targetUri: instModPathUri, targetRange };
|
||||||
return [link];
|
return [link];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { All } from '../../../../resources/hdlParser';
|
import { All } from '../../../../resources/hdlParser';
|
||||||
import { HdlSymbol } from '../../../hdlParser';
|
import { HdlSymbol } from '../../../hdlParser';
|
||||||
import { vlogSymbolStorage } from '../core';
|
import { hdlSymbolStorage } from '../core';
|
||||||
import { transformRange } from '../util';
|
import { transformRange } from '../util';
|
||||||
|
|
||||||
const tokenTypes = ['class', 'function', 'variable'];
|
const tokenTypes = ['class', 'function', 'variable'];
|
||||||
|
@ -2,7 +2,7 @@ import * as vscode from 'vscode';
|
|||||||
|
|
||||||
import { AllowNull } from '../../../global';
|
import { AllowNull } from '../../../global';
|
||||||
import { RawSymbol, Range } from '../../../hdlParser/common';
|
import { RawSymbol, Range } from '../../../hdlParser/common';
|
||||||
import { vlogSymbolStorage } from '../core';
|
import { hdlSymbolStorage } from '../core';
|
||||||
|
|
||||||
import { positionAfterEqual } from '../util';
|
import { positionAfterEqual } from '../util';
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ class VlogDocSymbolProvider implements vscode.DocumentSymbolProvider {
|
|||||||
// console.log('VlogDocSymbolProvider');
|
// console.log('VlogDocSymbolProvider');
|
||||||
|
|
||||||
const path = document.fileName;
|
const path = document.fileName;
|
||||||
const vlogAll = await vlogSymbolStorage.getSymbol(path);
|
const vlogAll = await hdlSymbolStorage.getSymbol(path);
|
||||||
|
|
||||||
if (!vlogAll || !vlogAll.content) {
|
if (!vlogAll || !vlogAll.content) {
|
||||||
return [];
|
return [];
|
||||||
|
@ -7,7 +7,7 @@ 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';
|
import { hdlSymbolStorage } from '../core';
|
||||||
|
|
||||||
|
|
||||||
class VlogHoverProvider implements vscode.HoverProvider {
|
class VlogHoverProvider implements vscode.HoverProvider {
|
||||||
@ -27,7 +27,7 @@ class VlogHoverProvider implements vscode.HoverProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const filePath = document.fileName;
|
const filePath = document.fileName;
|
||||||
const vlogAll = await vlogSymbolStorage.getSymbol(filePath);
|
const vlogAll = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
if (!vlogAll) {
|
if (!vlogAll) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@ -100,11 +100,20 @@ class VlogHoverProvider implements vscode.HoverProvider {
|
|||||||
|
|
||||||
|
|
||||||
// match port or param definition (position input)
|
// 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)) {
|
if (util.isPositionInput(lineText, position.character)) {
|
||||||
|
console.log('enter position input');
|
||||||
const currentInstResult = util.filterInstanceByPosition(position, scopeSymbols.symbols, currentModule);
|
const currentInstResult = util.filterInstanceByPosition(position, scopeSymbols.symbols, currentModule);
|
||||||
if (!currentInstResult || !currentInstResult.instModPath) {
|
if (!currentInstResult || !currentInstResult.instModPath) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
console.log(currentInstResult);
|
||||||
|
|
||||||
const instParamPromise = util.getInstParamByPosition(currentInstResult, position, targetWord);
|
const instParamPromise = util.getInstParamByPosition(currentInstResult, position, targetWord);
|
||||||
const instPortPromise = util.getInstPortByPosition(currentInstResult, position, targetWord);
|
const instPortPromise = util.getInstPortByPosition(currentInstResult, position, targetWord);
|
||||||
@ -130,6 +139,8 @@ class VlogHoverProvider implements vscode.HoverProvider {
|
|||||||
}
|
}
|
||||||
return new vscode.Hover(content);
|
return new vscode.Hover(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import * as vscode from 'vscode';
|
|||||||
import { All } from '../../../../resources/hdlParser';
|
import { All } from '../../../../resources/hdlParser';
|
||||||
import { isVerilogFile } from '../../../hdlFs/file';
|
import { isVerilogFile } from '../../../hdlFs/file';
|
||||||
import { Position, Range } from '../../../hdlParser/common';
|
import { Position, Range } from '../../../hdlParser/common';
|
||||||
import { vlogSymbolStorage } from '../core';
|
import { hdlSymbolStorage } from '../core';
|
||||||
|
|
||||||
|
|
||||||
class VlogLinter {
|
class VlogLinter {
|
||||||
@ -13,7 +13,7 @@ class VlogLinter {
|
|||||||
|
|
||||||
async lint(document: vscode.TextDocument) {
|
async lint(document: vscode.TextDocument) {
|
||||||
const filePath = document.fileName;
|
const filePath = document.fileName;
|
||||||
const vlogAll = await vlogSymbolStorage.getSymbol(filePath);
|
const vlogAll = await hdlSymbolStorage.getSymbol(filePath);
|
||||||
// console.log('lint all finish');
|
// console.log('lint all finish');
|
||||||
|
|
||||||
if (vlogAll) {
|
if (vlogAll) {
|
||||||
|
@ -301,11 +301,20 @@ function matchParams(singleWord: string, module: HdlModule): AllowNull<HdlModule
|
|||||||
|
|
||||||
|
|
||||||
function makePortDesc(port: HdlModulePort): string {
|
function makePortDesc(port: HdlModulePort): string {
|
||||||
let portDesc: string = port.type;
|
|
||||||
if (port.width && port.width !== Unknown) {
|
const portDescArray = [];
|
||||||
portDesc += ' ' + port.width;
|
portDescArray.push(port.type);
|
||||||
|
if (port.netType) {
|
||||||
|
portDescArray.push(port.netType);
|
||||||
}
|
}
|
||||||
portDesc += ' ' + port.name;
|
if (port.signed) {
|
||||||
|
portDescArray.push('signed');
|
||||||
|
}
|
||||||
|
if (port.width && port.width !== Unknown && port.width !== '1') {
|
||||||
|
portDescArray.push(port.width);
|
||||||
|
}
|
||||||
|
portDescArray.push(port.name);
|
||||||
|
const portDesc = portDescArray.join(' ');
|
||||||
return portDesc;
|
return portDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,6 @@ class Simulate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!hdlFile.isDir(simConfig.simulationHome)) {
|
if (!hdlFile.isDir(simConfig.simulationHome)) {
|
||||||
MainOutput.report('create dir ' + simConfig.simulationHome, ReportType.Info);
|
MainOutput.report('create dir ' + simConfig.simulationHome, ReportType.Info);
|
||||||
hdlDir.mkdir(simConfig.simulationHome);
|
hdlDir.mkdir(simConfig.simulationHome);
|
||||||
@ -166,7 +165,7 @@ class IcarusSimulate extends Simulate {
|
|||||||
return args.join(' ').trim();
|
return args.join(' ').trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
private makeThirdLibraryArguments(simLibPaths: string[]): { fileArgs: string[], dirArgs: string[] } {
|
private makeThirdLibraryArguments(simLibPaths: string[]): { fileArgsString: string, dirArgsString: string } {
|
||||||
const fileArgs = [];
|
const fileArgs = [];
|
||||||
const dirArgs = [];
|
const dirArgs = [];
|
||||||
for (const libPath of simLibPaths) {
|
for (const libPath of simLibPaths) {
|
||||||
@ -176,7 +175,9 @@ class IcarusSimulate extends Simulate {
|
|||||||
dirArgs.push('-y ' + libPath);
|
dirArgs.push('-y ' + libPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { fileArgs, dirArgs };
|
const fileArgsString = fileArgs.join(' ');
|
||||||
|
const dirArgsString = dirArgs.join(' ');
|
||||||
|
return { fileArgsString, dirArgsString };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -211,8 +212,8 @@ class IcarusSimulate extends Simulate {
|
|||||||
const dependenceArgs = this.makeDependenceArguments(dependences);
|
const dependenceArgs = this.makeDependenceArguments(dependences);
|
||||||
const thirdLibraryArgs = this.makeThirdLibraryArguments(simLibPaths);
|
const thirdLibraryArgs = this.makeThirdLibraryArguments(simLibPaths);
|
||||||
|
|
||||||
const thirdLibraryFileArgs = thirdLibraryArgs.fileArgs;
|
const thirdLibraryFileArgs = thirdLibraryArgs.fileArgsString;
|
||||||
const thirdLibraryDirArgs = thirdLibraryArgs.dirArgs;
|
const thirdLibraryDirArgs = thirdLibraryArgs.dirArgsString;
|
||||||
|
|
||||||
const iverilogPath = simConfig.iverilogPath;
|
const iverilogPath = simConfig.iverilogPath;
|
||||||
// default is -g2012
|
// default is -g2012
|
||||||
|
@ -131,7 +131,9 @@ interface HdlModulePort {
|
|||||||
type: HdlModulePortType
|
type: HdlModulePortType
|
||||||
width: string
|
width: string
|
||||||
range: Range
|
range: Range
|
||||||
desc?: string
|
desc?: string // for patch in hdlDoc
|
||||||
|
signed: string
|
||||||
|
netType: string
|
||||||
};
|
};
|
||||||
|
|
||||||
interface HdlModuleParam {
|
interface HdlModuleParam {
|
||||||
@ -169,6 +171,7 @@ interface RawSymbol {
|
|||||||
width?: string
|
width?: string
|
||||||
init?: string
|
init?: string
|
||||||
signed: number
|
signed: number
|
||||||
|
netType: string
|
||||||
};
|
};
|
||||||
|
|
||||||
interface InstModPathSearchResult {
|
interface InstModPathSearchResult {
|
||||||
|
@ -5,6 +5,7 @@ import { MainOutput, ReportType } from '../global/outputChannel';
|
|||||||
import * as common from './common';
|
import * as common from './common';
|
||||||
import { hdlFile, hdlPath } from '../hdlFs';
|
import { hdlFile, hdlPath } from '../hdlFs';
|
||||||
import { HdlSymbol } from './util';
|
import { HdlSymbol } from './util';
|
||||||
|
import { vhdlFast } from '../../resources/hdlParser';
|
||||||
|
|
||||||
class HdlParam {
|
class HdlParam {
|
||||||
private readonly topModules : Set<HdlModule> = new Set<HdlModule>();
|
private readonly topModules : Set<HdlModule> = new Set<HdlModule>();
|
||||||
|
@ -13,7 +13,7 @@ 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 { hdlSymbolStorage } from '../function/lsp/core';
|
||||||
import { vlogLinter } from '../function/lsp/linter';
|
import { vlogLinter } from '../function/lsp/linter';
|
||||||
import { isVerilogFile } from '../hdlFs/file';
|
import { isVerilogFile } from '../hdlFs/file';
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ class HdlAction extends BaseAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateSymbolStorage(path: string) {
|
async updateSymbolStorage(path: string) {
|
||||||
vlogSymbolStorage.updateSymbol(path);
|
hdlSymbolStorage.updateSymbol(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateLinter(path: string) {
|
async updateLinter(path: string) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user