diff --git a/closure/goog/base.js b/closure/goog/base.js index 4c65ec0381..f05eca00b4 100644 --- a/closure/goog/base.js +++ b/closure/goog/base.js @@ -2130,91 +2130,6 @@ goog.inherits = function(childCtor, parentCtor) { }; -/** - * Call up to the superclass. - * - * If this is called from a constructor, then this calls the superclass - * constructor with arguments 1-N. - * - * If this is called from a prototype method, then you must pass the name of the - * method as the second argument to this function. If you do not, you will get a - * runtime error. This calls the superclass' method with arguments 2-N. - * - * This function only works if you use goog.inherits to express inheritance - * relationships between your classes. - * - * This function is a compiler primitive. At compile-time, the compiler will do - * macro expansion to remove a lot of the extra overhead that this function - * introduces. The compiler will also enforce a lot of the assumptions that this - * function makes, and treat it as a compiler error if you break them. - * - * @param {!Object} me Should always be "this". - * @param {*=} opt_methodName The method name if calling a super method. - * @param {...*} var_args The rest of the arguments. - * @return {*} The return value of the superclass method. - * @suppress {es5Strict} This method can not be used in strict mode, but - * all Closure Library consumers must depend on this file. - * @deprecated goog.base is not strict mode compatible. Prefer the static - * "base" method added to the constructor by goog.inherits - * or ES6 classes and the "super" keyword. - */ -goog.base = function(me, opt_methodName, var_args) { - var caller = arguments.callee.caller; - - if (goog.STRICT_MODE_COMPATIBLE || (goog.DEBUG && !caller)) { - throw new Error( - 'arguments.caller not defined. goog.base() cannot be used ' + - 'with strict mode code. See ' + - 'http://www.ecma-international.org/ecma-262/5.1/#sec-C'); - } - - if (typeof caller.superClass_ !== 'undefined') { - // Copying using loop to avoid deop due to passing arguments object to - // function. This is faster in many JS engines as of late 2014. - var ctorArgs = new Array(arguments.length - 1); - for (var i = 1; i < arguments.length; i++) { - ctorArgs[i - 1] = arguments[i]; - } - // This is a constructor. Call the superclass constructor. - return /** @type {!Function} */ (caller.superClass_) - .constructor.apply(me, ctorArgs); - } - - if (typeof opt_methodName != 'string' && typeof opt_methodName != 'symbol') { - throw new Error( - 'method names provided to goog.base must be a string or a symbol'); - } - - // Copying using loop to avoid deop due to passing arguments object to - // function. This is faster in many JS engines as of late 2014. - var args = new Array(arguments.length - 2); - for (var i = 2; i < arguments.length; i++) { - args[i - 2] = arguments[i]; - } - var foundCaller = false; - for (var proto = me.constructor.prototype; proto; - proto = Object.getPrototypeOf(proto)) { - if (proto[opt_methodName] === caller) { - foundCaller = true; - } else if (foundCaller) { - return proto[opt_methodName].apply(me, args); - } - } - - // If we did not find the caller in the prototype chain, then one of two - // things happened: - // 1) The caller is an instance method. - // 2) This method was not called by the right caller. - if (me[opt_methodName] === caller) { - return me.constructor.prototype[opt_methodName].apply(me, args); - } else { - throw new Error( - 'goog.base called from a method of one name ' + - 'to a method of a different name'); - } -}; - - /** * Allow for aliasing within scope functions. This function exists for * uncompiled code - in compiled code the calls will be inlined and the aliases diff --git a/closure/goog/base_debug_loader_test.js b/closure/goog/base_debug_loader_test.js index a3e86dbe32..d48b1c490e 100644 --- a/closure/goog/base_debug_loader_test.js +++ b/closure/goog/base_debug_loader_test.js @@ -621,19 +621,19 @@ function testBaseClass() { } function B(x, y) { - goog.base(this, x, y); + B.base(this, 'constructor', x, y); this.foo += 2; } goog.inherits(B, A); function C(x, y) { - goog.base(this, x, y); + C.base(this, 'constructor', x, y); this.foo += 4; } goog.inherits(C, B); function D(x, y) { - goog.base(this, x, y); + D.base(this, 'constructor', x, y); this.foo += 8; } goog.inherits(D, C); @@ -645,45 +645,6 @@ function testBaseClass() { assertEquals(3, (new B(1, 0)).foo); } -function testBaseMethod() { - function A() {} - A.prototype.foo = function(x, y) { - return x + y; - }; - - function B() {} - goog.inherits(B, A); - B.prototype.foo = function(x, y) { - return 2 + goog.base(this, 'foo', x, y); - }; - - function C() {} - goog.inherits(C, B); - C.prototype.foo = function(x, y) { - return 4 + goog.base(this, 'foo', x, y); - }; - - const d = new C(); - d.foo = function(x, y) { - return 8 + goog.base(this, 'foo', x, y); - }; - - assertEquals(15, d.foo(1, 0)); - assertEquals(16, d.foo(1, 1)); - assertEquals(16, d.foo(2, 0)); - assertEquals(7, (new C()).foo(1, 0)); - assertEquals(3, (new B()).foo(1, 0)); - assertThrows(function() { - goog.base(d, 'foo', 1, 0); - }); - - delete B.prototype.foo; - assertEquals(13, d.foo(1, 0)); - - delete C.prototype.foo; - assertEquals(9, d.foo(1, 0)); -} - function testBaseMethodAndBaseCtor() { // This will fail on FF4.0 if the following bug is not fixed: @@ -696,11 +657,11 @@ function testBaseMethodAndBaseCtor() { }; function B(x, y) { - goog.base(this, x, y); + B.base(this, 'constructor', x, y); } goog.inherits(B, A); B.prototype.foo = function(x, y) { - goog.base(this, 'foo', x, y); + B.base(this, 'foo', x, y); this.bar = this.bar * 2; }; @@ -708,43 +669,6 @@ function testBaseMethodAndBaseCtor() { } -function testBaseMethodWithEs6Subclass() { - function A() {} - A.prototype.foo = function(x, y) { - return x + y; - }; - - function B() {} - goog.inherits(B, A); - B.prototype.foo = function(x, y) { - return 2 + goog.base(this, 'foo', x, y); - }; - - class C extends B { - foo(x, y) { - return 4 + super.foo(x, y); - } - - useBase(x, y) { - return 4 + goog.base(this, 'foo', x, y); - } - } - - const c = new C(); - - assertEquals(7, c.foo(1, 0)); - assertEquals(8, c.foo(1, 1)); - assertEquals(8, c.foo(2, 0)); - assertEquals(7, (new C()).foo(1, 0)); - assertThrows(function() { - goog.base(c, 'foo', 1, 0); - }); - assertThrows(function() { - c.useBase(0, 0); - }); -} - - //=== tests for bind() and friends === // Function.prototype.bind and Function.prototype.partial are purposefullly