google / google/closure-compiler
Error devirtualizing prototype methods of classes that share an interface's method
- Dominant language
- JavaScript
- Stars
- 7.7k
- Forks
- 1.2k
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 6
Description
The below code won't get devirtualized correctly:
``` javascript
/**
* @interface
*/
var Interface = function ()
{
};
Interface.prototype = {
doIt: function ()
{
}
};
/**
* @constructor
* @implements {Interface}
*/
var ClassA = goog.defineClass(null, {
constructor: function ()
{
},
/**
* @this {ClassA}
*
* @return {ClassA}
*/
doIt: function ()
{
console.log("do A");
return this;
}
});
/**
* @constructor
* @implements {Interface}
*/
var ClassB = goog.defineClass(null, {
constructor: function ()
{
},
/**
* @this {ClassB}
*
* @return {ClassB}
*/
doIt: function ()
{
console.log("do B");
return this;
}
});
/**
* @type {ClassA}
*/
var a = new ClassA();
a.doIt();
/**
* @type {ClassB}
*/
var b = new ClassB();
b.doIt().doIt().doIt().doIt();
```
Through advanced closure compiler, we would receive:
``` javascript
function d()
{
}
d.prototype.a = function ()
{
console.log("do A");
return this
};
function e()
{
}
e.prototype.a = function ()
{
console.log("do B");
return this
};
(new d).a();
(new e).a().a().a().a();
```
As we can see the "ClassA.doIt" and "ClassB.doIt" methods is not correctly devirtualize even though they are unrelated and returns the correct object type. And "Interface.doIt" is not even referenced.
Deleting the definition of "Interface.doIt", and devirtualization is executed correctly.
Contributor guide
Assessment
This issue has not been assessed yet.