GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

MailAddress.parse()   B
last analyzed

Complexity

Conditions 5

Size

Total Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 5
c 3
b 1
f 0
dl 0
loc 74
rs 8.1145

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
2
module MailAddress
3
4
  def self.parse(*addresses)
5
    lines = addresses.grep(String)
6
    line = lines.join('').strip
7
8
    # empty or <> or < or >
9
    if line.empty? || line.match(/\A[<>;, ]+\z/)
10
      return [ MailAddress::Address.new(line, nil, line) ]
11
    end
12
13
    # undisclosed-recipient
14
    if line.match(/undisclosed[ \-]recipients?: ?;?/i)
15
      return [ MailAddress::Address.new(line, nil, line) ]
16
    end
17
18
    phrase, address, objs = [], [], []
19
    original = ''
20
    depth, idx, end_paren_idx = 0, 0, 0
21
22
    tokens = _tokenize lines
23
    len    = tokens.length
24
    _next  = _find_next idx, tokens, len
25
26
    for idx in 0 ... len do
27
28
      token = tokens[idx]
29
      substr = token[0, 1]
30
      original << token
31
32
      if (end_paren_idx > 0 && end_paren_idx >= idx)
33
        next
34
      end
35
36
      if (substr == '(' && !address.empty?) then
37
        end_paren_idx = _find_next_paren(idx, tokens, len)
38
        if end_paren_idx == -1
39
          # end paren doesn't exist
40
          # but nothing to do
41
        end
42
        rem = tokens[idx .. end_paren_idx]
43
        phrase.push(rem.join(''))
44
      elsif (substr == '<') then
45
        depth += 1
46
      elsif (substr == '>') then
47
        depth -= 1 if depth > 0
48
      elsif (substr == ',' || substr == ';') then
49
        original.sub!(/[,;]\s*\z/, '')
50
51
        if depth > 0
52
          # raise "Unmatched '<>' in line"
53
          o = MailAddress::Address.new(original, nil, original)
54
          phrase.clear; address.clear
55
        else
56
          o = _complete(phrase, address, original)
57
        end
58
59
        objs.push(o) if o
60
        depth = 0
61
        end_paren_idx = 0
62
        original = ''
63
        _next = _find_next idx+1, tokens, len
64
      elsif (depth > 0) then
65
        token.strip!
66
        address.push(token)
67
      elsif (_next == '<') then
68
        phrase.push(token)
69
      elsif ( token.match(/^[.\@:;]/) || address.empty? || address[-1].match(/^[.\@:;]/) ) then
70
        token.strip!
71
        address.push(token)
72
      else
73
        phrase.push(token)
74
      end
75
    end
76
    objs
77
  end
78
79
  private
80
81
  def self._tokenize(addresses)
82
    line = addresses.join(',') # $_
83
    words = []
84
85
    line.gsub!(/\\/, '')
86
    line.sub!(/\A\s+/, '')
87
    line.gsub!(/[\r\n]+/,' ')
88
89
    while (line != '')
90
      tmp = nil
91
      if (
92
          line.match(/"[^"]+"/) && line.sub!(/\A(\\?"(?:[^"\\]+|\\.)*")(\s*)/, '')  || # "..."
93
          line.sub!(/\A([^\s()<>\@,;:\\".\[\]]+)(\s*)/, '') ||
94
          line.sub!(/\A([()<>\@,;:\\".\[\]])(\s*)/, '')
95
          )
96
        words.push("#{$1}#{$2}")
97
        next
98
      end
99
      raise "Unrecognized line: #{line}"
100
    end
101
102
    words.push(',')
103
    words
104
  end
105
106
  def self._find_next(idx, tokens, len)
107
    while (idx < len)
108
      c = tokens[idx].strip
109
      return c if c == ',' || c == ';' || c == '<'
110
      idx += 1
111
    end
112
    ""
113
  end
114
115
  # find next ending parenthesis
116
  def self._find_next_paren(idx, tokens, len)
117
    while (idx < len)
118
      c = tokens[idx].strip
119
      return idx if c.include?(')')
120
      idx += 1
121
    end
122
    -1
123
  end
124
125
  def self._complete (phrase, address, original)
126
    phrase.length > 0 || address.length > 0 or return nil
127
128
    name = phrase.join('').strip
129
130
    name = self.collapse_whitespace(name)
131
    name = name[1 .. -2] if name.start_with?('\'') && name.end_with?('\'')
132
    name = name[1 .. -2] if name.start_with?('"') && name.end_with?('"')
133
134
    # Replace escaped quotes and slashes.
135
    name = name.gsub(ESCAPED_DOUBLE_QUOTES_, '"')
136
    name = name.gsub(ESCAPED_BACKSLASHES_, '\\')
137
138
    new_address = MailAddress::Address.new(name, address.join(''), original)
139
    phrase.clear; address.clear
140
    new_address
141
  end
142
143
end
144