ronantakizawa/codereview-bench huggingface dataset:
Repository: discordjs/discord.js
File: packages/discord.js/src/managers/PollAnswerVoterManager.js (JavaScript)

Code before:
const User = require('../structures/User');

/**
 * Manages API methods for users who voted on a poll and stores their cache.
 * @extends {CachedManager}
 */
class PollAnswerVoterManager extends CachedManager {
  constructor(answer) {
    super(answer.client, User);

    /**
     * The poll answer that this manager belongs to
     * @type {PollAnswer}
     */
    this.answer = answer;
  }

  /**
   * The cache of this manager
   * @type {Collection<Snowflake, User>}
   * @name PollAnswerVoterManager#cache
   */

  /**
   * Fetches the users that voted on this poll answer. Resolves with a collection of users, mapped by their ids.
   * @param {BaseFetchPollAnswerVotersOptions} [options] Options for fetching the users
   * @returns {Promise<Collection<Snowflake, User>>}
   */
  async fetch({ after, limit }) {
    const poll = this.answer.poll;
    const query = makeURLSearchParams({ limit, after });
    const data = await this.client.rest.get(Routes.pollAnswerVoters(poll.channelId, poll.messageId, this.answer.id), {
      query,
    });

    return data.reduce((coll, rawUser) => {
      const user = this.client.users._add(rawUser);
      this.cache.set(user.id, user);
      return coll.set(user.id, user);
    }, new Collection());
  }
}

module.exports = PollAnswerVoterManager;


Review comment (suggestion):
```suggestion
   * @param {BaseFetchPollAnswerVotersOptions} [options={}] Options for fetching the users
```

Code after:
const { User } = require('../structures/User.js');

/**
 * Manages API methods for users who voted on a poll and stores their cache.
 * @extends {CachedManager}
 */
class PollAnswerVoterManager extends CachedManager {
  constructor(answer) {
    super(answer.client, User);

    /**
     * The poll answer that this manager belongs to
     * @type {PollAnswer}
     */
    this.answer = answer;
  }

  /**
   * The cache of this manager
   * @type {Collection<Snowflake, User>}
   * @name PollAnswerVoterManager#cache
   */

  /**
   * Fetches the users that voted on this poll answer. Resolves with a collection of users, mapped by their ids.
   * @param {BaseFetchPollAnswerVotersOptions} [options={}] Options for fetching the users
   * @returns {Promise<Collection<Snowflake, User>>}
   */
  async fetch({ after, limit } = {}) {
    const poll = this.answer.poll;
    const query = makeURLSearchParams({ limit, after });
    const data = await this.client.rest.get(Routes.pollAnswerVoters(poll.channelId, poll.messageId, this.answer.id), {
      query,
    });

    return data.users.reduce((coll, rawUser) => {
      const user = this.client.users._add(rawUser);
      this.cache.set(user.id, user);
      return coll.set(user.id, user);
    }, new Collection());
  }
}

exports.PollAnswerVoterManager = PollAnswerVoterManager;
Repository: discordjs/discord.js
File: packages/discord.js/src/structures/Poll.js (JavaScript)

