<s> import re <EOL> import subprocess <EOL> from tempfile import NamedTemporaryFile <EOL> import json <EOL> from appvalidator . constants import SPIDERMONKEY_INSTALLATION <EOL> from appvalidator . contextgenerator import ContextGenerator <EOL> import appvalidator . unicodehelper as unicodehelper <EOL> JS_ESCAPE = re . compile ( "<STR_LIT>" , re . I ) <EOL> def get_tree ( code , err = None , filename = None , shell = None ) : <EOL> """<STR_LIT>""" <EOL> if not code : <EOL> return None <EOL> try : <EOL> return _get_tree ( code , shell or SPIDERMONKEY_INSTALLATION ) <EOL> except JSReflectException as exc : <EOL> str_exc = str ( exc ) . strip ( "<STR_LIT>" ) <EOL> if "<STR_LIT>" in str_exc or "<STR_LIT>" in str_exc : <EOL> err . warning ( <EOL> err_id = ( "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ) , <EOL> warning = "<STR_LIT>" , <EOL> description = [ "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" % str_exc . split ( "<STR_LIT::>" , <NUM_LIT:1> ) [ - <NUM_LIT:1> ] . strip ( ) <EOL> ] , <EOL> filename = filename , <EOL> line = exc . line , <EOL> context = ContextGenerator ( code ) ) <EOL> elif "<STR_LIT>" in str_exc : <EOL> err . notice ( <EOL> err_id = ( "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" ) , <EOL> notice = "<STR_LIT>" , <EOL> description = "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> filename = filename ) <EOL> else : <EOL> err . error ( <EOL> err_id = ( "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" ) , <EOL> error = "<STR_LIT>" , <EOL> description = [ "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" , str ( exc ) ] , <EOL> filename = filename ) <EOL> class JSReflectException ( Exception ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , value ) : <EOL> self . value = value <EOL> self . line = None <EOL> def __str__ ( self ) : <EOL> return repr ( self . value ) <EOL> def line_num ( self , line_num ) : <EOL> "<STR_LIT>" <EOL> self . line = int ( line_num ) <EOL> return self <EOL> BOOTSTRAP_FILE_SCRIPT = """<STR_LIT>""" <EOL> BOOTSTRAP_SCRIPT = """<STR_LIT>""" <EOL> BOOTSTRAP_SCRIPT = re . sub ( "<STR_LIT>" , "<STR_LIT>" , BOOTSTRAP_SCRIPT ) <EOL> def _get_tree ( code , shell = SPIDERMONKEY_INSTALLATION ) : <EOL> """<STR_LIT>""" <EOL> if not code : <EOL> return None <EOL> parsed = get_tree_from_spidermonkey ( shell , code ) <EOL> if parsed . get ( "<STR_LIT:error>" ) : <EOL> if parsed [ "<STR_LIT>" ] . startswith ( "<STR_LIT>" ) : <EOL> raise RuntimeError ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( parsed [ "<STR_LIT>" ] , <EOL> shell ) ) <EOL> else : <EOL> raise JSReflectException ( parsed [ "<STR_LIT>" ] ) . line_num ( <EOL> parsed [ "<STR_LIT>" ] ) <EOL> return parsed <EOL> def run_js ( shell , script , code = None ) : <EOL> cmd = [ shell , "<STR_LIT>" , script ] <EOL> shell_obj = subprocess . Popen ( <EOL> cmd , shell = False , stdin = subprocess . PIPE , stderr = subprocess . PIPE , <EOL> stdout = subprocess . PIPE ) <EOL> data , stderr = shell_obj . communicate ( code ) <EOL> if stderr : <EOL> raise RuntimeError ( '<STR_LIT>' % ( cmd , stderr ) ) <EOL> if not data : <EOL> raise JSReflectException ( "<STR_LIT>" ) <EOL> return data , stderr <EOL> def serialize_code ( code ) : <EOL> return json . dumps ( JS_ESCAPE . sub ( "<STR_LIT:u>" , unicodehelper . decode ( code ) ) ) <EOL> def get_tree_from_spidermonkey ( shell , code ) : <EOL> data = run_with_serialize ( shell , code ) <EOL> data = unicodehelper . decode ( data ) <EOL> try : <EOL> return json . loads ( data , strict = False ) <EOL> except ValueError : <EOL> data = run_with_tempfile ( shell , code ) <EOL> data = unicodehelper . decode ( data ) <EOL> return json . loads ( data , strict = False ) <EOL> def run_with_serialize ( shell , code ) : <EOL> data , stderr = run_js ( shell , BOOTSTRAP_SCRIPT , serialize_code ( code ) ) <EOL> return data <EOL> def run_with_tempfile ( shell , code ) : <EOL> data = unicodehelper . decode ( code ) . encode ( '<STR_LIT:utf-8>' , '<STR_LIT:replace>' ) <EOL> with NamedTemporaryFile ( ) as f : <EOL> f . write ( data ) <EOL> f . flush ( ) <EOL> data , stderr = run_js ( shell , BOOTSTRAP_FILE_SCRIPT % f . name ) <EOL> return data </s>
