Skip to content

Commit

Permalink
Add parser
Browse files Browse the repository at this point in the history
  • Loading branch information
skad0 committed Aug 9, 2016
1 parent bc1b3e6 commit e1f76a4
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 58 deletions.
122 changes: 65 additions & 57 deletions lib/formats/deps.js/parser.js
Original file line number Diff line number Diff line change
@@ -1,69 +1,77 @@
'use strict';

const _ = require('lodash');
const naming = require('bem-naming');

module.exports = function parser(entityDeps) {
var result = {
entity: entityDeps.entity,
dependOn: []
};

function normalize(deps) {
if (typeof deps === 'string') {
deps = { block: deps };
}

if (!Array.isArray(deps)) {
deps = [deps];
}

return deps;
}

function add(mustOrShouldDeps, isMust) {
if (!mustOrShouldDeps) return;

normalize(mustOrShouldDeps).forEach(function (dep) {
var dependOnEntity = {
block: dep.block
};

['elem', 'modName', 'modVal'].forEach(function (field) {
dep[field] && (dependOnEntity[field] = dep[field]);
});
const decl = require('bem-decl');
const declNormalize = decl.normalizer('v2');
const BemEntityName = require('bem-entity-name');
const declAssign = function (nd, scope) {
// TODO: использовать здесь deps
nd = decl.assign(nd, scope);
nd.entity = new BemEntityName(nd.entity);
return nd;
};

var dependency = {
entity: dependOnEntity,
tech: dep.tech
};
/**
* @param {Array<{entity: BemEntityName, scope: {entity, tech: String}, data: *}>} depsData - List of deps
* @returns {Array<*>}
*/
module.exports = function parse(depsData) {
const mustDeps = [];
const shouldDeps = [];
const mustDepsIndex = {};
const shouldDepsIndex = {};

isMust && (dependency.order = 'dependenceBeforeDependants');
depsData.forEach(record => {
const scope = record.scope || { entity: record.entity };
const data = [].concat(record.data);

_.some(result.dependOn, dependency) || result.dependOn.push(dependency);
data.forEach(dep => {
if (dep.mustDeps) {
declNormalize(dep.mustDeps).forEach(function (nd) {
nd = declAssign(nd, scope);
const key = declKey(nd);
if (!mustDepsIndex[key]) {
mustDeps.push({ vertex: scope, dependOn: nd, ordered: true });
mustDepsIndex[key] = true;
}
});
}
if (dep.shouldDeps) {
declNormalize(dep.shouldDeps).forEach(function (nd) {
nd = declAssign(nd, scope);
const key = declKey(nd);
if (!shouldDepsIndex[key]) {
shouldDeps.push({ vertex: scope, dependOn: nd });
shouldDepsIndex[key] = true;
}
});
}
if (dep.noDeps) {
declNormalize(dep.noDeps).forEach(function (nd) {
nd = declAssign(nd, scope);
removeFromDeps(nd, mustDepsIndex, mustDeps);
removeFromDeps(nd, shouldDepsIndex, shouldDeps);
});
}
});
});

function declKey(nd) {
return nd.tech ? `${nd.entity.id}.${nd.tech}` : nd.entity.id;
}

function remove(noDeps) {
noDeps.forEach(function (noDep) {
result.dependOn.forEach(function (dep, idx) {
if ((naming.stringify(dep.entity) + dep.tech) === (naming.stringify(noDep) + noDep.tech)) {
result.dependOn.splice(idx, 1);
function removeFromDeps(decl, index, list) {
const key = declKey(decl);
if (index[key]) {
for (var i = 0, l = list.length; i < l; i++) {
if (declKey(list[i].vertex) === key) {
return list.splice(i, 1);
}
});
});
}
} else {
index[key] = true;
}
return null;
}

// `entityDeps.deps` is an array of all entity dependencies from all files
entityDeps.deps.forEach(function (entityOneFileDeps) {
entityOneFileDeps.forEach(function (oneTechDeps) {
oneTechDeps.tech && (result.tech = oneTechDeps.tech);

add(oneTechDeps.mustDeps, true);
add(oneTechDeps.shouldDeps);
remove(oneTechDeps.noDeps);
});
});

return result;
return mustDeps.concat(shouldDeps);
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"lib/**"
],
"dependencies": {
"bem-decl": "0.2.0",
"bem-decl": "bem-sdk/bem-decl#v0.2.0",
"bem-entity-name": "0.0.1",
"bem-graph": "bem-sdk/bem-graph#1bc3408",
"bem-naming": "1.0.1",
"bem-walk": "1.0.0-1",
Expand Down

0 comments on commit e1f76a4

Please sign in to comment.