Bug 1026080 part 2. Add binding codegen support for [] as a default value for sequence arguments and dictionary entries. r=khuey
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 23 Jun 2014 16:03:57 -0400
changeset 190311 015ae88823dd3cf29cb59ad201768999b0dadd3e
parent 190310 c793617a1d88448c7855ff81aafbaaa81a127f8e
child 190312 4b2ade04c59ba35cbe91dca571606697c5fe08cd
push id27004
push useremorley@mozilla.com
push dateTue, 24 Jun 2014 15:52:34 +0000
treeherdermozilla-central@7b174d47f3cc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs1026080
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1026080 part 2. Add binding codegen support for [] as a default value for sequence arguments and dictionary entries. r=khuey
dom/bindings/Codegen.py
dom/bindings/test/TestBindingHeader.h
dom/bindings/test/TestCodeGen.webidl
dom/bindings/test/TestExampleGen.webidl
dom/bindings/test/TestJSImplGen.webidl
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -5,17 +5,17 @@
 # Common codegen classes.
 
 import os
 import re
 import string
 import math
 import textwrap
 
-from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLUndefinedValue
+from WebIDL import BuiltinTypes, IDLBuiltinType, IDLNullValue, IDLSequenceType, IDLType, IDLAttribute, IDLUndefinedValue, IDLEmptySequenceValue
 from Configuration import NoSuchDescriptorError, getTypesFromDescriptor, getTypesFromDictionary, getTypesFromCallback, Descriptor
 
 AUTOGENERATED_WARNING_COMMENT = \
     "/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
 ADDPROPERTY_HOOK_NAME = '_addProperty'
 FINALIZE_HOOK_NAME = '_finalize'
 CONSTRUCT_HOOK_NAME = '_constructor'
 LEGACYCALLER_HOOK_NAME = '_legacycaller'
