mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-23 09:59:25 +00:00
implement shceduleReparse to reduce parsing load while typing
This commit is contained in:
@@ -92,7 +92,49 @@ class JavaDocInfo {
|
|||||||
this.version = version;
|
this.version = version;
|
||||||
/** @type {ParsedInfo} */
|
/** @type {ParsedInfo} */
|
||||||
this.parsed = null;
|
this.parsed = null;
|
||||||
|
/** @type {Promise} */
|
||||||
|
this.reparseWaiter = Promise.resolve();
|
||||||
|
/** @type {{ resolve: () => void, timer: * }} */
|
||||||
|
this.waitInfo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule this document for reparsing.
|
||||||
|
*
|
||||||
|
* To prevent redundant parsing while typing, a small delay is required
|
||||||
|
* before the reparse happens.
|
||||||
|
* When a key is pressed, `scheduleReparse()` starts a timer. If more
|
||||||
|
* keys are typed before the timer expires, the timer is restarted.
|
||||||
|
* Once typing pauses, the timer expires and the content reparsed.
|
||||||
|
*
|
||||||
|
* A `reparseWaiter` promise is used to delay the completion items
|
||||||
|
* retrieval until the reparse is complete.
|
||||||
|
*/
|
||||||
|
scheduleReparse() {
|
||||||
|
const createWaitTimer = () => {
|
||||||
|
return setTimeout(() => {
|
||||||
|
// reparse the content, resolve the reparseWaiter promise
|
||||||
|
// and reset the fields
|
||||||
|
reparse([this.uri], { includeMethods: true });
|
||||||
|
this.waitInfo.resolve();
|
||||||
|
this.waitInfo = null;
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
if (this.waitInfo) {
|
||||||
|
// we already have a promise pending - just restart the timer
|
||||||
|
trace('restart timer');
|
||||||
|
clearTimeout(this.waitInfo.timer);
|
||||||
|
this.waitInfo.timer = createWaitTimer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// create a new pending promise and start the timer
|
||||||
|
trace('start timer');
|
||||||
|
this.waitInfo = {
|
||||||
|
resolve: null,
|
||||||
|
timer: createWaitTimer(),
|
||||||
|
}
|
||||||
|
this.reparseWaiter = new Promise(resolve => this.waitInfo.resolve = resolve);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParsedInfo {
|
class ParsedInfo {
|
||||||
@@ -129,6 +171,7 @@ let first_parse_waiting = new Set();
|
|||||||
* @param {{includeMethods: boolean, first_parse?: boolean}} [opts]
|
* @param {{includeMethods: boolean, first_parse?: boolean}} [opts]
|
||||||
*/
|
*/
|
||||||
function reparse(uris, opts) {
|
function reparse(uris, opts) {
|
||||||
|
trace('reparse');
|
||||||
if (androidLibrary instanceof Promise) {
|
if (androidLibrary instanceof Promise) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -233,7 +276,10 @@ let documents = new TextDocuments({
|
|||||||
docinfo.content = `${docinfo.content.slice(0, start_index)}${change.text}${docinfo.content.slice(end_index)}`;
|
docinfo.content = `${docinfo.content.slice(0, start_index)}${change.text}${docinfo.content.slice(end_index)}`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
reparse([document.uri], { includeMethods: true });
|
|
||||||
|
docinfo.version = version;
|
||||||
|
docinfo.scheduleReparse();
|
||||||
|
|
||||||
return document;
|
return document;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -789,6 +835,18 @@ connection.onCompletion(
|
|||||||
if (!docinfo || !docinfo.parsed) {
|
if (!docinfo || !docinfo.parsed) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
trace('reparse waiter - ' + docinfo.version);
|
||||||
|
const preversion = docinfo.version;
|
||||||
|
await docinfo.reparseWaiter;
|
||||||
|
trace('retrieving completion items - ' + docinfo.version);
|
||||||
|
if (docinfo.version !== preversion) {
|
||||||
|
// if the content has changed, ignore the current request
|
||||||
|
/** @type {import('vscode-languageserver').CompletionList} */
|
||||||
|
return {
|
||||||
|
isIncomplete: true,
|
||||||
|
items: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
const parsed = docinfo.parsed;
|
const parsed = docinfo.parsed;
|
||||||
lastCompletionTypeMap = (parsed && parsed.typemap) || androidLibrary;
|
lastCompletionTypeMap = (parsed && parsed.typemap) || androidLibrary;
|
||||||
let locals = [], sourceTypes = [], show_instances = false;
|
let locals = [], sourceTypes = [], show_instances = false;
|
||||||
@@ -849,7 +907,10 @@ connection.onCompletion(
|
|||||||
...[
|
...[
|
||||||
...defaultCompletionTypes.types,
|
...defaultCompletionTypes.types,
|
||||||
...sourceTypes,
|
...sourceTypes,
|
||||||
].sort(sortBy.label),
|
] // exclude dotted (inner) types because they result in useless
|
||||||
|
// matches in the intellisense filter when . is pressed
|
||||||
|
.filter(x => !x.label.includes('.'))
|
||||||
|
.sort(sortBy.label),
|
||||||
...defaultCompletionTypes.packageNames,
|
...defaultCompletionTypes.packageNames,
|
||||||
].map((x,idx) => {
|
].map((x,idx) => {
|
||||||
x.sortText = `${10000+idx}-${x.label}`;
|
x.sortText = `${10000+idx}-${x.label}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user