import_astfrom_astimport*fromrope.baseimportfscommandsdefparse(source,filename='<string>'):# NOTE: the raw string should be given to `compile` functionifisinstance(source,unicode):source=fscommands.unicode_to_file_data(source)if'\r'insource:source=source.replace('\r\n','\n').replace('\r','\n')ifnotsource.endswith('\n'):source+='\n'try:returncompile(source,filename,'exec',_ast.PyCF_ONLY_AST)except(TypeError,ValueError),e:error=SyntaxError()error.lineno=1error.filename=filenameerror.msg=str(e)raiseerrordefwalk(node,walker):"""Walk the syntax tree"""method_name='_'+node.__class__.__name__method=getattr(walker,method_name,None)ifmethodisnotNone:returnmethod(node)forchildinget_child_nodes(node):walk(child,walker)defget_child_nodes(node):ifisinstance(node,_ast.Module):returnnode.bodyresult=[]ifnode._fieldsisnotNone:fornameinnode._fields:child=getattr(node,name)ifisinstance(child,list):forentryinchild:ifisinstance(entry,_ast.AST):result.append(entry)ifisinstance(child,_ast.AST):result.append(child)returnresultdefcall_for_nodes(node,callback,recursive=False):"""If callback returns `True` the child nodes are skipped"""result=callback(node)ifrecursiveandnotresult:forchildinget_child_nodes(node):call_for_nodes(child,callback,recursive)defget_children(node):result=[]ifnode._fieldsisnotNone:fornameinnode._fields:ifnamein['lineno','col_offset']:continuechild=getattr(node,name)result.append(child)returnresult