class ExtractPrototypeMemberDeclarations extends java.lang.Object implements CompilerPass
function B() { ... } \ B.prototype.foo = function() { ... } \___ExtractPrototypeMemberDeclarations.ExtractionInstance
... / B.prototype.bar = function() { ... } / ^---------------------------------ExtractPrototypeMemberDeclarations.PrototypeMemberDeclaration
becomes
function B() { ... } x = B.prototype; x.foo = function() { ... } ... x.bar = function() { ... }
Works almost like a redundant load elimination but limited to only
recognizing the class prototype declaration idiom. First it only works within
a basic block because we avoided DataFlowAnalysis
for compilation
performance. Secondly, we can avoid having to compute how long to
sub-expressing has to be. Example:
a.b.c.d = ... a.b.c = ... a.b = ... a.b.c = ...
Further more, we only introduce one temp variable to hold a single
prototype at a time. So all the ExtractPrototypeMemberDeclarations.PrototypeMemberDeclaration
to be extracted must be in a single line. We call this a single
ExtractPrototypeMemberDeclarations.ExtractionInstance
.
Alternatively, for users who do not want a global variable to be introduced, we will create an anonymous function instead.
function B() { ... } (function (x) { x.foo = function() { ... } ... x.bar = function() { ... } )(B.prototype)The RHS of the declarations can have side effects, however, one good way to break this is the following:
function B() { ... } B.prototype.foo = (function() { B.prototype = somethingElse(); return 0 })(); ...Such logic is highly unlikely and we will assume that it never occurs.
Modifier and Type | Class and Description |
---|---|
private class |
ExtractPrototypeMemberDeclarations.ExtractionInstance |
private class |
ExtractPrototypeMemberDeclarations.GatherExtractionInfo
Collects all the possible extraction instances in a node traversal.
|
(package private) static class |
ExtractPrototypeMemberDeclarations.Pattern |
private static class |
ExtractPrototypeMemberDeclarations.PrototypeMemberDeclaration
Abstraction for a prototype member declaration.
|
Modifier and Type | Field and Description |
---|---|
private AbstractCompiler |
compiler |
private ExtractPrototypeMemberDeclarations.Pattern |
pattern |
private java.lang.String |
prototypeAlias |
Constructor and Description |
---|
ExtractPrototypeMemberDeclarations(AbstractCompiler compiler,
ExtractPrototypeMemberDeclarations.Pattern pattern) |
Modifier and Type | Method and Description |
---|---|
private void |
doExtraction(ExtractPrototypeMemberDeclarations.GatherExtractionInfo info)
Declares the temp variable to point to prototype objects and iterates
through all ExtractInstance and performs extraction there.
|
private void |
extractInstance(ExtractPrototypeMemberDeclarations.ExtractionInstance instance)
At a given ExtractionInstance, stores and prototype object in the temp
variable and rewrite each member declaration to assign to the temp variable
instead.
|
void |
process(Node externs,
Node root)
Process the JS with root node root.
|
private void |
replacePrototypeMemberDeclaration(ExtractPrototypeMemberDeclarations.PrototypeMemberDeclaration declar)
Replaces a member declaration to an assignment to the temp prototype
object.
|
private java.lang.String prototypeAlias
private final AbstractCompiler compiler
private final ExtractPrototypeMemberDeclarations.Pattern pattern
ExtractPrototypeMemberDeclarations(AbstractCompiler compiler, ExtractPrototypeMemberDeclarations.Pattern pattern)
public void process(Node externs, Node root)
CompilerPass
process
in interface CompilerPass
externs
- Top of external JS treeroot
- Top of JS treeprivate void doExtraction(ExtractPrototypeMemberDeclarations.GatherExtractionInfo info)
private void extractInstance(ExtractPrototypeMemberDeclarations.ExtractionInstance instance)
private void replacePrototypeMemberDeclaration(ExtractPrototypeMemberDeclarations.PrototypeMemberDeclaration declar)