Bug 983301 part 2. Change Promise to not be distinguishable from any other type. r=peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 31 Jul 2015 13:30:55 -0400
changeset 287331 27db61bad678e26b030a8a2b2de586e0d6abcaf7
parent 287330 565c77fa874c6c979327975879a3eddd7dec7d53
child 287332 bb6a924f93259aa2fe54c42fc1ced60c1b907c78
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs983301
milestone42.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 983301 part 2. Change Promise to not be distinguishable from any other type. r=peterv
dom/bindings/Configuration.py
dom/bindings/parser/WebIDL.py
dom/bindings/parser/tests/test_distinguishability.py
dom/webidl/FetchEvent.webidl
dom/workers/ServiceWorkerEvents.cpp
dom/workers/ServiceWorkerEvents.h
--- a/dom/bindings/Configuration.py
+++ b/dom/bindings/Configuration.py
@@ -131,20 +131,20 @@ class Configuration:
         # a union type, so there can be multiple tuples with union types that
         # have the same name.
         self.unionsPerFilename = defaultdict(list)
 
         for (t, descriptor, _) in getAllTypes(self.descriptors, self.dictionaries, self.callbacks):
             while True:
                 if t.isMozMap():
                     t = t.inner
+                elif t.unroll() != t:
+                    t = t.unroll()
                 elif t.isPromise():
                     t = t.promiseInnerType()
-                elif t.unroll() != t:
-                    t = t.unroll()
                 else:
                     break
             if t.isUnion():
                 filenamesForUnion = self.filenamesPerUnion[t.name]
                 if t.filename() not in filenamesForUnion:
                     if len(filenamesForUnion) == 0:
                         # This is the first file that we found a union with this
                         # name in, record the union as part of the file.
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -2021,16 +2021,19 @@ class IDLNullableType(IDLType):
         return self.inner.isSharedTypedArray()
 
     def isDictionary(self):
         return self.inner.isDictionary()
 
     def isInterface(self):
         return self.inner.isInterface()
 
+    def isPromise(self):
+        return self.inner.isPromise()
+
     def isCallbackInterface(self):
         return self.inner.isCallbackInterface()
 
     def isNonCallbackInterface(self):
         return self.inner.isNonCallbackInterface()
 
     def isEnum(self):
         return self.inner.isEnum()
@@ -2153,21 +2156,24 @@ class IDLSequenceType(IDLType):
         self.inner = self.inner.complete(scope)
         self.name = self.inner.name + "Sequence"
         return self
 
     def unroll(self):
         return self.inner.unroll()
 
     def isDistinguishableFrom(self, other):
+        if other.isPromise():
+            return False
         if other.isUnion():
             # Just forward to the union; it'll deal
             return other.isDistinguishableFrom(self)
         return (other.isPrimitive() or other.isString() or other.isEnum() or
-                other.isDate() or other.isInterface() or other.isDictionary() or
+                other.isDate() or other.isInterface() or
+                other.isDictionary() or
                 other.isCallback() or other.isMozMap())
 
     def _getDependentObjects(self):
         return self.inner._getDependentObjects()
 
 class IDLMozMapType(IDLType):
     # XXXbz This is pretty similar to IDLSequenceType in various ways.
     # And maybe to IDLNullableType.  Should we have a superclass for
@@ -2212,16 +2218,18 @@ class IDLMozMapType(IDLType):
 
     def unroll(self):
         # We do not unroll our inner.  Just stop at ourselves.  That
         # lets us add headers for both ourselves and our inner as
         # needed.
         return self
 
     def isDistinguishableFrom(self, other):
+        if other.isPromise():
+            return False
         if other.isUnion():
             # Just forward to the union; it'll deal
             return other.isDistinguishableFrom(self)
         return (other.isPrimitive() or other.isString() or other.isEnum() or
                 other.isDate() or other.isNonCallbackInterface() or other.isSequence())
 
     def isExposedInAllOf(self, exposureSet):
         return self.inner.unroll().isExposedInAllOf(exposureSet)
@@ -2437,16 +2445,18 @@ class IDLArrayType(IDLType):
         assert not self.inner.isSequence()
 
         return self
 
     def unroll(self):
         return self.inner.unroll()
 
     def isDistinguishableFrom(self, other):
+        if other.isPromise():
+            return False
         if other.isUnion():
             # Just forward to the union; it'll deal
             return other.isDistinguishableFrom(self)
         return (other.isPrimitive() or other.isString() or other.isEnum() or
                 other.isDate() or other.isNonCallbackInterface())
 
     def _getDependentObjects(self):
         return self.inner._getDependentObjects()
@@ -2671,16 +2681,20 @@ class IDLWrapperType(IDLType):
         elif self.isEnum():
             return IDLType.Tags.enum
         elif self.isDictionary():
             return IDLType.Tags.dictionary
         else:
             assert False
 
     def isDistinguishableFrom(self, other):
