Bug 1259850 - Start searching from the most specialized csu, r=terrence

Previously, this mostly "worked" purely by chance -- it started gathering method definitions at the 'csu' variable, which JS helpfully hoisted up to the toplevel. It had the last value assigned to csu within the loop, which would have been the basest base class (don't think too hard about the case of multiple inheritance, it was wrong). Then we find all descendants, which was *too* much, but it ended up just making the analysis conservative.

MozReview-Commit-ID: 2Ps8gJpztw2

--HG--
extra : rebase_source : b52ccf514e70fd00e5e73cdef59df379efb32487
This commit is contained in:
Steve Fink 2016-03-25 15:25:46 -07:00
parent 77be2fa2f9
commit 8afd1f9d6b

View File

@ -47,6 +47,24 @@ function processCSU(csuName, csu)
}
}
// Return the nearest ancestor method definition, or all nearest definitions in
// the case of multiple inheritance.
function nearestAncestorMethods(csu, method)
{
var key = csu + ":" + method;
if (classFunctions.has(key))
return new Set(classFunctions.get(key));
var functions = new Set();
if (superclasses.has(csu)) {
for (var parent of superclasses.get(csu))
functions.update(nearestAncestorMethods(parent, method));
}
return functions;
}
function findVirtualFunctions(initialCSU, field, suppressed)
{
var worklist = [initialCSU];
@ -73,7 +91,15 @@ function findVirtualFunctions(initialCSU, field, suppressed)
worklist.push(...superclasses.get(csu));
}
worklist = [csu];
// Now return a list of all the instantiations of the method named 'field'
// that could execute on an instance of initialCSU or a descendant class.
// Start with the class itself, or if it doesn't define the method, all
// nearest ancestor definitions.
functions.update(nearestAncestorMethods(initialCSU, field));
// Then recurse through all descendants to add in their definitions.
var worklist = [initialCSU];
while (worklist.length) {
var csu = worklist.pop();
var key = csu + ":" + field;