Code before:
        answer?._patch(answerResult);
      }
    } else {
      this.resultsFinalized ??= false;
    }

    if (data.question) {
      this.question = {
        text: data.question.text,
      };
    }

    if (data.answers) {
      for (const answer of data.answers) {
        const existing = this.answers.get(answer.answer_id);
        if (existing) {
          existing._patch(answer);
        } else {
          this.answers.set(answer.answer_id, new PollAnswer(this.client, answer, this));
        }
      }
    }

    if (data.partial) {
      Object.defineProperty(this, '_partial', { value: data.partial });
    }
  }

  /**
   * The date when this poll expires
   * @type {?Date}
   * @readonly
   */
  get expiresAt() {
    return this.expiresTimestamp && new Date(this.expiresTimestamp);
  }

  /**
   * Whether or not this poll is a partial
   * @type {boolean}
   * @readonly
   */
  get partial() {
    return this._partial || typeof this.layoutType !== 'number' || typeof this.allowMultiselect !== 'boolean';
  }

  /**
   * Fetches the message that started this poll, then updates the poll from the fetched message.
   * @returns {Promise<Poll>}
   */
  async fetch() {

Review comment (suggestion):
I believe this `_partial` property could just be removed. We should be able to keep only the `typeof` checks in the `partial` getter, which is also what's done in the rest of the entities that have partials

Code after:
    } else {
      this.question ??= {
        text: null,
      };
    }

    /**
     * The answers of this poll
     * @type {Collection<number, PollAnswer|PartialPollAnswer>}
     */
    this.answers ??= new Collection();

    if (data.answers) {
      for (const answer of data.answers) {
        const existing = this.answers.get(answer.answer_id);
        if (existing) {
          existing._patch(answer);
        } else {
          this.answers.set(answer.answer_id, new PollAnswer(this.client, answer, this));
        }
      }
    }
  }

  /**
   * The date when this poll expires
   * @type {?Date}
   * @readonly
   */
  get expiresAt() {
    return this.expiresTimestamp && new Date(this.expiresTimestamp);
  }

  /**
   * Whether this poll is a partial
   * @type {boolean}
   * @readonly
   */
  get partial() {
    return this.allowMultiselect === null;
  }

  /**
   * Fetches the message that started this poll, then updates the poll from the fetched message.
   * @returns {Promise<Poll>}
   */
  async fetch() {
    await this.channel.messages.fetch(this.messageId);

    return this;
  }
Repository: discordjs/discord.js
File: packages/discord.js/src/client/actions/MessagePollVoteAdd.js (JavaScript)

Code before:
    if (!message.poll && includePollPartial && includePollAnswerPartial) {
      message.poll = new Poll(this.client, { ...data, answers: [], partial: true }, message, channel);

      const pollAnswer = new PollAnswer(this.client, data, message.poll);

      message.poll.answers.set(data.answer_id, pollAnswer);
    }

    const answer = message.poll.answers.get(data.answer_id);

    if (!answer) return false;

    const user = this.getUser(data);

    answer.voters._add(user);
    answer.voteCount++;

    /**
     * Emitted whenever a user votes in a poll.
     * @event Client#messagePollVoteAdd
     * @param {PollAnswer} pollAnswer The answer that was voted on
     * @param {Snowflake} userId The id of the user that voted
     */
    this.client.emit(Events.MessagePollVoteAdd, answer, data.user_id);

    const { poll } = message;

    return { poll };
  }
}

module.exports = MessagePollVoteAddAction;


Review comment (suggestion):
this feels a bit silly
```suggestion
    return { poll: message.poll };
```

Code after:
'use strict';

const { Action } = require('./Action.js');
const { Events } = require('../../util/Events.js');

class MessagePollVoteAddAction extends Action {
  handle(data) {
    const channel = this.getChannel({ id: data.channel_id, ...('guild_id' in data && { guild_id: data.guild_id }) });
    if (!channel?.isTextBased()) return false;

    const message = this.getMessage(data, channel);
    if (!message) return false;

    const poll = this.getPoll(data, message, channel);
    if (!poll) return false;

    const answer = poll.answers.get(data.answer_id);
    if (!answer) return false;

    const user = this.getUser(data);

    if (user) {
      answer.voters._add(user);
    }

    answer.voteCount++;

    /**
     * Emitted whenever a user votes in a poll.
     * @event Client#messagePollVoteAdd
     * @param {PollAnswer} pollAnswer The answer that was voted on
     * @param {Snowflake} userId The id of the user that voted
     */
    this.client.emit(Events.MessagePollVoteAdd, answer, data.user_id);

    return { poll };
  }
}

exports.MessagePollVoteAddAction = MessagePollVoteAddAction;
Repository: discordjs/discord.js
File: packages/discord.js/src/structures/PollAnswer.js (JavaScript)

