class Steep::Source

def self.parse(source_code, path:, factory:, labeling: ASTUtils::Labeling.new)

def self.parse(source_code, path:, factory:, labeling: ASTUtils::Labeling.new)
  buffer = ::Parser::Source::Buffer.new(path.to_s, 1)
  buffer.source = source_code
  node = parser.parse(buffer).yield_self do |n|
    if n
      labeling.translate(n, {})
    else
      return new(path: path, node: nil, mapping: {})
    end
  end
  annotations = []
  _, comments, _ = yield_self do
    buffer = ::Parser::Source::Buffer.new(path.to_s)
    buffer.source = source_code
    parser = ::Parser::Ruby25.new
    parser.tokenize(buffer)
  end
  buffer = AST::Buffer.new(name: path, content: source_code)
  comments.each do |comment|
    src = comment.text.gsub(/\A#\s*/, '')
    location = AST::Location.new(buffer: buffer,
                                 start_pos: comment.location.expression.begin_pos + 1,
                                 end_pos: comment.location.expression.end_pos)
    annotation = AnnotationParser.new(factory: factory).parse(src, location: location)
    if annotation
      annotations << LocatedAnnotation.new(line: comment.location.line, source: src, annotation: annotation)
    end
  end
  mapping = {}
  construct_mapping(node: node, annotations: annotations, mapping: mapping)
  annotations.each do |annot|
    mapping[node.__id__] = [] unless mapping.key?(node.__id__)
    mapping[node.__id__] << annot.annotation
  end
  new(path: path, node: node, mapping: mapping)
end