Beispiel #1
0
def findAssociatedComment(node):
    # traverse <node> tree left-most, looking for comments
    from ecmascript.frontend import treeutil  # ugly here, but due to import cycle

    ##
    # For every <start_node> find the enclosing statement node, and from that
    # the node of the first token (as this will carry a pot. comment)
    def statement_head_from(start_node):
        # 1. find enclosing "local root" node
        # (e.g. the enclosing statement or file node)
        tnode = start_node
        stmt_node = None
        while True:  # this will always terminate, as every JS node is a child of a statement
            if tnode.isStatement():
                stmt_node = tnode
                break
            elif tnode.type == 'file':
                # TODO: (bug#6765) why does/n't it crash without this?!
                #       are file-level comments being picked up correctly?!
                stmt_node = tnode
                break
            elif tnode.parent:
                tnode = tnode.parent
            else:
                break
        # 2. determine left-most token
        #if stmt_node.isPrefixOp():
        #    head_token_node = stmt_node
        #else:
        #    head_token_node = treeutil.findLeftmostChild(stmt_node)
        head_token_node = stmt_node.toListG().next()
        return head_token_node

    # --------------------------------------------------------------------------

    res = None
    if node.comments:
        res = node
    else:
        # above current expression
        left_most = treeutil.findLeftmostChild(
            node)  # this might return <node> itself
        if left_most.comments:
            res = left_most
        else:
            # above key : value in maps
            next_root = treeutil.findAncestor(node, ["keyvalue"], radius=5)
            if next_root:
                if next_root.comments:
                    res = next_root
            else:
                # above current statement
                stmt_head = statement_head_from(node)
                if stmt_head and stmt_head.comments:
                    res = stmt_head
    return res
Beispiel #2
0
def findAssociatedComment(node):
    # traverse <node> tree left-most, looking for comments
    from ecmascript.frontend import treeutil # ugly here, but due to import cycle

    ##
    # For every <start_node> find the enclosing statement node, and from that
    # the node of the first token (as this will carry a pot. comment) 
    def statement_head_from(start_node):
        # 1. find enclosing "local root" node
        # (e.g. the enclosing statement or file node)
        tnode = start_node
        stmt_node = None
        while True:  # this will always terminate, as every JS node is a child of a statement
            if tnode.isStatement():
                stmt_node = tnode
                break
            elif tnode.type == 'file': 
                # TODO: (bug#6765) why does/n't it crash without this?!
                #       are file-level comments being picked up correctly?!
                stmt_node = tnode
                break
            elif tnode.parent: 
                tnode = tnode.parent
            else: 
                break
        # 2. determine left-most token
        #if stmt_node.isPrefixOp():
        #    head_token_node = stmt_node
        #else:
        #    head_token_node = treeutil.findLeftmostChild(stmt_node)
        head_token_node = stmt_node.toListG().next()
        return head_token_node

    # --------------------------------------------------------------------------

    res = None
    if node.comments:
        res = node
    else:
        # above current expression
        left_most = treeutil.findLeftmostChild(node) # this might return <node> itself
        if left_most.comments:
            res = left_most
        else:
            # above key : value in maps
            next_root = treeutil.findAncestor(node, ["keyvalue"], radius=5)
            if next_root:
                if next_root.comments:
                    res = next_root
            else:
                # above current statement
                stmt_head = statement_head_from(node)
                if stmt_head and stmt_head.comments:
                    res = stmt_head
    return res
Beispiel #3
0
def findAssociatedComment(node):
    # traverse <node> tree left-most, looking for comments
    from ecmascript.frontend import treeutil  # ugly here, but due to import cycle

    if node.comments:
        return node
    else:
        if node.children:
            left_most = treeutil.findLeftmostChild(node)
            return findAssociatedComment(left_most)
    return None
Beispiel #4
0
        def checkNodeContext(node):
            context = 'interesting' # every context is interesting, maybe we get more specific or reset to ''

            # don't treat label references
            if node.parent.type in ("break", "continue"):
                return ''

            # as _isInterestingReference is run on *any* var node while
            # traversing the tree intermediate occurrences var nodes like
            # in 'a.b().c[d].e' are run through it as well; but it is enough to treat
            # the longest left-most expression, so we restrict ourself to the "head" var
            # expression like 'a.b' here, and skip other occurrences (like 'c', 'd'
            # and 'e' in the example)
            #myFirst = node.getFirstChild(mandatory=False, ignoreComments=True)
            #if not treeutil.checkFirstChainChild(myFirst): # see if myFirst is the first identifier in a chain
            #    context = ''

            leftmostChild = treeutil.findLeftmostChild(node)  # works for leafs too

            # get the top-most dotaccessor of this identifier/constant
            if leftmostChild.hasParentContext("dotaccessor/*"): # operand of a dotaccessor
                localTop = leftmostChild.parent.parent.getHighestPureDotParent()
            else:
                localTop = leftmostChild 
            
            # testing for the 'a.b' in 'a.b().c[d].e'; bare 'a' in 'a' is also caught
            if localTop != node:
                context = ''

            # '/^\s*$/.test(value)' or '[].push' or '{}.toString'
            elif leftmostChild.type in ("constant", "array", "map"):
                context = ''

            ## testing for the 'a' in 'a.b().c[d].e'
            #elif not treeutil.checkFirstChainChild(treeutil.findLeftmostChild(localTop)):
            #    context = ''

            # check name in 'new ...' position
            elif ((node.hasParentContext("operation/first") and node.parent.parent.get("operator",0) == "new")
                or (node.hasParentContext("operation/first/call/operand") and
                    node.parent.parent.parent.parent.get("operator",0) == "new") # WISH: hasParentContext("operation[@operator='new']/...")
                ):
                context = 'new'

            # check name in call position
            elif (node.hasParentContext("call/operand")):
                context = 'call'

            # check name in "'extend' : ..." position
            elif (node.hasParentContext("keyvalue/*") and node.parent.parent.get('key') in ['extend']): #, 'include']):
                #print "-- found context: %s" % node.parent.parent.get('key')
                context = 'extend'

            return context
