From 449d9bef501681285a555113ec9cb54b36037baa Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 30 Jul 2013 10:39:35 -0700 Subject: [PATCH] Bug 895728 part 4. Fix unions to work with the new boolean/numeric/string setup. r=khuey --- dom/bindings/Codegen.py | 51 +++++++++++++++++++------ dom/bindings/test/TestCodeGen.webidl | 9 +++++ dom/bindings/test/TestExampleGen.webidl | 9 +++++ dom/bindings/test/TestJSImplGen.webidl | 9 +++++ 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index cf1842aee347..d0e3020874e8 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -2911,18 +2911,44 @@ for (uint32_t i = 0; i < length; ++i) { else: templateBody = CGGeneric() - otherMemberTypes = filter(lambda t: t.isString() or t.isEnum(), - memberTypes) - otherMemberTypes.extend(t for t in memberTypes if t.isPrimitive()) - if len(otherMemberTypes) > 0: - assert len(otherMemberTypes) == 1 - memberType = otherMemberTypes[0] - if memberType.isEnum(): - name = memberType.inner.identifier.name + stringTypes = [t for t in memberTypes if t.isString() or t.isEnum()] + numericTypes = [t for t in memberTypes if t.isNumeric()] + booleanTypes = [t for t in memberTypes if t.isBoolean()] + if stringTypes or numericTypes or booleanTypes: + assert len(stringTypes) <= 1 + assert len(numericTypes) <= 1 + assert len(booleanTypes) <= 1 + # We will wrap all this stuff in a do { } while (0); so we + # can use "break" for flow control. + def getStringOrPrimitiveConversion(memberType): + if memberType.isEnum(): + name = memberType.inner.identifier.name + else: + name = memberType.name + return CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${mutableVal}, tryNext)) || !tryNext;\n" + "break;" % (unionArgumentObj, name)) + other = CGList([], "\n") + stringConversion = map(getStringOrPrimitiveConversion, stringTypes) + numericConversion = map(getStringOrPrimitiveConversion, numericTypes) + booleanConversion = map(getStringOrPrimitiveConversion, booleanTypes) + if stringConversion: + if booleanConversion: + other.append(CGIfWrapper(booleanConversion[0], + "${val}.isBoolean()")) + if numericConversion: + other.append(CGIfWrapper(numericConversion[0], + "${val}.isNumber()")) + other.append(stringConversion[0]) + elif numericConversion: + if booleanConversion: + other.append(CGIfWrapper(booleanConversion[0], + "${val}.isBoolean()")) + other.append(numericConversion[0]) else: - name = memberType.name - other = CGGeneric("done = (failed = !%s.TrySetTo%s(cx, ${val}, ${mutableVal}, tryNext)) || !tryNext;" % (unionArgumentObj, name)) - names.append(name) + assert booleanConversion + other.append(booleanConversion[0]) + + other = CGWrapper(CGIndenter(other), pre="do {\n", post="\n} while (0);") if hasObjectTypes: other = CGWrapper(CGIndenter(other), "{\n", post="\n}") if object: @@ -2931,6 +2957,9 @@ for (uint32_t i = 0; i < length; ++i) { other = CGWrapper(other, pre="if (!done) ") join = "\n" templateBody = CGList([templateBody, other], join) + else: + assert templateBody.define() == "" + templateBody = other else: other = None diff --git a/dom/bindings/test/TestCodeGen.webidl b/dom/bindings/test/TestCodeGen.webidl index 3657516a0e53..d548e44d30c9 100644 --- a/dom/bindings/test/TestCodeGen.webidl +++ b/dom/bindings/test/TestCodeGen.webidl @@ -435,6 +435,15 @@ interface TestInterface { // Union types void passUnion((object or long) arg); + // Commented out tests 2-9 to avoid creating all those unused union types + /* void passUnion2((long or boolean) arg); + void passUnion3((object or long or boolean) arg); + void passUnion4((Node or long or boolean) arg); + void passUnion5((object or boolean) arg); + void passUnion6((object or DOMString) arg); + void passUnion7((object or DOMString or long) arg); + void passUnion8((object or DOMString or boolean) arg); + void passUnion9((object or DOMString or long or boolean) arg); */ void passUnionWithNullable((object? or long) arg); void passNullableUnion((object or long)? arg); void passOptionalUnion(optional (object or long) arg); diff --git a/dom/bindings/test/TestExampleGen.webidl b/dom/bindings/test/TestExampleGen.webidl index c7bf2d2fb598..4b1038395ff7 100644 --- a/dom/bindings/test/TestExampleGen.webidl +++ b/dom/bindings/test/TestExampleGen.webidl @@ -331,6 +331,15 @@ interface TestExampleInterface { // Union types void passUnion((object or long) arg); + // Commented out tests 2-9 to avoid creating all those unused union types + /* void passUnion2((long or boolean) arg); + void passUnion3((object or long or boolean) arg); + void passUnion4((Node or long or boolean) arg); + void passUnion5((object or boolean) arg); + void passUnion6((object or DOMString) arg); + void passUnion7((object or DOMString or long) arg); + void passUnion8((object or DOMString or boolean) arg); + void passUnion9((object or DOMString or long or boolean) arg); */ void passUnionWithNullable((object? or long) arg); void passNullableUnion((object or long)? arg); void passOptionalUnion(optional (object or long) arg); diff --git a/dom/bindings/test/TestJSImplGen.webidl b/dom/bindings/test/TestJSImplGen.webidl index 1ac87e34f7b3..53c028053c5d 100644 --- a/dom/bindings/test/TestJSImplGen.webidl +++ b/dom/bindings/test/TestJSImplGen.webidl @@ -353,6 +353,15 @@ interface TestJSImplInterface { // Union types void passUnion((object or long) arg); + // Commented out tests 2-9 to avoid creating all those unused union types + /* void passUnion2((long or boolean) arg); + void passUnion3((object or long or boolean) arg); + void passUnion4((Node or long or boolean) arg); + void passUnion5((object or boolean) arg); + void passUnion6((object or DOMString) arg); + void passUnion7((object or DOMString or long) arg); + void passUnion8((object or DOMString or boolean) arg); + void passUnion9((object or DOMString or long or boolean) arg); */ void passUnionWithNullable((object? or long) arg); // FIXME: Bug 863948 Nullable unions not supported yet // void passNullableUnion((object or long)? arg);