almost ready...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2017-06-20 06:57:37 +03:00
parent c4e6e48756
commit cad40b850e

View File

@ -1019,7 +1019,7 @@ var FeatureSetProto = {
// - if not ??? (XXX) // - if not ??? (XXX)
// XXX should we report stuff here??? // XXX should we report stuff here???
// XXX TODO: // XXX TODO:
// - resolve exclusive aliases and conflicts... // - wrapper to pass in applicability filter...
_buildFeatureListReorder: function(lst, filter){ _buildFeatureListReorder: function(lst, filter){
var all = this.features var all = this.features
lst = (lst == null || lst == '*') ? all : lst lst = (lst == null || lst == '*') ? all : lst
@ -1071,10 +1071,10 @@ var FeatureSetProto = {
// normalize the list -- remove non-features and resolve aliases... // normalize the list -- remove non-features and resolve aliases...
.map(function(n){ .map(function(n){
var f = that[n] var f = that[n]
// resolve exclusive tags... // exclusive tags...
while(f == null && data.exclusive && n in data.exclusive){ if(f == null && data.exclusive && n in data.exclusive){
var n = data.exclusive[n][0] store[n] = null
f = that[n] return false
} }
// feature not defined or is not a feature... // feature not defined or is not a feature...
if(f == null){ if(f == null){
@ -1116,10 +1116,6 @@ var FeatureSetProto = {
// traverse down... // traverse down...
expand(target, _lst, store, data, _seen.concat([f])) expand(target, _lst, store, data, _seen.concat([f]))
// XXX makes sense to push the dep here -- at the tail of the recursion...
data.list
&& data.list.push(f)
} }
}) })
@ -1143,57 +1139,121 @@ var FeatureSetProto = {
// ...we need to do this on the build stage to include correct // ...we need to do this on the build stage to include correct
// deps and suggesntions... // deps and suggesntions...
var exclusive = {} var exclusive = {}
var rev_exclusive = {}
all all
.filter(function(f){ return !!that[f].exclusive }) .filter(function(f){ return !!that[f].exclusive })
.forEach(function(k){ .forEach(function(k){
(that[k].exclusive || []) (that[k].exclusive || [])
.forEach(function(e){ .forEach(function(e){
exclusive[e] = (exclusive[e] || []).concat([k]) }) }) exclusive[e] = (exclusive[e] || []).concat([k])
rev_exclusive[k] = (rev_exclusive[k] || []).concat([e]) }) })
// feature tree... // XXX revise:
var features = expand('depends', lst, {}, // - should this be this depending on closure so much???
{ var expandFeatures = function(lst, features){
features = features || {}
// feature tree...
var expand_data = {
loops: loops, loops: loops,
disable_loops: disable_loops,
disabled: disabled, disabled: disabled,
disable_loops: disable_loops,
missing: missing, missing: missing,
exclusive: exclusive, exclusive: exclusive,
}) }
// suggestion list... features = expand('depends', lst, features, expand_data)
// ...this will be used to check if we need to break on missing
// features, e.g. if a feature is suggested we can silently skip // suggestion list...
// it otherwise err... // ...this will be used to check if we need to break on missing
// // features, e.g. if a feature is suggested we can silently skip
// NOTE: this stage does not track suggested feature dependencies... // it otherwise err...
// NOTE: we do not need loop detection active here... //
var suggested = Object.keys( // NOTE: this stage does not track suggested feature dependencies...
expand('suggested', Object.keys(features), {}, { disabled: disabled })) // NOTE: we do not need loop detection active here...
.filter(function(f){ return !(f in features) }) var s = Object.keys(
// get suggestion dependencies... expand('suggested', Object.keys(features), {}, { disabled: disabled }))
suggested = expand('depends', suggested, {}, .filter(function(f){ return !(f in features) })
{ // get suggestion dependencies...
loops: loops, // NOTE: we do not care bout missing here...
disabled: disabled, s = expand('depends', s, {},
}) {
Object.keys(suggested) loops: loops,
disabled: disabled,
disable_loops: disable_loops,
exclusive: exclusive,
})
Object.keys(s)
.forEach(function(f){
// keep only suggested features -- diff with features...
if(f in features){
delete s[f]
// mix suggested into features...
} else {
features[f] = s[f]
}
})
}
var features = {}
expandFeatures(lst, features)
// check for exclusivity conflicts and aliases...
var conflicts = {}
Object.keys(features)
.forEach(function(f){ .forEach(function(f){
// keep only suggested features -- diff with features... // alias...
if(f in features){ while(f in exclusive){
delete suggested[f] var candidates = (exclusive[f] || [])
.filter(function(c){ return c in features })
// mix suggested into features... // resolve alias to non-included feature...
} else { if(candidates.length == 0){
features[f] = suggested[f] var target = exclusive[f][0]
// expand target...
expandFeatures([target], features)
// link alias to existing feature...
} else {
var target = candidates[0]
}
// remove the alias...
delete features[f]
// replace dependencies...
Object.keys(features)
.forEach(function(e){
var i = features[e].indexOf(f)
i >= 0
&& features[e].splice(i, 1, target)
})
f = target
}
// exclusive feature...
if(f in rev_exclusive){
// XXX handle multiple groups... (???)
var group = rev_exclusive[f]
var candidates = (exclusive[group] || [])
.filter(function(c){ return c in features })
if(!(group in conflicts) && candidates.length > 1){
conflicts[group] = candidates
}
} }
}) })
// resolve any conflicts found...
Object.keys(conflicts)
.forEach(function(group){
// XXX is this how we decide which feature to keep???
disabled = disabled.concat(conflicts[group].slice(1))})
// check/resolve for exclusivity conflicts and aliases... // reverse dependency index...
// XXX
// reverse dependencies -- who pulled who in... (index)
// ...this is used to clear out orphaned features later and for // ...this is used to clear out orphaned features later and for
// introspection... // introspection...
var rev_features = {} var rev_features = {}
@ -1289,11 +1349,12 @@ var FeatureSetProto = {
// NOTE: this requires the list to be ordered from high to low // NOTE: this requires the list to be ordered from high to low
// priority, i.e. the same order they should be loaded in... // priority, i.e. the same order they should be loaded in...
// NOTE: dependency loops will throw this into and "infinite" loop... // NOTE: dependency loops will throw this into and "infinite" loop...
// var loop_limit = list.length + 1
// XXX need a better loop detection strategy...
var loop_limit = list.length
do { do {
var moves = 0 var moves = 0
if(list.length == 0){
break
}
list list
.slice() .slice()
.forEach(function(e){ .forEach(function(e){
@ -1333,15 +1394,19 @@ var FeatureSetProto = {
// report loop limit... // report loop limit...
loop_limit <= 0 loop_limit <= 0
&& console.error('Hit loop limit while sorting dependencies!') && console.error('Hit loop limit while sorting dependencies!')
// report conflicts...
Object.keys(conflicts)
.forEach(function(group){
console.error('Exclusive "'+ group +'" conflict at:', conflicts[group]) })
return { return {
list: list, list: list,
suggested: Object.keys(suggested),
features: features, features: features,
rev_features: rev_features, rev_features: rev_features,
exclusive: exclusive, exclusive: exclusive,
conflicts: conflicts,
missing: missing, missing: missing,
loops: loops, loops: loops,
filtered_out: filtered_out, filtered_out: filtered_out,