jsParse: Make getCompletions() asynchronous
Part of the possible completions involves evaluating the part of the passed in text that looks like an object, so that we can query it for properties. Using a Function or eval() for that means that we can only complete text that does not use `await`. To get over that limitation, evaluate the text in an AsyncFunction instead. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2842>
This commit is contained in:
parent
13e20e47bf
commit
c0fbd74d07
@ -1,6 +1,8 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
/* exported getCompletions, getCommonPrefix, getDeclaredConstants */
|
||||
|
||||
const AsyncFunction = async function () {}.constructor;
|
||||
|
||||
/**
|
||||
* Returns a list of potential completions for text. Completions either
|
||||
* follow a dot (e.g. foo.ba -> bar) or they are picked from globalCompletionList (e.g. fo -> foo)
|
||||
@ -13,7 +15,7 @@
|
||||
* @param {string} commandHeader
|
||||
* @param {readonly string[]} [globalCompletionList]
|
||||
*/
|
||||
function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
async function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
let methods = [];
|
||||
let expr_, base;
|
||||
let attrHead = '';
|
||||
@ -29,7 +31,7 @@ function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
if (matches) {
|
||||
[expr_, base, attrHead] = matches;
|
||||
|
||||
methods = getPropertyNamesFromExpression(base, commandHeader).filter(
|
||||
methods = (await getPropertyNamesFromExpression(base, commandHeader)).filter(
|
||||
attr => attr.slice(0, attrHead.length) === attrHead);
|
||||
}
|
||||
|
||||
@ -193,13 +195,13 @@ function getAllProps(obj) {
|
||||
* @param {string} expr
|
||||
* @param {string=} commandHeader
|
||||
*/
|
||||
function getPropertyNamesFromExpression(expr, commandHeader = '') {
|
||||
async function getPropertyNamesFromExpression(expr, commandHeader = '') {
|
||||
let obj = {};
|
||||
if (!isUnsafeExpression(expr)) {
|
||||
try {
|
||||
const lines = expr.split(';');
|
||||
const lines = expr.split('\n');
|
||||
lines.push(`return ${lines.pop()}`);
|
||||
obj = Function(commandHeader + lines.join(';'))();
|
||||
obj = await AsyncFunction(commandHeader + lines.join(';'))();
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user