Beispiel #1
0
def buildSubscriptNode(provider, node, source_ref):
    # Subscript expression nodes.

    assert getKind(node.ctx) == "Load", source_ref

    # The subscribt "[]" operator is one of many different things. This is
    # expressed by this kind, there are "slice" lookups (two values, even if one
    # is using default), and then "index" lookups. The form with three argument
    # is really an "index" lookup, with a slice object. And the "..." lookup is
    # also an index loopup, with it as the argument. So this splits things into
    # two different operations, "subscript" with a single "subscript" object. Or
    # a slice lookup with a lower and higher boundary. These things should
    # behave similar, but they are different slots.
    kind = getKind(node.slice)

    if kind == "Index":
        return ExpressionSubscriptLookup(
            subscribed=buildNode(provider, node.value, source_ref),
            subscript=buildNode(provider, node.slice.value, source_ref),
            source_ref=source_ref)
    elif kind == "Slice":
        lower = buildNode(provider, node.slice.lower, source_ref, True)
        upper = buildNode(provider, node.slice.upper, source_ref, True)

        if node.slice.step is not None:
            step = buildNode(provider, node.slice.step, source_ref)

            return ExpressionSubscriptLookup(
                subscribed=buildNode(provider, node.value, source_ref),
                subscript=ExpressionSliceObject(lower=lower,
                                                upper=upper,
                                                step=step,
                                                source_ref=source_ref),
                source_ref=source_ref)
        else:
            return ExpressionSliceLookup(expression=buildNode(
                provider, node.value, source_ref),
                                         lower=lower,
                                         upper=upper,
                                         source_ref=source_ref)
    elif kind == "ExtSlice":
        return ExpressionSubscriptLookup(
            subscribed=buildNode(provider, node.value, source_ref),
            subscript=buildExtSliceNode(provider, node, source_ref),
            source_ref=source_ref)
    elif kind == "Ellipsis":
        return ExpressionSubscriptLookup(
            subscribed=buildNode(provider, node.value, source_ref),
            subscript=ExpressionConstantRef(constant=Ellipsis,
                                            source_ref=source_ref),
            source_ref=source_ref)
    else:
        assert False, kind
