Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⚡ Use frozen const when parsing empty arrays #283

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions lib/net/imap/response_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ def parse(str)
T_TEXT = :TEXT # any char except CRLF
T_EOF = :EOF # end of response string

# Use to avoid allocation when we know the result is empty
EMPTY_ARRAY = [].freeze
private_constant :EMPTY_ARRAY

module ResponseConditions
OK = "OK"
NO = "NO"
Expand Down Expand Up @@ -596,7 +600,7 @@ def tagged_ext_simple
# "(" [tagged-ext-comp] ")"
def tagged_ext_val
if lpar?
_ = peek_rpar? ? [] : tagged_ext_comp
_ = peek_rpar? ? EMPTY_ARRAY : tagged_ext_comp
rpar
_
else
Expand Down Expand Up @@ -1356,7 +1360,7 @@ def mailbox_data__list
# ; This is the list information pointed to by the ABNF
# ; item "mailbox-data", which is defined above
def mailbox_list
lpar; attr = peek_rpar? ? [] : mbx_list_flags; rpar
lpar; attr = peek_rpar? ? EMPTY_ARRAY : mbx_list_flags; rpar
SP!; delim = nquoted
SP!; name = mailbox
# TODO: mbox-list-extended
Expand Down Expand Up @@ -1456,8 +1460,12 @@ def acl_data
# obsolete-search-response = "SEARCH" *(SP nz-number)
def mailbox_data__search
name = label_in("SEARCH", "SORT")
data = []
while _ = SP? && nz_number? do data << _ end
if (_ = SP? && nz_number?)
data = [_]
while _ = SP? && nz_number? do data << _ end
else
data = EMPTY_ARRAY
end
if lpar?
label("MODSEQ"); SP!
modseq = mod_sequence_value
Expand Down Expand Up @@ -1506,7 +1514,7 @@ def thread_members
else nested = thread_nested; break
end
end
members.reverse.inject(nested || []) {|subthreads, number|
members.reverse.inject(nested || EMPTY_ARRAY) {|subthreads, number|
[ThreadMember.new(number, subthreads)]
}.first
end
Expand Down Expand Up @@ -1678,7 +1686,7 @@ def namespace_response

# namespace = nil / "(" 1*namespace-descr ")"
def namespace
NIL? and return []
NIL? and return EMPTY_ARRAY
lpar
list = [namespace_descr]
list << namespace_descr until rpar?
Expand Down Expand Up @@ -1805,13 +1813,13 @@ def resp_text_code
data =
case name
when "CAPABILITY" then resp_code__capability
when "PERMANENTFLAGS" then SP? ? flag_perm__list : []
when "PERMANENTFLAGS" then SP? ? flag_perm__list : EMPTY_ARRAY
when "UIDNEXT" then SP!; nz_number
when "UIDVALIDITY" then SP!; nz_number
when "UNSEEN" then SP!; nz_number # rev1 only
when "APPENDUID" then SP!; resp_code_apnd__data # rev2, UIDPLUS
when "COPYUID" then SP!; resp_code_copy__data # rev2, UIDPLUS
when "BADCHARSET" then SP? ? charset__list : []
when "BADCHARSET" then SP? ? charset__list : EMPTY_ARRAY
when "ALERT", "PARSE", "READ-ONLY", "READ-WRITE", "TRYCREATE",
"UNAVAILABLE", "AUTHENTICATIONFAILED", "AUTHORIZATIONFAILED",
"EXPIRED", "PRIVACYREQUIRED", "CONTACTADMIN", "NOPERM", "INUSE",
Expand Down Expand Up @@ -1942,7 +1950,7 @@ def x_gm_label; accept(T_BSLASH) ? atom.capitalize.to_sym : astring end

# See https://developers.google.com/gmail/imap/imap-extensions
def x_gm_labels
lpar; return [] if rpar?
lpar; return EMPTY_ARRAY if rpar?
labels = []
labels << x_gm_label
labels << x_gm_label while SP?
Expand Down