@@ -3574,24 +3574,16 @@ def getJSToNativeConversionInfo(type, de
             return template
         return (
             "if (${haveValue}) {\n" +
             indent(template) +
             "} else {\n" +
             indent(setDefault) +
             "}\n")
 
-    # A helper function for handling null default values.  Much like
-    # handleDefault, but checks that the default value, if it exists, is null.
-    def handleDefaultNull(template, codeToSetNull):
-        if (defaultValue is not None and
-            not isinstance(defaultValue, IDLNullValue)):
-            raise TypeError("Can't handle non-null default value here")
-        return handleDefault(template, codeToSetNull)
-
     # A helper function for wrapping up the template body for
     # possibly-nullable objecty stuff
     def wrapObjectTemplate(templateBody, type, codeToSetNull, failureCode=None):
         if isNullOrUndefined and type.nullable():
             # Just ignore templateBody and set ourselves to null.
             # Note that we don't have to worry about default values
             # here either, since we already examined this value.
             return codeToSetNull
@@ -3618,18 +3610,22 @@ def getJSToNativeConversionInfo(type, de
                   $*{failureBody}
                 }
                 """,
                 templateBody=templateBody,
                 elifLine=elifLine,
                 elifBody=elifBody,
                 failureBody=onFailureNotAnObject(failureCode).define())
 
-            if type.nullable():
-                templateBody = handleDefaultNull(templateBody, codeToSetNull)
+            if isinstance(defaultValue, IDLNullValue):
+                assert type.nullable() # Parser should enforce this
+                templateBody = handleDefault(templateBody, codeToSetNull)
+            elif isinstance(defaultValue, IDLEmptySequenceValue):
+                # Our caller will handle it
+                pass
             else:
                 assert defaultValue is None
 
         return templateBody
 
     # A helper function for converting things that look like a JSObject*.
     def handleJSObjectType(type, isMember, failureCode):
         if not isMember:
@@ -3758,16 +3754,23 @@ def getJSToNativeConversionInfo(type, de
             notSequence=notSequence,
             sequenceType=sequenceType,
             arrayRef=arrayRef,
             elementType=elementInfo.declType.define(),
             elementConversion=elementConversion)
 
         templateBody = wrapObjectTemplate(templateBody, type,
                                           "${declName}.SetNull();\n", notSequence)
+        if isinstance(defaultValue, IDLEmptySequenceValue):
+            if type.nullable():
+                codeToSetEmpty = "${declName}.SetValue();\n"
+            else:
+                codeToSetEmpty = "/* Array is already empty; nothing to do */\n"
+            templateBody = handleDefault(templateBody, codeToSetEmpty)
+
         # Sequence arguments that might contain traceable things need
         # to get traced
         if not isMember and typeNeedsRooting(elementType):
             holderType = CGTemplatedType("SequenceRooter", elementInfo.declType)
             # If our sequence is nullable, this will set the Nullable to be
             # not-null, but that's ok because we make an explicit SetNull() call
             # on it as needed if our JS value is actually null.
             holderArgs = "cx, &%s" % arrayRef
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -374,18 +374,20 @@ public:
   void ReceiveWeakNullableCastableObjectSequence(nsTArray<TestInterface*> &);
   void ReceiveWeakCastableObjectNullableSequence(Nullable< nsTArray<TestInterface*> >&);
   void ReceiveWeakNullableCastableObjectNullableSequence(Nullable< nsTArray<TestInterface*> >&);
   void PassCastableObjectSequence(const Sequence< OwningNonNull<TestInterface> >&);
   void PassNullableCastableObjectSequence(const Sequence< nsRefPtr<TestInterface> > &);
   void PassCastableObjectNullableSequence(const Nullable< Sequence< OwningNonNull<TestInterface> > >&);
   void PassNullableCastableObjectNullableSequence(const Nullable< Sequence< nsRefPtr<TestInterface> > >&);
   void PassOptionalSequence(const Optional<Sequence<int32_t> >&);
+  void PassOptionalSequenceWithDefaultValue(const Sequence<int32_t> &);
   void PassOptionalNullableSequence(const Optional<Nullable<Sequence<int32_t> > >&);
   void PassOptionalNullableSequenceWithDefaultValue(const Nullable< Sequence<int32_t> >&);
+  void PassOptionalNullableSequenceWithDefaultValue2(const Nullable< Sequence<int32_t> >&);
   void PassOptionalObjectSequence(const Optional<Sequence<OwningNonNull<TestInterface> > >&);
   void PassExternalInterfaceSequence(const Sequence<nsRefPtr<TestExternalInterface> >&);
   void PassNullableExternalInterfaceSequence(const Sequence<nsRefPtr<TestExternalInterface> >&);
 
   void ReceiveStringSequence(nsTArray<nsString>&);
   void PassStringSequence(const Sequence<nsString>&);
 
   void ReceiveByteStringSequence(nsTArray<nsCString>&);
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -335,18 +335,20 @@ interface TestInterface {
   sequence<TestInterface?> receiveWeakNullableCastableObjectSequence();
   sequence<TestInterface>? receiveWeakCastableObjectNullableSequence();
   sequence<TestInterface?>? receiveWeakNullableCastableObjectNullableSequence();
   void passCastableObjectSequence(sequence<TestInterface> arg);
   void passNullableCastableObjectSequence(sequence<TestInterface?> arg);
   void passCastableObjectNullableSequence(sequence<TestInterface>? arg);
   void passNullableCastableObjectNullableSequence(sequence<TestInterface?>? arg);
   void passOptionalSequence(optional sequence<long> arg);
+  void passOptionalSequenceWithDefaultValue(optional sequence<long> arg = []);
   void passOptionalNullableSequence(optional sequence<long>? arg);
   void passOptionalNullableSequenceWithDefaultValue(optional sequence<long>? arg = null);
+  void passOptionalNullableSequenceWithDefaultValue2(optional sequence<long>? arg = []);
   void passOptionalObjectSequence(optional sequence<TestInterface> arg);
   void passExternalInterfaceSequence(sequence<TestExternalInterface> arg);
   void passNullableExternalInterfaceSequence(sequence<TestExternalInterface?> arg);
 
   sequence<DOMString> receiveStringSequence();
   void passStringSequence(sequence<DOMString> arg);
 
   sequence<ByteString> receiveByteStringSequence();
@@ -877,16 +879,22 @@ dictionary Dict : ParentDict {
   (EventInit or long) eventInitOrLongWithDefaultValue3 = 5;
   (CustomEventInit or long) eventInitOrLongWithDefaultValue4 = 5;
 #endif
 
   ArrayBuffer arrayBuffer;
   ArrayBuffer? nullableArrayBuffer;
   Uint8Array uint8Array;
   Float64Array? float64Array = null;
+
+  sequence<long> seq1;
+  sequence<long> seq2 = [];
+  sequence<long>? seq3;
+  sequence<long>? seq4 = null;
+  sequence<long>? seq5 = [];
 };
 
 dictionary ParentDict : GrandparentDict {
   long c = 5;
   TestInterface someInterface;
   TestInterface? someNullableInterface = null;
   TestExternalInterface someExternalInterface;
   any parentAny;
--- a/dom/bindings/test/TestExampleGen.webidl
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -226,18 +226,20 @@ interface TestExampleInterface {
   sequence<TestInterface?> receiveWeakNullableCastableObjectSequence();
   sequence<TestInterface>? receiveWeakCastableObjectNullableSequence();
   sequence<TestInterface?>? receiveWeakNullableCastableObjectNullableSequence();
   void passCastableObjectSequence(sequence<TestInterface> arg);
   void passNullableCastableObjectSequence(sequence<TestInterface?> arg);
   void passCastableObjectNullableSequence(sequence<TestInterface>? arg);
   void passNullableCastableObjectNullableSequence(sequence<TestInterface?>? arg);
   void passOptionalSequence(optional sequence<long> arg);
+  void passOptionalSequenceWithDefaultValue(optional sequence<long> arg = []);
   void passOptionalNullableSequence(optional sequence<long>? arg);
   void passOptionalNullableSequenceWithDefaultValue(optional sequence<long>? arg = null);
+  void passOptionalNullableSequenceWithDefaultValue2(optional sequence<long>? arg = []);
   void passOptionalObjectSequence(optional sequence<TestInterface> arg);
   void passExternalInterfaceSequence(sequence<TestExternalInterface> arg);
   void passNullableExternalInterfaceSequence(sequence<TestExternalInterface?> arg);
 
   sequence<DOMString> receiveStringSequence();
   void passStringSequence(sequence<DOMString> arg);
 
   sequence<ByteString> receiveByteStringSequence();
--- a/dom/bindings/test/TestJSImplGen.webidl
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -247,18 +247,20 @@ interface TestJSImplInterface {
   sequence<TestJSImplInterface?> receiveWeakNullableCastableObjectSequence();
   sequence<TestJSImplInterface>? receiveWeakCastableObjectNullableSequence();
   sequence<TestJSImplInterface?>? receiveWeakNullableCastableObjectNullableSequence();
   void passCastableObjectSequence(sequence<TestJSImplInterface> arg);
   void passNullableCastableObjectSequence(sequence<TestJSImplInterface?> arg);
   void passCastableObjectNullableSequence(sequence<TestJSImplInterface>? arg);
   void passNullableCastableObjectNullableSequence(sequence<TestJSImplInterface?>? arg);
   void passOptionalSequence(optional sequence<long> arg);
+  void passOptionalSequenceWithDefaultValue(optional sequence<long> arg = []);
   void passOptionalNullableSequence(optional sequence<long>? arg);
   void passOptionalNullableSequenceWithDefaultValue(optional sequence<long>? arg = null);
+  void passOptionalNullableSequenceWithDefaultValue2(optional sequence<long>? arg = []);
   void passOptionalObjectSequence(optional sequence<TestJSImplInterface> arg);
   void passExternalInterfaceSequence(sequence<TestExternalInterface> arg);
   void passNullableExternalInterfaceSequence(sequence<TestExternalInterface?> arg);
 
   sequence<DOMString> receiveStringSequence();
   sequence<ByteString> receiveByteStringSequence();
   // Callback interface problem.  See bug 843261.
   //void passStringSequence(sequence<DOMString> arg);