Build Transform hasFixup¶
Author: | Rawld Gill |
---|
Summary¶
Transforms has.js expressions that reference static has feature values as presented in a profile into expressions that facilitate dead code removal by the Google Closure Compiler.
Description¶
Profiles may contain the property staticHasFeatures
a map from has feature name to booleanish. The presence of
a has feature name in the map indicates the resulting built code should assume the particular feature is either always
available (if truthy) or never available (if falsy). If multiple profile resources include a value for the property
staticHasFeatures
, then each property value is mixed on a per-has-feature basis in the order they appear on
the command line. The special value of -1 indicates the feature is not known at build time and should be removed from
the final staticHasFeature
map. For example, assume the following two profile resources exists
profile-a
profile = {
staticHasFeatures:{
featureX:1,
featureY:1,
featureZ:0
}
// other profile properties, if any
};
profile-b
profile = {
staticHasFeatures:{
featureY:0,
featureZ:-1,
anotherFeature:1
}
// other profile properties, if any
};
If these two profiles were provided on the command line as follows
~/dev/dtk/util/buildscripts> ./build.sh -p profile-a -p profile-b
Then the aggregate profile would have the following value for the property staticHasFeatures
:
staticHasFeatures:{
featureX:1, // only mentioned in profile-a
featureY:0, // profile-b value overrides profile-a value
anotherFeature:1 // only mentioned in profile-b
}
Notice that "featureZ" was removed because the profile-b which was mixed after profile-a contains the value of -1 for that property.
Has feature values are used to transform two kinds of expressions:
// adding a has test
has.add("feature-value", // other stuff
// resolving a has feature value
has("feature-value")
These expressions are discovered by regular expression scanning of resources. The regular expressions have the following characteristics:
- has.add must be presented without any white space around the dot
- white space (if any) around the left parenthesis is ignored
- white space (if any) around the right parenthesis in the has feature test expression is ignored
- quotes may be either single- or double-quotes
Given a has feature x where the profile property staticHasFeatures[
x ]
is truthy, this profile will rewrite
has.add(
x
as
true && had.add(
x
The resulting code can then be processed by a subsequent transform, for example optimization by the Google Closure
Compiler, which will eliminate the dead code, while maintaining intended semantics (recall that has.add includes a
now
parameter that instructs the function to execute the test immediately and return result. For example, if the has
feature "featureX" is set to truthy in staticHasFeatures
, then the following code:
if(has.add("featureX", function(){ /* some test */}, 1)){
// do something
}else{
// don't do something
}
would be transformed to:
if(true || has.add("featureX", function(){ /* some test */}, 1)){
// do something
}else{
// don't do something
}
which would be reduced to:
// do something
by the Google Closure Compiler in simple mode.
This design eliminates the need to determine the boundaries of the has.add argument list--a task that is impossible to accomplish correctly without a proper parser.
Similarly, has feature tests with know values are replaced with the constant integers 1
(if the static value is
true) and 0
(if the static value if false). For example, for "featureX" set static true as described above, then the
following code
if(has("featureX")){
// do something
}else{
// don't do something
}
Would be transformed to
if(1){
// do something
}else{
// don't do something
}
Which would be reduced to
// do something
By the Google Closure Compiler in simple mode.
Profile Knobs¶
staticHasFeatures
(see below for default)
- [map from feature name to booleanish or -1] If -1, then the has feature is removed from the
staticHasFeatures
; otherwise, if truthy, then the feature is assumed to be always true in the built code and conversely. MultiplestaticHasFeatures
maps may be provided from multiple profile resources. If more than onestaticHasFeatures
property value is provided, then they are mixed on a per-has-feature basis in the order they appear on the command line.
Source Location¶
util/build/transforms/hasFixup.js