def buildSubscriptNode(provider, node, source_ref):
    # Subscript expression nodes, various types are dispatched here.

    assert getKind(node.ctx) == "Load", source_ref

    # The subscript "[]" operator is one of many different things. This is
    # expressed by this kind, there are "slice" lookups (two values, even if one
    # is using default), and then "index" lookups. The form with three argument
    # is really an "index" lookup, with a slice object. And the "..." lookup is
    # also an index loop-up, with it as the argument. So this splits things into
    # two different operations, "subscript" with a single "subscript" object. Or
    # a slice lookup with a lower and higher boundary. These things should
    # behave similar, but they are different slots.
    kind = getKind(node.slice)

    if kind == "Index":
        return ExpressionSubscriptLookup(
            subscribed = buildNode(provider, node.value, source_ref),
            subscript  = buildNode(provider, node.slice.value, source_ref),
            source_ref = source_ref
        )
    elif kind == "Slice":
        lower = buildNode(
            provider   = provider,
            node       = node.slice.lower,
            source_ref = source_ref,
            allow_none = True
        )
        upper = buildNode(
            provider   = provider,
            node       = node.slice.upper,
            source_ref = source_ref,
            allow_none = True
        )
        step = buildNode(
            provider   = provider,
            node       = node.slice.step,
            source_ref = source_ref,
            allow_none = True
        )


        # For Python3 there is no slicing operation, this is always done
        # with subscript using a slice object. For Python2, it is only done
        # if no "step" is provided.
        use_sliceobj = step is not None or python_version >= 300

        if use_sliceobj:
            return ExpressionSubscriptLookup(
                subscribed = buildNode(provider, node.value, source_ref),
                subscript  = ExpressionBuiltinSlice(
                    start      = lower,
                    stop       = upper,
                    step       = step,
                    source_ref = source_ref
                ),
                source_ref = source_ref
            )
        else:
            return ExpressionSliceLookup(
                expression = buildNode(provider, node.value, source_ref),
                lower      = lower,
                upper      = upper,
                source_ref = source_ref
            )
    elif kind == "ExtSlice":
        return ExpressionSubscriptLookup(
            subscribed = buildNode(provider, node.value, source_ref),
            subscript  = buildExtSliceNode(provider, node, source_ref),
            source_ref = source_ref
        )
    elif kind == "Ellipsis":
        return ExpressionSubscriptLookup(
            subscribed = buildNode(provider, node.value, source_ref),
            subscript  = ExpressionConstantEllipsisRef(
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    else:
        assert False, kind
def _buildInplaceAssignSliceNode(
    provider,
    lookup_source,
    lower,
    upper,
    tmp_variable1,
    tmp_variable2,
    tmp_variable3,
    tmp_variable4,
    operator,
    expression,
    source_ref,
):

    # Due to the 3 inputs, which we need to also put into temporary variables,
    # there are too many variables here, but they are needed.
    # pylint: disable=too-many-locals

    # First assign the target value, lower and upper to temporary variables.
    copy_to_tmp = StatementAssignmentVariable(variable=tmp_variable1,
                                              source=lookup_source,
                                              source_ref=source_ref)

    final_statements = [
        StatementReleaseVariable(variable=tmp_variable1, source_ref=source_ref)
    ]
    statements = []

    if lower is not None:
        statements.append(
            StatementAssignmentVariable(variable=tmp_variable2,
                                        source=lower,
                                        source_ref=source_ref))
        final_statements.append(
            StatementReleaseVariable(variable=tmp_variable2,
                                     source_ref=source_ref))

        lower_ref1 = ExpressionTempVariableRef(variable=tmp_variable2,
                                               source_ref=source_ref)
        lower_ref2 = ExpressionTempVariableRef(variable=tmp_variable2,
                                               source_ref=source_ref)
    else:
        assert tmp_variable2 is None

        lower_ref1 = lower_ref2 = None

    if upper is not None:
        statements.append(
            StatementAssignmentVariable(variable=tmp_variable3,
                                        source=upper,
                                        source_ref=source_ref))
        final_statements.append(
            StatementReleaseVariable(variable=tmp_variable3,
                                     source_ref=source_ref))

        upper_ref1 = ExpressionTempVariableRef(variable=tmp_variable3,
                                               source_ref=source_ref)
        upper_ref2 = ExpressionTempVariableRef(variable=tmp_variable3,
                                               source_ref=source_ref)
    else:
        assert tmp_variable3 is None

        upper_ref1 = upper_ref2 = None

    use_sliceobj = python_version >= 300

    # Second assign the in-place result over the original value.
    if use_sliceobj:
        statements += (
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=ExpressionSubscriptLookup(
                    expression=ExpressionTempVariableRef(
                        variable=tmp_variable1, source_ref=source_ref),
                    subscript=makeExpressionBuiltinSlice(
                        start=lower_ref2,
                        stop=upper_ref2,
                        step=None,
                        source_ref=source_ref,
                    ),
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=makeExpressionOperationBinaryInplace(
                    operator=operator,
                    left=ExpressionTempVariableRef(variable=tmp_variable4,
                                                   source_ref=source_ref),
                    right=expression,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentSubscript(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                subscript=makeExpressionBuiltinSlice(start=lower_ref1,
                                                     stop=upper_ref1,
                                                     step=None,
                                                     source_ref=source_ref),
                source=ExpressionTempVariableRef(variable=tmp_variable4,
                                                 source_ref=source_ref),
                source_ref=source_ref,
            ),
        )
    else:
        statements += (
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=ExpressionSliceLookup(
                    expression=ExpressionTempVariableRef(
                        variable=tmp_variable1, source_ref=source_ref),
                    lower=lower_ref2,
                    upper=upper_ref2,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentVariable(
                variable=tmp_variable4,
                source=makeExpressionOperationBinaryInplace(
                    operator=operator,
                    left=ExpressionTempVariableRef(variable=tmp_variable4,
                                                   source_ref=source_ref),
                    right=expression,
                    source_ref=source_ref,
                ),
                source_ref=source_ref,
            ),
            StatementAssignmentSlice(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                lower=lower_ref1,
                upper=upper_ref1,
                source=ExpressionTempVariableRef(variable=tmp_variable4,
                                                 source_ref=source_ref),
                source_ref=source_ref,
            ),
        )

    final_statements.append(
        StatementReleaseVariable(variable=tmp_variable4,
                                 source_ref=source_ref))

    return (
        copy_to_tmp,
        makeTryFinallyStatement(
            provider=provider,
            tried=statements,
            final=final_statements,
            source_ref=source_ref,
        ),
    )
def _buildInplaceAssignSliceNode(provider, lookup_source, lower, upper,
                                 tmp_variable1, tmp_variable2, tmp_variable3,
                                 operator, expression, source_ref):

    # First assign the target value, lower and upper to temporary variables.
    copy_to_tmp = StatementAssignmentVariable(
        variable_ref = ExpressionTargetTempVariableRef(
            variable   = tmp_variable1.makeReference(provider),
            source_ref = source_ref
        ),
        source       = lookup_source,
        source_ref   = source_ref
    )

    final_statements = [
        StatementDelVariable(
            variable_ref = ExpressionTargetTempVariableRef(
                variable   = tmp_variable1.makeReference(provider),
                source_ref = source_ref
            ),
            tolerant     = False,
            source_ref   = source_ref
        )
    ]
    statements = []

    if lower is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_variable2.makeReference(provider),
                    source_ref = source_ref
                ),
                source       = lower,
                source_ref   = source_ref
            )
        )
        final_statements.append(
            StatementDelVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_variable2.makeReference(provider),
                    source_ref = source_ref
                ),
                tolerant     = True,
                source_ref   = source_ref
            )
        )

        lower_ref1 = ExpressionTempVariableRef(
            variable   = tmp_variable2.makeReference(provider),
            source_ref = source_ref
        )
        lower_ref2 = ExpressionTempVariableRef(
            variable   = tmp_variable2.makeReference(provider),
            source_ref = source_ref
        )
    else:
        assert tmp_variable2 is None

        lower_ref1 = lower_ref2 = None

    if upper is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_variable3.makeReference( provider ),
                    source_ref = source_ref
                ),
                source     = upper,
                source_ref = source_ref
            )
        )
        final_statements.append(
            StatementDelVariable(
                variable_ref = ExpressionTargetTempVariableRef(
                    variable   = tmp_variable3.makeReference(provider),
                    source_ref = source_ref
                ),
                tolerant     = True,
                source_ref   = source_ref
            )
        )

        upper_ref1 = ExpressionTempVariableRef(
            variable   = tmp_variable3.makeReference( provider ),
            source_ref = source_ref
        )
        upper_ref2 = ExpressionTempVariableRef(
            variable   = tmp_variable3.makeReference(provider),
            source_ref = source_ref
        )
    else:
        assert tmp_variable3 is None

        upper_ref1 = upper_ref2 = None

    # Second assign the inplace result over the original value.
    statements.append(
        StatementAssignmentSlice(
            expression = ExpressionTempVariableRef(
                variable   = tmp_variable1.makeReference(provider),
                source_ref = source_ref
            ),
            lower      = lower_ref1,
            upper      = upper_ref1,
            source     = ExpressionOperationBinaryInplace(
                operator   = operator,
                left       = ExpressionSliceLookup(
                    expression = ExpressionTempVariableRef(
                        variable   = tmp_variable1.makeReference(provider),
                        source_ref = source_ref
                    ),
                    lower      = lower_ref2,
                    upper      = upper_ref2,
                    source_ref = source_ref
                ),
                right      = expression,
                source_ref = source_ref
            ),
            source_ref = source_ref
        )
    )

    return (
        copy_to_tmp,
        makeTryFinallyStatement(
            tried      = statements,
            final      = final_statements,
            source_ref = source_ref
        )
    )
