class SwiftAST::Parser

Public Instance Methods

isAlphaDigit(str) click to toggle source
# File lib/swift_ast_dump_parser.rb, line 166
def isAlphaDigit(str)
  !str.match(/[^A-Za-z@_0-9]/)
end
isalpha(str) click to toggle source
# File lib/swift_ast_dump_parser.rb, line 163
def isalpha(str)
  !str.match(/[^A-Za-z@_]/)
end
isalphaOrDot(str) click to toggle source
# File lib/swift_ast_dump_parser.rb, line 169
def isalphaOrDot(str)
  !str.match(/[^A-Za-z@_.,]/)
end
parse(string) click to toggle source
# File lib/swift_ast_dump_parser.rb, line 4
def parse(string)
  @scanner = StringScanner.new(string)
  node = scan_children.first
  node
end
parse_build_log_output(string) click to toggle source
# File lib/swift_ast_dump_parser.rb, line 11
def parse_build_log_output(string)
  @scanner = StringScanner.new(string)
  return unless @scanner.scan_until(/^\(source_file/)
  unscan("(source_file")
  children = scan_children

  return if children.empty?
  Node.new("ast", [], children)
end
scan_children(level = 0) click to toggle source
# File lib/swift_ast_dump_parser.rb, line 41
def scan_children(level = 0)
  children = []
  while true
    return children unless whitespaces = whitespaces_at(level)
    node_name = scan_name?
    return children if node_name == "source_file" && level != 0 && unscan(node_name + whitespaces)
    node_parameters = scan_parameters

    node_children = scan_children(level + 1)

    while next_params = scan_parameters_from_types  # these are stupid params alike
      break if next_params.empty?
      node_parameters += next_params
      node_children += scan_children(level + 1)
    end  
    node = Node.new(node_name, node_parameters, node_children)

    children << node
    @scanner.scan(/(\s|\\|\n|\r|\t)*\)[\w\s]*/)
  end  
  children
end
scan_line_and_column() click to toggle source
# File lib/swift_ast_dump_parser.rb, line 159
def scan_line_and_column
  @scanner.scan(/:\d+:\d+/)
end
scan_name?() click to toggle source
# File lib/swift_ast_dump_parser.rb, line 78
def scan_name? 
  el_name = @scanner.scan(/#?[\w:]+/)
  el_name
end
scan_parameter?(is_parsing_rvalue = false) click to toggle source
# File lib/swift_ast_dump_parser.rb, line 83
def scan_parameter?(is_parsing_rvalue = false)
  #white spaces are skipped

  # scan everything until space or opening sequence like ( < ' ".
  # Since we can end up with closing bracket - we alos check for )

  prefix = @scanner.scan(/[^\s()'"\[\\]+/) if is_parsing_rvalue
  prefix = @scanner.scan(/[^\s()<'"\[\\=]+/) unless is_parsing_rvalue

  next_char = @scanner.peek(1)
  return nil unless next_char
  should_unwrap_strings = !is_parsing_rvalue && !prefix

  case next_char
  when " "   # next parameter
    result = prefix
  when "\\"   # next parameter
    @scanner.scan(/./)
    result = prefix

  when "\n"   # next parameter
    result = prefix
  when ")"   # closing bracket == end of element
    result = prefix
  when "\""  # doube quoted string
    result = @scanner.scan(/./) + @scanner.scan_until(/"/)
    result = result[1..-2] if should_unwrap_strings             
    result = (prefix || "") + result
  when "'"  # single quoted string
    result =  @scanner.scan(/./) + @scanner.scan_until(/'/)
    result = result[1..-2] if should_unwrap_strings             
    result = (prefix || "") + result + (scan_parameter?(is_parsing_rvalue) || "")
  when "<"  # kinda generic
    result = (prefix || "") + @scanner.scan(/./)
    #in some cases this can be last char, just because we can end up with a=sdsd.function.<
    result += @scanner.scan_until(/>/) + (scan_parameter?(is_parsing_rvalue) || "") 
  when "("
    #rare case for enums in type (EnumType).enumValue
    if !prefix && @scanner.check(/\([\w\s\(\)<>,:\]\[\.?]+\)\.\w+/)
      return @scanner.scan(/\([\w\s\(\)<>,:\]\[\.?]+\)\.\w+/)
    end  

    return nil if !prefix && !is_parsing_rvalue
    result = (prefix || "") + @scanner.scan_until(/\)/) + (scan_parameter?(is_parsing_rvalue) || "")
   when "["
    result = (prefix || "") + scan_range + (scan_parameter?(is_parsing_rvalue) || "")
    #rare case for tuple_shuffle_expr [with ([ProductDict], UserDict)]0: ([ProductDict], UserDict)
    if result.start_with?("[with") && result.end_with?("]0:")
      result = result + @scanner.scan_until(/\n/).chomp("\n")

    end  
   when "=" 
    result = prefix + @scanner.scan(/./) + (scan_parameter?(true) || "")

  end  

  result

end
scan_parameters() click to toggle source
# File lib/swift_ast_dump_parser.rb, line 22
def scan_parameters
  parameters = []

  while true
    @scanner.skip(/\s*/)
    parameter = scan_parameter?
    break unless parameter
    parameters << parameter
  end

  parameters
end
scan_parameters_from_types() click to toggle source
# File lib/swift_ast_dump_parser.rb, line 35
def scan_parameters_from_types
  first_param = @scanner.scan(/\d+:/)
  return [] unless first_param
  return [first_param] + scan_parameters
end
scan_range() click to toggle source
# File lib/swift_ast_dump_parser.rb, line 143
def scan_range
  return unless @scanner.peek(1) == "["
  result = @scanner.scan(/./)

  while true
    inside = @scanner.scan(/[^\]\[]+/)  #everything but [ or ]
    result += inside || ""
    next_char = @scanner.peek(1)

    return result + @scanner.scan(/./) if next_char == "]" # we found the end
    result += scan_range if next_char == "["
    raise "Unexpected character #{next_char} - [ or ] expected" if next_char != "[" && next_char != "]"
  end

end
unscan(string) click to toggle source
# File lib/swift_ast_dump_parser.rb, line 74
def unscan(string)
  @scanner.pos = @scanner.pos - string.length
end
whitespaces_at(level = 0) click to toggle source
# File lib/swift_ast_dump_parser.rb, line 64
def whitespaces_at(level = 0)
  whitespaces = @scanner.scan(/(\s|\\|\n|\r|\t)*\(/)
  if level == 0 && whitespaces.nil?
     whitespaces = @scanner.scan(/.*?\(source_file/m)
     return nil unless whitespaces
     unscan("source_file")
  end
  whitespaces 
end