<s> import re , sys , json <EOL> from jasy . js . tokenize . Lang import keywords <EOL> from jasy . js . parse . Lang import expressions , futureReserved <EOL> all = [ "<STR_LIT>" ] <EOL> high_unicode = re . compile ( r"<STR_LIT>" ) <EOL> ascii_encoder = json . JSONEncoder ( ensure_ascii = True ) <EOL> unicode_encoder = json . JSONEncoder ( ensure_ascii = False ) <EOL> class Compressor : <EOL> __semicolonSymbol = "<STR_LIT:;>" <EOL> __commaSymbol = "<STR_LIT:U+002C>" <EOL> def __init__ ( self , format = None ) : <EOL> if format : <EOL> if format . has ( "<STR_LIT>" ) : <EOL> self . __semicolonSymbol = "<STR_LIT>" <EOL> if format . has ( "<STR_LIT>" ) : <EOL> self . __commaSymbol = "<STR_LIT>" <EOL> self . __forcedSemicolon = False <EOL> def compress ( self , node ) : <EOL> type = node . type <EOL> result = None <EOL> if type in self . __simple : <EOL> result = type <EOL> elif type in self . __prefixes : <EOL> if getattr ( node , "<STR_LIT>" , False ) : <EOL> result = self . compress ( node [ <NUM_LIT:0> ] ) + self . __prefixes [ node . type ] <EOL> else : <EOL> result = self . __prefixes [ node . type ] + self . compress ( node [ <NUM_LIT:0> ] ) <EOL> elif type in self . __dividers : <EOL> first = self . compress ( node [ <NUM_LIT:0> ] ) <EOL> second = self . compress ( node [ <NUM_LIT:1> ] ) <EOL> divider = self . __dividers [ node . type ] <EOL> if node . type not in ( "<STR_LIT>" , "<STR_LIT>" ) : <EOL> result = "<STR_LIT>" % ( first , divider , second ) <EOL> else : <EOL> result = first <EOL> if first . endswith ( divider ) : <EOL> result += "<STR_LIT:U+0020>" <EOL> result += divider <EOL> if second . startswith ( divider ) : <EOL> result += "<STR_LIT:U+0020>" <EOL> result += second <EOL> else : <EOL> try : <EOL> result = getattr ( self , "<STR_LIT>" % type ) ( node ) <EOL> except KeyError : <EOL> print ( "<STR_LIT>" % ( type , node . line , node . getFileName ( ) ) ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> if getattr ( node , "<STR_LIT>" , None ) : <EOL> return "<STR_LIT>" % result <EOL> else : <EOL> return result <EOL> def __statements ( self , node ) : <EOL> result = [ ] <EOL> for child in node : <EOL> result . append ( self . compress ( child ) ) <EOL> return "<STR_LIT>" . join ( result ) <EOL> def __handleForcedSemicolon ( self , node ) : <EOL> if node . type == "<STR_LIT>" and not hasattr ( node , "<STR_LIT>" ) : <EOL> self . __forcedSemicolon = True <EOL> def __addSemicolon ( self , result ) : <EOL> if not result . endswith ( self . __semicolonSymbol ) : <EOL> if self . __forcedSemicolon : <EOL> self . __forcedSemicolon = False <EOL> return result + self . __semicolonSymbol <EOL> else : <EOL> return result <EOL> def __removeSemicolon ( self , result ) : <EOL> if self . __forcedSemicolon : <EOL> self . __forcedSemicolon = False <EOL> return result <EOL> if result . endswith ( self . __semicolonSymbol ) : <EOL> return result [ : - len ( self . __semicolonSymbol ) ] <EOL> else : <EOL> return result <EOL> __simple_property = re . compile ( r"<STR_LIT>" ) <EOL> __number_property = re . compile ( r"<STR_LIT>" ) <EOL> __simple = [ "<STR_LIT:true>" , "<STR_LIT:false>" , "<STR_LIT:null>" , "<STR_LIT>" , "<STR_LIT>" ] <EOL> __dividers = { <EOL> "<STR_LIT>" : '<STR_LIT:+>' , <EOL> "<STR_LIT>" : '<STR_LIT:->' , <EOL> "<STR_LIT>" : '<STR_LIT:*>' , <EOL> "<STR_LIT>" : '<STR_LIT:/>' , <EOL> "<STR_LIT>" : '<STR_LIT:%>' , <EOL> "<STR_LIT>" : '<STR_LIT:.>' , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT:<>' , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT:>>' , <EOL> "<STR_LIT>" : '<STR_LIT:|>' , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : '<STR_LIT:&>' <EOL> } <EOL> __prefixes = { <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : '<STR_LIT>' , <EOL> "<STR_LIT>" : "<STR_LIT:!>" , <EOL> "<STR_LIT>" : "<STR_LIT:+>" , <EOL> "<STR_LIT>" : "<STR_LIT:->" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" , <EOL> "<STR_LIT>" : "<STR_LIT>" <EOL> } <EOL> def type_script ( self , node ) : <EOL> return self . __statements ( node ) <EOL> def type_comma ( self , node ) : <EOL> return self . __commaSymbol . join ( map ( self . compress , node ) ) <EOL> def type_object_init ( self , node ) : <EOL> return "<STR_LIT>" % self . __commaSymbol . join ( map ( self . compress , node ) ) <EOL> def type_property_init ( self , node ) : <EOL> key = self . compress ( node [ <NUM_LIT:0> ] ) <EOL> value = self . compress ( node [ <NUM_LIT:1> ] ) <EOL> if type ( key ) in ( int , float ) : <EOL> pass <EOL> elif self . __number_property . match ( key ) : <EOL> pass <EOL> elif key in keywords or key in futureReserved or not self . __simple_property . match ( key ) : <EOL> key = self . type_string ( node [ <NUM_LIT:0> ] ) <EOL> return "<STR_LIT>" % ( key , value ) <EOL> def type_array_init ( self , node ) : <EOL> def helper ( child ) : <EOL> return self . compress ( child ) if child != None else "<STR_LIT>" <EOL> return "<STR_LIT>" % "<STR_LIT:U+002C>" . join ( map ( helper , node ) ) <EOL> def type_array_comp ( self , node ) : <EOL> return "<STR_LIT>" % ( self . compress ( node . expression ) , self . compress ( node . tail ) ) <EOL> def type_string ( self , node ) : <EOL> ascii = ascii_encoder . encode ( node . value ) <EOL> if high_unicode . search ( ascii ) : <EOL> return ascii <EOL> else : <EOL> return unicode_encoder . encode ( node . value ) <EOL> def type_number ( self , node ) : <EOL> value = node . value <EOL> if type ( value ) == str : <EOL> if value . startswith ( "<STR_LIT>" ) and len ( value ) > <NUM_LIT:2> : <EOL> value = value [ <NUM_LIT:1> : ] <EOL> elif value . endswith ( "<STR_LIT>" ) : <EOL> value = value [ : - <NUM_LIT:2> ] <EOL> elif int ( value ) == value and node . parent . type != "<STR_LIT>" : <EOL> value = int ( value ) <EOL> return "<STR_LIT:%s>" % value <EOL> def type_regexp ( self , node ) : <EOL> return node . value <EOL> def type_identifier ( self , node ) : <EOL> return node . value <EOL> def type_list ( self , node ) : <EOL> return "<STR_LIT:U+002C>" . join ( map ( self . compress , node ) ) <EOL> def type_index ( self , node ) : <EOL> return "<STR_LIT>" % ( self . compress ( node [ <NUM_LIT:0> ] ) , self . compress ( node [ <NUM_LIT:1> ] ) ) <EOL> def type_declaration ( self , node ) : <EOL> names = getattr ( node , "<STR_LIT>" , None ) <EOL> if names : <EOL> result = self . compress ( names ) <EOL> else : <EOL> result = node . name <EOL> initializer = getattr ( node , "<STR_LIT>" , None ) <EOL> if initializer : <EOL> result += "<STR_LIT>" % self . compress ( node . initializer ) <EOL> return result <EOL> def type_assign ( self , node ) : <EOL> assignOp = getattr ( node , "<STR_LIT>" , None ) <EOL> operator = "<STR_LIT:=>" if not assignOp else self . __dividers [ assignOp ] + "<STR_LIT:=>" <EOL> return self . compress ( node [ <NUM_LIT:0> ] ) + operator + self . compress ( node [ <NUM_LIT:1> ] ) <EOL> def type_call ( self , node ) : <EOL> return "<STR_LIT>" % ( self . compress ( node [ <NUM_LIT:0> ] ) , self . compress ( node [ <NUM_LIT:1> ] ) ) <EOL> def type_new_with_args ( self , node ) : <EOL> result = "<STR_LIT>" % self . compress ( node [ <NUM_LIT:0> ] ) <EOL> if len ( node [ <NUM_LIT:1> ] ) > <NUM_LIT:0> : <EOL> result += "<STR_LIT>" % self . compress ( node [ <NUM_LIT:1> ] ) <EOL> else : <EOL> parent = getattr ( node , "<STR_LIT>" , None ) <EOL> if parent and parent . type is "<STR_LIT>" : <EOL> result += "<STR_LIT>" <EOL> return result <EOL> def type_exception ( self , node ) : <EOL> return node . value <EOL> def type_generator ( self , node ) : <EOL> """<STR_LIT>""" <EOL> result = self . compress ( getattr ( node , "<STR_LIT>" ) ) <EOL> tail = getattr ( node , "<STR_LIT>" , None ) <EOL> if tail : <EOL> result += "<STR_LIT>" % self . compress ( tail ) <EOL> return result <EOL> def type_comp_tail ( self , node ) : <EOL> """<STR_LIT>""" <EOL> result = self . compress ( getattr ( node , "<STR_LIT>" ) ) <EOL> guard = getattr ( node , "<STR_LIT>" , None ) <EOL> if guard : <EOL> result += "<STR_LIT>" % self . compress ( guard ) <EOL> return result <EOL> def type_in ( self , node ) : <EOL> first = self . compress ( node [ <NUM_LIT:0> ] ) <EOL> second = self . compress ( node [ <NUM_LIT:1> ] ) <EOL> if first . endswith ( "<STR_LIT:'>" ) or first . endswith ( '<STR_LIT:">' ) : <EOL> pattern = "<STR_LIT>" <EOL> else : <EOL> pattern = "<STR_LIT>" <EOL> return pattern % ( first , second ) <EOL> def type_instanceof ( self , node ) : <EOL> first = self . compress ( node [ <NUM_LIT:0> ] ) <EOL> second = self . compress ( node [ <NUM_LIT:1> ] ) <EOL> return "<STR_LIT>" % ( first , second ) <EOL> def type_block ( self , node ) : <EOL> return "<STR_LIT>" % self . __removeSemicolon ( self . __statements ( node ) ) <EOL> def type_let_block ( self , node ) : <EOL> begin = "<STR_LIT>" % "<STR_LIT:U+002C>" . join ( map ( self . compress , node . variables ) ) <EOL> if hasattr ( node , "<STR_LIT>" ) : <EOL> end = self . compress ( node . block ) <EOL> elif hasattr ( node , "<STR_LIT>" ) : <EOL> end = self . compress ( node . expression ) <EOL> return begin + end <EOL> def type_const ( self , node ) : <EOL> return self . __addSemicolon ( "<STR_LIT>" % self . type_list ( node ) ) <EOL> def type_var ( self , node ) : <EOL> return self . __addSemicolon ( "<STR_LIT>" % self . type_list ( node ) ) <EOL> def type_let ( self , node ) : <EOL> return self . __addSemicolon ( "<STR_LIT>" % self . type_list ( node ) ) <EOL> def type_semicolon ( self , node ) : <EOL> expression = getattr ( node , "<STR_LIT>" , None ) <EOL> return self . __addSemicolon ( self . compress ( expression ) if expression else "<STR_LIT>" ) <EOL> def type_label ( self , node ) : <EOL> return self . __addSemicolon ( "<STR_LIT>" % ( node . label , self . compress ( node . statement ) ) ) <EOL> def type_break ( self , node ) : <EOL> return self . __addSemicolon ( "<STR_LIT>" if not hasattr ( node , "<STR_LIT:label>" ) else "<STR_LIT>" % node . label ) <EOL> def type_continue ( self , node ) : <EOL> return self . __addSemicolon ( "<STR_LIT>" if not hasattr ( node , "<STR_LIT:label>" ) else "<STR_LIT>" % node . label ) <EOL> def type_function ( self , node ) : <EOL> if node . type == "<STR_LIT>" : <EOL> result = "<STR_LIT>" <EOL> elif node . type == "<STR_LIT>" : <EOL> result = "<STR_LIT>" <EOL> else : <EOL> result = "<STR_LIT>" <EOL> name = getattr ( node , "<STR_LIT:name>" , None ) <EOL> if name : <EOL> result += "<STR_LIT>" % name <EOL> params = getattr ( node , "<STR_LIT>" , None ) <EOL> result += "<STR_LIT>" % self . compress ( params ) if params else "<STR_LIT>" <EOL> if getattr ( node , "<STR_LIT>" , False ) : <EOL> result += self . compress ( node . body ) <EOL> else : <EOL> result += "<STR_LIT>" % self . __removeSemicolon ( self . compress ( node . body ) ) <EOL> return result <EOL> def type_getter ( self , node ) : <EOL> return self . type_function ( node ) <EOL> def type_setter ( self , node ) : <EOL> return self . type_function ( node ) <EOL> def type_return ( self , node ) : <EOL> result = "<STR_LIT>" <EOL> if hasattr ( node , "<STR_LIT:value>" ) : <EOL> valueCode = self . compress ( node . value ) <EOL> if not valueCode . startswith ( ( "<STR_LIT:(>" , "<STR_LIT:[>" , "<STR_LIT:{>" , "<STR_LIT:'>" , '<STR_LIT:">' , "<STR_LIT:!>" , "<STR_LIT:->" , "<STR_LIT:/>" ) ) : <EOL> result += "<STR_LIT:U+0020>" <EOL> result += valueCode <EOL> return self . __addSemicolon ( result ) <EOL> def type_throw ( self , node ) : <EOL> return self . __addSemicolon ( "<STR_LIT>" % self . compress ( node . exception ) ) <EOL> def type_try ( self , node ) : <EOL> result = "<STR_LIT>" % self . compress ( node . tryBlock ) <EOL> for catch in node : <EOL> if catch . type == "<STR_LIT>" : <EOL> if hasattr ( catch , "<STR_LIT>" ) : <EOL> result += "<STR_LIT>" % ( self . compress ( catch . exception ) , self . compress ( catch . guard ) , self . compress ( catch . block ) ) <EOL> else : <EOL> result += "<STR_LIT>" % ( self . compress ( catch . exception ) , self . compress ( catch . block ) ) <EOL> if hasattr ( node , "<STR_LIT>" ) : <EOL> result += "<STR_LIT>" % self . compress ( node . finallyBlock ) <EOL> return result <EOL> def type_while ( self , node ) : <EOL> result = "<STR_LIT>" % ( self . compress ( node . condition ) , self . compress ( node . body ) ) <EOL> self . __handleForcedSemicolon ( node . body ) <EOL> return result <EOL> def type_do ( self , node ) : <EOL> body = self . compress ( node . body ) <EOL> if not body . startswith ( "<STR_LIT:{>" ) : <EOL> body = "<STR_LIT>" % body <EOL> return self . __addSemicolon ( "<STR_LIT>" % ( body , self . compress ( node . condition ) ) ) <EOL> def type_for_in ( self , node ) : <EOL> varDecl = getattr ( node , "<STR_LIT>" , None ) <EOL> body = getattr ( node , "<STR_LIT:body>" , None ) <EOL> if body : <EOL> body = self . compress ( body ) <EOL> else : <EOL> body = "<STR_LIT>" <EOL> result = "<STR_LIT>" <EOL> if node . isEach : <EOL> result += "<STR_LIT>" <EOL> result += "<STR_LIT>" % ( self . __removeSemicolon ( self . compress ( node . iterator ) ) , self . compress ( node . object ) , body ) <EOL> if body : <EOL> self . __handleForcedSemicolon ( node . body ) <EOL> return result <EOL> def type_for ( self , node ) : <EOL> setup = getattr ( node , "<STR_LIT>" , None ) <EOL> condition = getattr ( node , "<STR_LIT>" , None ) <EOL> update = getattr ( node , "<STR_LIT>" , None ) <EOL> result = "<STR_LIT>" <EOL> result += self . __addSemicolon ( self . compress ( setup ) if setup else "<STR_LIT>" ) <EOL> result += self . __addSemicolon ( self . compress ( condition ) if condition else "<STR_LIT>" ) <EOL> result += self . compress ( update ) if update else "<STR_LIT>" <EOL> result += "<STR_LIT>" % self . compress ( node . body ) <EOL> self . __handleForcedSemicolon ( node . body ) <EOL> return result <EOL> def type_hook ( self , node ) : <EOL> """<STR_LIT>""" <EOL> condition = node . condition <EOL> thenPart = node . thenPart <EOL> elsePart = node . elsePart <EOL> if condition . type == "<STR_LIT>" : <EOL> [ thenPart , elsePart ] = [ elsePart , thenPart ] <EOL> condition = condition [ <NUM_LIT:0> ] <EOL> return "<STR_LIT>" % ( self . compress ( condition ) , self . compress ( thenPart ) , self . compress ( elsePart ) ) <EOL> def type_if ( self , node ) : <EOL> result = "<STR_LIT>" % ( self . compress ( node . condition ) , self . compress ( node . thenPart ) ) <EOL> elsePart = getattr ( node , "<STR_LIT>" , None ) <EOL> if elsePart : <EOL> result += "<STR_LIT>" <EOL> elseCode = self . compress ( elsePart ) <EOL> if not elseCode . startswith ( ( "<STR_LIT:{>" , "<STR_LIT:(>" , "<STR_LIT:;>" ) ) : <EOL> result += "<STR_LIT:U+0020>" <EOL> result += elseCode <EOL> self . __handleForcedSemicolon ( elsePart ) <EOL> return result <EOL> def type_switch ( self , node ) : <EOL> result = "<STR_LIT>" % self . compress ( node . discriminant ) <EOL> for case in node : <EOL> if case . type == "<STR_LIT>" : <EOL> labelCode = self . compress ( case . label ) <EOL> if labelCode . startswith ( '<STR_LIT:">' ) : <EOL> result += "<STR_LIT>" % labelCode <EOL> else : <EOL> result += "<STR_LIT>" % labelCode <EOL> elif case . type == "<STR_LIT:default>" : <EOL> result += "<STR_LIT>" <EOL> else : <EOL> continue <EOL> for statement in case . statements : <EOL> temp = self . compress ( statement ) <EOL> if len ( temp ) > <NUM_LIT:0> : <EOL> result += self . __addSemicolon ( temp ) <EOL> return "<STR_LIT>" % self . __removeSemicolon ( result ) </s>
