DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (5b81998bb7ab)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
import WebIDL

def WebIDLTest(parser, harness):
    parser.parse("""
        interface TestNullableEquivalency1 {
          attribute long  a;
          attribute long? b;
        };

        interface TestNullableEquivalency2 {
          attribute ArrayBuffer  a;
          attribute ArrayBuffer? b;
        };

        /* Can't have dictionary-valued attributes, so can't test that here */

        enum TestNullableEquivalency4Enum {
          "Foo",
          "Bar"
        };

        interface TestNullableEquivalency4 {
          attribute TestNullableEquivalency4Enum  a;
          attribute TestNullableEquivalency4Enum? b;
        };

        interface TestNullableEquivalency5 {
          attribute TestNullableEquivalency4  a;
          attribute TestNullableEquivalency4? b;
        };

        interface TestNullableEquivalency6 {
          attribute boolean  a;
          attribute boolean? b;
        };

        interface TestNullableEquivalency7 {
          attribute DOMString  a;
          attribute DOMString? b;
        };

        interface TestNullableEquivalency8 {
          attribute float  a;
          attribute float? b;
        };

        interface TestNullableEquivalency9 {
          attribute double  a;
          attribute double? b;
        };

        interface TestNullableEquivalency10 {
          attribute object  a;
          attribute object? b;
        };

        interface TestNullableEquivalency11 {
          attribute double[]  a;
          attribute double[]? b;
        };

        interface TestNullableEquivalency12 {
          attribute TestNullableEquivalency9[]  a;
          attribute TestNullableEquivalency9[]? b;
        };
    """)

    for decl in parser.finish():
        if decl.isInterface():
            checkEquivalent(decl, harness)

def checkEquivalent(iface, harness):
    type1 = iface.members[0].type
    type2 = iface.members[1].type

    harness.check(type1.nullable(), False, 'attr1 should not be nullable')
    harness.check(type2.nullable(), True, 'attr2 should be nullable')

    # We don't know about type1, but type2, the nullable type, definitely
    # shouldn't be builtin.
    harness.check(type2.builtin, False, 'attr2 should not be builtin')

    # Ensure that all attributes of type2 match those in type1, except for:
    #  - names on an ignore list,
    #  - names beginning with '_',
    #  - functions which throw when called with no args, and
    #  - class-level non-callables ("static variables").
    #
    # Yes, this is an ugly, fragile hack.  But it finds bugs...
    for attr in dir(type1):
        if attr.startswith('_') or \
           attr in ['nullable', 'builtin', 'filename', 'location',
                    'inner', 'QName', 'getDeps'] or \
           (hasattr(type(type1), attr) and not callable(getattr(type1, attr))):
            continue

        a1 = getattr(type1, attr)

        if callable(a1):
            try:
                v1 = a1()
            except:
                # Can't call a1 with no args, so skip this attriute.
                continue

            try:
                a2 = getattr(type2, attr)
            except:
                harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
                continue

            if not callable(a2):
                harness.ok(False, "%s attribute on type %s in %s wasn't callable" % (attr, type2, iface))
                continue

            v2 = a2()
            harness.check(v2, v1, '%s method return value' % attr)
        else:
            try:
                a2 = getattr(type2, attr)
            except:
                harness.ok(False, 'Missing %s attribute on type %s in %s' % (attr, type2, iface))
                continue

            harness.check(a2, a1, '%s attribute should match' % attr)