Bug 955366 - Use Maps and Sets in IRC code, convert modes. r=aleth
authorPatrick Cloke <clokep@gmail.com>
Tue, 06 May 2014 20:29:18 -0400
changeset 16181 9c05e894da1e6e96537892c3ff9988e06fbc1ecc
parent 16180 fe529f9dd6975c6ba574e0a083363c8aa5292efa
child 16182 ffcaadc29781221084cc697e0c23a321fa33a4a5
push id10115
push userclokep@gmail.com
push dateThu, 08 May 2014 14:05:31 +0000
treeherdercomm-central@da34b03c7e57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaleth
bugs955366
Bug 955366 - Use Maps and Sets in IRC code, convert modes. r=aleth
chat/protocols/irc/irc.js
chat/protocols/irc/ircBase.jsm
--- a/chat/protocols/irc/irc.js
+++ b/chat/protocols/irc/irc.js
@@ -89,23 +89,23 @@ function ircMessage(aData) {
 
 // This handles a mode change string for both channels and participants. A mode
 // change string is of the form:
 //   aAddNewMode is true if modes are being added, false otherwise.
 //   aNewModes is an array of mode characters.
 function _setMode(aAddNewMode, aNewModes) {
   // Check each mode being added/removed.
   for each (let newMode in aNewModes) {
-    let index = this._modes.indexOf(newMode);
+    let hasMode = this._modes.has(newMode);
     // If the mode is in the list of modes and we want to remove it.
-    if (index != -1 && !aAddNewMode)
-      this._modes.splice(index, 1);
+    if (hasMode && !aAddNewMode)
+      this._modes.remove(newMode);
     // If the mode is not in the list of modes and we want to add it.
-    else if (index == -1 && aAddNewMode)
-      this._modes.push(newMode);
+    else if (!hasMode && aAddNewMode)
+      this._modes.add(newMode);
   }
 }
 
 // This copies all the properties of aBase to aPrototype (which is expected to
 // be the prototype of an object). This is necessary because JavaScript does not
 // support multiple inheritance and both conversation objects have a lot of
 // shared code (but inherit from objects exposing different XPCOM interfaces).
 function copySharedBaseToPrototype(aBase, aPrototype) {
@@ -258,24 +258,24 @@ const GenericIRCConversation = {
     this._account.removeConversation(this.name);
     if (this._observedNicks.length)
       Services.obs.removeObserver(this, "user-info-received");
   }
 };
 
 function ircChannel(aAccount, aName, aNick) {
   this._init(aAccount, aName, aNick);
-  this._modes = [];
+  this._modes = new Set();
   this._observedNicks = [];
   this.banMasks = [];
   this._firstJoin = true;
 }
 ircChannel.prototype = {
   __proto__: GenericConvChatPrototype,
-  _modes: [],
+  _modes: null,
   _receivedInitialMode: false,
   // For IRC you're not in a channel until the JOIN command is received, open
   // all channels (initially) as left.
   _left: true,
   // True until successfully joined for the first time.
   _firstJoin: false,
   banMasks: [],
 
@@ -514,26 +514,24 @@ ircChannel.prototype = {
     this.writeMessage(aSetter, msg, {system: true});
     this.checkTopicSettable();
 
     this._receivedInitialMode = true;
   },
 
   setModesFromRestriction: function(aRestriction) {
     // First remove all types from the list of modes.
-    for each (let mode in this._account.channelRestrictionToModeMap) {
-      let index = this._modes.indexOf(mode);
-      this._modes.splice(index, index != -1);
-    }
+    for each (let mode in this._account.channelRestrictionToModeMap)
+      this._modes.delete(mode);
 
     // Add the new mode onto the list.
     if (aRestriction in this._account.channelRestrictionToModeMap) {
       let mode = this._account.channelRestrictionToModeMap[aRestriction];
       if (mode)
-        this._modes.push(mode);
+        this._modes.add(mode);
     }
   },
 
   get topic() this._topic, // can't add a setter without redefining the getter
   set topic(aTopic) {
     this._account.sendMessage("TOPIC", [this.name, aTopic]);
   },
   _previousTopicSettable: null,
@@ -547,33 +545,35 @@ ircChannel.prototype = {
   get topicSettable() {
     // If we're not in the room yet, we don't exist.
     if (!this.hasParticipant(this.nick))
       return false;
 
     // If the channel mode is +t, hops and ops can set the topic; otherwise
     // everyone can.
     let participant = this.getParticipant(this.nick);
-    return this._modes.indexOf("t") == -1 || participant.op ||
-           participant.halfOp;
+    return this._modes.has("t") || participant.op || participant.halfOp;
   }
 };
 copySharedBaseToPrototype(GenericIRCConversation, ircChannel.prototype);
 
 function ircParticipant(aName, aConv) {
   this._name = aName;
   this._conv = aConv;
   this._account = aConv._account;
-  this._modes = [];
+  this._modes = new Set();
 
   // Handle multi-prefix modes.
   let i;
   for (i = 0; i < this._name.length &&
-              this._name[i] in this._account.userPrefixToModeMap; ++i)
-    this._modes.push(this._account.userPrefixToModeMap[this._name[i]]);
+              this._name[i] in this._account.userPrefixToModeMap; ++i) {
+    let mode = this._account.userPrefixToModeMap[this._name[i]];
+    if (mode)
+      this._modes.add(mode);
+  }
   this._name = this._name.slice(i);
 }
 ircParticipant.prototype = {
   __proto__: GenericConvChatBuddyPrototype,
 
   setMode: function(aAddNewMode, aNewModes, aSetter) {
     _setMode.call(this, aAddNewMode, aNewModes);
 
@@ -584,21 +584,20 @@ ircParticipant.prototype = {
     this._conv.notifyObservers(this, "chat-buddy-update");
 
     // In case the new mode now lets us edit the topic.
     if (this._account.normalize(this.name) ==
         this._account.normalize(this._account._nickname))
       this._conv.checkTopicSettable();
   },
 
-  get voiced() this._modes.indexOf("v") != -1,
-  get halfOp() this._modes.indexOf("h") != -1,
-  get op() this._modes.indexOf("o") != -1,
-  get founder()
-    this._modes.indexOf("O") != -1 || this._modes.indexOf("q") != -1,
+  get voiced() this._modes.has("v"),
+  get halfOp() this._modes.has("h"),
+  get op() this._modes.has("o"),
+  get founder() this._modes.has("O") || this._modes.has("q"),
   get typing() false
 };
 
 function ircConversation(aAccount, aName) {
   let nick = aAccount.normalize(aName);
   if (aAccount.whoisInformation.has(nick))
     aName = aAccount.whoisInformation.get(nick)["nick"];
 
@@ -897,17 +896,17 @@ ircAccount.prototype = {
       }
       this.sendMessage("AWAY", text); // Mark as away.
     }
     else if (type == Ci.imIStatusInfo.STATUS_AVAILABLE && this.isAway)
       this.sendMessage("AWAY"); // Mark as back.
   },
 
   // The user's user mode.
-  _modes: [],
+  _modes: null,
   _userModeReceived: false,
   setUserMode: function(aNick, aNewModes, aSetter, aDisplayFullMode) {
     if (this.normalizeNick(aNick) != this.normalizeNick(this._nickname)) {
       WARN("Received unexpected mode for " + aNick);
       return false;
     }
 
     // Are modes being added or removed?
@@ -922,17 +921,17 @@ ircAccount.prototype = {
     // We should not report this initial mode message as a mode change
     // initiated by the user, but instead display the full mode
     // and then remember we have done so.
     this._userModeReceived = true;
 
     if (this._showServerTab) {
       let msg;
       if (aDisplayFullMode)
-        msg = _("message.yourmode", this._modes.join(""));
+        msg = _("message.yourmode", [mode for (mode of this._modes)].join(""));
       else {
         msg = _("message.usermode", aNewModes, aNick,
                 aSetter || this._currentServerName);
       }
       this.getConversation(this._currentServerName)
           .writeMessage(this._currentServerName, msg, {system: true});
     }
     return true;
--- a/chat/protocols/irc/ircBase.jsm
+++ b/chat/protocols/irc/ircBase.jsm
@@ -328,17 +328,17 @@ var ircBase = {
     },
     "001": function(aMessage) { // RPL_WELCOME
       // Welcome to the Internet Relay Network <nick>!<user>@<host>
       this.reportConnected();
       this._socket.resetPingTimer();
       this._currentServerName = aMessage.servername;
 
       // Clear user mode.
-      this._modes = [];
+      this._modes = new Set();
       this._userModeReceived = false;
 
       // Check if our nick has changed.
       if (aMessage.params[0] != this._nickname)
         this.changeBuddyNick(this._nickname, aMessage.params[0]);
 
       // Request our own whois entry so we can set the prefix.
       this.requestBuddyInfo(this._nickname);