+        if self.isPromise():
+            return False
+        if other.isPromise():
+            return False
         if other.isUnion():
             # Just forward to the union; it'll deal
             return other.isDistinguishableFrom(self)
         assert self.isInterface() or self.isEnum() or self.isDictionary()
         if self.isEnum():
             return (other.isPrimitive() or other.isInterface() or other.isObject() or
                     other.isCallback() or other.isDictionary() or
                     other.isSequence() or other.isMozMap() or other.isArray() or
@@ -2930,16 +2944,18 @@ class IDLBuiltinType(IDLType):
 
     def includesRestrictedFloat(self):
         return self.isFloat() and not self.isUnrestricted()
 
     def tag(self):
         return IDLBuiltinType.TagLookup[self._typeTag]
 
     def isDistinguishableFrom(self, other):
+        if other.isPromise():
+            return False
         if other.isUnion():
             # Just forward to the union; it'll deal
             return other.isDistinguishableFrom(self)
         if self.isBoolean():
             return (other.isNumeric() or other.isString() or other.isEnum() or
                     other.isInterface() or other.isObject() or
                     other.isCallback() or other.isDictionary() or
                     other.isSequence() or other.isMozMap() or other.isArray() or
@@ -4187,16 +4203,18 @@ class IDLCallbackType(IDLType):
 
     def isCallback(self):
         return True
 
     def tag(self):
         return IDLType.Tags.callback
 
     def isDistinguishableFrom(self, other):
+        if other.isPromise():
+            return False
         if other.isUnion():
             # Just forward to the union; it'll deal
             return other.isDistinguishableFrom(self)
         return (other.isPrimitive() or other.isString() or other.isEnum() or
                 other.isNonCallbackInterface() or other.isDate() or
                 other.isSequence())
 
     def _getDependentObjects(self):
--- a/dom/bindings/parser/tests/test_distinguishability.py
+++ b/dom/bindings/parser/tests/test_distinguishability.py
@@ -155,39 +155,41 @@ def WebIDLTest(parser, harness):
                  "Interface", "Interface?",
                  "AncestorInterface", "UnrelatedInterface",
                  "ImplementedInterface", "CallbackInterface",
                  "CallbackInterface?", "CallbackInterface2",
                  "object", "Callback", "Callback2", "optional Dict",
                  "optional Dict2", "sequence<long>", "sequence<short>",
                  "MozMap<object>", "MozMap<Dict>", "MozMap<long>",
                  "long[]", "short[]", "Date", "Date?", "any",
+                 "Promise<any>", "Promise<any>?",
                  "USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer", "SharedArrayBufferView",
                  "Uint8Array", "SharedUint8Array", "Uint16Array", "SharedUint16Array" ]
     # When we can parse Date and RegExp, we need to add them here.
 
     # Try to categorize things a bit to keep list lengths down
     def allBut(list1, list2):
-        return [a for a in list1 if a not in list2 and a != "any"]
+        return [a for a in list1 if a not in list2 and
+                (a != "any" and a != "Promise<any>" and a != "Promise<any>?")]
     numerics = [ "long", "short", "long?", "short?" ]
     booleans = [ "boolean", "boolean?" ]
     primitives = numerics + booleans
     nonNumerics = allBut(argTypes, numerics)
     nonBooleans = allBut(argTypes, booleans)
     strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString" ]
     nonStrings = allBut(argTypes, strings)
     nonObjects = primitives + strings
     objects = allBut(argTypes, nonObjects )
     bufferSourceTypes = ["ArrayBuffer", "ArrayBufferView", "Uint8Array", "Uint16Array"]
     sharedBufferSourceTypes = ["SharedArrayBuffer", "SharedArrayBufferView", "SharedUint8Array", "SharedUint16Array"]
     interfaces = [ "Interface", "Interface?", "AncestorInterface",
                    "UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
     nullables = ["long?", "short?", "boolean?", "Interface?",
                  "CallbackInterface?", "optional Dict", "optional Dict2",
-                 "Date?", "any"]
+                 "Date?", "any", "Promise<any>?"]
     dates = [ "Date", "Date?" ]
     sequences = [ "sequence<long>", "sequence<short>" ]
     arrays = [ "long[]", "short[]" ]
     nonUserObjects = nonObjects + interfaces + dates + sequences
     otherObjects = allBut(argTypes, nonUserObjects + ["object"])
     notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
                             otherObjects + dates + sequences + bufferSourceTypes + sharedBufferSourceTypes)
     mozMaps = [ "MozMap<object>", "MozMap<Dict>", "MozMap<long>" ]
