Skip to content
This repository has been archived by the owner on Oct 9, 2020. It is now read-only.

Commit

Permalink
fix conditional inlining
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed Sep 1, 2016
1 parent 65cbc1e commit 3337e1e
Showing 1 changed file with 82 additions and 73 deletions.
155 changes: 82 additions & 73 deletions lib/trace.js
Original file line number Diff line number Diff line change
Expand Up @@ -730,95 +730,104 @@ Trace.prototype.inlineConditions = function(tree, loader, traceOpts) {
var conditionalResolutions = {};
var importsSystemEnv = false;

// for each conditional in the tree, work out its substitution
Object.keys(tree)
.filter(function(m) {
return tree[m] && tree[m].conditional;
})
.forEach(function(c) {
var branches = Trace.getConditionalResolutions(tree[c].conditional, canonicalConditionalEnv, canonicalInlineConditionals).branches;
// get the list of all conditional dependencies in the tree
var allConditionals = [];
Object.keys(tree).forEach(function(m) {
if (!tree[m] || tree[m].conditional)
return;

if (branches.length > 1)
throw new TypeError('Error building condition ' + c + '. ' + inconsistencyErrorMsg);
if (branches.length == 0)
throw new TypeError('No exact resolution found at all for condition ' + c + '.');
Object.keys(tree[m].depMap).forEach(function(d) {
var dep = tree[m].depMap[d];

conditionalResolutions[c] = branches[0];
if (dep.match(/#[\:\?\{]/)) {
if (allConditionals.indexOf(dep) === -1)
allConditionals.push(dep);
}
});
});

// resolve any chained conditionals
Object.keys(conditionalResolutions).forEach(function(c) {
var resolution = conditionalResolutions[c];
// determine the conditional resolutions
return Promise.all(allConditionals.map(function(c) {
return self.getLoadRecord(c, traceOpts)
.then(function(load) {
var branches = Trace.getConditionalResolutions(load.conditional, canonicalConditionalEnv, canonicalInlineConditionals).branches;

var seen = [];
while (conditionalResolutions[resolution] && seen.indexOf(resolution) == -1) {
seen.push(resolution);
resolution = conditionalResolutions[resolution];
conditionalResolutions[c] = resolution;
}
if (seen.indexOf(resolution) != -1)
throw new Error('Circular conditional resolution ' + seen.join(' -> ') + ' -> ' + resolution);
});
if (branches.length === 1)
conditionalResolutions[c] = branches[0];
});
}))
.then(function() {
// resolve any chained conditionals
Object.keys(conditionalResolutions).forEach(function(c) {
var resolution = conditionalResolutions[c];

var seen = [];
while (conditionalResolutions[resolution] && seen.indexOf(resolution) == -1) {
seen.push(resolution);
resolution = conditionalResolutions[resolution];
conditionalResolutions[c] = resolution;
}
if (seen.indexOf(resolution) != -1)
throw new Error('Circular conditional resolution ' + seen.join(' -> ') + ' -> ' + resolution);
});

// finally we do a deep clone of the tree, applying the conditional resolutions as we go
// if we have a dependency on a condition not in the tree, we throw as it would be an unresolved external
var inlinedTree = {};
Object.keys(tree).forEach(function(m) {
var load = tree[m];
// finally we do a deep clone of the tree, applying the conditional resolutions as we go
// if we have a dependency on a condition not in the tree, we throw as it would be an unresolved external
var inlinedTree = {};
Object.keys(tree).forEach(function(m) {
var load = tree[m];

if (typeof load == 'boolean') {
inlinedTree[m] = load;
return;
}
if (typeof load == 'boolean') {
inlinedTree[m] = load;
return;
}

if (load.conditional)
return;
if (load.conditional)
return;

var clonedLoad = extend({}, load);
clonedLoad.depMap = {};
Object.keys(load.depMap).forEach(function(d) {
var normalizedDep = load.depMap[d];
var clonedLoad = extend({}, load);
clonedLoad.depMap = {};
Object.keys(load.depMap).forEach(function(d) {
var normalizedDep = load.depMap[d];

normalizedDep = conditionalResolutions[normalizedDep] || normalizedDep;
normalizedDep = conditionalResolutions[normalizedDep] || normalizedDep;

if (normalizedDep == '@system-env')
importsSystemEnv = true;
if (normalizedDep == '@system-env')
importsSystemEnv = true;

if (normalizedDep.indexOf(/#[\:\?\{]/) != -1)
throw new Error('Unable to inline conditional dependency ' + normalizedDep + '. Try including the ' + d + ' dependency of ' + load.name + ' in the build.');
clonedLoad.depMap[d] = normalizedDep;
});

clonedLoad.depMap[d] = normalizedDep;
inlinedTree[m] = clonedLoad;
});

inlinedTree[m] = clonedLoad;
});

// if we explicitly import from the system environment, then we need to build it into a static build
// this is normally excluded as it is a system module in SystemJS but won't be available in static
// builds which is exactly what this function acts on
if (importsSystemEnv) {
inlinedTree['@system-env'] = {
name: '@system-env',
path: null,
metadata: {
format: 'json'
},
deps: [],
depMap: {},
source: JSON.stringify({
production: canonicalInlineConditionals['@system-env|production'],
browser: canonicalInlineConditionals['@system-env|browser'],
node: canonicalInlineConditionals['@system-env|node'],
dev: canonicalInlineConditionals['@system-env|dev'],
default: true
}),
fresh: true,
timestamp: null,
configHash: loader.configHash,
};
}
// if we explicitly import from the system environment, then we need to build it into a static build
// this is normally excluded as it is a system module in SystemJS but won't be available in static
// builds which is exactly what this function acts on
if (importsSystemEnv) {
inlinedTree['@system-env'] = {
name: '@system-env',
path: null,
metadata: {
format: 'json'
},
deps: [],
depMap: {},
source: JSON.stringify({
production: canonicalInlineConditionals['@system-env|production'],
browser: canonicalInlineConditionals['@system-env|browser'],
node: canonicalInlineConditionals['@system-env|node'],
dev: canonicalInlineConditionals['@system-env|dev'],
default: true
}),
fresh: true,
timestamp: null,
configHash: loader.configHash,
};
}

return inlinedTree;
return inlinedTree;
});
});
});
};
Expand Down

0 comments on commit 3337e1e

Please sign in to comment.