Code before:

    /**
     * The raw emoji of this answer
     * @name PollAnswer#_emoji
     * @type {?APIPartialEmoji}
     * @private
     */
    Object.defineProperty(this, '_emoji', { value: data.poll_media?.emoji ?? null });

    this._patch(data);
  }

  _patch(data) {
    // This `count` field comes from `poll.results.answer_counts`
    if ('count' in data) {
      /**
       * The amount of votes this answer has
       * @type {number}
       */
      this.voteCount = data.count;
    } else if (data.poll_media?.text) {
      this.text = data.poll_media.text;
    } else if (data.poll_media?.emoji) {
      Object.defineProperty(this, '_emoji', { value: data.poll_media.emoji });
    } else {
      this.voteCount ??= this.voters.cache.size ?? 0;
    }
  }

  /**
   * The emoji of this answer
   * @type {?(GuildEmoji|Emoji)}
   */
  get emoji() {
    if (!this._emoji || (!this._emoji.id && !this._emoji.name)) return null;
    return this.client.emojis.resolve(this._emoji.id) ?? new Emoji(this.client, this._emoji);
  }

  /**
   * Whether this poll answer is a partial.
   * @type {boolean}
   * @readonly
   */
  get partial() {
    return this.poll.partial || (this.text === null && this.emoji === null);
  }

  /**
   * Options used for fetching voters of a poll answer.
   * @typedef {Object} BaseFetchPollAnswerVotersOptions
   * @property {number} [limit] The maximum number of voters to fetch

Review comment (performance):
```suggestion
      this.voteCount ??= this.voters.cache.size;
```

Code after:
     * @private
     */
    Object.defineProperty(this, '_emoji', { value: null });

    this._patch(data);
  }

  _patch(data) {
    // This `count` field comes from `poll.results.answer_counts`
    if ('count' in data) {
      /**
       * The amount of votes this answer has
       * @type {number}
       */
      this.voteCount = data.count;
    } else {
      this.voteCount ??= this.voters.cache.size;
    }

    /**
     * The text of this answer
     * @type {?string}
     */
    this.text ??= data.poll_media?.text ?? null;

    if (data.poll_media?.emoji) {
      Object.defineProperty(this, '_emoji', { value: data.poll_media.emoji });
    }
  }

  /**
   * The emoji of this answer
   * @type {?(GuildEmoji|Emoji)}
   */
  get emoji() {
    if (!this._emoji || (!this._emoji.id && !this._emoji.name)) return null;
    return resolveGuildEmoji(this.client, this._emoji.id) ?? new Emoji(this.client, this._emoji);
  }

  /**
   * Whether this poll answer is a partial.
   * @type {boolean}
   * @readonly
   */
  get partial() {
    return this.poll.partial || (this.text === null && this.emoji === null);
  }

  /**
   * Options used for fetching voters of a poll answer.
   * @typedef {Object} BaseFetchPollAnswerVotersOptions
Repository: discordjs/discord.js
File: packages/discord.js/src/managers/PollAnswerVoterManager.js (JavaScript)

Code before:
const User = require('../structures/User');

/**
 * Manages API methods for users who voted on a poll and stores their cache.
 * @extends {CachedManager}
 */
class PollAnswerVoterManager extends CachedManager {
  constructor(answer) {
    super(answer.client, User);

    /**
     * The poll answer that this manager belongs to
     * @type {PollAnswer}
     */
    this.answer = answer;
  }

  /**
   * The cache of this manager
   * @type {Collection<Snowflake, User>}
   * @name PollAnswerVoterManager#cache
   */

  /**
   * Fetches the users that voted on this poll answer. Resolves with a collection of users, mapped by their ids.
   * @param {BaseFetchPollAnswerVotersOptions} [options = {}] Options for fetching the users
   * @returns {Promise<Collection<Snowflake, User>>}
   */
  async fetch({ after, limit } = {}) {
    const poll = this.answer.poll;
    const query = makeURLSearchParams({ limit, after });
    const data = await this.client.rest.get(Routes.pollAnswerVoters(poll.channelId, poll.messageId, this.answer.id), {
      query,
    });

    return data.reduce((coll, rawUser) => {
      const user = this.client.users._add(rawUser);
      this.cache.set(user.id, user);
      return coll.set(user.id, user);
    }, new Collection());
  }
}