def _buildInplaceAssignSliceNode(lookup_source, lower, upper, tmp_variable1,
                                 tmp_variable2, tmp_variable3, operator,
                                 expression, source_ref):

    # Due to the 3 inputs, which we need to also put into temporary variables,
    # there are too many variables here, but they are needed.
    # pylint: disable=R0914

    # First assign the target value, lower and upper to temporary variables.
    copy_to_tmp = StatementAssignmentVariable(
        variable_ref=ExpressionTargetTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
        source=lookup_source,
        source_ref=source_ref)

    final_statements = [
        StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
            variable=tmp_variable1, source_ref=source_ref),
                             tolerant=False,
                             source_ref=source_ref)
    ]
    statements = []

    if lower is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_variable2, source_ref=source_ref),
                source=lower,
                source_ref=source_ref))
        final_statements.append(
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_variable2, source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref))

        lower_ref1 = ExpressionTempVariableRef(variable=tmp_variable2,
                                               source_ref=source_ref)
        lower_ref2 = ExpressionTempVariableRef(variable=tmp_variable2,
                                               source_ref=source_ref)
    else:
        assert tmp_variable2 is None

        lower_ref1 = lower_ref2 = None

    if upper is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_variable3, source_ref=source_ref),
                source=upper,
                source_ref=source_ref))
        final_statements.append(
            StatementDelVariable(variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_variable3, source_ref=source_ref),
                                 tolerant=True,
                                 source_ref=source_ref))

        upper_ref1 = ExpressionTempVariableRef(variable=tmp_variable3,
                                               source_ref=source_ref)
        upper_ref2 = ExpressionTempVariableRef(variable=tmp_variable3,
                                               source_ref=source_ref)
    else:
        assert tmp_variable3 is None

        upper_ref1 = upper_ref2 = None

    use_sliceobj = Utils.python_version >= 300

    # Second assign the in-place result over the original value.
    if use_sliceobj:
        statements.append(
            StatementAssignmentSubscript(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                subscript=ExpressionSliceObject(lower=lower_ref1,
                                                upper=upper_ref1,
                                                step=None,
                                                source_ref=source_ref),
                source=ExpressionOperationBinaryInplace(
                    operator=operator,
                    left=ExpressionSubscriptLookup(
                        subscribed=ExpressionTempVariableRef(
                            variable=tmp_variable1, source_ref=source_ref),
                        subscript=ExpressionSliceObject(lower=lower_ref2,
                                                        upper=upper_ref2,
                                                        step=None,
                                                        source_ref=source_ref),
                        source_ref=source_ref),
                    right=expression,
                    source_ref=source_ref),
                source_ref=source_ref))
    else:
        statements.append(
            StatementAssignmentSlice(
                expression=ExpressionTempVariableRef(variable=tmp_variable1,
                                                     source_ref=source_ref),
                lower=lower_ref1,
                upper=upper_ref1,
                source=ExpressionOperationBinaryInplace(
                    operator=operator,
                    left=ExpressionSliceLookup(
                        expression=ExpressionTempVariableRef(
                            variable=tmp_variable1, source_ref=source_ref),
                        lower=lower_ref2,
                        upper=upper_ref2,
                        source_ref=source_ref),
                    right=expression,
                    source_ref=source_ref),
                source_ref=source_ref))

    return (copy_to_tmp,
            makeTryFinallyStatement(tried=statements,
                                    final=final_statements,
                                    source_ref=source_ref))