@@ -233,16 +235,18 @@ def WebIDLTest(parser, harness):
     setDistinguishable("MozMap<object>", nonUserObjects)
     setDistinguishable("MozMap<Dict>", nonUserObjects)
     setDistinguishable("MozMap<long>", nonUserObjects)
     setDistinguishable("long[]", allBut(nonUserObjects, sequences))
     setDistinguishable("short[]", allBut(nonUserObjects, sequences))
     setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
     setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
     setDistinguishable("any", [])
+    setDistinguishable("Promise<any>", [])
+    setDistinguishable("Promise<any>?", [])
     setDistinguishable("ArrayBuffer", allBut(argTypes, ["ArrayBuffer", "object"]))
     setDistinguishable("ArrayBufferView", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"]))
     setDistinguishable("Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"]))
     setDistinguishable("Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"]))
     setDistinguishable("SharedArrayBuffer", allBut(argTypes, ["SharedArrayBuffer", "object"]))
     setDistinguishable("SharedArrayBufferView", allBut(argTypes, ["SharedArrayBufferView", "SharedUint8Array", "SharedUint16Array", "object"]))
     setDistinguishable("SharedUint8Array", allBut(argTypes, ["SharedArrayBufferView", "SharedUint8Array", "object"]))
     setDistinguishable("SharedUint16Array", allBut(argTypes, ["SharedArrayBufferView", "SharedUint16Array", "object"]))
@@ -260,16 +264,17 @@ def WebIDLTest(parser, harness):
           interface ImplementedInterface {};
           Interface implements ImplementedInterface;
           callback interface CallbackInterface {};
           callback interface CallbackInterface2 {};
           callback Callback = any();
           callback Callback2 = long(short arg);
           dictionary Dict {};
           dictionary Dict2 {};
+          interface _Promise {};
           interface TestInterface {%s
           };
         """
         methodTemplate = """
             void myMethod(%s arg);"""
         methods = (methodTemplate % type1) + (methodTemplate % type2)
         idl = idlTemplate % methods
         parser = parser.reset()
--- a/dom/webidl/FetchEvent.webidl
+++ b/dom/webidl/FetchEvent.webidl
@@ -13,16 +13,16 @@
 interface FetchEvent : Event {
   readonly attribute Request request;
 
   // https://github.com/slightlyoff/ServiceWorker/issues/631
   readonly attribute Client? client; // The window issuing the request.
   readonly attribute boolean isReload;
 
   [Throws]
-  void respondWith((Response or Promise<Response>) r);
+  void respondWith(Promise<Response> r);
 };
 
 dictionary FetchEventInit : EventInit {
   Request request;
   Client client;
   boolean isReload;
 };
--- a/dom/workers/ServiceWorkerEvents.cpp
+++ b/dom/workers/ServiceWorkerEvents.cpp
@@ -343,44 +343,29 @@ RespondWithHandler::CancelRequest(nsresu
   nsCOMPtr<nsIRunnable> runnable =
     new CancelChannelRunnable(mInterceptedChannel, aStatus);
   NS_DispatchToMainThread(runnable);
 }
 
 } // namespace
 
 void
-FetchEvent::RespondWith(const ResponseOrPromise& aArg, ErrorResult& aRv)
+FetchEvent::RespondWith(Promise& aArg, ErrorResult& aRv)
 {
   if (mWaitToRespond) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return;
   }
 
-  nsRefPtr<Promise> promise;
-
-  if (aArg.IsResponse()) {
-    nsRefPtr<Response> res = &aArg.GetAsResponse();
-    WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
-    MOZ_ASSERT(worker);
-    worker->AssertIsOnWorkerThread();
-    promise = Promise::Create(worker->GlobalScope(), aRv);
-    if (NS_WARN_IF(aRv.Failed())) {
-      return;
-    }
-    promise->MaybeResolve(res);
-  } else if (aArg.IsPromise()) {
-    promise = &aArg.GetAsPromise();
-  }
   nsRefPtr<InternalRequest> ir = mRequest->GetInternalRequest();
   mWaitToRespond = true;
   nsRefPtr<RespondWithHandler> handler =
     new RespondWithHandler(mChannel, mServiceWorker, mRequest->Mode(),
                            ir->IsClientRequest());
-  promise->AppendNativeHandler(handler);
+  aArg.AppendNativeHandler(handler);
 }
 
 already_AddRefed<ServiceWorkerClient>
 FetchEvent::GetClient()
 {
   if (!mClient) {
     if (!mClientInfo) {
       return nullptr;
--- a/dom/workers/ServiceWorkerEvents.h
+++ b/dom/workers/ServiceWorkerEvents.h
@@ -86,17 +86,17 @@ public:
 
   bool
   IsReload() const
   {
     return mIsReload;
   }
 
   void
-  RespondWith(const ResponseOrPromise& aArg, ErrorResult& aRv);
+  RespondWith(Promise& aArg, ErrorResult& aRv);
 
   already_AddRefed<Promise>
   ForwardTo(const nsAString& aUrl);
 
   already_AddRefed<Promise>
   Default();
 };