def fixPassStatements(nodes): for node in gatherSubNodesD(nodes): if getNodeKind(node) == "NAME" and node.value == "pass": pass_idx = getNodeIndex(node) after_node = node.parent.children[pass_idx + 1] if getNodeKind(after_node) == "SEMI": after_node.remove() node.parent.insert_child(pass_idx, makeLeaf("PYJS", "/*", node.prefix)) node.prefix = " " node.parent.insert_child(pass_idx + 2, makeLeaf("PYJS", "*/", ' '))
def fixIndents(nodes): prefix = "" for sub_node in gatherSubNodesD(nodes): if getNodeKind(sub_node) == "DEDENT": space_rgx = re.compile(r"(.*?)( +)(\n*)$", re.S) m = space_rgx.match(sub_node.prefix) if m: prefix = m.group(2) sub_node.prefix = m.group(1) + m.group(3) elif getNodeKind(sub_node) == "NAME": if prefix: sub_node.prefix = " " * len(prefix) prefix = ""
def processOne(self, match): first_kw_idx = None for arg_idx, arg in enumerate(match.args): if not isinstance(arg.node, Leaf): for n in arg.node.children: if getNodeKind(n) == "COMMA": continue if getNodeKind(n) == "EQUAL": first_kw_idx = arg_idx break if first_kw_idx is not None: break if first_kw_idx is not None: for kw_arg_info in match.args[first_kw_idx:]: kw_arg_info.node.remove() obj_node = makeTrailer() match.node.append_child(obj_node) obj_node.append_child(makeLeaf("LBRACE", "{", " ")) for kw_arg_info in match.args[first_kw_idx:]: kw_arg_node = kw_arg_info.node if getNodeKind(kw_arg_node) == "COMMA": continue arg_name = eq_sym = None for arg_sub_node in kw_arg_node.children[:]: if getNodeKind( arg_sub_node) == "NAME" and arg_name is None: arg_name = str(arg_sub_node) arg_sub_node.remove() elif getNodeKind(arg_sub_node) == "EQUAL": eq_sym = str(arg_sub_node) arg_sub_node.remove() if not (arg_name and eq_sym): raise Exception("cannot get arg name & '=' from %r" % kw_arg_node.toString()) obj_node.append_child(makeLeaf("PYJS", arg_name, "")) obj_node.append_child(makeLeaf("COLON", ":", "")) if kw_arg_node.children: kw_arg_node.children[0].prefix = " " for n in kw_arg_node.children[:]: n.remove() obj_node.append_child(n) if kw_arg_info != match.args[-1]: obj_node.append_child(makeLeaf("COMMA", ",", "")) obj_node.append_child(makeLeaf("RBRACE", "}", " "))
def gather(self, node): """ return list of AnonObjs containing the info we need """ tv = Treeverser(node) matches = tv.gatherMatches(self.TRYEX_PATTERN) infos = [] for match in matches: info = AnonObj() info.node = match.node info.try_word = match.try_word info.try_colon = match.try_colon info.try_suite = match.try_suite[0] if "exc_clause" in match: info.exc_clause = match.exc_clause for node in gatherSubNodesD(info.exc_clause): if getNodeKind(node) == "NAME" and node.value == "as": info.exc_as = node as_idx = getNodeIndex(node) info.exc_as_name = node.parent.children[as_idx + 1] info.exc_word = match.exc_word if "exc_what" in match: info.exc_what = match.exc_what[0] info.exc_colon = match.exc_colon info.exc_suite = match.exc_suite[0] if "fin_word" in match: info.fin_word = match.fin_word info.fin_colon = match.fin_colon info.fin_suite = match.fin_suite[0] infos.append(info) return infos
def processOne(self, match): func_indent = self.calcIndent(match.node) if self.in_class: match.def_word.remove() match.name.prefix = func_indent else: match.def_word.replace(makeLeaf("NAME", "function", func_indent)) match.colon.remove() func_suite = match.suite func_suite.insert_child(0, makeLeaf("LBRACE", "{", ' ')) last_dedent_idx = self.findNodeReverseIndex(func_suite, "DEDENT") func_suite.insert_child(last_dedent_idx, makeLeaf("RBRACE", "}", func_indent)) func_suite.insert_child(last_dedent_idx + 1, makeLeaf("NEWLINE", "\n", "")) # remove any "self" param + comma + space before closing paren self_param = self.findSelfParam(match.params) if self_param: child_nodes = self_param.parent.children self_param.remove() if child_nodes: first_node = child_nodes[0] if getNodeKind(first_node) == "COMMA": first_node.remove() if len(child_nodes) == 2: child_nodes[-1].prefix = ""
def processOne(self, match): comp_op_kind = getNodeKind(match.comp_op) if comp_op_kind == "EQEQUAL": match.comp_op.replace(makeLeaf("PYJS", "===", match.comp_op.prefix)) elif comp_op_kind == "NOTEQUAL": match.comp_op.replace(makeLeaf("PYJS", "!==", match.comp_op.prefix)) elif comp_op_kind == "NAME" and match.comp_op.toString() == "is": if match.right.toString() == "None": match.comp_op.replace( makeLeaf("PYJS", "===", match.comp_op.prefix)) match.right.replace( makeLeaf("PYJS", "null", match.right.prefix)) elif match.right.toString() == "...": clearNode(match.node) match.node.append_child( makeLeaf("PYJS", "!_pyjs.isDef", match.comp_op.prefix)) match.node.append_child(makeLeaf("LPAR", "(")) match.left.prefix = " " match.node.append_child(match.left) match.node.append_child(makeLeaf("RPAR", ")", " ")) else: clearNode(match.node) match.node.append_child( makeLeaf("PYJS", "Object.is", match.comp_op.prefix)) match.node.append_child(makeLeaf("LPAR", "(")) match.left.prefix = " " match.node.append_child(match.left) match.node.append_child(makeLeaf("COMMA", ",", "")) match.right.prefix = " " match.node.append_child(match.right.clone()) match.node.append_child(makeLeaf("RPAR", ")", " ")) elif comp_op_kind == "comp_op" and match.comp_op.toString( ) == "is not": if match.right.toString() == "None": match.comp_op.replace( makeLeaf("PYJS", "!==", match.comp_op.prefix)) match.right.replace( makeLeaf("PYJS", "null", match.right.prefix)) elif match.right.toString() == "...": clearNode(match.node) match.node.append_child( makeLeaf("PYJS", "_pyjs.isDef", match.comp_op.prefix)) match.node.append_child(makeLeaf("LPAR", "(")) match.left.prefix = " " match.node.append_child(match.left) match.node.append_child(makeLeaf("RPAR", ")", " ")) else: clearNode(match.node) match.node.append_child( makeLeaf("PYJS", "!Object.is", match.comp_op.prefix)) match.node.append_child(makeLeaf("LPAR", "(")) match.left.prefix = " " match.node.append_child(match.left) match.node.append_child(makeLeaf("COMMA", ",", "")) match.right.prefix = " " match.node.append_child(match.right.clone()) match.node.append_child(makeLeaf("RPAR", ")", " "))
def fixSemicolons(nodes): STMT_PATTERN = """ simple_stmt < stmt=any newl='\\n' > """ tv = Treeverser(nodes) matches = tv.gatherMatches(STMT_PATTERN) infos = [] for match in matches: if getNodeKind(match.stmt) != "STRING": # stmt is not a comment par_node = match.newl.parent newl_idx = par_node.children.index(match.newl) if getNodeKind(par_node.children[newl_idx - 1]) != "SEMI": par_node.insert_child(newl_idx, makeLeaf("SEMI", ";", '')) return infos
def processAll(self, matches): done_vars = [] for match in matches: if getNodeKind(match.left) == "atom": name_node = match.left elif getNodeKind(match.left) == "NAME": name_node = match.left else: name_node = self.findNodeForward(match.left, "NAME", None) if name_node: str_name_node = name_node.toString() if str_name_node != "self" and str_name_node not in done_vars: name_node.parent.insert_child( 0, makeLeaf("PYJS", "let", name_node.prefix)) name_node.prefix = " " done_vars.append(str_name_node)
def findNodeReverse( self, parent, kind, fallback=... ): nodes = list( reversed( parent.children ) ) for node in nodes: if getNodeKind( node ) == kind: return node if fallback is not ...: return fallback raise Exception( "cannot find {}".format( kind ) )
def findNodeForward( self, parent, kind, fallback=... ): nodes = gatherSubNodesD( parent ) for node in nodes: if getNodeKind( node ) == kind: return node if fallback is not ...: return fallback raise Exception( "cannot find {}".format( kind ) )
def processOne_NO_PYJS( self, match ): """ this results in right.reduce( ( a, c ) => a.replace( /%(s|i|r)?/, c.toString () ), left ); which is self-contained but a bit long-winded """ is_multi = getNodeKind( match.right ) == "power" or \ len( str( match.right ).split( "," ) ) > 1 new = makeStatement() if not is_multi: new.append_child( makeLeaf( "LSQB", "[", ' ' ) ) new.append_child( match.right ) if not is_multi: new.append_child( makeLeaf( "RSQB", "]", ' ' ) ) new.append_child( makeLeaf( "DOT", ".", '' ) ) new.append_child( makeLeaf( "PYJS", "reduce", '' ) ) new.append_child( makeLeaf( "LPAR", "(", '' ) ) new.append_child( makeLeaf( "LPAR", "(", ' ' ) ) new.append_child( makeLeaf( "PYJS", "a", ' ' ) ) new.append_child( makeLeaf( "COMMA", ",", "" ) ) new.append_child( makeLeaf( "PYJS", "c", ' ' ) ) new.append_child( makeLeaf( "RPAR", ")", ' ' ) ) new.append_child( makeLeaf( "PYJS", "=>", ' ' ) ) new.append_child( makeLeaf( "PYJS", "a", ' ' ) ) new.append_child( makeLeaf( "DOT", ".", '' ) ) new.append_child( makeLeaf( "PYJS", "replace", '' ) ) new.append_child( makeLeaf( "LPAR", "(", '' ) ) new.append_child( makeLeaf( "PYJS", "/%(s|i|r)?/", ' ' ) ) new.append_child( makeLeaf( "COMMA", ",", "" ) ) new.append_child( makeLeaf( "PYJS", "c", ' ' ) ) new.append_child( makeLeaf( "DOT", ".", '' ) ) new.append_child( makeLeaf( "PYJS", "toString", '' ) ) new.append_child( makeLeaf( "LPAR", "(", ' ' ) ) new.append_child( makeLeaf( "RPAR", ")", '' ) ) new.append_child( makeLeaf( "RPAR", ")", ' ' ) ) new.append_child( makeLeaf( "COMMA", ",", "" ) ) match.left.prefix = ' ' new.append_child( match.left ) new.append_child( makeLeaf( "RPAR", ")", ' ' ) ) match.percent_sym.parent.replace( new )
def fixComments( nodes ): """ comments in triple-quotes are made into block comments (/* ... */); comments after # are made into inline comments (// ...) """ for node in gatherSubNodesD( nodes ): if getNodeKind( node ) == "STRING": text = node.value tquote_m = tquote_comment_rgx.match( text ) if tquote_m: node.value = "/*" + tquote_m.group( 2 ) + "*/" else: text = node.prefix if white_space_rgx.sub( "", node.prefix ) else "" hash_m = hash_comment_rgx.match( text ) if hash_m: comm_body = hash_m.group( 3 ) comm_lines = [ comm_line.replace( "#", "//" ) if ( comm_line.strip() and comm_line.strip()[ 0 ] == "#" ) else comm_line for comm_line in comm_body.split( "\n" ) ] comm_body = "\n".join( comm_lines ) node.prefix = hash_m.group( 1 ) + "//" + comm_body
def processOne_PYJS( self, match ): """ this results in _pyjs.stringInterpolate( left, right ); which is a short but needs the external function """ is_multi = getNodeKind( match.right ) == "power" or \ len( str( match.right ).split( "," ) ) > 1 new = makeStatement() new.append_child( makeLeaf( "NAME", "_pyjs.stringInterpolate", match.left.prefix ) ) new.append_child( makeLeaf( "LPAR", "(" ) ) match.left.prefix = ' ' new.append_child( match.left ) new.append_child( makeLeaf( "COMMA", ",", "" ) ) if not is_multi: new.append_child( makeLeaf( "LSQB", "[", ' ' ) ) new.append_child( match.right ) if not is_multi: new.append_child( makeLeaf( "RSQB", "]", ' ' ) ) new.append_child( makeLeaf( "RPAR", ")", " " ) ) match.percent_sym.parent.replace( new )
def fixSimpleRenames(func_node): for node in gatherSubNodesD(func_node): if getNodeKind(node) == "NAME": if node.value in m_fix_simple_names: node.value = m_fix_simple_names[node.value]
def isTestFuncNode(self, node): return getNodeKind(node) == 'funcdef' and node.toString().startswith( 'def test_')
def calcIndent( self, node ): count = 0 for out_node in getOutNodes( node ): if getNodeKind( out_node ) == "suite": count += 1 return " " * count
def findSelfParam(self, node): for sub_node in gatherSubNodesD(node): if getNodeKind(sub_node) == "NAME" and sub_node.value == "self": return sub_node return None