[WebIDL] Implement overload resolution algorithm
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Aug 2016 17:02:23 +0000 (17:02 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 2 Aug 2016 17:02:23 +0000 (17:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=160394

Reviewed by Darin Adler.

Source/WebCore:

Implement overload resolution algorithm:
- http://heycam.github.io/webidl/#es-overloads

This means that our support for operation overloading in our IDL is
now a lot more extensive than it used to be and is now compliant with
the Web IDL specification.

In particular, overloading should now work for a lot more parameter
types which means that:
- We should be able to drop some custom bindings code in a follow-up patch.
- We will be able to drop the [StrictTypeChecking] attribute which was
  a hack used to make overloading work for parameters of type DOMString.

Also, the order of the overloads in the IDL no longer impacts the
generated bindings code. It used to be that you needed to put the
overloads with the more specific parameter types first in order for the
generated bindings code to be somewhat correct.

No new tests, rebaselined bindings tests.

* bindings/scripts/CodeGenerator.pm:
(IsStringOrEnumType):
* bindings/scripts/CodeGeneratorJS.pm:
(IsNullableType):
(StripNullable):
(ComputeEffectiveOverloadSet):
(AreTypesDistinguishableForOverloadResolution):
(GetDistinguishingArgumentIndex):
(GetOverloadThatMatches):
(GenerateOverloadedFunction):
* bindings/scripts/test/JS/JSTestGlobalObject.cpp:
(WebCore::jsTestGlobalObjectInstanceFunctionEnabledAtRuntimeOperation):
* bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::jsTestObjPrototypeFunctionEnabledAtRuntimeOperation):
(WebCore::jsTestObjPrototypeFunctionOverloadedMethod):
(WebCore::jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter1):
(WebCore::jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter):
(WebCore::jsTestObjConstructorFunctionOverloadedMethod1):
(WebCore::jsTestObjPrototypeFunctionTestPromiseOverloadedFunction):
(WebCore::jsTestObjConstructorFunctionOverloadedMethod12): Deleted.
(WebCore::jsTestObjPrototypeFunctionTestPromiseOverloadedFunction2Promise): Deleted.
* bindings/scripts/test/TestObj.idl:
* dom/EventTarget.h:
* dom/EventTarget.idl:
* html/HTMLOptionsCollection.h:
* html/HTMLOptionsCollection.idl:
* html/HTMLSelectElement.h:
(WebCore::HTMLSelectElement::add):
* html/HTMLSelectElement.idl:

LayoutTests:

Update / Rebaseline existing test. There is no major behavior change.
We sometimes get a different exception message than we used to.

* fast/canvas/canvas-clip-path-expected.txt:
* fast/canvas/canvas-fill-path-expected.txt:
* fast/canvas/canvas-path-addPath-expected.txt:
* fast/canvas/canvas-path-isPointInPath-expected.txt:
* fast/canvas/canvas-path-isPointInStroke-expected.txt:
* fast/canvas/canvas-putImageData-expected.txt:
* fast/canvas/canvas-putImageData.js:
* fast/canvas/canvas-stroke-path-expected.txt:
* fast/canvas/webgl/script-tests/texImageTest.js:
* fast/canvas/webgl/texImageTest-expected.txt:
* fast/dom/HTMLSelectElement/add-expected.txt:
* fast/dom/HTMLSelectElement/add.html:
* fast/dom/HTMLSelectElement/options-collection-add-expected.txt:
* fast/dom/HTMLSelectElement/options-collection-add.html:
* fast/dom/incompatible-operations-expected.txt:
* js/dom/select-options-add-expected.txt:
* webaudio/audiobuffer-expected.txt:
* webaudio/audiobuffer.html:
* webgl/1.0.2/resources/webgl_test_files/conformance/textures/tex-image-with-invalid-data.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@204028 268f45cc-cd09-0410-ab3c-d52691b4dbfc

32 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/canvas/canvas-clip-path-expected.txt
LayoutTests/fast/canvas/canvas-fill-path-expected.txt
LayoutTests/fast/canvas/canvas-path-addPath-expected.txt
LayoutTests/fast/canvas/canvas-path-isPointInPath-expected.txt
LayoutTests/fast/canvas/canvas-path-isPointInStroke-expected.txt
LayoutTests/fast/canvas/canvas-putImageData-expected.txt
LayoutTests/fast/canvas/canvas-putImageData.js
LayoutTests/fast/canvas/canvas-stroke-path-expected.txt
LayoutTests/fast/canvas/webgl/script-tests/texImageTest.js
LayoutTests/fast/canvas/webgl/texImageTest-expected.txt
LayoutTests/fast/dom/HTMLSelectElement/add-expected.txt
LayoutTests/fast/dom/HTMLSelectElement/add.html
LayoutTests/fast/dom/HTMLSelectElement/options-collection-add-expected.txt
LayoutTests/fast/dom/HTMLSelectElement/options-collection-add.html
LayoutTests/fast/dom/incompatible-operations-expected.txt
LayoutTests/js/dom/select-options-add-expected.txt
LayoutTests/webaudio/audiobuffer-expected.txt
LayoutTests/webaudio/audiobuffer.html
LayoutTests/webgl/1.0.2/resources/webgl_test_files/conformance/textures/tex-image-with-invalid-data.html
Source/WebCore/ChangeLog
Source/WebCore/bindings/scripts/CodeGenerator.pm
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestGlobalObject.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
Source/WebCore/bindings/scripts/test/TestObj.idl
Source/WebCore/dom/EventTarget.h
Source/WebCore/dom/EventTarget.idl
Source/WebCore/html/HTMLOptionsCollection.h
Source/WebCore/html/HTMLOptionsCollection.idl
Source/WebCore/html/HTMLSelectElement.h
Source/WebCore/html/HTMLSelectElement.idl

index a9e681e..f80d5f0 100644 (file)
@@ -1,3 +1,33 @@
+2016-08-02  Chris Dumez  <cdumez@apple.com>
+
+        [WebIDL] Implement overload resolution algorithm
+        https://bugs.webkit.org/show_bug.cgi?id=160394
+
+        Reviewed by Darin Adler.
+
+        Update / Rebaseline existing test. There is no major behavior change.
+        We sometimes get a different exception message than we used to.
+
+        * fast/canvas/canvas-clip-path-expected.txt:
+        * fast/canvas/canvas-fill-path-expected.txt:
+        * fast/canvas/canvas-path-addPath-expected.txt:
+        * fast/canvas/canvas-path-isPointInPath-expected.txt:
+        * fast/canvas/canvas-path-isPointInStroke-expected.txt:
+        * fast/canvas/canvas-putImageData-expected.txt:
+        * fast/canvas/canvas-putImageData.js:
+        * fast/canvas/canvas-stroke-path-expected.txt:
+        * fast/canvas/webgl/script-tests/texImageTest.js:
+        * fast/canvas/webgl/texImageTest-expected.txt:
+        * fast/dom/HTMLSelectElement/add-expected.txt:
+        * fast/dom/HTMLSelectElement/add.html:
+        * fast/dom/HTMLSelectElement/options-collection-add-expected.txt:
+        * fast/dom/HTMLSelectElement/options-collection-add.html:
+        * fast/dom/incompatible-operations-expected.txt:
+        * js/dom/select-options-add-expected.txt:
+        * webaudio/audiobuffer-expected.txt:
+        * webaudio/audiobuffer.html:
+        * webgl/1.0.2/resources/webgl_test_files/conformance/textures/tex-image-with-invalid-data.html:
+
 2016-08-02  Per Arne Vollan  <pvollan@apple.com>
 
         Unreviewed test gardening.
index 004b111..3e9929f 100644 (file)
@@ -32,14 +32,14 @@ PASS ctx.clip(Number.MAX_VALUE) threw exception TypeError: Argument 1 ('winding'
 PASS ctx.clip(function() {}) threw exception TypeError: Argument 1 ('winding') to CanvasRenderingContext2D.clip must be one of: "nonzero", "evenodd".
 PASS ctx.clip(false) threw exception TypeError: Argument 1 ('winding') to CanvasRenderingContext2D.clip must be one of: "nonzero", "evenodd".
 PASS ctx.clip(new Date()) threw exception TypeError: Argument 1 ('winding') to CanvasRenderingContext2D.clip must be one of: "nonzero", "evenodd".
-PASS ctx.clip(0, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.clip(null, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.clip('path2d', 'nonzero') threw exception TypeError: Type error.
-PASS ctx.clip(undefined, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.clip(Number.MAX_VALUE, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.clip(function() {}, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.clip(false, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.clip(new Date(), 'nonzero') threw exception TypeError: Type error.
+PASS ctx.clip(0, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.clip must be an instance of DOMPath.
+PASS ctx.clip(null, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.clip must be an instance of DOMPath.
+PASS ctx.clip('path2d', 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.clip must be an instance of DOMPath.
+PASS ctx.clip(undefined, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.clip must be an instance of DOMPath.
+PASS ctx.clip(Number.MAX_VALUE, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.clip must be an instance of DOMPath.
+PASS ctx.clip(function() {}, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.clip must be an instance of DOMPath.
+PASS ctx.clip(false, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.clip must be an instance of DOMPath.
+PASS ctx.clip(new Date(), 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.clip must be an instance of DOMPath.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 8641e7a..c9370bb 100644 (file)
@@ -31,14 +31,14 @@ PASS ctx.fill(Number.MAX_VALUE) threw exception TypeError: Argument 1 ('winding'
 PASS ctx.fill(function() {}) threw exception TypeError: Argument 1 ('winding') to CanvasRenderingContext2D.fill must be one of: "nonzero", "evenodd".
 PASS ctx.fill(false) threw exception TypeError: Argument 1 ('winding') to CanvasRenderingContext2D.fill must be one of: "nonzero", "evenodd".
 PASS ctx.fill(new Date()) threw exception TypeError: Argument 1 ('winding') to CanvasRenderingContext2D.fill must be one of: "nonzero", "evenodd".
-PASS ctx.fill(0, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.fill(null, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.fill('path2d', 'nonzero') threw exception TypeError: Type error.
+PASS ctx.fill(0, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.fill must be an instance of DOMPath.
+PASS ctx.fill(null, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.fill must be an instance of DOMPath.
+PASS ctx.fill('path2d', 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.fill must be an instance of DOMPath.
 FAIL ctx.fill(undefined) should throw an exception. Was undefined.
-PASS ctx.fill(Number.MAX_VALUE, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.fill(function() {}, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.fill(false, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.fill(new Date(), 'nonzero') threw exception TypeError: Type error.
+PASS ctx.fill(Number.MAX_VALUE, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.fill must be an instance of DOMPath.
+PASS ctx.fill(function() {}, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.fill must be an instance of DOMPath.
+PASS ctx.fill(false, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.fill must be an instance of DOMPath.
+PASS ctx.fill(new Date(), 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.fill must be an instance of DOMPath.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 7abf9c1..164b17c 100644 (file)
@@ -31,12 +31,12 @@ Add path B to path A with singular transformation matrix (3).
 PASS refTest(result.data, expected.data) is true
 
 Various tests of invalid values.
-PASS pathA.addPath(matrix, pathB) threw exception TypeError: Type error.
-PASS pathA.addPath(pathB, ctx.canvas) threw exception TypeError: Type error.
-PASS pathA.addPath(pathB, null) threw exception TypeError: Type error.
-PASS pathA.addPath(pathB, undefined) threw exception TypeError: Type error.
-PASS pathA.addPath(pathB, 0) threw exception TypeError: Type error.
-PASS pathA.addPath(pathB, "0") threw exception TypeError: Type error.
+PASS pathA.addPath(matrix, pathB) threw exception TypeError: Argument 1 ('path') to Path2D.addPath must be an instance of DOMPath.
+PASS pathA.addPath(pathB, ctx.canvas) threw exception TypeError: Argument 2 ('transform') to Path2D.addPath must be an instance of SVGMatrix.
+PASS pathA.addPath(pathB, null) threw exception TypeError: Argument 2 ('transform') to Path2D.addPath must be an instance of SVGMatrix.
+PASS pathA.addPath(pathB, undefined) threw exception TypeError: Argument 2 ('transform') to Path2D.addPath must be an instance of SVGMatrix.
+PASS pathA.addPath(pathB, 0) threw exception TypeError: Argument 2 ('transform') to Path2D.addPath must be an instance of SVGMatrix.
+PASS pathA.addPath(pathB, "0") threw exception TypeError: Argument 2 ('transform') to Path2D.addPath must be an instance of SVGMatrix.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 9dd609c..8a57247 100644 (file)
@@ -10,20 +10,20 @@ PASS ctx.isPointInPath(path, 50, 50, 'nonzero') is true
 PASS ctx.isPointInPath(path, 50, 50, 'evenodd') is false
 PASS ctx.isPointInPath(path, 50, 50, 'nonzero') is false
 PASS ctx.isPointInPath(null, 50, 50) threw exception TypeError: Argument 3 ('winding') to CanvasRenderingContext2D.isPointInPath must be one of: "nonzero", "evenodd".
-PASS ctx.isPointInPath(null, 50, 50, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.isPointInPath(null, 50, 50, 'evenodd') threw exception TypeError: Type error.
+PASS ctx.isPointInPath(null, 50, 50, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
+PASS ctx.isPointInPath(null, 50, 50, 'evenodd') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
 PASS ctx.isPointInPath([], 50, 50) threw exception TypeError: Argument 3 ('winding') to CanvasRenderingContext2D.isPointInPath must be one of: "nonzero", "evenodd".
-PASS ctx.isPointInPath([], 50, 50, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.isPointInPath([], 50, 50, 'evenodd') threw exception TypeError: Type error.
+PASS ctx.isPointInPath([], 50, 50, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
+PASS ctx.isPointInPath([], 50, 50, 'evenodd') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
 PASS ctx.isPointInPath({}, 50, 50) threw exception TypeError: Argument 3 ('winding') to CanvasRenderingContext2D.isPointInPath must be one of: "nonzero", "evenodd".
-PASS ctx.isPointInPath({}, 50, 50, 'nonzero') threw exception TypeError: Type error.
-PASS ctx.isPointInPath({}, 50, 50, 'evenodd') threw exception TypeError: Type error.
-PASS ctx.isPointInPath('path2d', 50, 50, 'evenodd') threw exception TypeError: Type error.
-PASS ctx.isPointInPath(undefined, 50, 50, 'evenodd') threw exception TypeError: Type error.
-PASS ctx.isPointInPath(Number.MAX_VALUE, 50, 50, 'evenodd') threw exception TypeError: Type error.
-PASS ctx.isPointInPath(function() {}, 50, 50, 'evenodd') threw exception TypeError: Type error.
-PASS ctx.isPointInPath(false, 50, 50, 'evenodd') threw exception TypeError: Type error.
-PASS ctx.isPointInPath(new Date(), 50, 50, 'evenodd') threw exception TypeError: Type error.
+PASS ctx.isPointInPath({}, 50, 50, 'nonzero') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
+PASS ctx.isPointInPath({}, 50, 50, 'evenodd') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
+PASS ctx.isPointInPath('path2d', 50, 50, 'evenodd') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
+PASS ctx.isPointInPath(undefined, 50, 50, 'evenodd') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
+PASS ctx.isPointInPath(Number.MAX_VALUE, 50, 50, 'evenodd') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
+PASS ctx.isPointInPath(function() {}, 50, 50, 'evenodd') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
+PASS ctx.isPointInPath(false, 50, 50, 'evenodd') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
+PASS ctx.isPointInPath(new Date(), 50, 50, 'evenodd') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInPath must be an instance of DOMPath.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 8dfba8d..1ffd51f 100644 (file)
@@ -21,9 +21,9 @@ PASS ctx.isPointInStroke(path,70,122) is false
 PASS ctx.isPointInStroke(path,18,70) is false
 PASS ctx.isPointInStroke(path,NaN,122) is false
 PASS ctx.isPointInStroke(path,18,NaN) is false
-PASS ctx.isPointInStroke(null,70,20) threw exception TypeError: Type error.
-PASS ctx.isPointInStroke([],20,70) threw exception TypeError: Type error.
-PASS ctx.isPointInStroke({},120,70) threw exception TypeError: Type error.
+PASS ctx.isPointInStroke(null,70,20) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInStroke must be an instance of DOMPath.
+PASS ctx.isPointInStroke([],20,70) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInStroke must be an instance of DOMPath.
+PASS ctx.isPointInStroke({},120,70) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.isPointInStroke must be an instance of DOMPath.
 PASS ctx.isPointInPath('path2d', 50, 50) threw exception TypeError: Argument 3 ('winding') to CanvasRenderingContext2D.isPointInPath must be one of: "nonzero", "evenodd".
 PASS ctx.isPointInPath(undefined, 50, 50) threw exception TypeError: Argument 3 ('winding') to CanvasRenderingContext2D.isPointInPath must be one of: "nonzero", "evenodd".
 PASS ctx.isPointInPath(Number.MAX_VALUE, 50, 50) threw exception TypeError: Argument 3 ('winding') to CanvasRenderingContext2D.isPointInPath must be one of: "nonzero", "evenodd".
index 50e1b0f..a02fa57 100644 (file)
@@ -144,7 +144,7 @@ PASS getPixel(1,1) is [0,128,0,255]
 PASS getPixel(9,9) is [0,128,0,255]
 PASS getPixel(1,1) is [0,128,0,255]
 PASS getPixel(9,9) is [0,128,0,255]
-PASS context.putImageData({}, 0, 0) threw exception TypeError: Type error.
+PASS context.putImageData({}, 0, 0) threw exception TypeError: Argument 1 ('imagedata') to CanvasRenderingContext2D.putImageData must be an instance of ImageData.
 PASS context.putImageData(buffer, NaN, 0, 0, 0, 0, 0) threw exception TypeError: The provided value is non-finite.
 PASS context.putImageData(buffer, 0, NaN, 0, 0, 0, 0) threw exception TypeError: The provided value is non-finite.
 PASS context.putImageData(buffer, 0, 0, NaN, 0, 0, 0) threw exception TypeError: The provided value is non-finite.
index c29ba83..711847d 100644 (file)
@@ -201,7 +201,7 @@ pixelShouldBe(1, 1, [0, 128,0,255]);
 pixelShouldBe(9, 9, [0, 128,0,255]);
 
 
-shouldThrow("context.putImageData({}, 0, 0)", "'TypeError: Type error'");
+shouldThrowErrorName("context.putImageData({}, 0, 0)", "TypeError");
 shouldThrow("context.putImageData(buffer, NaN, 0, 0, 0, 0, 0)", "'TypeError: The provided value is non-finite'");
 shouldThrow("context.putImageData(buffer, 0, NaN, 0, 0, 0, 0)", "'TypeError: The provided value is non-finite'");
 shouldThrow("context.putImageData(buffer, 0, 0, NaN, 0, 0, 0)", "'TypeError: The provided value is non-finite'");
index 398dff6..7857b81 100644 (file)
@@ -17,14 +17,14 @@ PASS areaColor(imageData.data, {r:0,g:255,b:0,a:255}) is true
 PASS areaColor(imageData.data, {r:0,g:255,b:0,a:255}) is true
 PASS areaColor(imageData.data, {r:0,g:255,b:0,a:255}) is true
 
-PASS ctx.stroke(0) threw exception TypeError: Type error.
-PASS ctx.stroke(null) threw exception TypeError: Type error.
-PASS ctx.stroke('path2d') threw exception TypeError: Type error.
-PASS ctx.stroke(undefined) threw exception TypeError: Type error.
-PASS ctx.stroke(Number.MAX_VALUE) threw exception TypeError: Type error.
-PASS ctx.stroke(function() {}) threw exception TypeError: Type error.
-PASS ctx.stroke(false) threw exception TypeError: Type error.
-PASS ctx.stroke(new Date()) threw exception TypeError: Type error.
+PASS ctx.stroke(0) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.stroke must be an instance of DOMPath.
+PASS ctx.stroke(null) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.stroke must be an instance of DOMPath.
+PASS ctx.stroke('path2d') threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.stroke must be an instance of DOMPath.
+PASS ctx.stroke(undefined) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.stroke must be an instance of DOMPath.
+PASS ctx.stroke(Number.MAX_VALUE) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.stroke must be an instance of DOMPath.
+PASS ctx.stroke(function() {}) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.stroke must be an instance of DOMPath.
+PASS ctx.stroke(false) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.stroke must be an instance of DOMPath.
+PASS ctx.stroke(new Date()) threw exception TypeError: Argument 1 ('path') to CanvasRenderingContext2D.stroke must be an instance of DOMPath.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index c1a9d4e..8e9658f 100644 (file)
@@ -25,7 +25,7 @@ shouldBeUndefined("context.texImage2D(context.TEXTURE_2D, 0, context.RGBA, conte
 
 shouldThrow("context.texSubImage2D(context.TEXTURE_2D)");
 shouldBeUndefined("context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, 0, 0, context.RGBA, context.UNSIGNED_BYTE, null)");
-shouldThrow("context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, 0, 0, context.RGBA, context.UNSIGNED_BYTE, 0)");
+shouldBeUndefined("context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, 0, 0, context.RGBA, context.UNSIGNED_BYTE, 0)"); // We do not do strict type checking on ArrayBufferView.
 shouldThrow("context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, 0, context.UNSIGNED_BYTE, 0)");
 shouldBeUndefined("context.pixelStorei(context.UNPACK_FLIP_Y_WEBGL, false)");
 shouldBeUndefined("context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, context.RGBA, context.UNSIGNED_BYTE, imageData)");
index a8f798b..2bee87e 100644 (file)
@@ -15,7 +15,7 @@ PASS context.pixelStorei(context.UNPACK_FLIP_Y_WEBGL, true) is undefined.
 PASS context.texImage2D(context.TEXTURE_2D, 0, context.RGBA, context.RGBA, context.UNSIGNED_BYTE, video) is undefined.
 PASS context.texSubImage2D(context.TEXTURE_2D) threw exception TypeError: Not enough arguments.
 PASS context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, 0, 0, context.RGBA, context.UNSIGNED_BYTE, null) is undefined.
-PASS context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, 0, 0, context.RGBA, context.UNSIGNED_BYTE, 0) threw exception TypeError: Type error.
+PASS context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, 0, 0, context.RGBA, context.UNSIGNED_BYTE, 0) is undefined.
 PASS context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, 0, context.UNSIGNED_BYTE, 0) threw exception TypeError: Type error.
 PASS context.pixelStorei(context.UNPACK_FLIP_Y_WEBGL, false) is undefined.
 PASS context.texSubImage2D(context.TEXTURE_2D, 0, 10, 20, context.RGBA, context.UNSIGNED_BYTE, imageData) is undefined.
index 75f6f21..b33f71f 100644 (file)
@@ -9,9 +9,9 @@ PASS testAdd() threw exception TypeError: Not enough arguments.
 
 Call HTMLSelectElement.add() with one argument:
 PASS testAdd(createOption("Y1")) is "0,1,2,Y1"
-PASS testAdd("foo") threw exception TypeError: Type error.
-PASS testAdd(undefined) threw exception TypeError: Type error.
-PASS testAdd(null) threw exception TypeError: Type error.
+PASS testAdd("foo") threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
+PASS testAdd(undefined) threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
+PASS testAdd(null) threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
 
 Call HTMLSelectElement.add() with two arguments:
 PASS testAdd(createOption("Y2"), null) is "0,1,2,Y2"
@@ -40,9 +40,9 @@ PASS testAdd(createOption("Y24"), -2) is "0,1,2,Y24"
 PASS testAdd(createOption("X"), mySelect.options[0]) is "X,0,1,2"
 PASS testAdd(createOption("X"), mySelect.options[1]) is "0,X,1,2"
 PASS testAdd(createOption("X"), mySelect.options[2]) is "0,1,X,2"
-PASS testAdd("foo", 0) threw exception TypeError: Type error.
-PASS testAdd(undefined, 0) threw exception TypeError: Type error.
-PASS testAdd(null, 0) threw exception TypeError: Type error.
+PASS testAdd("foo", 0) threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
+PASS testAdd(undefined, 0) threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
+PASS testAdd(null, 0) threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
 
 Call HTMLSelectElement.add() with three arguments (when it only takes two arguments):
 PASS testAdd(createOption("X"), 0, "unnecessary extra argument - should be ignored") is "X,0,1,2"
index 4f9f653..0164e82 100644 (file)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/js-test-pre.js"></script>
 <script src="resources/html-select-and-options-collection-utilities.js"></script>
 </head>
 <body>
@@ -23,9 +23,9 @@ shouldThrow("testAdd()");
 
 debug("<br>Call HTMLSelectElement.add() with one argument:");
 shouldBeEqualToString('testAdd(createOption("Y1"))', "0,1,2,Y1");
-shouldThrow('testAdd("foo")');
-shouldThrow("testAdd(undefined)");
-shouldThrow("testAdd(null)");
+shouldThrowErrorName('testAdd("foo")', "TypeError");
+shouldThrowErrorName("testAdd(undefined)", "TypeError");
+shouldThrowErrorName("testAdd(null)", "TypeError");
 
 debug("<br>Call HTMLSelectElement.add() with two arguments:");
 shouldBeEqualToString('testAdd(createOption("Y2"), null)', "0,1,2,Y2");
@@ -54,13 +54,14 @@ shouldBeEqualToString('testAdd(createOption("Y24"), -2)', "0,1,2,Y24");
 shouldBeEqualToString('testAdd(createOption("X"), mySelect.options[0])', "X,0,1,2");
 shouldBeEqualToString('testAdd(createOption("X"), mySelect.options[1])', "0,X,1,2");
 shouldBeEqualToString('testAdd(createOption("X"), mySelect.options[2])', "0,1,X,2");
-shouldThrow('testAdd("foo", 0)', "'TypeError: Type error'");
-shouldThrow('testAdd(undefined, 0)', "'TypeError: Type error'");
-shouldThrow('testAdd(null, 0)', "'TypeError: Type error'");
+shouldThrowErrorName('testAdd("foo", 0)', "TypeError");
+shouldThrowErrorName('testAdd(undefined, 0)', "TypeError");
+shouldThrowErrorName('testAdd(null, 0)', "TypeError");
 
 debug("<br>Call HTMLSelectElement.add() with three arguments (when it only takes two arguments):");
 shouldBeEqualToString('testAdd(createOption("X"), 0, "unnecessary extra argument - should be ignored")', "X,0,1,2");
 shouldBeEqualToString('testAdd(createOption("X"), mySelect.options[1], "unnecessary extra argument - should be ignored")', "0,X,1,2");
 </script>
+<script src="../../../resources/js-test-post.js"></script>
 </body>
 </html>
index 1da02d6..d6cc8b5 100644 (file)
@@ -9,9 +9,9 @@ PASS testAdd() threw exception TypeError: Not enough arguments.
 
 Call HTMLOptionsCollection.add() with only one argument:
 PASS testAdd(createOption("Y9")) is "0,1,2,Y9"
-PASS testAdd("foo") threw exception TypeError: Type error.
-PASS testAdd(undefined) threw exception TypeError: Type error.
-PASS testAdd(null) threw exception TypeError: Type error.
+PASS testAdd("foo") threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
+PASS testAdd(undefined) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
+PASS testAdd(null) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 
 Call HTMLOptionsCollection.add() with two arguments:
 PASS testAdd(createGroup("Y1", "Y2"), null) is "0,1,2,Y1,Y2"
@@ -52,9 +52,9 @@ PASS testAdd(createOption("X"), mySelect.options[1]) is "0,X,1,2"
 PASS testAdd(createOption("X"), mySelect.options[2]) is "0,1,X,2"
 PASS testAdd(createOption("Y25"), 0, 1) is "Y25,0,1,2"
 PASS testAdd(createOption("Y25"), mySelect.options[0], 1) is "Y25,0,1,2"
-PASS testAdd("foo", 0) threw exception TypeError: Type error.
-PASS testAdd(undefined, 0) threw exception TypeError: Type error.
-PASS testAdd(null, 0) threw exception TypeError: Type error.
+PASS testAdd("foo", 0) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
+PASS testAdd(undefined, 0) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
+PASS testAdd(null, 0) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 
 Call HTMLOptionsCollection.add() with three arguments (when it only takes two arguments):
 PASS testAdd(createOption("X"), 0, "unnecessary extra argument - should be ignored") is "X,0,1,2"
index a383122..aa09c97 100644 (file)
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <html>
 <head>
-<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/js-test-pre.js"></script>
 <script src="resources/html-select-and-options-collection-utilities.js"></script>
 </head>
 <body>
@@ -29,9 +29,9 @@ shouldThrow("testAdd()");
 
 debug("<br>Call HTMLOptionsCollection.add() with only one argument:");
 shouldBeEqualToString('testAdd(createOption("Y9"))', "0,1,2,Y9");
-shouldThrow('testAdd("foo")');
-shouldThrow("testAdd(undefined)");
-shouldThrow("testAdd(null)");
+shouldThrowErrorName('testAdd("foo")', "TypeError");
+shouldThrowErrorName("testAdd(undefined)", "TypeError");
+shouldThrowErrorName("testAdd(null)", "TypeError");
 
 debug("<br>Call HTMLOptionsCollection.add() with two arguments:");
 shouldBeEqualToString('testAdd(createGroup("Y1", "Y2"), null)', "0,1,2,Y1,Y2");
@@ -76,14 +76,15 @@ shouldBeEqualToString('testAdd(createOption("X"), mySelect.options[1])', "0,X,1,
 shouldBeEqualToString('testAdd(createOption("X"), mySelect.options[2])', "0,1,X,2");
 shouldBeEqualToString('testAdd(createOption("Y25"), 0, 1)', "Y25,0,1,2");
 shouldBeEqualToString('testAdd(createOption("Y25"), mySelect.options[0], 1)', "Y25,0,1,2");
-shouldThrow('testAdd("foo", 0)', "'TypeError: Type error'");
-shouldThrow('testAdd(undefined, 0)', "'TypeError: Type error'");
-shouldThrow('testAdd(null, 0)', "'TypeError: Type error'");
+shouldThrowErrorName('testAdd("foo", 0)', "TypeError");
+shouldThrowErrorName('testAdd(undefined, 0)', "TypeError");
+shouldThrowErrorName('testAdd(null, 0)', "TypeError");
 
 debug("<br>Call HTMLOptionsCollection.add() with three arguments (when it only takes two arguments):");
 shouldBeEqualToString('testAdd(createOption("X"), 0, "unnecessary extra argument - should be ignored")', "X,0,1,2");
 shouldBeEqualToString('testAdd(createOption("X"), mySelect.options[1], "unnecessary extra argument - should be ignored")', "0,X,1,2");
 shouldBeEqualToString('testAdd(createGroup("G1", "G2"), 1, "unnecessary extra argument - should be ignored")', "0,G1,G2,1,2");
 </script>
+<script src="../../../resources/js-test-post.js"></script>
 </body>
 </html>
index 6eaed9a..8440190 100644 (file)
@@ -12,11 +12,11 @@ PASS aNode.isSameNode(void 0) is false
 PASS aNode.lookupPrefix(aDOMImplementation) is null
 PASS aNode.lookupPrefix(void 0) is null
 PASS aNode.cloneNode(aDOMImplementation) instanceof HTMLDivElement is true
-PASS aSelect.add(aDOMImplementation, aDOMImplementation) threw exception TypeError: Type error.
-PASS aSelect.add(aDOMImplementation, anOption) threw exception TypeError: Type error.
+PASS aSelect.add(aDOMImplementation, aDOMImplementation) threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
+PASS aSelect.add(aDOMImplementation, anOption) threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
 PASS aSelect.add(anOption, aDOMImplementation) is undefined.
-PASS aSelect.add(void 0, void 0) threw exception TypeError: Type error.
-PASS aSelect.add(void 0, anOption) threw exception TypeError: Type error.
+PASS aSelect.add(void 0, void 0) threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
+PASS aSelect.add(void 0, anOption) threw exception TypeError: Argument 1 ('element') to HTMLSelectElement.add must be an instance of HTMLElement.
 PASS aSelect.add(anOption, void 0) is undefined.
 PASS successfullyParsed is true
 
index a705ccf..4249b3f 100644 (file)
@@ -34,42 +34,42 @@ PASS select1.options.length is 3
 PASS select1.selectedIndex is 0
 
 1.5 Add a non-element (string)
-PASS select1.options.add(option1) threw exception TypeError: Type error.
+PASS select1.options.add(option1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select1.options.length is 3
 PASS select1.selectedIndex is 0
 
 1.6 Add a non-element (number)
-PASS select1.options.add(option1) threw exception TypeError: Type error.
+PASS select1.options.add(option1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select1.options.length is 3
 PASS select1.selectedIndex is 0
 
 1.7 Add a non-element (boolean)
-PASS select1.options.add(option1) threw exception TypeError: Type error.
+PASS select1.options.add(option1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select1.options.length is 3
 PASS select1.selectedIndex is 0
 
 1.8 Add undefined
-PASS select1.options.add(option1) threw exception TypeError: Type error.
+PASS select1.options.add(option1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select1.options.length is 3
 PASS select1.selectedIndex is 0
 
 1.9 Add null
-PASS select1.options.add(option1) threw exception TypeError: Type error.
+PASS select1.options.add(option1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select1.options.length is 3
 PASS select1.selectedIndex is 0
 
 1.10 Add negative infinity
-PASS select1.options.add(option1) threw exception TypeError: Type error.
+PASS select1.options.add(option1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select1.options.length is 3
 PASS select1.selectedIndex is 0
 
 1.11 Add NaN
-PASS select1.options.add(option1) threw exception TypeError: Type error.
+PASS select1.options.add(option1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select1.options.length is 3
 PASS select1.selectedIndex is 0
 
 1.12 Add positive infinity
-PASS select1.options.add(option1) threw exception TypeError: Type error.
+PASS select1.options.add(option1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select1.options.length is 3
 PASS select1.selectedIndex is 0
 
@@ -183,42 +183,42 @@ PASS select2.options.length is 11
 PASS select2.selectedIndex is 4
 
 2.13 Add a non-element (string)
-PASS select2.options.add(option2, 1) threw exception TypeError: Type error.
+PASS select2.options.add(option2, 1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select2.options.length is 11
 PASS select2.selectedIndex is 4
 
 2.14 Add a non-element (number)
-PASS select2.options.add(option2, 1) threw exception TypeError: Type error.
+PASS select2.options.add(option2, 1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select2.options.length is 11
 PASS select2.selectedIndex is 4
 
 2.15 Add a non-element (boolean)
-PASS select2.options.add(option2, 1) threw exception TypeError: Type error.
+PASS select2.options.add(option2, 1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select2.options.length is 11
 PASS select2.selectedIndex is 4
 
 2.16 Add undefined
-PASS select2.options.add(option2, 1) threw exception TypeError: Type error.
+PASS select2.options.add(option2, 1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select2.options.length is 11
 PASS select2.selectedIndex is 4
 
 2.17 Add null
-PASS select2.options.add(option2, 1) threw exception TypeError: Type error.
+PASS select2.options.add(option2, 1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select2.options.length is 11
 PASS select2.selectedIndex is 4
 
 2.18 Add negative infinity
-PASS select2.options.add(option2, 1) threw exception TypeError: Type error.
+PASS select2.options.add(option2, 1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select2.options.length is 11
 PASS select2.selectedIndex is 4
 
 2.19 Add NaN
-PASS select2.options.add(option2, 1) threw exception TypeError: Type error.
+PASS select2.options.add(option2, 1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select2.options.length is 11
 PASS select2.selectedIndex is 4
 
 2.20 Add positive infinity
-PASS select2.options.add(option2, 1) threw exception TypeError: Type error.
+PASS select2.options.add(option2, 1) threw exception TypeError: Argument 1 ('element') to HTMLOptionsCollection.add must be an instance of HTMLElement.
 PASS select2.options.length is 11
 PASS select2.selectedIndex is 4
 
index a95e702..bfc5633 100644 (file)
@@ -12,7 +12,7 @@ PASS getChannelData(1) returns a Float32Array object.
 PASS getChannelData(2) returns a Float32Array object.
 PASS getChannelData(3) returns a Float32Array object.
 PASS Exception has been thrown correctly when index is not less than numberOfChannels.
-PASS context.createBuffer(null, false) threw exception TypeError: Type error.
+PASS context.createBuffer(null, false) threw exception TypeError: Argument 1 ('buffer') to webkitAudioContext.createBuffer must be an instance of ArrayBuffer.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index b705fe2..f0dddf0 100644 (file)
@@ -49,7 +49,7 @@ try {
     testPassed("Exception has been thrown correctly when index is not less than numberOfChannels.");
 }
 
-shouldThrow("context.createBuffer(null, false)", "'TypeError: Type error'");
+shouldThrowErrorName("context.createBuffer(null, false)", "TypeError");
 
 </script>
 
index c623be2..7ecc763 100644 (file)
@@ -71,7 +71,7 @@ function test(desc, func, expected) {
         exc = x;
     }
 
-    if (expected == gl.INVALID_OPERATION) {
+    if (expected == gl.INVALID_OPERATION || expected == gl.INVALID_VALUE) {
       glErrorShouldBe(gl, expected);
     } else if (expected == "exception") {
         if (exc) {
@@ -89,17 +89,18 @@ test("Passing a buffer not large enough to texImage2D should generate an INVALID
      },
      gl.INVALID_OPERATION);
 
-test("Passing texImage2D parameter data of Number type should throw an exception",
+// We do not do strict type checking for ArrayBufferView type.
+test("Passing texImage2D parameter data of Number type should generate an INVALID_OPERATION",
      function () {
         gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, 42);
      },
-     "exception");
+     gl.INVALID_OPERATION);
 
-test("Passing texImage2D parameter data of String type should throw a TypeError",
+test("Passing texImage2D parameter data of String type should generate an INVALID_OPERATION",
      function () {
         gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
      },
-     "exception");
+     gl.INVALID_OPERATION);
 test("Passing a buffer not large enough to texSubImage2D should generate an INVALID_OPERATION",
      function () {
         var tooSmall = new Uint8Array(64);
@@ -107,17 +108,17 @@ test("Passing a buffer not large enough to texSubImage2D should generate an INVA
      },
      gl.INVALID_OPERATION);
 
-test("Passing texSubImage2D parameter data of Number type should throw a TypeError",
+test("Passing texSubImage2D parameter data of Number type should generate an INVALID_VALUE",
      function () {
         gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, 42);
      },
-     "exception");
+     gl.INVALID_VALUE);
 
-test("Passing texSubImage2D parameter data of String type should throw a TypeError",
+test("Passing texSubImage2D parameter data of String type should generate an INVALID_VALUE",
      function () {
         gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 64, 64, gl.RGBA, gl.UNSIGNED_BYTE, "not a buffer");
      },
-     "exception");
+     gl.INVALID_VALUE);
 
 debug("");
 var successfullyParsed = true;
index ea1dd6f..b3b753b 100644 (file)
@@ -1,3 +1,60 @@
+2016-08-02  Chris Dumez  <cdumez@apple.com>
+
+        [WebIDL] Implement overload resolution algorithm
+        https://bugs.webkit.org/show_bug.cgi?id=160394
+
+        Reviewed by Darin Adler.
+
+        Implement overload resolution algorithm:
+        - http://heycam.github.io/webidl/#es-overloads
+
+        This means that our support for operation overloading in our IDL is
+        now a lot more extensive than it used to be and is now compliant with
+        the Web IDL specification.
+
+        In particular, overloading should now work for a lot more parameter
+        types which means that:
+        - We should be able to drop some custom bindings code in a follow-up patch.
+        - We will be able to drop the [StrictTypeChecking] attribute which was
+          a hack used to make overloading work for parameters of type DOMString.
+
+        Also, the order of the overloads in the IDL no longer impacts the
+        generated bindings code. It used to be that you needed to put the
+        overloads with the more specific parameter types first in order for the
+        generated bindings code to be somewhat correct.
+
+        No new tests, rebaselined bindings tests.
+
+        * bindings/scripts/CodeGenerator.pm:
+        (IsStringOrEnumType):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (IsNullableType):
+        (StripNullable):
+        (ComputeEffectiveOverloadSet):
+        (AreTypesDistinguishableForOverloadResolution):
+        (GetDistinguishingArgumentIndex):
+        (GetOverloadThatMatches):
+        (GenerateOverloadedFunction):
+        * bindings/scripts/test/JS/JSTestGlobalObject.cpp:
+        (WebCore::jsTestGlobalObjectInstanceFunctionEnabledAtRuntimeOperation):
+        * bindings/scripts/test/JS/JSTestObj.cpp:
+        (WebCore::jsTestObjPrototypeFunctionEnabledAtRuntimeOperation):
+        (WebCore::jsTestObjPrototypeFunctionOverloadedMethod):
+        (WebCore::jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter1):
+        (WebCore::jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter):
+        (WebCore::jsTestObjConstructorFunctionOverloadedMethod1):
+        (WebCore::jsTestObjPrototypeFunctionTestPromiseOverloadedFunction):
+        (WebCore::jsTestObjConstructorFunctionOverloadedMethod12): Deleted.
+        (WebCore::jsTestObjPrototypeFunctionTestPromiseOverloadedFunction2Promise): Deleted.
+        * bindings/scripts/test/TestObj.idl:
+        * dom/EventTarget.h:
+        * dom/EventTarget.idl:
+        * html/HTMLOptionsCollection.h:
+        * html/HTMLOptionsCollection.idl:
+        * html/HTMLSelectElement.h:
+        (WebCore::HTMLSelectElement::add):
+        * html/HTMLSelectElement.idl:
+
 2016-08-02  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [macOS] Guard workaround in r203314 for only OSes which need it
index f8fba19..f0cb089 100644 (file)
@@ -358,6 +358,15 @@ sub IsNumericType
     return 0;
 }
 
+sub IsStringOrEnumType
+{
+    my ($object, $type) = @_;
+    
+    return 1 if $type eq "DOMString";
+    return 1 if $object->IsEnumType($type);
+    return 0;
+}
+
 sub IsIntegerType
 {
     my ($object, $type) = @_;
index a0a5f7f..9ff301c 100644 (file)
@@ -1643,6 +1643,305 @@ sub GeneratePropertiesHashTable
     return $propertyCount;
 }
 
+sub IsNullableType
+{
+    my $type = shift;
+
+    return substr($type, -1) eq "?";
+}
+
+sub StripNullable
+{
+    my $type = shift;
+
+    chop($type) if IsNullableType($type);
+    return $type;
+}
+
+# This computes an effective overload set for a given operation / constructor,
+# which represents the allowable invocations.This set is used as input for
+# the Web IDL overload resolution algorithm.
+# http://heycam.github.io/webidl/#dfn-effective-overload-set
+sub ComputeEffectiveOverloadSet
+{
+    my ($overloads) = @_;
+
+    my %allSets;
+    my $addTuple = sub {
+        my $tuple = shift;
+        # The Web IDL specification uses a flat set of tuples but we use a hash where the key is the
+        # number of parameters and the value is the set of tuples for the given number of parameters.
+        my $length = scalar(@{@$tuple[1]});
+        if (!exists($allSets{$length})) {
+            $allSets{$length} = [ $tuple ];
+        } else {
+            push(@{$allSets{$length}}, $tuple);
+        }
+    };
+
+    my $m = LengthOfLongestFunctionParameterList($overloads);
+    foreach my $overload (@{$overloads}) {
+        my $n = @{$overload->parameters};
+        my @t;
+        my @o;
+        my $isVariadic = 0;
+        foreach my $parameter (@{$overload->parameters}) {
+            push(@t, $parameter->isNullable ? $parameter->type . "?" : $parameter->type);
+            if ($parameter->isOptional) {
+                push(@o, "optional");
+            } elsif ($parameter->isVariadic) {
+                push(@o, "variadic");
+                $isVariadic = 1;
+            } else {
+                push(@o, "required");
+            }
+        }
+        &$addTuple([$overload, [@t], [@o]]);
+        if ($isVariadic) {
+            my @newT = @t;
+            my @newO = @o;
+            for (my $i = $n; $i < $m; $i++) {
+                push(@newT, $t[-1]);
+                push(@newO, "variadic");
+                &$addTuple([$overload, [@newT], [@newO]]);
+            }
+        }
+        for (my $i = $n - 1; $i >= 0; $i--) {
+            my $parameter = @{$overload->parameters}[$i];
+            last unless ($parameter->isOptional || $parameter->isVariadic);
+            pop(@t);
+            pop(@o);
+            &$addTuple([$overload, [@t], [@o]]);
+        }
+    }
+    return %allSets;
+}
+
+# Determines if two types are distinguishable in the context of overload resolution,
+# according to the Web IDL specification:
+# http://heycam.github.io/webidl/#dfn-distinguishable
+sub AreTypesDistinguishableForOverloadResolution
+{
+    my ($typeA, $typeB) = @_;
+
+    my $isDictionary = sub {
+        my $type = shift;
+        return $type eq "Dictionary" || $codeGenerator->IsDictionaryType($type);
+    };
+    my $isCallbackFunctionOrDictionary = sub {
+        my $type = shift;
+        return $codeGenerator->IsFunctionOnlyCallbackInterface($type) || &$isDictionary($type);
+    };
+
+    # FIXME: The WebIDL mandates this but this currently does not work because some of our IDL is wrong.
+    # return 0 if IsNullableType($typeA) && IsNullableType($typeB);
+
+    $typeA = StripNullable($typeA);
+    $typeB = StripNullable($typeB);
+
+    return 0 if $typeA eq $typeB;
+    return 0 if $typeA eq "object" or $typeB eq "object";
+    return 0 if $codeGenerator->IsNumericType($typeA) && $codeGenerator->IsNumericType($typeB);
+    return 0 if $codeGenerator->IsStringOrEnumType($typeA) && $codeGenerator->IsStringOrEnumType($typeB);
+    return 0 if &$isDictionary($typeA) && &$isDictionary($typeB);
+    return 0 if $codeGenerator->IsCallbackInterface($typeA) && $codeGenerator->IsCallbackInterface($typeB);
+    return 0 if &$isCallbackFunctionOrDictionary($typeA) && &$isCallbackFunctionOrDictionary($typeB);
+    return 0 if $codeGenerator->GetArrayOrSequenceType($typeA) && $codeGenerator->GetArrayOrSequenceType($typeB);
+    # FIXME: return 0 if typeA and typeB are both exception types.
+    return 1;
+}
+
+# If there is more than one entry in an effective overload set that has a given type list length,
+# then for those entries there must be an index i such that for each pair of entries the types
+# at index i are distinguishable. The lowest such index is termed the distinguishing argument index.
+# http://heycam.github.io/webidl/#dfn-distinguishing-argument-index
+sub GetDistinguishingArgumentIndex
+{
+    my ($function, $S) = @_;
+
+    # FIXME: Consider all the tuples, not just the 2 first ones?
+    my $firstTupleTypes = @{@{$S}[0]}[1];
+    my $secondTupleTypes = @{@{$S}[1]}[1];
+    for (my $index = 0; $index < scalar(@$firstTupleTypes); $index++) {
+        return $index if AreTypesDistinguishableForOverloadResolution(@{$firstTupleTypes}[$index], @{$secondTupleTypes}[$index]);
+    }
+    die "Undistinguishable overloads for operation " . $function->signature->name . " with length: " . scalar(@$firstTupleTypes);
+}
+
+sub GetOverloadThatMatches
+{
+    my ($S, $parameterIndex, $matches) = @_;
+
+    for my $tuple (@{$S}) {
+        my $type = @{@{$tuple}[1]}[$parameterIndex];
+        my $optionality = @{@{$tuple}[2]}[$parameterIndex];
+        my $isNullable = IsNullableType($type);
+        return @{$tuple}[0] if $matches->(StripNullable($type), $optionality, $isNullable);
+    }
+}
+
+# Implements the overload resolution algorithm, as defined in the Web IDL specification:
+# http://heycam.github.io/webidl/#es-overloads
+sub GenerateOverloadedFunction
+{
+    my ($function, $interface) = @_;
+    my %allSets = ComputeEffectiveOverloadSet($function->{overloads});
+
+    my $kind = $function->isStatic ? "Constructor" : (OperationShouldBeOnInstance($interface, $function) ? "Instance" : "Prototype");
+    my $interfaceName = $interface->name;
+    my $functionName = "js${interfaceName}${kind}Function" . $codeGenerator->WK_ucfirst($function->signature->name);
+
+    my $generateOverloadCallIfNecessary = sub {
+        my ($overload, $condition) = @_;
+        return unless $overload;
+        my $conditionalString = $codeGenerator->GenerateConditionalString($overload->signature);
+        push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
+        push(@implContent, "        if ($condition)\n    ") if $condition;
+        push(@implContent, "        return ${functionName}$overload->{overloadIndex}(state);\n");
+        push(@implContent, "#endif\n") if $conditionalString;
+    };
+    my $isOptionalParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $optionality eq "optional";
+    };
+    my $isDictionaryParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $type eq "Dictionary" || $codeGenerator->IsDictionaryType($type);
+    };
+    my $isNullableOrDictionaryParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $isNullable || &$isDictionaryParameter($type, $optionality, $isNullable);
+    };
+    my $isRegExpOrObjectParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $type eq "RegExp" || $type eq "object";
+    };
+    my $isObjectOrErrorParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $type eq "object" || $type eq "Error";
+    };
+    my $isObjectOrErrorOrDOMExceptionParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return 1 if &$isObjectOrErrorParameter($type, $optionality, $isNullable);
+        return $type eq "DOMException";
+    };
+    my $isObjectOrCallbackFunctionParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $type eq "object" || $codeGenerator->IsFunctionOnlyCallbackInterface($type);
+    };
+    my $isArrayOrSequenceParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $codeGenerator->GetArrayOrSequenceType($type);
+    };
+    my $isDictionaryOrObjectOrCallbackInterfaceParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return 1 if &$isDictionaryParameter($type, $optionality, $isNullable);
+        return 1 if $type eq "object";
+        return 1 if $codeGenerator->IsCallbackInterface($type) && !$codeGenerator->IsFunctionOnlyCallbackInterface($type);
+        return 0;
+    };
+    my $isBooleanParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $type eq "boolean";
+    };
+    my $isNumericParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $codeGenerator->IsNumericType($type);
+    };
+    my $isStringOrEnumParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $codeGenerator->IsStringOrEnumType($type);
+    };
+    my $isAnyParameter = sub {
+        my ($type, $optionality, $isNullable) = @_;
+        return $type eq "any";
+    };
+
+    my $maxArgCount = LengthOfLongestFunctionParameterList($function->{overloads});
+
+    push(@implContent, <<END);    
+EncodedJSValue JSC_HOST_CALL ${functionName}(ExecState* state)
+{
+    size_t argsCount = std::min<size_t>($maxArgCount, state->argumentCount());
+END
+
+    for my $length ( sort keys %allSets ) {
+        push(@implContent, <<END);
+    if (argsCount == $length) {
+END
+        my $S = $allSets{$length};
+        if (scalar(@$S) > 1) {
+            my $d = GetDistinguishingArgumentIndex($function, $S);
+            push(@implContent, "        JSValue distinguishingArg = state->uncheckedArgument($d);\n");
+
+            my $overload = GetOverloadThatMatches($S, $d, \&$isOptionalParameter);
+            &$generateOverloadCallIfNecessary($overload, "distinguishingArg.isUndefined()");
+
+            $overload = GetOverloadThatMatches($S, $d, \&$isNullableOrDictionaryParameter);
+            &$generateOverloadCallIfNecessary($overload, "distinguishingArg.isUndefinedOrNull()");
+
+            for my $tuple (@{$S}) {
+                my $overload = @{$tuple}[0];
+                my $type = StripNullable(@{@{$tuple}[1]}[$d]);
+                if ($codeGenerator->IsWrapperType($type) || $codeGenerator->IsTypedArrayType($type)) {
+                    &$generateOverloadCallIfNecessary($overload, "distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JS${type}::info())");
+                }
+            }
+
+            $overload = GetOverloadThatMatches($S, $d, \&$isRegExpOrObjectParameter);
+            &$generateOverloadCallIfNecessary($overload, "distinguishingArg.isObject() && asObject(distinguishingArg)->type() == RegExpObjectType");
+
+            $overload = GetOverloadThatMatches($S, $d, \&$isObjectOrErrorOrDOMExceptionParameter);
+            &$generateOverloadCallIfNecessary($overload, "distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSDOMCoreException::info())");
+
+            $overload = GetOverloadThatMatches($S, $d, \&$isObjectOrErrorParameter);
+            &$generateOverloadCallIfNecessary($overload, "distinguishingArg.isObject() && asObject(distinguishingArg)->type() == ErrorInstanceType");
+
+            $overload = GetOverloadThatMatches($S, $d, \&$isObjectOrCallbackFunctionParameter);
+            &$generateOverloadCallIfNecessary($overload, "distinguishingArg.isFunction()");
+
+            $overload = GetOverloadThatMatches($S, $d, \&$isArrayOrSequenceParameter);
+            &$generateOverloadCallIfNecessary($overload, "distinguishingArg.isObject() && isJSArray(distinguishingArg)");
+
+            $overload = GetOverloadThatMatches($S, $d, \&$isDictionaryOrObjectOrCallbackInterfaceParameter);
+            &$generateOverloadCallIfNecessary($overload, "distinguishingArg.isObject() && asObject(distinguishingArg)->type() != RegExpObjectType");
+
+            my $booleanOverload = GetOverloadThatMatches($S, $d, \&$isBooleanParameter);
+            &$generateOverloadCallIfNecessary($booleanOverload, "distinguishingArg.isBoolean()");
+
+            my $numericOverload = GetOverloadThatMatches($S, $d, \&$isNumericParameter);
+            &$generateOverloadCallIfNecessary($numericOverload, "distinguishingArg.isNumber()");
+
+            # Fallbacks.
+            $overload = GetOverloadThatMatches($S, $d, \&$isStringOrEnumParameter);
+            if ($overload) {
+                &$generateOverloadCallIfNecessary($overload);
+            } elsif ($numericOverload) {
+                &$generateOverloadCallIfNecessary($numericOverload);
+            } elsif ($booleanOverload) {
+                &$generateOverloadCallIfNecessary($booleanOverload);
+            } else {
+                $overload = GetOverloadThatMatches($S, $d, \&$isAnyParameter);
+                &$generateOverloadCallIfNecessary($overload);
+            }
+        } else {
+            # Only 1 overload with this number of parameters.
+            my $overload = @{@{$S}[0]}[0];
+            &$generateOverloadCallIfNecessary($overload);
+        }
+        push(@implContent, <<END);
+    }
+END
+    }
+    my $minArgCount = GetFunctionLength($function);
+    if ($minArgCount > 0) {
+        push(@implContent, "    return argsCount < $minArgCount ? throwVMError(state, createNotEnoughArgumentsError(state)) : throwVMTypeError(state);\n")
+    } else {
+        push(@implContent, "    return throwVMTypeError(state);\n")
+    }
+    push(@implContent, "}\n\n");
+}
+
 sub GenerateParametersCheckExpression
 {
     my $numParameters = shift;
@@ -1768,61 +2067,6 @@ sub LengthOfLongestFunctionParameterList
     return $result;
 }
 
-sub GenerateOverloadedFunction
-{
-    my ($function, $interface) = @_;
-
-    # Generate code for choosing the correct overload to call. Overloads are
-    # chosen based on the total number of arguments passed and the type of
-    # values passed in non-primitive argument slots. When more than a single
-    # overload is applicable, precedence is given according to the order of
-    # declaration in the IDL.
-
-    my $kind = $function->isStatic ? "Constructor" : (OperationShouldBeOnInstance($interface, $function) ? "Instance" : "Prototype");
-    my $interfaceName = $interface->name;
-    my $functionName = "js${interfaceName}${kind}Function" . $codeGenerator->WK_ucfirst($function->signature->name);
-
-    # FIXME: Implement support for overloaded functions with variadic arguments.
-    my $lengthOfLongestOverloadedFunctionParameterList = LengthOfLongestFunctionParameterList($function->{overloads});
-
-    push(@implContent, "EncodedJSValue JSC_HOST_CALL ${functionName}(ExecState* state)\n");
-    push(@implContent, <<END);
-{
-    size_t argsCount = std::min<size_t>($lengthOfLongestOverloadedFunctionParameterList, state->argumentCount());
-END
-
-    my %fetchedArguments = ();
-    my $leastNumMandatoryParams = 255;
-
-    foreach my $overload (@{$function->{overloads}}) {
-        my ($numMandatoryParams, $parametersCheck, @neededArguments) = GenerateFunctionParametersCheck($overload);
-        $leastNumMandatoryParams = $numMandatoryParams if ($numMandatoryParams < $leastNumMandatoryParams);
-
-        foreach my $parameterIndex (@neededArguments) {
-            next if exists $fetchedArguments{$parameterIndex};
-            push(@implContent, "    JSValue arg$parameterIndex(state->argument($parameterIndex));\n");
-            $fetchedArguments{$parameterIndex} = 1;
-        }
-
-        my $conditionalString = $codeGenerator->GenerateConditionalString($overload->signature);
-        push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
-
-        push(@implContent, "    if ($parametersCheck)\n");
-        push(@implContent, "        return ${functionName}$overload->{overloadIndex}(state);\n");
-        push(@implContent, "#endif\n\n") if $conditionalString;
-
-    }
-    if ($leastNumMandatoryParams >= 1) {
-        push(@implContent, "    if (UNLIKELY(argsCount < $leastNumMandatoryParams))\n");
-        push(@implContent, "        return throwVMError(state, createNotEnoughArgumentsError(state));\n");
-    }
-    push(@implContent, <<END);
-    return throwVMTypeError(state);
-}
-
-END
-}
-
 sub GetNativeTypeForConversions
 {
     my $interface = shift;
index 492a6f5..e7d952c 100644 (file)
@@ -398,19 +398,17 @@ static inline EncodedJSValue jsTestGlobalObjectInstanceFunctionEnabledAtRuntimeO
 EncodedJSValue JSC_HOST_CALL jsTestGlobalObjectInstanceFunctionEnabledAtRuntimeOperation(ExecState* state)
 {
     size_t argsCount = std::min<size_t>(1, state->argumentCount());
+    if (argsCount == 1) {
+        JSValue distinguishingArg = state->uncheckedArgument(0);
 #if ENABLE(TEST_FEATURE)
-    if (argsCount == 1)
-        return jsTestGlobalObjectInstanceFunctionEnabledAtRuntimeOperation1(state);
+        if (distinguishingArg.isNumber())
+            return jsTestGlobalObjectInstanceFunctionEnabledAtRuntimeOperation2(state);
 #endif
-
 #if ENABLE(TEST_FEATURE)
-    if (argsCount == 1)
-        return jsTestGlobalObjectInstanceFunctionEnabledAtRuntimeOperation2(state);
+        return jsTestGlobalObjectInstanceFunctionEnabledAtRuntimeOperation1(state);
 #endif
-
-    if (UNLIKELY(argsCount < 1))
-        return throwVMError(state, createNotEnoughArgumentsError(state));
-    return throwVMTypeError(state);
+    }
+    return argsCount < 1 ? throwVMError(state, createNotEnoughArgumentsError(state)) : throwVMTypeError(state);
 }
 
 #if ENABLE(TEST_FEATURE)
index 10be464..1c1591a 100644 (file)
@@ -3869,19 +3869,17 @@ static inline EncodedJSValue jsTestObjPrototypeFunctionEnabledAtRuntimeOperation
 EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionEnabledAtRuntimeOperation(ExecState* state)
 {
     size_t argsCount = std::min<size_t>(1, state->argumentCount());
+    if (argsCount == 1) {
+        JSValue distinguishingArg = state->uncheckedArgument(0);
 #if ENABLE(TEST_FEATURE)
-    if (argsCount == 1)
-        return jsTestObjPrototypeFunctionEnabledAtRuntimeOperation1(state);
+        if (distinguishingArg.isNumber())
+            return jsTestObjPrototypeFunctionEnabledAtRuntimeOperation2(state);
 #endif
-
 #if ENABLE(TEST_FEATURE)
-    if (argsCount == 1)
-        return jsTestObjPrototypeFunctionEnabledAtRuntimeOperation2(state);
+        return jsTestObjPrototypeFunctionEnabledAtRuntimeOperation1(state);
 #endif
-
-    if (UNLIKELY(argsCount < 1))
-        return throwVMError(state, createNotEnoughArgumentsError(state));
-    return throwVMTypeError(state);
+    }
+    return argsCount < 1 ? throwVMError(state, createNotEnoughArgumentsError(state)) : throwVMTypeError(state);
 }
 
 EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionVoidMethod(ExecState* state)
@@ -5422,34 +5420,41 @@ static inline EncodedJSValue jsTestObjPrototypeFunctionOverloadedMethod12(ExecSt
 EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethod(ExecState* state)
 {
     size_t argsCount = std::min<size_t>(2, state->argumentCount());
-    JSValue arg0(state->argument(0));
-    JSValue arg1(state->argument(1));
-    if ((argsCount == 2 && (arg0.isUndefinedOrNull() || (arg0.isObject() && asObject(arg0)->inherits(JSTestObj::info()))) && (arg1.isUndefinedOrNull() || arg1.isString() || arg1.isObject())))
-        return jsTestObjPrototypeFunctionOverloadedMethod1(state);
-    if ((argsCount == 1 && (arg0.isUndefinedOrNull() || (arg0.isObject() && asObject(arg0)->inherits(JSTestObj::info())))) || (argsCount == 2 && (arg0.isUndefinedOrNull() || (arg0.isObject() && asObject(arg0)->inherits(JSTestObj::info())))))
-        return jsTestObjPrototypeFunctionOverloadedMethod2(state);
-    if ((argsCount == 1 && (arg0.isUndefinedOrNull() || arg0.isString() || arg0.isObject())))
-        return jsTestObjPrototypeFunctionOverloadedMethod3(state);
-    if (argsCount == 1)
-        return jsTestObjPrototypeFunctionOverloadedMethod4(state);
-    if ((argsCount == 1 && (arg0.isNull() || arg0.isObject())))
-        return jsTestObjPrototypeFunctionOverloadedMethod5(state);
-    if ((argsCount == 1 && (arg0.isUndefinedOrNull() || (arg0.isObject() && asObject(arg0)->inherits(JSDOMStringList::info())))))
-        return jsTestObjPrototypeFunctionOverloadedMethod6(state);
-    if ((argsCount == 1 && (arg0.isUndefinedOrNull() || (arg0.isObject() && isJSArray(arg0)))))
-        return jsTestObjPrototypeFunctionOverloadedMethod7(state);
-    if ((argsCount == 1 && ((arg0.isObject() && asObject(arg0)->inherits(JSTestObj::info())))))
-        return jsTestObjPrototypeFunctionOverloadedMethod8(state);
-    if ((argsCount == 1 && ((arg0.isObject() && isJSArray(arg0)))))
-        return jsTestObjPrototypeFunctionOverloadedMethod9(state);
-    if ((argsCount == 1 && ((arg0.isObject() && isJSArray(arg0)))))
-        return jsTestObjPrototypeFunctionOverloadedMethod10(state);
-    if (argsCount == 1)
-        return jsTestObjPrototypeFunctionOverloadedMethod11(state);
-    if ()
+    if (argsCount == 0) {
         return jsTestObjPrototypeFunctionOverloadedMethod12(state);
-    if (UNLIKELY(argsCount < 1))
-        return throwVMError(state, createNotEnoughArgumentsError(state));
+    }
+    if (argsCount == 1) {
+        JSValue distinguishingArg = state->uncheckedArgument(0);
+        if (distinguishingArg.isUndefinedOrNull())
+            return jsTestObjPrototypeFunctionOverloadedMethod2(state);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSTestObj::info()))
+            return jsTestObjPrototypeFunctionOverloadedMethod2(state);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSTestCallback::info()))
+            return jsTestObjPrototypeFunctionOverloadedMethod5(state);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSDOMStringList::info()))
+            return jsTestObjPrototypeFunctionOverloadedMethod6(state);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSTestObj::info()))
+            return jsTestObjPrototypeFunctionOverloadedMethod8(state);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSBlob::info()))
+            return jsTestObjPrototypeFunctionOverloadedMethod12(state);
+        if (distinguishingArg.isObject() && isJSArray(distinguishingArg))
+            return jsTestObjPrototypeFunctionOverloadedMethod7(state);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->type() != RegExpObjectType)
+            return jsTestObjPrototypeFunctionOverloadedMethod5(state);
+        if (distinguishingArg.isNumber())
+            return jsTestObjPrototypeFunctionOverloadedMethod4(state);
+        return jsTestObjPrototypeFunctionOverloadedMethod3(state);
+    }
+    if (argsCount == 2) {
+        JSValue distinguishingArg = state->uncheckedArgument(1);
+        if (distinguishingArg.isUndefined())
+            return jsTestObjPrototypeFunctionOverloadedMethod2(state);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSBlob::info()))
+            return jsTestObjPrototypeFunctionOverloadedMethod12(state);
+        if (distinguishingArg.isNumber())
+            return jsTestObjPrototypeFunctionOverloadedMethod2(state);
+        return jsTestObjPrototypeFunctionOverloadedMethod1(state);
+    }
     return throwVMTypeError(state);
 }
 
@@ -5463,19 +5468,16 @@ static inline EncodedJSValue jsTestObjPrototypeFunctionOverloadedMethodWithOptio
     auto& impl = castedThis->wrapped();
     if (UNLIKELY(state->argumentCount() < 1))
         return throwVMError(state, createNotEnoughArgumentsError(state));
-    TestObj* objArg1 = nullptr;
-    if (!state->argument(0).isUndefinedOrNull()) {
-        objArg1 = JSTestObj::toWrapped(state->uncheckedArgument(0));
-        if (UNLIKELY(!objArg1))
-            return throwArgumentTypeError(*state, 0, "objArg1", "TestObject", "overloadedMethodWithOptionalParameter", "TestObj");
-    }
-    TestObj* objArg2 = nullptr;
+    auto strArg = state->argument(0).toWTFString(state);
+    if (UNLIKELY(state->hadException()))
+        return JSValue::encode(jsUndefined());
+    TestObj* objArg = nullptr;
     if (!state->argument(1).isUndefinedOrNull()) {
-        objArg2 = JSTestObj::toWrapped(state->uncheckedArgument(1));
-        if (UNLIKELY(!objArg2))
-            return throwArgumentTypeError(*state, 1, "objArg2", "TestObject", "overloadedMethodWithOptionalParameter", "TestObj");
+        objArg = JSTestObj::toWrapped(state->uncheckedArgument(1));
+        if (UNLIKELY(!objArg))
+            return throwArgumentTypeError(*state, 1, "objArg", "TestObject", "overloadedMethodWithOptionalParameter", "TestObj");
     }
-    impl.overloadedMethodWithOptionalParameter(WTFMove(objArg1), WTFMove(objArg2));
+    impl.overloadedMethodWithOptionalParameter(WTFMove(strArg), WTFMove(objArg));
     return JSValue::encode(jsUndefined());
 }
 
@@ -5505,15 +5507,23 @@ static inline EncodedJSValue jsTestObjPrototypeFunctionOverloadedMethodWithOptio
 EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter(ExecState* state)
 {
     size_t argsCount = std::min<size_t>(2, state->argumentCount());
-    JSValue arg0(state->argument(0));
-    JSValue arg1(state->argument(1));
-    if ((argsCount == 1 && (arg0.isUndefinedOrNull() || (arg0.isObject() && asObject(arg0)->inherits(JSTestObj::info())))) || (argsCount == 2 && (arg0.isUndefinedOrNull() || (arg0.isObject() && asObject(arg0)->inherits(JSTestObj::info()))) && (arg1.isUndefinedOrNull() || (arg1.isObject() && asObject(arg1)->inherits(JSTestObj::info())))))
+    if (argsCount == 1) {
+        JSValue distinguishingArg = state->uncheckedArgument(0);
+        if (distinguishingArg.isUndefinedOrNull())
+            return jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter2(state);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSTestObj::info()))
+            return jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter2(state);
         return jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter1(state);
-    if ((argsCount == 1 && (arg0.isUndefinedOrNull() || (arg0.isObject() && asObject(arg0)->inherits(JSTestObj::info())))) || (argsCount == 2 && (arg0.isUndefinedOrNull() || (arg0.isObject() && asObject(arg0)->inherits(JSTestObj::info())))))
-        return jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter2(state);
-    if (UNLIKELY(argsCount < 1))
-        return throwVMError(state, createNotEnoughArgumentsError(state));
-    return throwVMTypeError(state);
+    }
+    if (argsCount == 2) {
+        JSValue distinguishingArg = state->uncheckedArgument(0);
+        if (distinguishingArg.isUndefinedOrNull())
+            return jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter2(state);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSTestObj::info()))
+            return jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter2(state);
+        return jsTestObjPrototypeFunctionOverloadedMethodWithOptionalParameter1(state);
+    }
+    return argsCount < 1 ? throwVMError(state, createNotEnoughArgumentsError(state)) : throwVMTypeError(state);
 }
 
 EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionClassMethod(ExecState* state)
@@ -5569,20 +5579,17 @@ static inline EncodedJSValue jsTestObjConstructorFunctionOverloadedMethod12(Exec
 EncodedJSValue JSC_HOST_CALL jsTestObjConstructorFunctionOverloadedMethod1(ExecState* state)
 {
     size_t argsCount = std::min<size_t>(1, state->argumentCount());
+    if (argsCount == 1) {
+        JSValue distinguishingArg = state->uncheckedArgument(0);
 #if ENABLE(Condition1)
-    if (argsCount == 1)
-        return jsTestObjConstructorFunctionOverloadedMethod11(state);
+        if (distinguishingArg.isNumber())
+            return jsTestObjConstructorFunctionOverloadedMethod11(state);
 #endif
-
-    JSValue arg0(state->argument(0));
 #if ENABLE(Condition1)
-    if ((argsCount == 1 && (arg0.isUndefinedOrNull() || arg0.isString() || arg0.isObject())))
         return jsTestObjConstructorFunctionOverloadedMethod12(state);
 #endif
-
-    if (UNLIKELY(argsCount < 1))
-        return throwVMError(state, createNotEnoughArgumentsError(state));
-    return throwVMTypeError(state);
+    }
+    return argsCount < 1 ? throwVMError(state, createNotEnoughArgumentsError(state)) : throwVMTypeError(state);
 }
 
 EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionClassMethodWithClamp(ExecState* state)
@@ -6082,14 +6089,15 @@ static inline EncodedJSValue jsTestObjPrototypeFunctionTestPromiseOverloadedFunc
 EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionTestPromiseOverloadedFunction(ExecState* state)
 {
     size_t argsCount = std::min<size_t>(1, state->argumentCount());
-    if (argsCount == 1)
+    if (argsCount == 1) {
+        JSValue distinguishingArg = state->uncheckedArgument(0);
+        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSFetchRequest::info()))
+            return jsTestObjPrototypeFunctionTestPromiseOverloadedFunction2(state);
+        if (distinguishingArg.isNumber())
+            return jsTestObjPrototypeFunctionTestPromiseOverloadedFunction1(state);
         return jsTestObjPrototypeFunctionTestPromiseOverloadedFunction1(state);
-    JSValue arg0(state->argument(0));
-    if ((argsCount == 1 && ((arg0.isObject() && asObject(arg0)->inherits(JSFetchRequest::info())))))
-        return jsTestObjPrototypeFunctionTestPromiseOverloadedFunction2(state);
-    if (UNLIKELY(argsCount < 1))
-        return throwVMError(state, createNotEnoughArgumentsError(state));
-    return throwVMTypeError(state);
+    }
+    return argsCount < 1 ? throwVMError(state, createNotEnoughArgumentsError(state)) : throwVMTypeError(state);
 }
 
 static EncodedJSValue jsTestObjConstructorFunctionTestStaticPromiseFunctionPromise(ExecState*, JSPromiseDeferred*);
index 30252a8..417d91c 100644 (file)
@@ -266,7 +266,7 @@ enum TestConfidence { "high", "kinda-low" };
     // FIXME: Implement support for overloaded functions with variadic arguments.
     void    overloadedMethod(Blob... blobArgs);
 
-    void overloadedMethodWithOptionalParameter(TestObj? objArg1, optional TestObj? objArg2 = null);
+    void overloadedMethodWithOptionalParameter(DOMString strArg, optional TestObj? objArg = null);
     void overloadedMethodWithOptionalParameter(TestObj? objArg, optional long longArg);
 #endif
 
@@ -277,7 +277,7 @@ enum TestConfidence { "high", "kinda-low" };
 
     // Static method with conditional on overloaded methods
     [Conditional=Condition1] static void overloadedMethod1(long arg);
-    [Conditional=Condition1] static void overloadedMethod1([StrictTypeChecking] DOMString type);
+    [Conditional=Condition1] static void overloadedMethod1(DOMString type);
 
     void classMethodWithClamp([Clamp] unsigned short objArgsShort, [Clamp] unsigned long objArgsLong);
     void classMethodWithEnforceRange([EnforceRange] unsigned short objArgsShort, [EnforceRange] unsigned long objArgsLong);
index 053feb2..43982a6 100644 (file)
@@ -139,8 +139,8 @@ public:
         bool once;
     };
 
-    void addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture);
-    void removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture);
+    void addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture = false);
+    void removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture = false);
     void addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, const AddEventListenerOptions&);
     void removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, const ListenerOptions&);
     virtual bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions& = { });
index 000d1d9..119279b 100644 (file)
     ObjCProtocol,
 ] interface EventTarget {
 #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
-    [ImplementedAs=addEventListenerForBindings] void addEventListener([AtomicString] DOMString type, EventListener? listener, optional AddEventListenerOptions options);
-    [ImplementedAs=removeEventListenerForBindings] void removeEventListener([AtomicString] DOMString type, EventListener? listener, optional EventListenerOptions options);
+    // FIXME: Should be:
+    // void addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options);
+    // void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
+    [ImplementedAs=addEventListenerForBindings] void addEventListener([AtomicString] DOMString type, EventListener? listener);
+    [ImplementedAs=addEventListenerForBindings] void addEventListener([AtomicString] DOMString type, EventListener? listener, AddEventListenerOptions options);
+    [ImplementedAs=removeEventListenerForBindings] void removeEventListener([AtomicString] DOMString type, EventListener? listener);
+    [ImplementedAs=removeEventListenerForBindings] void removeEventListener([AtomicString] DOMString type, EventListener? listener, EventListenerOptions options);
 #endif
 
-    [ObjCLegacyUnnamedParameters, ImplementedAs=addEventListenerForBindings] void addEventListener([AtomicString] DOMString type, EventListener? listener, optional boolean useCapture = false);
-    [ObjCLegacyUnnamedParameters, ImplementedAs=removeEventListenerForBindings] void removeEventListener([AtomicString] DOMString type, EventListener? listener, optional boolean useCapture = false);
+    [ObjCLegacyUnnamedParameters, ImplementedAs=addEventListenerForBindings] void addEventListener([AtomicString] DOMString type, EventListener? listener, boolean useCapture);
+    [ObjCLegacyUnnamedParameters, ImplementedAs=removeEventListenerForBindings] void removeEventListener([AtomicString] DOMString type, EventListener? listener, boolean useCapture);
 
     [ImplementedAs=dispatchEventForBindings, RaisesException] boolean dispatchEvent(Event event);
 };
index d1e1467..fc991d7 100644 (file)
@@ -44,6 +44,7 @@ public:
 
     void add(HTMLElement&, HTMLElement* beforeElement, ExceptionCode&);
     void add(HTMLElement&, int beforeIndex, ExceptionCode&);
+    void add(HTMLElement& element, ExceptionCode& ec) { add(element, nullptr, ec); }
     void remove(int index);
     void remove(HTMLOptionElement&);
 
index d409658..97b7e6b 100644 (file)
 #endif
 
 #if (!defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C) && (!defined(LANGUAGE_GOBJECT) || !LANGUAGE_GOBJECT)
-    [RaisesException] void add(HTMLElement element, optional HTMLElement? before = null);
-    [RaisesException] void add(HTMLElement element, optional long index = 0);
+    // FIXME: Should be:
+    // void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
+    [RaisesException] void add(HTMLElement element);
+    [RaisesException] void add(HTMLElement element, HTMLElement? before);
+    [RaisesException] void add(HTMLElement element, long index);
 #else
     [RaisesException] void add(HTMLOptionElement option, unsigned long index);
 #endif
index 9ef8850..9bcb502 100644 (file)
@@ -54,6 +54,7 @@ public:
 
     void add(HTMLElement&, HTMLElement* beforeElement, ExceptionCode&);
     void add(HTMLElement&, int beforeIndex, ExceptionCode&);
+    void add(HTMLElement& element, ExceptionCode& ec) { add(element, nullptr, ec); }
 
     using Node::remove;
     void remove(HTMLOptionElement&);
index ab9a5ab..d0d23b7 100644 (file)
     HTMLOptionElement? namedItem(DOMString name);
 #endif
 
-    [ObjCLegacyUnnamedParameters, RaisesException] void add(HTMLElement element, optional HTMLElement? before = null);
+    [ObjCLegacyUnnamedParameters, RaisesException] void add(HTMLElement element, HTMLElement? before);
 #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
-    [RaisesException] void add(HTMLElement element, optional long index = 0);
+    // FIXME: Should be:
+    // void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
+    [RaisesException] void add(HTMLElement element, long index);
+    [RaisesException] void add(HTMLElement element);
+
     // In JavaScript, we support both option index and option object parameters.
     // As of this writing this cannot be auto-generated.
     [Custom] void remove(/* indexOrOption */);