module.exports = PollAnswerVoterManager;


Review comment (suggestion):
```suggestion
   * @param {BaseFetchPollAnswerVotersOptions} [options={}] Options for fetching the users
```

Code after:
const { User } = require('../structures/User.js');

/**
 * Manages API methods for users who voted on a poll and stores their cache.
 * @extends {CachedManager}
 */
class PollAnswerVoterManager extends CachedManager {
  constructor(answer) {
    super(answer.client, User);

    /**
     * The poll answer that this manager belongs to
     * @type {PollAnswer}
     */
    this.answer = answer;
  }

  /**
   * The cache of this manager
   * @type {Collection<Snowflake, User>}
   * @name PollAnswerVoterManager#cache
   */

  /**
   * Fetches the users that voted on this poll answer. Resolves with a collection of users, mapped by their ids.
   * @param {BaseFetchPollAnswerVotersOptions} [options={}] Options for fetching the users
   * @returns {Promise<Collection<Snowflake, User>>}
   */
  async fetch({ after, limit } = {}) {
    const poll = this.answer.poll;
    const query = makeURLSearchParams({ limit, after });
    const data = await this.client.rest.get(Routes.pollAnswerVoters(poll.channelId, poll.messageId, this.answer.id), {
      query,
    });

    return data.users.reduce((coll, rawUser) => {
      const user = this.client.users._add(rawUser);
      this.cache.set(user.id, user);
      return coll.set(user.id, user);
    }, new Collection());
  }
}

exports.PollAnswerVoterManager = PollAnswerVoterManager;
Repository: discordjs/discord.js
File: packages/discord.js/src/structures/Poll.js (JavaScript)

