Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remote ssh performance #164

Merged
merged 20 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
name: Test and QA
on: [push, pull_request]
on:
push:
branches:
- 'master'
pull_request:
branches:
- '**'

jobs:
test:
Expand All @@ -18,16 +24,16 @@ jobs:
node-version: '16'
- name: Install NPM dependencies
run: npm ci --production=false --unsafe-perm
- name: Compile ANTLR
run: npm run compile:antlr4ts
- name: Compile extension
run: npm run compile
- name: Create bundle
run: npm run webpack
- name: Run headless tests and collect coverage
uses: GabrielBB/xvfb-action@v1
with:
run: npm run coverage
working-directory: ./
options: ''
- name: Check bundle
run: npm run webpack
- name: Verify files
if: runner.os == 'Linux'
run: ls -l dist/client/extension.js dist/server/server.js coverage/index.html
Expand Down
5 changes: 1 addition & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
// "--disable-extensions",
"--extensionDevelopmentPath=${workspaceRoot}"
],
"args": ["--disable-extensions", "--extensionDevelopmentPath=${workspaceRoot}"],
"outFiles": ["${workspaceRoot}/dist/client/**/*.js"],
"preLaunchTask": {
"type": "npm",
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@
"type": "boolean",
"default": false,
"description": "Compile all files when opened."
}
}
}
}
],
Expand Down Expand Up @@ -487,5 +487,11 @@
"vscode-languageclient": "^7.0.0",
"vscode-languageserver": "^7.0.0",
"vscode-languageserver-textdocument": "^1.0.4"
},
"__metadata": {
"id": "3788d090-07a9-4840-9cf7-cd455e906cf0",
"publisherDisplayName": "Eirik Prestegårdshus",
"publisherId": "f9c1f1d6-09c5-489a-b8ac-a8a96b90a5ab",
"isPreReleaseVersion": false
}
}
2 changes: 1 addition & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function activate(context: ExtensionContext) {
const hoverProvider = new SystemVerilogHoverProvider();
const formatProvider = new SystemVerilogFormatProvider(outputChannel);
const moduleInstantiator = new SystemVerilogModuleInstantiator(formatProvider, symProvider);
const referenceProvider = new SystemVerilogReferenceProvider();
const referenceProvider = new SystemVerilogReferenceProvider(defProvider);

context.subscriptions.push(statusBar);
context.subscriptions.push(languages.registerDocumentSymbolProvider(selector, docProvider));
Expand Down
28 changes: 16 additions & 12 deletions src/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export class SystemVerilogIndexer {
*/
public async build_index(): Promise<any> {
let cancelled = false;
this.building = true;
this.symbolsCount = 0;
this.statusbar.text = 'SystemVerilog: Indexing..';
this.initialize();
Expand All @@ -66,24 +65,29 @@ export class SystemVerilogIndexer {
cancellable: true
},
async (_progress, token) => {
this.symbols = new Map<string, Array<SystemVerilogSymbol>>();
const uris: Uri[] = await this.find_files(token);
console.time('build_index'); // eslint-disable-line no-console
for (let filenr = 0; filenr < uris.length; filenr += this.parallelProcessing) {
const subset = uris.slice(filenr, filenr + this.parallelProcessing);
if (token.isCancellationRequested) {
cancelled = true;
break;
if (!this.building) {
this.building = true;
this.symbols = new Map<string, Array<SystemVerilogSymbol>>();
const uris: Uri[] = await this.find_files(token);
console.time('build_index'); // eslint-disable-line no-console
for (let filenr = 0; filenr < uris.length; filenr += this.parallelProcessing) {
const subset = uris.slice(filenr, filenr + this.parallelProcessing);
if (token.isCancellationRequested) {
cancelled = true;
break;
}
await Promise.all(subset.map((uri) => this.processFile(uri, uris.length))); // eslint-disable-line no-await-in-loop
}
await Promise.all(subset.map((uri) => this.processFile(uri, uris.length))); // eslint-disable-line no-await-in-loop
} else {
return Promise.reject();
}
}
)
.then(() => {
this.building = false;
console.timeEnd('build_index'); // eslint-disable-line no-console
this.building = false;
if (cancelled) {
this.statusbar.text = 'SystemVerilog: Indexing cancelled';
this.statusbar.text = `SystemVerilog: Indexing cancelled at ${this.symbolsCount} indexed objects`;
} else {
this.statusbar.text = `SystemVerilog: ${this.symbolsCount} indexed objects`;
}
Expand Down
204 changes: 90 additions & 114 deletions src/providers/DefinitionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,84 @@ export class SystemVerilogDefinitionProvider implements DefinitionProvider {
position: Position,
token: CancellationToken
): Promise<Definition> {
// eslint-disable-next-line no-async-promise-executor
return new Promise<Definition>(async (resolve, _reject) => {
return new Promise<Definition>((resolve, _reject) => {
const range = document.getWordRangeAtPosition(position);
const line = document.lineAt(position.line).text;
const word = document.getText(range);
const results: Location[] = [];

if (!range) {
resolve(results);
return undefined;
}

// don't attempt to find a reference for a symbol in a comment
const inside = isLineInsideComments();
if (inside) {
resolve(results);
if (isLineInsideComments()) {
return undefined;
}
// Port
await findPortInModule();

// Package
await findInPackage();

// Lookup all symbols in the current document
if (results.length === 0) {
try {
const symbols: DocumentSymbol[] = await commands.executeCommand(
'vscode.executeDocumentSymbolProvider',
document.uri,
word
);
getDocumentSymbols(results, symbols, word, range, document.uri);
} catch (reason) {
console.log(reason); // eslint-disable-line no-console
const matchPort = line.match(`\\.\\s*${word}\\s*\\(`);
const matchPackage = line.match(`\\b(\\w+)\\s*::\\s*(${word})`);

// Return a promise to find object in a portlist
if (matchPort && matchPort.index === range.start.character - 1) {
const container = moduleFromPort(document, range);
if (container) {
commands
.executeCommand('vscode.executeWorkspaceSymbolProvider', `¤${container}`)
.then((res: SymbolInformation[]) => {
return Promise.all(
res.map(async (x) => {
commands
.executeCommand('vscode.executeDocumentSymbolProvider', x.location.uri, word)
.then((symbols: Array<SymbolInformation | DocumentSymbol>) => {
results.concat(extractLocations(symbols, word, x.location.uri, container));
});
})
);
})
.then(() => {
resolve(results);
});
}
}

// Look up all indexed symbols
if (results.length === 0) {
const res: SymbolInformation[] = await commands.executeCommand(
'vscode.executeWorkspaceSymbolProvider',
`¤${word}`,
token
);
if (res.length !== 0) {
res.map((x) => results.push(x.location));
}
// Return a promise to find object in a package
else if (matchPackage && line.indexOf(word, matchPackage.index) === range.start.character) {
commands
.executeCommand('vscode.executeWorkspaceSymbolProvider', `¤${matchPackage[1]}`, token)
.then((ws_symbols: SymbolInformation[]) => {
if (ws_symbols.length && ws_symbols[0].location) {
return ws_symbols[0].location.uri;
}
})
.then((uri) => {
if (uri) {
return commands
.executeCommand('vscode.executeDocumentSymbolProvider', uri, word)
.then((symbols: Array<DocumentSymbol | SymbolInformation>) => {
results.concat(extractLocations(symbols, word, uri, matchPackage[1]));
resolve(results);
});
} else {
resolve(undefined);
}
});
}
// Lookup all symbols in the current document
else {
commands
.executeCommand('vscode.executeDocumentSymbolProvider', document.uri, word, token)
.then((res: Array<DocumentSymbol | SymbolInformation>) => {
let o = extractLocations(res, word, document.uri);
if (o.length) {
resolve(o);
} else {
// Look up all indexed symbols
commands
.executeCommand('vscode.executeWorkspaceSymbolProvider', `¤${word}`, token)
.then((syms: SymbolInformation[]) => {
resolve(syms.map((x) => x.location));
});
}
});
}

resolve(results);

function isLineInsideComments(): Boolean {
/* eslint-disable spaced-comment */
Expand Down Expand Up @@ -85,99 +114,46 @@ export class SystemVerilogDefinitionProvider implements DefinitionProvider {
}
return false;
}

async function findInPackage() {
const regexPackage = '\\b(\\w+)\\s*::\\s*(word)';
const matchPackage = line.match(regexPackage.replace('word', word));
if (matchPackage && line.indexOf(word, matchPackage.index) === range.start.character) {
await commands
.executeCommand('vscode.executeWorkspaceSymbolProvider', `¤${matchPackage[1]}`, token)
.then((ws_symbols: SymbolInformation[]) => {
if (ws_symbols.length && ws_symbols[0].location) {
return ws_symbols[0].location.uri;
}
})
.then(async (uri) => {
if (uri) {
await commands
.executeCommand('vscode.executeDocumentSymbolProvider', uri, word)
.then((symbols) => {
getDocumentSymbols(results, symbols, word, range, uri, matchPackage[1]);
});
}
});
}
}

async function findPortInModule() {
const regexPort = '\\.word\\s*\\(';
const matchPort = line.match(regexPort.replace('word', word));
if (matchPort && matchPort.index === range.start.character - 1) {
const container = moduleFromPort(document, range);
if (container) {
await commands
.executeCommand('vscode.executeWorkspaceSymbolProvider', `¤${container}`)
.then((res: SymbolInformation[]) =>
Promise.all(
res.map(async (x) =>
commands
.executeCommand(
'vscode.executeDocumentSymbolProvider',
x.location.uri,
word
)
.then((symbols) => {
getDocumentSymbols(
results,
symbols,
word,
range,
x.location.uri,
container
);
})
)
)
);
}
}
}
});
}
}

// Retrieves locations from the hierarchical DocumentSymbols
function getDocumentSymbols(
results: Location[],
entries,
function flattenDocumentSymbols(docSyms) {
let o = [];
if (docSyms) {
for (let s of docSyms) {
o.push(s);
o = o.concat(flattenDocumentSymbols(s.children));
}
}
return o;
}

function extractLocations(
docSyms: Array<DocumentSymbol | SymbolInformation>,
word: string,
range: Range,
uri: Uri,
containerName?: string
): void {
if (!entries) {
return;
}
for (const entry of entries) {
if (entry.name === word && entry.kind !== getSymbolKind('potential_reference')) {
): Location[] {
let locs: Location[] = [];
for (let s of flattenDocumentSymbols(docSyms)) {
if (s.name === word && s.kind !== getSymbolKind('potential_reference')) {
if (containerName) {
if (entry.containerName === containerName) {
results.push({
if (s.containerName === containerName) {
locs.push({
uri,
range: entry.range
range: s.range
});
}
} else if (range.start.line !== entry.range.start.line) {
joecrop marked this conversation as resolved.
Show resolved Hide resolved
results.push({
} else {
locs.push({
uri,
range: entry.range
range: s.range
});
}
}
if (entry.children.length > 0) {
getDocumentSymbols(results, entry.children, word, range, uri);
}
}
return locs;
}

export function moduleFromPort(document, range): string {
Expand Down
7 changes: 5 additions & 2 deletions src/providers/ReferenceProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export class SystemVerilogReferenceProvider implements ReferenceProvider {
public results: Location[];
public includeDeclaration: Boolean;

public constructor(definitionProvider) {
this.definitionProvider = definitionProvider;
}

public async provideReferences(
document: TextDocument,
position: Position,
Expand All @@ -25,10 +29,9 @@ export class SystemVerilogReferenceProvider implements ReferenceProvider {
}

// Get the original definition of the symbol 'Location' so we can compare against other symbols we find
this.definitionProvider = new SystemVerilogDefinitionProvider();
const defLocation = await this.getDefinitionLocation(document, position, token);

// Get all symbols in the worksace that match `word`
// Get all symbols in the workspace that match `word`
const allSymbols: SymbolInformation[] = await commands.executeCommand(
'vscode.executeWorkspaceSymbolProvider',
`¬¤${word}`,
Expand Down
Loading