Пример #1
0
def post_process_ast(ast, src, name=None):
    """Post-process the parsed AST."""
    ast = definitions.finalize_ast(ast)
    ast = ast.Visit(pep484.ConvertTypingToNative(name))

    if name:
        ast = ast.Replace(name=name)
        ast = ast.Visit(visitors.AddNamePrefix())
    else:
        # If there's no unique name, hash the sourcecode.
        ast = ast.Replace(name=hashlib.md5(src.encode("utf-8")).hexdigest())
    ast = ast.Visit(visitors.StripExternalNamePrefix())

    # Now that we have resolved external names, process any class decorators that
    # do code generation.
    try:
        ast = ast.Visit(decorate.DecorateClassVisitor())
    except TypeError as e:
        # Convert errors into ParseError. Unfortunately we no longer have location
        # information if an error is raised during transformation of a class node.
        raise ParseError.from_exc(e)

    # Typeshed files that explicitly import and refer to "__builtin__" need to
    # have that rewritten to builtins
    ast = ast.Visit(visitors.RenameBuiltinsPrefix())

    return ast
Пример #2
0
  def parse(self, src, name, filename):
    """Parse a PYI file and return the corresponding AST.

    Note that parse() should be called exactly once per _Parser instance.  It
    holds aggregated state during parsing and is not designed to be reused.

    Args:
      src: The source text to parse.
      name: The name of the module to be created.
      filename: The name of the source file.

    Returns:
      A pytd.TypeDeclUnit() representing the parsed pyi.

    Raises:
      ParseError: If the PYI source could not be parsed.
    """
    # Ensure instances do not get reused.
    assert not self._used
    self._used = True

    self._filename = filename
    self._ast_name = name
    self._type_map = {}

    try:
      defs = parser_ext.parse(self, src)
      ast = self._build_type_decl_unit(defs)
    except ParseError as e:
      if self._error_location:
        line = e.line or self._error_location[0]
        try:
          text = src.splitlines()[line-1]
        except IndexError:
          text = None
        raise ParseError(utils.message(e), line=line, filename=self._filename,
                         column=self._error_location[1], text=text)
      else:
        raise e

    ast = ast.Visit(_PropertyToConstant())
    ast = ast.Visit(_InsertTypeParameters())
    # TODO(kramm): This is in the wrong place- it should happen after resolving
    # local names, in load_pytd.
    ast = ast.Visit(pep484.ConvertTypingToNative(name))

    if name:
      ast = ast.Replace(name=name)
      ast = ast.Visit(visitors.AddNamePrefix())
    else:
      # If there's no unique name, hash the sourcecode.
      ast = ast.Replace(name=hashlib.md5(src.encode("utf-8")).hexdigest())
    ast = ast.Visit(visitors.StripExternalNamePrefix())

    # Typeshed files that explicitly import and refer to "builtins" need to have
    # that rewritten to __builtin__
    ast = ast.Visit(visitors.RenameBuiltinsPrefix())

    return ast.Replace(is_package=utils.is_pyi_directory_init(filename))
Пример #3
0
def post_process_ast(ast, src, name=None):
    """Post-process the parsed AST."""
    ast = definitions.finalize_ast(ast)
    ast = ast.Visit(pep484.ConvertTypingToNative(name))

    if name:
        ast = ast.Replace(name=name)
        ast = ast.Visit(visitors.AddNamePrefix())
    else:
        # If there's no unique name, hash the sourcecode.
        ast = ast.Replace(name=hashlib.md5(src.encode("utf-8")).hexdigest())
    ast = ast.Visit(visitors.StripExternalNamePrefix())

    # Typeshed files that explicitly import and refer to "__builtin__" need to
    # have that rewritten to builtins
    return ast.Visit(visitors.RenameBuiltinsPrefix())
Пример #4
0
def post_process_ast(ast, src, name=None):
  """Post-process the parsed AST."""
  ast = definitions.finalize_ast(ast)
  ast = ast.Visit(pep484.ConvertTypingToNative(name))

  if name:
    ast = ast.Replace(name=name)
    ast = ast.Visit(visitors.AddNamePrefix())
  else:
    # If there's no unique name, hash the sourcecode.
    ast = ast.Replace(name=hashlib.md5(src.encode("utf-8")).hexdigest())
  ast = ast.Visit(visitors.StripExternalNamePrefix())

  # Now that we have resolved external names, validate any class decorators that
  # do code generation. (We will generate the class lazily, but we should check
  # for errors at parse time so they can be reported early.)
  try:
    ast = ast.Visit(decorate.ValidateDecoratedClassVisitor())
  except TypeError as e:
    # Convert errors into ParseError. Unfortunately we no longer have location
    # information if an error is raised during transformation of a class node.
    raise ParseError.from_exc(e)

  return ast