149 lines
4.0 KiB
JavaScript
149 lines
4.0 KiB
JavaScript
|
import R from 'ramda'
|
||
|
import removeDiacritics from '../utils/remove-diacritics'
|
||
|
|
||
|
|
||
|
import { createSelector } from 'reselect'
|
||
|
import {variablesSelector} from './selectors'
|
||
|
import traversalGuide from './traversalGuide'
|
||
|
|
||
|
/* AIM : Parse all the variables and extract their references to other variables.
|
||
|
Rank the results by count. */
|
||
|
|
||
|
// Use http://regexr.com/ to understand and write regexps !!
|
||
|
|
||
|
|
||
|
|
||
|
// Returns a list of used variables
|
||
|
let findUsedVariables = (schema, toAnalyse, variables) =>
|
||
|
R.cond([
|
||
|
[R.is(Function), extractor =>
|
||
|
R.pipe(
|
||
|
extractor,
|
||
|
R.unless(R.isArrayLike, R.of),
|
||
|
R.map(R.cond([
|
||
|
[R.is(String), name => findVariables(variables, name)],
|
||
|
[R.is(Object), tags => findVariables(variables, null, tags)]
|
||
|
])),
|
||
|
R.unnest,
|
||
|
R.map(R.unless(R.is(String), found => findUsedVariables(traversalGuide, found, variables)))
|
||
|
)(toAnalyse)
|
||
|
],
|
||
|
[R.is(Object), traversalObject =>
|
||
|
R.toPairs(traversalObject).reduce(
|
||
|
(res, [key, value]) => {
|
||
|
return toAnalyse[key] != null ?
|
||
|
[...res, ...findUsedVariables(value, toAnalyse[key], variables)] :
|
||
|
res
|
||
|
}, []
|
||
|
)],
|
||
|
[R.T, yo => []]
|
||
|
])(schema)
|
||
|
|
||
|
// R.cond([
|
||
|
// [R.isArrayLike, R.map(name => {
|
||
|
// let found = findVariables(variables, name)
|
||
|
// return typeof found == 'object' ?
|
||
|
// findUsedVariables(traversalGuide, found, variables)
|
||
|
// : found
|
||
|
// })],
|
||
|
// [R.is(Object), tags => {
|
||
|
// let found = findVariables(variables, null, tags)
|
||
|
// return typeof found == 'object' ?
|
||
|
// findUsedVariables(traversalGuide, found, variables)
|
||
|
// : found
|
||
|
// }]
|
||
|
// ])(schema(toAnalyse))
|
||
|
|
||
|
|
||
|
let calculableVariables = createSelector(
|
||
|
[variablesSelector],
|
||
|
R.pipe(R.pluck('calculable'), R.unnest)
|
||
|
)
|
||
|
|
||
|
|
||
|
// let data = require('../sertarien.yaml')
|
||
|
// let getAllUsedVariables = R.pipe(
|
||
|
// R.map(findUsedVariables(traversalGuide)),
|
||
|
// R.flatten,
|
||
|
// R.countBy(R.identity),
|
||
|
// R.toPairs,
|
||
|
// R.sortBy(R.last),
|
||
|
// R.reverse,
|
||
|
// R.map(R.join(': '))
|
||
|
// )
|
||
|
|
||
|
let findVariablesByName = name =>
|
||
|
R.filter(variable => removeDiacritics(variable.variable) == name)
|
||
|
|
||
|
let findVariablesByTags = tags =>
|
||
|
R.filter(R.pipe(
|
||
|
R.prop('tags'),
|
||
|
R.whereEq(tags)
|
||
|
))
|
||
|
//
|
||
|
// let findVariables = (variables, name, tags) => {
|
||
|
// // Raise error if searching on both name and tags provided gives multiple results
|
||
|
// let results = variables
|
||
|
// if (R.is(String, name)) {
|
||
|
// results = findVariablesByName(name)(variables)
|
||
|
// if (!results.length)
|
||
|
// return `Final variable ${name}`
|
||
|
// }
|
||
|
// if (tags != null) {
|
||
|
// results = findVariablesByTags(tags)(variables)
|
||
|
// }
|
||
|
// if (results.length == 0)
|
||
|
// return `Final variable ${name}`
|
||
|
// if (name != null && results.length > 1)
|
||
|
// return `More than one variable corresponds to this name, tags tuple : ${name}, ${tags}`
|
||
|
//
|
||
|
// return results
|
||
|
// }
|
||
|
|
||
|
let findVariables = (variables, name, tags) =>
|
||
|
R.pipe(
|
||
|
variables => R.is(String, name)
|
||
|
? findVariablesByName(name)(variables)
|
||
|
: variables,
|
||
|
variables => R.is(Object, tags)
|
||
|
? findVariablesByTags(tags)(variables)
|
||
|
: variables,
|
||
|
R.cond([
|
||
|
[ R.isEmpty, () => variableNotFound(name)],
|
||
|
[ (variables) => R.is(String, name) && variables.length > 1,
|
||
|
() => variableNameCollision(name, tags)],
|
||
|
[ R.T,
|
||
|
R.identity]
|
||
|
]),
|
||
|
)(variables)
|
||
|
|
||
|
let variableNotFound = name =>
|
||
|
`Final variable ${name}`
|
||
|
// Should do a query to openfisca web api
|
||
|
// - input var -> end with an input var object
|
||
|
// - var calling other vars -> recursively call
|
||
|
|
||
|
let variableNameCollision = (name, tags) =>
|
||
|
`More than one variable corresponds to this name, tags tuple : ${name}, ${tags}`
|
||
|
|
||
|
|
||
|
export let usedVariables = createSelector(
|
||
|
[state => state.rootVariables, calculableVariables],
|
||
|
(roots, variables) => {
|
||
|
// get all variables from these roots, rec !
|
||
|
return R.compose(
|
||
|
R.uniq,
|
||
|
R.flatten,
|
||
|
R.map(rootObject => findUsedVariables(traversalGuide, rootObject, variables)),
|
||
|
R.map(root => findVariables(variables, removeDiacritics(root))[0])
|
||
|
)(roots)
|
||
|
|
||
|
}
|
||
|
)
|
||
|
|
||
|
|
||
|
// export let usedVariables = createSelector(
|
||
|
// [calculableVariables],
|
||
|
// getAllUsedVariables
|
||
|
// )
|