Class: Terrestrial::Cli::Parser::Swift

Inherits:
Object
  • Object
show all
Defined in:
lib/terrestrial/cli/parser/swift.rb

Constant Summary collapse

LANGUAGE =
:swift
NSLOCALIZEDSTRING_REGEX =
/NSLocalizedString\(.*"(.*)".*\)/
STRING_REGEX =
/"([^"]*)"/
DOT_TRANSLATED_REGEX =
/"([^"]*)".translated\W/
TRANSLATED_WITH_CONTEXT_REGEX =
/"([^"]*)".translatedWithContext/
VARIABLE_REGEX =
/\\\((.*?)\)/

Class Method Summary collapse

Class Method Details

.analyse_line_for_strings(line, index, file_path) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/terrestrial/cli/parser/swift.rb', line 23

def self.analyse_line_for_strings(line, index, file_path)
  results = []
  line.scan(STRING_REGEX).each do |match|
    unless looks_suspicious(line)
      results.push(Hash.new.tap do |entry|
        entry["language"] = LANGUAGE
        entry["file"] = file_path
        entry["line_number"] = index + 1
        entry["string"] = match[0]
        entry["type"] = find_variables(match[0]).any? ? "stringWithFormat" : "unknown"
        # entry.variables = find_variables(match[0])
      end)
    end
  end
  results
end

.find_api_calls(file) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/terrestrial/cli/parser/swift.rb', line 40

def self.find_api_calls(file)
  results = []
  File.readlines(file).each_with_index do |line, index|
    line.scan(DOT_TRANSLATED_REGEX).each do |match|
      results.push(Hash.new.tap do |h|
        h["file"] = file
        h["line_number"] = index + 1
        h["string"] = match[0]
        h["type"] = ".translated"
        h["context"] = ""
      end)
    end

    line.scan(TRANSLATED_WITH_CONTEXT_REGEX).each do |match|
      results.push(Hash.new.tap do |h|
        h["file"] = file
        h["line_number"] = index + 1
        h["string"] = match[0]
        h["type"] = "translatedWithContext"
        h["context"] = get_context(line, h["string"])
      end)
    end
  end
  results
end

.find_strings(file) ⇒ Object



13
14
15
16
17
18
19
20
21
# File 'lib/terrestrial/cli/parser/swift.rb', line 13

def self.find_strings(file)
  results = []
  if is_view_controller?(file)
    File.readlines(file).each_with_index do |line, index|
      results.concat analyse_line_for_strings(line, index, file)
    end
  end
  results
end

.find_variables(string) ⇒ Object



70
71
72
73
# File 'lib/terrestrial/cli/parser/swift.rb', line 70

def self.find_variables(string)
  # tries to find \(asd) inside the string itself
  string.scan(VARIABLE_REGEX).map {|matches| matches[0]}
end

.get_context(line, match) ⇒ Object



66
67
68
# File 'lib/terrestrial/cli/parser/swift.rb', line 66

def self.get_context(line, match)
  line.match(/"#{match}"\.translatedWithContext\("([^"]*)"\)/)[1]
end

.is_view_controller?(file) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/terrestrial/cli/parser/swift.rb', line 75

def self.is_view_controller?(file)
  !file.match(/ViewController/).nil?
end

.looks_suspicious(line) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/terrestrial/cli/parser/swift.rb', line 79

def self.looks_suspicious(line)
  without_strings = line.gsub(STRING_REGEX, "")
  without_strings.include?("_LOG") || 
  without_strings.include?("_LOG") || 
  without_strings.include?("DLog") || 
  without_strings.include?("NSLog") || 
  without_strings.include?("NSAssert") ||
  without_strings.downcase.include?(".translated") || 
  without_strings.downcase.include?("nslocalizedstring") || 
  without_strings.downcase.include?("uistoryboard") ||
  without_strings.downcase.include?("instantiateviewcontrollerwithidentifier") ||
  without_strings.downcase.include?("uiimage") ||
  without_strings.downcase.include?("nsentitydescription") ||
  without_strings.downcase.include?("nspredicate") ||
  without_strings.downcase.include?("dateformat") ||
  without_strings.downcase.include?("datefromstring") ||
  without_strings.downcase.include?("==") ||
  without_strings.downcase.include?("isequaltostring") ||
  without_strings.downcase.include?("valueforkey") ||
  without_strings.downcase.include?("cellidentifier") ||
  without_strings.downcase.include?("uifont") ||
  without_strings.downcase.include?("print(")
end