extensionSystem: Store extensions in a Map

After making the extensions map private to the ExtensionManager, we can
switch it to a proper hash table which is more appropriate.

https://bugzilla.gnome.org/show_bug.cgi?id=789852
This commit is contained in:
Florian Müllner 2019-07-08 00:01:11 +02:00 committed by Florian Müllner
parent 1d6ddf060b
commit 43cb3754d9
5 changed files with 37 additions and 30 deletions

View File

@ -70,7 +70,7 @@ function getCurrentExtension() {
// Walk up the directory tree, looking for an extension with // Walk up the directory tree, looking for an extension with
// the same UUID as a directory name. // the same UUID as a directory name.
while (file != null) { while (file != null) {
let extension = extensionManager.extensions[file.get_basename()]; let extension = extensionManager.lookup(file.get_basename());
if (extension !== undefined) if (extension !== undefined)
return extension; return extension;
file = file.get_parent(); file = file.get_parent();

View File

@ -44,7 +44,7 @@ function installExtension(uuid, invocation) {
} }
function uninstallExtension(uuid) { function uninstallExtension(uuid) {
let extension = Main.extensionManager.extensions[uuid]; let extension = Main.extensionManager.lookup(uuid);
if (!extension) if (!extension)
return false; return false;
@ -113,7 +113,7 @@ function updateExtension(uuid) {
_httpSession.queue_message(message, (session, message) => { _httpSession.queue_message(message, (session, message) => {
gotExtensionZipFile(session, message, uuid, newExtensionTmpDir, () => { gotExtensionZipFile(session, message, uuid, newExtensionTmpDir, () => {
let oldExtension = Main.extensionManager.extensions[uuid]; let oldExtension = Main.extensionManager.lookup(uuid);
let extensionDir = oldExtension.dir; let extensionDir = oldExtension.dir;
if (!Main.extensionManager.unloadExtension(oldExtension)) if (!Main.extensionManager.unloadExtension(oldExtension))
@ -151,9 +151,9 @@ function updateExtension(uuid) {
function checkForUpdates() { function checkForUpdates() {
let metadatas = {}; let metadatas = {};
for (let uuid in Main.extensionManager.extensions) { Main.extensionManager.getUuids().forEach(uuid => {
metadatas[uuid] = Main.extensionManager.extensions[uuid].metadata; metadatas[uuid] = Main.extensionManager.extensions[uuid].metadata;
} });
let params = { shell_version: Config.PACKAGE_VERSION, let params = { shell_version: Config.PACKAGE_VERSION,
installed: JSON.stringify(metadatas) }; installed: JSON.stringify(metadatas) };

View File

@ -18,7 +18,7 @@ var ExtensionManager = class {
this._initted = false; this._initted = false;
this._enabled = false; this._enabled = false;
this._extensions = {}; this._extensions = new Map();
this._enabledExtensions = []; this._enabledExtensions = [];
this._extensionOrder = []; this._extensionOrder = [];
@ -29,12 +29,16 @@ var ExtensionManager = class {
this._sessionUpdated(); this._sessionUpdated();
} }
get extensions() { lookup(uuid) {
return this._extensions; return this._extensions.get(uuid);
}
getUuids() {
return [...this._extensions.keys()];
} }
_callExtensionDisable(uuid) { _callExtensionDisable(uuid) {
let extension = this._extensions[uuid]; let extension = this.lookup(uuid);
if (!extension) if (!extension)
return; return;
@ -56,7 +60,7 @@ var ExtensionManager = class {
for (let i = 0; i < orderReversed.length; i++) { for (let i = 0; i < orderReversed.length; i++) {
let uuid = orderReversed[i]; let uuid = orderReversed[i];
try { try {
this._extensions[uuid].stateObj.disable(); this.lookup(uuid).stateObj.disable();
} catch (e) { } catch (e) {
this.logExtensionError(uuid, e); this.logExtensionError(uuid, e);
} }
@ -77,7 +81,7 @@ var ExtensionManager = class {
for (let i = 0; i < order.length; i++) { for (let i = 0; i < order.length; i++) {
let uuid = order[i]; let uuid = order[i];
try { try {
this._extensions[uuid].stateObj.enable(); this.lookup(uuid).stateObj.enable();
} catch (e) { } catch (e) {
this.logExtensionError(uuid, e); this.logExtensionError(uuid, e);
} }
@ -92,7 +96,7 @@ var ExtensionManager = class {
} }
_callExtensionEnable(uuid) { _callExtensionEnable(uuid) {
let extension = this._extensions[uuid]; let extension = this.lookup(uuid);
if (!extension) if (!extension)
return; return;
@ -136,7 +140,7 @@ var ExtensionManager = class {
} }
enableExtension(uuid) { enableExtension(uuid) {
if (!this._extensions[uuid]) if (!this._extensions.has(uuid))
return false; return false;
let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY); let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
@ -149,7 +153,7 @@ var ExtensionManager = class {
} }
disableExtension(uuid) { disableExtension(uuid) {
if (!this._extensions[uuid]) if (!this._extensions.has(uuid))
return false; return false;
let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY); let enabledExtensions = global.settings.get_strv(ENABLED_EXTENSIONS_KEY);
@ -162,7 +166,7 @@ var ExtensionManager = class {
} }
logExtensionError(uuid, error) { logExtensionError(uuid, error) {
let extension = this._extensions[uuid]; let extension = this.lookup(uuid);
if (!extension) if (!extension)
return; return;
@ -221,7 +225,7 @@ var ExtensionManager = class {
hasPrefs: dir.get_child('prefs.js').query_exists(null), hasPrefs: dir.get_child('prefs.js').query_exists(null),
canChange: false canChange: false
}; };
this._extensions[uuid] = extension; this._extensions.set(uuid, extension);
return extension; return extension;
} }
@ -259,7 +263,7 @@ var ExtensionManager = class {
extension.state = ExtensionState.UNINSTALLED; extension.state = ExtensionState.UNINSTALLED;
this.emit('extension-state-changed', extension); this.emit('extension-state-changed', extension);
delete this._extensions[extension.uuid]; this._extensions.delete(extension.uuid);
return true; return true;
} }
@ -284,7 +288,7 @@ var ExtensionManager = class {
} }
_callExtensionInit(uuid) { _callExtensionInit(uuid) {
let extension = this._extensions[uuid]; let extension = this.lookup(uuid);
let dir = extension.dir; let dir = extension.dir;
if (!extension) if (!extension)
@ -385,8 +389,7 @@ var ExtensionManager = class {
} }
_onSettingsWritableChanged() { _onSettingsWritableChanged() {
for (let uuid in this._extensions) { for (let extension of this._extensions.values()) {
let extension = ExtensionUtils.extensions[uuid];
this._updateCanChange(extension); this._updateCanChange(extension);
this.emit('extension-state-changed', extension); this.emit('extension-state-changed', extension);
} }
@ -397,8 +400,11 @@ var ExtensionManager = class {
// extensions when allowed by the sessionMode, so // extensions when allowed by the sessionMode, so
// temporarily disable them all // temporarily disable them all
this._enabledExtensions = []; this._enabledExtensions = [];
for (let uuid in this._extensions)
this.reloadExtension(this._extensions[uuid]); // The loop modifies the extensions map, so iterate over a copy
let extensions = [...this._extensions.values()];
for (let extension of extensions)
this.reloadExtension(extension);
this._enabledExtensions = this._getEnabledExtensions(); this._enabledExtensions = this._getEnabledExtensions();
if (Main.sessionMode.allowExtensions) { if (Main.sessionMode.allowExtensions) {
@ -426,7 +432,7 @@ var ExtensionManager = class {
if (fileType != Gio.FileType.DIRECTORY) if (fileType != Gio.FileType.DIRECTORY)
return; return;
let uuid = info.get_name(); let uuid = info.get_name();
let existing = this._extensions[uuid]; let existing = this.lookup(uuid);
if (existing) { if (existing) {
log(`Extension ${uuid} already installed in ${existing.path}. ${dir.get_path()} will not be loaded`); log(`Extension ${uuid} already installed in ${existing.path}. ${dir.get_path()} will not be loaded`);
return; return;

View File

@ -624,15 +624,16 @@ var Extensions = class Extensions {
this._extensionsList.add(this._noExtensions); this._extensionsList.add(this._noExtensions);
this.actor.add(this._extensionsList); this.actor.add(this._extensionsList);
for (let uuid in Main.extensionManager.extensions) Main.extensionManager.getUuids().forEach(uuid => {
this._loadExtension(null, uuid); this._loadExtension(null, uuid);
});
Main.extensionManager.connect('extension-loaded', Main.extensionManager.connect('extension-loaded',
this._loadExtension.bind(this)); this._loadExtension.bind(this));
} }
_loadExtension(o, uuid) { _loadExtension(o, uuid) {
let extension = Main.extensionManager.extensions[uuid]; let extension = Main.extensionManager.lookup(uuid);
// There can be cases where we create dummy extension metadata // There can be cases where we create dummy extension metadata
// that's not really a proper extension. Don't bother with these. // that's not really a proper extension. Don't bother with these.
if (!extension.metadata.name) if (!extension.metadata.name)

View File

@ -255,20 +255,20 @@ var GnomeShellExtensions = class {
ListExtensions() { ListExtensions() {
let out = {}; let out = {};
for (let uuid in Main.extensionManager.extensions) { Main.extensionManager.getUuids().forEach(uuid => {
let dbusObj = this.GetExtensionInfo(uuid); let dbusObj = this.GetExtensionInfo(uuid);
out[uuid] = dbusObj; out[uuid] = dbusObj;
} });
return out; return out;
} }
GetExtensionInfo(uuid) { GetExtensionInfo(uuid) {
let extension = Main.extensionManager.extensions[uuid] || {}; let extension = Main.extensionManager.lookup(uuid) || {};
return ExtensionUtils.serializeExtension(extension); return ExtensionUtils.serializeExtension(extension);
} }
GetExtensionErrors(uuid) { GetExtensionErrors(uuid) {
let extension = Main.extensionManager.extensions[uuid]; let extension = Main.extensionManager.lookup(uuid);
if (!extension) if (!extension)
return []; return [];
@ -304,7 +304,7 @@ var GnomeShellExtensions = class {
} }
ReloadExtension(uuid) { ReloadExtension(uuid) {
let extension = Main.extensionManager.extensions[uuid]; let extension = Main.extensionManager.lookup(uuid);
if (!extension) if (!extension)
return; return;