def _buildInplaceAssignSliceNode(result, lookup_source, lower, upper,
                                 tmp_variable1, tmp_variable2, tmp_variable3,
                                 operator, expression, source_ref):

    # First assign the target value, lower and upper to temporary variables.
    statements = [
        StatementAssignmentVariable(
            variable_ref=ExpressionTargetTempVariableRef(
                variable=tmp_variable1.makeReference(result),
                source_ref=source_ref),
            source=lookup_source,
            source_ref=source_ref)
    ]

    if lower is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_variable2.makeReference(result),
                    source_ref=source_ref),
                source=lower,
                source_ref=source_ref))

        lower_ref1 = ExpressionTempVariableRef(
            variable=tmp_variable2.makeReference(result),
            source_ref=source_ref)
        lower_ref2 = ExpressionTempVariableRef(
            variable=tmp_variable2.makeReference(result),
            source_ref=source_ref)
    else:
        assert tmp_variable2 is None

        lower_ref1 = lower_ref2 = None

    if upper is not None:
        statements.append(
            StatementAssignmentVariable(
                variable_ref=ExpressionTargetTempVariableRef(
                    variable=tmp_variable3.makeReference(result),
                    source_ref=source_ref),
                source=upper,
                source_ref=source_ref))

        upper_ref1 = ExpressionTempVariableRef(
            variable=tmp_variable3.makeReference(result),
            source_ref=source_ref)
        upper_ref2 = ExpressionTempVariableRef(
            variable=tmp_variable3.makeReference(result),
            source_ref=source_ref)
    else:
        assert tmp_variable3 is None

        upper_ref1 = upper_ref2 = None

    # Second assign the inplace result over the original value.
    statements.append(
        StatementAssignmentSlice(
            expression=ExpressionTempVariableRef(
                variable=tmp_variable1.makeReference(result),
                source_ref=source_ref),
            lower=lower_ref1,
            upper=upper_ref1,
            source=ExpressionOperationBinaryInplace(
                operator=operator,
                left=ExpressionSliceLookup(
                    expression=ExpressionTempVariableRef(
                        variable=tmp_variable1.makeReference(result),
                        source_ref=source_ref),
                    lower=lower_ref2,
                    upper=upper_ref2,
                    source_ref=source_ref),
                right=expression,
                source_ref=source_ref),
            source_ref=source_ref))

    return statements