From 941df6ef14d8c5caf45fe9674628a6de65ec9bdc Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Thu, 22 Jun 2017 04:07:37 +0300 Subject: [PATCH] cleanup... Signed-off-by: Alex A. Naanou --- features.js | 341 ---------------------------------------------------- 1 file changed, 341 deletions(-) diff --git a/features.js b/features.js index c202ec1..88de1c7 100755 --- a/features.js +++ b/features.js @@ -667,347 +667,6 @@ var FeatureSetProto = { } }, - - _buildFeatureList: function(lst, filter){ - lst = (lst == null || lst == '*') ? this.features : lst - lst = lst.constructor !== Array ? [lst] : lst - - var that = this - - // XXX disabled handling is wrong at this point... (???) - // - if a feature is encountered before it is disabled it - // will still get loaded... - // - need to also resolve disable loops... - // a disable declaration that will disable the declaring feature... - var expand = function(target, lst, store, data, _seen){ - data = data || {} - _seen = _seen || [] - - // user filter... - lst = filter ? - lst.filter(function(n){ return filter.call(that, n) }) - : lst - - // clear disabled... - // NOTE: we do as a separate stage to avoid loading a - // feature before it is disabled in the same list... - lst = data.disabled ? - lst - .filter(function(n){ - // feature disabled -> record and skip... - if(n[0] == '-'){ - n = n.slice(1) - if(_seen.indexOf(n) >= 0){ - // NOTE: a disable loop is when a feature tries to disable - // a feature up in the same chain... - // XXX should this break or accumulate??? - console.warn(`Disable loop detected at "${n}" in chain: ${_seen}`) - var loop = _seen.slice(_seen.indexOf(n)).concat([n]) - data.disable_loops = (data.disable_loops || []).push(loop) - return false - } - // XXX STUB -- need to resolve actual loops and - // make the disable global... - if(n in store){ - console.warn('Disabling a feature after it is loaded:', n, _seen) - } - data.disabled.push(n) - return false - } - // skip already disabled features... - if(data.disabled.indexOf(n) >= 0){ - return false - } - return true - }) - : lst - - // traverse the tree... - lst - // normalize the list -- remove non-features and resolve aliases... - .map(function(n){ - var f = that[n] - // resolve exclusive tags... - while(f == null && data.exclusive && n in data.exclusive){ - var n = data.exclusive[n][0] - f = that[n] - } - // feature not defined or is not a feature... - if(f == null){ - data.missing - && data.missing.indexOf(n) < 0 - && data.missing.push(n) - return false - } - return n - }) - .filter(function(e){ return e }) - - // sort the list... - // build the sort table: [ , , ] - .map(function(e, i){ - return [ that[e].getPriority ? that[e].getPriority() : i, i, e ] }) - // sort by priority or index... - // NOTE: JS compares lists as strings so we have to compare - // the list manually... - .sort(function(a, b){ return a[0] - b[0] || a[1] - b[1] }) - // cleanup -- drop the sort table... - .map(function(e){ return e[2] }) - - // traverse down... - .forEach(function(f){ - // dependency loop detection... - if(_seen.indexOf(f) >= 0){ - var loop = _seen.slice(_seen.indexOf(f)).concat([f]) - data.loops - && data.loops.push(loop) - return - } - - // skip already done features... - if(f in store){ - return - } - - //var feature = store[f] = that[f] - var feature = that[f] - if(feature){ - var _lst = [] - - // merge lists... - ;(target instanceof Array ? target : [target]) - .forEach(function(t){ - _lst = _lst.concat(feature[t] || []) - }) - store[f] = _lst - - // traverse down... - 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) - } - }) - - return store - } - - //var list = [] - var loops = [] - var disable_loops = [] - var disabled = [] - var missing = [] - - // build exclusive groups... - // XXX use these as aliases... - // ...we need to do this on the build stage to include correct - // deps and suggesntions... - var exclusive = {} - var rev_exclusive = {} - var _exclusive = {} - // NOTE: we do not need loop detection active here... - Object.keys(expand('exclusive', lst, _exclusive)) - .forEach(function(k){ - (_exclusive[k] || []) - .forEach(function(e){ - exclusive[e] = (exclusive[e] || []).concat([k]) - //rev_exclusive[k] = (rev_exclusive[k] || []).concat([e]) - }) }) - - // feature tree... - var features = expand('depends', lst, {}, - { - //list: list, - loops: loops, - disable_loops: disable_loops, - disabled: disabled, - missing: missing, - exclusive: exclusive, - }) - - // suggestion list... - // NOTE: this stage does not track suggested feature dependencies... - // NOTE: we do not need loop detection active here... - var suggested = Object.keys( - expand('suggested', Object.keys(features), {}, {disabled: disabled})) - .filter(function(f){ return !(f in features) }) - // get suggestion dependencies... - suggested = expand('depends', suggested, {}, - { - //list: list, - loops: loops, - }) - // keep only suggested features.. - // XXX this might get affected by disabled... - Object.keys(suggested) - .forEach(function(f){ - f in features - && (delete suggested[f]) }) - - // check/resolve for exclusivity conflicts... - // XXX this might get affected by disabled... - // XXX - - // report dependency loops... - // XXX a loop error should be raised only when one of the loop elements - // is encountered during the linearisation process... - // XXX this might get affected by disabled... - // XXX should we report this here??? - loops.length > 0 - && loops - .forEach(function(loop){ - console.warn('feature loop detected:\n\t' + loop.join('\n\t\t-> ')) }) - //*/ - - // combine the lists... - // XXX - var list = [] - expand(['depends', 'suggested'], lst, {}, - { - list: list, - disabled: disabled, - missing: missing, - exclusive: exclusive, - }) - - // XXX - return { - list: list, - features: features, - suggested: suggested, - exclusive: exclusive, - disabled: disabled, - missing: missing, - loops: loops, - disable_loops: disable_loops, - } - }, - - // C3 implementation... - // - // NOTE: this is different from the pure C3 in that we do not care - // about the dependency order and sort the dependency list... - // NOTE: this returns the list in reverse order, i.e. from the input - // feature and up the dependency list - // - // Problems: - // - too picky about candidates -- errors in cases that can be solved by re-ordering... - // - priority is less significant than level order - // Ex: - // ImageGridFeatures._buildFeatureListC3(['ui', 'location']) - // -> ["location", "introspection", "lifecycle", "workspace", "base", "ui"] - // ImageGridFeatures._buildFeatureListC3(['location', 'ui']) - // -> ["introspection", "lifecycle", "workspace", "base", "ui", "location"] - _buildFeatureListC3: function(lst, filter){ - lst = (lst == null || lst == '*') ? this.features : lst - lst = lst.constructor !== Array ? [lst] : lst - - var that = this - - var expand = function(lst, data, _seen){ - _seen = _seen || [] - data = data || {} - - /*/ user filter... - lst = filter ? - lst.filter(function(n){ return filter.call(that, n) }) - : lst - //*/ - - // disabled filter... - // XXX - - lst = lst - // normalize the list -- remove non-features and resolve aliases... - .map(function(n){ - var f = that[n] - // resolve exclusive tags... - while(f == null && data.exclusive && n in data.exclusive){ - var n = data.exclusive[n][0] - f = that[n] - } - // feature not defined or is not a feature... - if(f == null){ - data.missing - && data.missing.indexOf(n) < 0 - && data.missing.push(n) - return false - } - return n - }) - .filter(function(e){ return e }) - - // sort the list... - // build the sort table: [ , , ] - .map(function(e, i){ - return [ that[e].getPriority ? that[e].getPriority() : i, i, e ] }) - // sort by priority or index -- min -> max - // NOTE: this will maintain the order of similar priority actions... - // NOTE: JS compares lists as strings so we have to compare - // the list manually... - .sort(function(a, b){ return a[0] - b[0] || a[1] - b[1] }) - // cleanup -- drop the sort table... - .map(function(e){ return e[2] }) - - // traverse... - .map(function(e){ - // detect loops... - if(_seen.indexOf(e) >= 0){ - var loop = _seen.slice(_seen.indexOf(e)).concat([e]) - console.warn('LOOP:', loop) - //data.loops - // && data.loops.push(loop) - return - } - - var L = that[e].depends || [] - - // traverse down... - //return [e].concat(expand(L.slice(), data, _seen.concat([e]))) - return L.length > 0 ? - [e].concat(expand(L.slice(), data, _seen.concat([e]))) - : [e] - }) - // XXX for some reason this breaks C3... - //.concat([lst]) - - // merge... - var res = [] - var cur = null - while(lst.length > 0){ - cur = lst - // get the heads... - .map(function(e){ return e && e[0] }) - // check if the head is in any of the tails... - .filter(function(h){ - return h && lst - .filter(function(e){ return e.slice(1).indexOf(h) >= 0 }).length == 0 }) - .shift() - - // XXX no candidate found... - if(cur == null){ - console.error('no candidate found!!') - break - } - - // cleanup... - lst = lst - .map(function(e){ return e && e.filter(function(f){ return f != cur }) }) - .filter(function(e){ return e && e.length > 0 }) - - cur - && res.push(cur) - cur = null - } - - return res - } - - return expand(lst) - }, - - // Build list of features in an appropriate order to load... // // Algorithm: