def call_Select(self, node: ast.Call, args: List[ast.AST]):
        r'''
        Transformation #1:
        seq.Select(x: f(x)).Select(y: g(y))
        => Select(Select(seq, x: f(x)), y: g(y))
        is turned into
        seq.Select(x: g(f(x)))
        => Select(seq, x: g(f(x)))

        Transformation #2:
        seq.SelectMany(x: f(x)).Select(y: g(y))
        => Select(SelectMany(seq, x: f(x)), y: g(y))
        is turned into
        seq.SelectMany(x: f(x).Select(y: g(y)))
        => SelectMany(seq, x: Select(f(x), y: g(y)))

        Transformation #3:
        seq.Where(x: f(x)).Select(y: g(y))
        => Select(Where(seq, x: f(x), y: g(y))
        is not altered.
        '''
        source = args[0]
        transform = args[1]
        assert isinstance(transform, ast.Lambda)

        parent_select = self.visit(source)
        if is_call_of(parent_select, 'Select'):
            return self.visit_Select_of_Select(parent_select, transform)
        elif is_call_of(parent_select, 'SelectMany'):
            return self.visit_Select_of_SelectMany(parent_select, transform)
        else:
            selection = self.visit(transform)
            return make_Select(parent_select, selection)
    def call_SelectMany(self, node: ast.Call, args: List[ast.AST]):
        r'''
        Transformation #1:
        seq.SelectMany(x: f(x)).SelectMany(y: f(y))
        => SelectMany(SelectMany(seq, x: f(x)), y: f(y))
        is turned into:
        seq.SelectMany(x: f(x).SelectMany(y: f(y)))
        => SelectMany(seq, x: SelectMany(f(x), y: f(y)))

        Transformation #2:
        seq.Select(x: f(x)).SelectMany(y: g(y))
        => SelectMany(Select(seq, x: f(x)), y:g(y))
        is turned into
        seq.SelectMany(x: g(f(x)))
        => SelectMany(seq, x: g(f(x)))

        Transformation #3:
        seq.Where(x: f(x)).SelectMany(y: g(y))
        '''
        selection = args[1]
        assert isinstance(selection, ast.Lambda)
        parent_select = self.visit(args[0])
        if is_call_of(parent_select, 'SelectMany'):
            return self.visit_SelectMany_of_SelectMany(parent_select,
                                                       selection)
        elif is_call_of(parent_select, 'Select'):
            return self.visit_SelectMany_of_Select(parent_select, selection)
        else:
            return function_call(
                'SelectMany',
                [parent_select, self.visit(selection)])
Ejemplo n.º 3
0
def _is_method_call_on_first(node: ast.Call):
    """
    Determine if this is a call like First(seq).method(args).
    """
    if not isinstance(node.func, ast.Attribute):
        return False

    if not is_call_of(node.func.value, "First"):
        return False

    return True
    def call_Where(self, node: ast.Call, args: List[ast.AST]) -> ast.AST:
        r'''
        Transformation #1:
        seq.Where(x: f(x)).Where(x: g(x))
        => Where(Where(seq, x: f(x)), y: g(y))
        is turned into
        seq.Where(x: f(x) and g(y))
        => Where(seq, x: f(x) and g(y))

        Transformation #2:
        seq.Select(x: f(x)).Where(y: g(y))
        => Where(Select(seq, x: f(x)), y: g(y))
        Is turned into:
        seq.Where(x: g(f(x))).Select(x: f(x))
        => Select(Where(seq, x: g(f(x)), f(x))

        Transformation #3:
        seq.SelectMany(x: f(x)).Where(y: g(y))
        => Where(SelectMany(seq, x: f(x)), y: g(y))
        Is turned into:
        seq.SelectMany(x: f(x).Where(y: g(y)))
        => SelectMany(seq, x: Where(f(x), g(y)))
        '''
        source = args[0]
        filter = args[1]
        assert isinstance(filter, ast.Lambda)

        parent_where = self.visit(source)
        if is_call_of(parent_where, 'Where'):
            return self.visit_Where_of_Where(parent_where, filter)
        elif is_call_of(parent_where, 'Select'):
            return self.visit_Where_of_Select(parent_where, filter)
        elif is_call_of(parent_where, 'SelectMany'):
            return self.visit_Where_of_SelectMany(parent_where, filter)
        else:
            f = self.visit(filter)
            if lambda_is_true(f):
                return parent_where
            else:
                return function_call('Where', [parent_where, f])
Ejemplo n.º 5
0
    def visit_Attribute(self, node):
        """
        If this is a reference against a dict, then we can de-ref it if there is a key.
        Otherwise, we need to make sure to make a new version of the Attribute so it does
        not get reused'
        """
        if is_call_of(node.value, "First"):
            return self.visit_Attribute_Of_First(node.value.args[0],
                                                 node.attr)  # type: ignore

        visited_value = self.visit(node.value)
        if isinstance(visited_value, ast.Dict):
            return self.visit_Subscript_Dict_with_value(
                visited_value, node.attr)

        return ast.Attribute(value=visited_value,
                             attr=node.attr,
                             ctx=ast.Load())
    def visit_Subscript(self, node):
        r'''
        Simple Reduction
        (t1, t2, t3...)[1] => t2

        Move [] past a First()
        seq.First()[0] => seq.Select(j: j[0]).First()
        '''
        v = self.visit(node.value)
        s = self.visit(node.slice)
        if type(v) is ast.Tuple:
            return self.visit_Subscript_Tuple(v, s)
        if type(v) is ast.List:
            return self.visit_Subscript_List(v, s)

        if is_call_of(v, 'First'):
            return self.visit_Subscript_Of_First(v.args[0], s)

        # Nothing interesting, so do the normal thing several levels down.
        return ast.Subscript(v, s, ast.Load())
Ejemplo n.º 7
0
def test_is_call_not_a_call():
    start = _parse_ast("dude1")
    assert not is_call_of(start, "dude1")
Ejemplo n.º 8
0
def test_is_call_to_expected_method():
    start = _parse_ast("a.dude(10)")
    assert not is_call_of(start, "dude")
Ejemplo n.º 9
0
def test_is_call_to_unexpected_function():
    start = _parse_ast("dude(10)")
    assert not is_call_of(start, "dude1")
Ejemplo n.º 10
0
def test_is_call_to_expected_function():
    start = _parse_ast('dude(10)')
    assert is_call_of(start, 'dude')
Ejemplo n.º 11
0
def test_is_call_not_a_call():
    start = _parse_ast('dude1')
    assert not is_call_of(start, 'dude1')
Ejemplo n.º 12
0
def test_is_call_to_expected_method():
    start = _parse_ast('a.dude(10)')
    assert not is_call_of(start, 'dude')