Beispiel #5
0
def findAssociatedComment(node):
    # traverse <node> tree left-most, looking for comments
    from ecmascript.frontend import treeutil # ugly here, but due to import cycle

    if node.comments:
        return node
    else:
        if node.children:
            left_most = treeutil.findLeftmostChild(node)
            return findAssociatedComment(left_most)
    return None
        def checkNodeContext(node):

            ##
            # Getting the longest left-most dotaccessor in the expression <node>
            # is in, e.g. the 'a.b' in 'a.b().c.d[0].e'.
            #
            # The idea is to only treat 'a.b' as interesting, and ignore all
            # other vars in such an expression. So the check is to see whether
            # <node> represents 'a.b'.
            #
            # To get this we 
            # (a) use the leftmostChild of <node> ("downwards")
            #     (If <node> represents 'a.b', this should be 'a', but would
            #     be 'c' if in 'c.d'). The leftmostChild is also used
            #     elsewhere, so it is passed in as a param.
            # (b) from that search upwards the tree to get the highest enclosing
            #     dotaccessor node.
            # If this is identical to <node>, <node> is interesting.
            #
            def is_leftmost_and_highest_pure_dotaccessor(node, leftmost_child):

                res = False

                # as _isInterestingReference is run on *any* var node while
                # traversing the tree intermediate occurrences var nodes like
                # in 'a.b().c[d].e' are run through it as well; but it is enough to treat
                # the longest left-most expression, so we restrict ourself to the "head" var
                # expression like 'a.b' here, and skip other occurrences (like 'c', 'd'
                # and 'e' in the example)
                #myFirst = node.getFirstChild(mandatory=False, ignoreComments=True)
                #if not treeutil.checkFirstChainChild(myFirst): # see if myFirst is the first identifier in a chain
                #    context = ''


                # get the top-most dotaccessor of this identifier/constant(?)
                ##localTop = treeutil.findVarRoot(leftmostChild)
                
                # testing for the 'a.b' in 'a.b().c[d].e'; bare 'a' in 'a' is also caught
                ##if localTop != node:
                ##    context = ''

                # ----------------------------------------------------

                # assumption: not is_right_dot_operand(node), so
                # we're on the 'left' axis of the (left-leaning) expression
                var_root = treeutil.findVarRoot(leftmost_child) # get the highest pur dotaccessor above it
                res = var_root == node

                return res

            def is_right_dot_operand(node):
                return node.parent.type == "dotaccessor" and node.parent.getChild(1) == node

            # ------------------------------------------------------------------

            context = 'interesting' # every context is interesting, maybe we get more specific or reset to ''

            # don't treat label references
            if node.parent.type in ("break", "continue"):
                context = ''

            # skip right dot operands (the 'b' in 'a.b')
            elif is_right_dot_operand(node):
                context = ''

            else:
                leftmost_child = treeutil.findLeftmostChild(node) # get left-most child

                # skip inner parts of a complex dotaccessor chain ('.c' in 'a.b().c.d[3].f')
                if not is_leftmost_and_highest_pure_dotaccessor(node, leftmost_child):
                    context = ''

                # '/^\s*$/.test(value)' or '[].push' or '{}.toString'
                elif leftmost_child.type in ("constant", "array", "map"):
                    context = ''

                # check name in 'new ...' position
                elif treeutil.isNEWoperand(node):
                    context = 'new'

                # check name in call position
                elif (node.hasParentContext("call/operand")):
                    context = 'call'

                # check name in "'extend' : ..." position
                elif (node.hasParentContext("keyvalue/*") and node.parent.parent.get('key') in ['extend']): #, 'include']):
                    #print "-- found context: %s" % node.parent.parent.get('key')
                    context = 'extend'

            return context
        def checkNodeContext(node):

            ##
            # Getting the longest left-most dotaccessor in the expression <node>
            # is in, e.g. the 'a.b' in 'a.b().c.d[0].e'.
            #
            # The idea is to only treat 'a.b' as interesting, and ignore all
            # other vars in such an expression. So the check is to see whether
            # <node> represents 'a.b'.
            #
            # To get this we
            # (a) use the leftmostChild of <node> ("downwards")
            #     (If <node> represents 'a.b', this should be 'a', but would
            #     be 'c' if in 'c.d'). The leftmostChild is also used
            #     elsewhere, so it is passed in as a param.
            # (b) from that search upwards the tree to get the highest enclosing
            #     dotaccessor node.
            # If this is identical to <node>, <node> is interesting.
            #
            def is_leftmost_and_highest_pure_dotaccessor(node, leftmost_child):

                res = False

                # as _isInterestingReference is run on *any* var node while
                # traversing the tree intermediate occurrences var nodes like
                # in 'a.b().c[d].e' are run through it as well; but it is enough to treat
                # the longest left-most expression, so we restrict ourself to the "head" var
                # expression like 'a.b' here, and skip other occurrences (like 'c', 'd'
                # and 'e' in the example)
                #myFirst = node.getFirstChild(mandatory=False, ignoreComments=True)
                #if not treeutil.checkFirstChainChild(myFirst): # see if myFirst is the first identifier in a chain
                #    context = ''

                # get the top-most dotaccessor of this identifier/constant(?)
                ##localTop = treeutil.findVarRoot(leftmostChild)

                # testing for the 'a.b' in 'a.b().c[d].e'; bare 'a' in 'a' is also caught
                ##if localTop != node:
                ##    context = ''

                # ----------------------------------------------------

                # assumption: not is_right_dot_operand(node), so
                # we're on the 'left' axis of the (left-leaning) expression
                var_root = treeutil.findVarRoot(
                    leftmost_child)  # get the highest pur dotaccessor above it
                res = var_root == node

                return res

            def is_right_dot_operand(node):
                return node.parent.type == "dotaccessor" and node.parent.getChild(
                    1) == node

            # ------------------------------------------------------------------

            context = 'interesting'  # every context is interesting, maybe we get more specific or reset to ''

            # don't treat label references
            if node.parent.type in ("break", "continue"):
                context = ''

            # skip right dot operands (the 'b' in 'a.b')
            elif is_right_dot_operand(node):
                context = ''

            else:
                leftmost_child = treeutil.findLeftmostChild(
                    node)  # get left-most child

                # skip inner parts of a complex dotaccessor chain ('.c' in 'a.b().c.d[3].f')
                if not is_leftmost_and_highest_pure_dotaccessor(
                        node, leftmost_child):
                    context = ''

                # '/^\s*$/.test(value)' or '[].push' or '{}.toString'
                elif leftmost_child.type in ("constant", "array", "map"):
                    context = ''

                # check name in 'new ...' position
                elif treeutil.isNEWoperand(node):
                    context = 'new'

                # check name in call position
                elif (node.hasParentContext("call/operand")):
                    context = 'call'

                # check name in "'extend' : ..." position
                elif (node.hasParentContext("keyvalue/*")
                      and node.parent.parent.get('key')
                      in ['extend']):  #, 'include']):
                    #print "-- found context: %s" % node.parent.parent.get('key')
                    context = 'extend'

            return context