Code before:
    /**
     * The id of the message that started this poll
     * @type {Snowflake}
     */
    this.messageId = data.message_id;

    /**
     * The message that started this poll
     * @name Poll#message
     * @type {Message}
     * @readonly
     */

    Object.defineProperty(this, 'message', { value: message });

    /**
     * The media for a poll's question
     * @typedef {Object} PollQuestionMedia
     * @property {?string} text The text of this question
     */

    /**
     * The media for this poll's question
     * @type {PollQuestionMedia}
     */
    this.question = {
      text: data.question.text ?? null,
    };

    /**
     * The timestamp when this poll expires
     * @type {?number}
     */
    this.expiresTimestamp = data.expiry && Date.parse(data.expiry);

    /**
     * Whether this poll allows multiple answers
     * @type {boolean}
     */
    this.allowMultiselect = data.allow_multiselect;

    /**
     * The layout type of this poll
     * @type {PollLayoutType}
     */
    this.layoutType = data.layout_type;

    /**
     * Whether this poll is a partial
     * @name Poll#_partial
     * @type {boolean}

Review comment (suggestion):
This is being set in the `_patch()` method, can be removed from here (a default value also needs to be set there)

Code after:
     * The id of the message that started this poll
     * @type {Snowflake}
     */
    this.messageId = data.message_id ?? message.id;

    /**
     * The message that started this poll
     * @name Poll#message
     * @type {Message}
     * @readonly
     */

    Object.defineProperty(this, 'message', { value: message });

    this._patch(data);
  }

  _patch(data) {
    if (data.results) {
      /**
       * Whether this poll's results have been precisely counted
       * @type {boolean}
       */
      this.resultsFinalized = data.results.is_finalized;

      for (const answerResult of data.results.answer_counts) {
        const answer = this.answers.get(answerResult.id);
        answer?._patch(answerResult);
      }
    } else {
      this.resultsFinalized ??= false;
    }

    if ('allow_multiselect' in data) {
      /**
       * Whether this poll allows multiple answers
       * @type {boolean}
       */
      this.allowMultiselect = data.allow_multiselect;
    } else {
      this.allowMultiselect ??= null;
    }

    if ('layout_type' in data) {
      /**
       * The layout type of this poll
       * @type {PollLayoutType}
       */
      this.layoutType = data.layout_type;
    } else {
      this.layoutType ??= null;
Repository: discordjs/discord.js
File: packages/discord.js/src/structures/PollAnswer.js (JavaScript)

Code before:
 * Represents an answer to a {@link Poll}
 * @extends {Base}
 */
class PollAnswer extends Base {
  constructor(client, data, poll) {
    super(client);

    /**
     * The {@link Poll} this answer is part of
     * @name PollAnswer#poll
     * @type {Poll|PartialPoll}
     * @readonly
     */
    Object.defineProperty(this, 'poll', { value: poll });

    /**
     * The id of this answer
     * @type {number}
     */
    this.id = data.answer_id;

    /**
     * The text of this answer
     * @type {?string}
     */
    this.text = data.poll_media?.text ?? null;

    /**
     * The manager of the voters for this answer
     * @type {PollAnswerVoterManager}
     */
    this.voters = new PollAnswerVoterManager(this);

    /**
     * The raw emoji of this answer
     * @name PollAnswer#_emoji
     * @type {?APIPartialEmoji}
     * @private
     */
    Object.defineProperty(this, '_emoji', { value: data.poll_media?.emoji ?? null });

    this._patch(data);
  }

  _patch(data) {
    // This `count` field comes from `poll.results.answer_counts`
    if ('count' in data) {
      /**
       * The amount of votes this answer has
       * @type {number}
       */

Review comment (suggestion):
This can be removed from here, as it's being set in the `_patch()` method (just needs a default value)

Code after:
/**
 * Represents an answer to a {@link Poll}
 * @extends {Base}
 */
class PollAnswer extends Base {
  constructor(client, data, poll) {
    super(client);

    /**
     * The {@link Poll} this answer is part of
     * @name PollAnswer#poll
     * @type {Poll|PartialPoll}
     * @readonly
     */
    Object.defineProperty(this, 'poll', { value: poll });

    /**
     * The id of this answer
     * @type {number}
     */
    this.id = data.answer_id;

    /**
     * The manager of the voters for this answer
     * @type {PollAnswerVoterManager}
     */
    this.voters = new PollAnswerVoterManager(this);

    /**
     * The raw emoji of this answer
     * @name PollAnswer#_emoji
     * @type {?APIPartialEmoji}
     * @private
     */
    Object.defineProperty(this, '_emoji', { value: null });

    this._patch(data);
  }

  _patch(data) {
    // This `count` field comes from `poll.results.answer_counts`
    if ('count' in data) {
      /**
       * The amount of votes this answer has
       * @type {number}
       */
      this.voteCount = data.count;
    } else {
      this.voteCount ??= this.voters.cache.size;
    }
Repository: discordjs/discord.js
File: packages/discord.js/src/structures/PollAnswer.js (JavaScript)

Code before:

    /**
     * The id of this answer
     * @type {number}
     */
    this.id = data.answer_id;

    /**
     * The text of this answer
     * @type {?string}
     */
    this.text = data.poll_media?.text ?? null;

    /**
     * The manager of the voters for this answer
     * @type {PollAnswerVoterManager}
     */
    this.voters = new PollAnswerVoterManager(this);

    /**
     * The raw emoji of this answer
     * @name PollAnswer#_emoji
     * @type {?APIPartialEmoji}
     * @private
     */
    Object.defineProperty(this, '_emoji', { value: data.poll_media?.emoji ?? null });

    this._patch(data);
  }

  _patch(data) {
    // This `count` field comes from `poll.results.answer_counts`
    if ('count' in data) {
      /**
       * The amount of votes this answer has
       * @type {number}
       */
      this.voteCount = data.count;
    }

    if (data.poll_media?.text) {
      this.text = data.poll_media.text;
    }

    if (data.poll_media?.emoji) {
      Object.defineProperty(this, '_emoji', { value: data.poll_media.emoji });
    }

    this.voteCount ??= this.voters.cache.size;
  }


Review comment (suggestion):
This can be removed from here, as it's being set in the `_patch()` method (just needs a default value)

Code after:
    Object.defineProperty(this, 'poll', { value: poll });

    /**
     * The id of this answer
     * @type {number}
     */
    this.id = data.answer_id;

    /**
     * The manager of the voters for this answer
     * @type {PollAnswerVoterManager}
     */
    this.voters = new PollAnswerVoterManager(this);

    /**
     * The raw emoji of this answer
     * @name PollAnswer#_emoji
     * @type {?APIPartialEmoji}
     * @private
     */
    Object.defineProperty(this, '_emoji', { value: null });

    this._patch(data);
  }

  _patch(data) {
    // This `count` field comes from `poll.results.answer_counts`
    if ('count' in data) {
      /**
       * The amount of votes this answer has
       * @type {number}
       */
      this.voteCount = data.count;
    } else {
      this.voteCount ??= this.voters.cache.size;
    }

    /**
     * The text of this answer
     * @type {?string}
     */
    this.text ??= data.poll_media?.text ?? null;

    if (data.poll_media?.emoji) {
      Object.defineProperty(this, '_emoji', { value: data.poll_media.emoji });
    }
  }

  /**
   * The emoji of this answer
   * @type {?(GuildEmoji|Emoji)}
Repository: discordjs/discord.js
File: packages/discord.js/src/structures/Poll.js (JavaScript)

Code before:
     * @readonly
     */

    Object.defineProperty(this, 'message', { value: message });

    /**
     * The media for a poll's question
     * @typedef {Object} PollQuestionMedia
     * @property {?string} text The text of this question
     */

    /**
     * The media for this poll's question
     * @type {PollQuestionMedia}
     */
    this.question = {
      text: data.question.text ?? null,
    };

    /**
     * The timestamp when this poll expires
     * @type {?number}
     */
    this.expiresTimestamp = data.expiry && Date.parse(data.expiry);

    /**
     * Whether this poll allows multiple answers
     * @type {boolean}
     */
    this.allowMultiselect = data.allow_multiselect;

    /**
     * The layout type of this poll
     * @type {PollLayoutType}
     */
    this.layoutType = data.layout_type;

    /**
     * Whether this poll is a partial
     * @name Poll#_partial
     * @type {boolean}
     * @private
     */
    Object.defineProperty(this, '_partial', { value: data.partial ?? false });

    this._patch(data);
  }

  _patch(data) {
    if (data.results) {
      /**

Review comment (suggestion):
Due to partials, I believe the `allowMultiselect` and `layoutType` updates below should be moved into `_patch()`

Code after:
     */

    Object.defineProperty(this, 'message', { value: message });

    this._patch(data);
  }

  _patch(data) {
    if (data.results) {
      /**
       * Whether this poll's results have been precisely counted
       * @type {boolean}
       */
      this.resultsFinalized = data.results.is_finalized;

      for (const answerResult of data.results.answer_counts) {
        const answer = this.answers.get(answerResult.id);
        answer?._patch(answerResult);
      }
    } else {
      this.resultsFinalized ??= false;
    }

    if ('allow_multiselect' in data) {
      /**
       * Whether this poll allows multiple answers
       * @type {boolean}
       */
      this.allowMultiselect = data.allow_multiselect;
    } else {
      this.allowMultiselect ??= null;
    }

    if ('layout_type' in data) {
      /**
       * The layout type of this poll
       * @type {PollLayoutType}
       */
      this.layoutType = data.layout_type;
    } else {
      this.layoutType ??= null;
    }

    if ('expiry' in data) {
      /**
       * The timestamp when this poll expires
       * @type {?number}
       */
      this.expiresTimestamp = data.expiry && Date.parse(data.expiry);
    } else {
      this.expiresTimestamp ??= null;