js/src/jsapi-tests/binast/invalid/lib/filter_utils.py
author Tooru Fujisawa <arai_a@mac.com>
Tue, 05 Feb 2019 00:34:08 +0900
changeset 516095 1143fee910c70ae6ea25e325b7908f38c8cfeba6
child 517440 0934e6142eb942c5f3ba28bb426c85eb47dbd897
permissions -rw-r--r--
Bug 1524965 - Part 3: Add a script to generate testcases for BinAST with invalid content. r=Yoric Integrated binjs_convert_from_json into encode.py. encode.py now generates invalid BinAST file if --binjs_convert_from_json option is provided. Source of test files are located inside js/src/jsapi-tests/binast/invalid/tests, with .js file as a source of JSON, and .py file for filtering the JSON. The generated tests are located inside js/src/jit-test/tests/binast/invalid. filter_utils.py provides some utility functions that is used by filter script, to handle tagged tuple/list structure in the JSON encoded AST. Actual testcases are added in Part 4. Differential Revision: https://phabricator.services.mozilla.com/D18560

# Utilities to modify JSON encoded AST
#
# All functions raise exception on unexpected case, to avoid overlooking AST
# change.


def assert_tagged_tuple(obj):
    """
    Assert that the object is a tagged tuple

    :param obj (dict)
           The tagged tuple
    """
    type_ = obj['@TYPE']
    if type_ != 'tagged tuple':
        raise Exception('expected a tagged tuple, got {}'.format(type_))


def assert_list(obj):
    """
    Assert that the object is a list

    :param obj (dict)
           The list
    """
    type_ = obj['@TYPE']
    if type_ != 'list':
        raise Exception('expected a list, got {}'.format(type_))


def assert_interface(obj, expected_name):
    """
    Assert that the object is a tagged tuple for given interface

    :param obj (dict)
           The tagged tuple
    :param expected_name (string)
           The name of the interface
    """
    assert_tagged_tuple(obj)
    actual_name = obj['@INTERFACE']
    if actual_name != expected_name:
        raise Exception('expected {}, got {}'.format(expected_name, actual_name))


def get_field(obj, name):
    """
    Returns the field of the tagged tuple.

    :param obj (dict)
           The tagged tuple
    :param name (string)
           The name of the field to get
    :return (dict)
            The field value
    :raises Exception
            If there's no such field
    """
    assert_tagged_tuple(obj)
    fields = obj['@FIELDS']
    for field in fields:
        if field['@FIELD_NAME'] == name:
            return field['@FIELD_VALUE']
    raise Exception('No such field: {}'.format(name))


def replace_field(obj, name, value):
    """
    Replaces the field of the tagged tuple.

    :param obj (dict)
           the tagged tuple
    :param name (string)
           the name of the field to replace
    :param value (dict)
           the value of the field
    :raises Exception
            If there's no such field
    """
    assert_tagged_tuple(obj)
    fields = obj['@FIELDS']
    for field in fields:
        if field['@FIELD_NAME'] == name:
            field['@FIELD_VALUE'] = value
            return
    raise Exception('No such field: {}'.format(name))


def remove_field(obj, name):
    """
    Removes the field from the tagged tuple

    :param obj (dict)
           the tagged tuple
    :param name (string)
           the name of the field to remove
    :raises Exception
            If there's no such field
    """
    assert_tagged_tuple(obj)
    i = 0
    fields = obj['@FIELDS']
    for field in fields:
        if field['@FIELD_NAME'] == name:
            del fields[i]
            return
        i += 1
    raise Exception('No such field: {}'.format(name))


def get_element(obj, i):
    """
    Returns the element of the list.

    :param obj (dict)
           The list
    :param i (int)
           The indef of the element to get
    :return (dict)
            The element value
    :raises Exception
            On out of bound access
    """
    assert_list(obj)
    elements = obj['@VALUE']
    if i >= len(elements):
        raise Exception('Out of bound: {} < {}'.format(i, len(elements)))
    return elements[i]


def replace_element(obj, i, value):
    """
    Replaces the element of the list.

    :param obj (dict)
           the list
    :param i (int)
           The indef of the element to replace
    :param value (dict)
           the value of the element
    :raises Exception
            On out of bound access
    """
    assert_list(obj)
    elements = obj['@VALUE']
    if i >= len(elements):
        raise Exception('Out of bound: {} < {}'.format(i, len(elements)))
    elements[i] = value


def append_element(obj, value):
    """
    Appends the element to the list.

    :param obj (dict)
           the list
    :param value (dict)
           the value to be added to the list
    """
    assert_list(obj)
    elements = obj['@VALUE']
    elements.append(value)


def remove_element(obj, i):
    """
    Removes the element from the list

    :param obj (dict)
           the list
    :param i (int)
           The indef of the element to remove
    :raises Exception
            On out of bound access
    """
    assert_list(obj)
    elements = obj['@VALUE']
    if i >= len(elements):
        raise Exception('Out of bound: {} < {}'.format(i, len(elements)))
    del elements[i]