diff --git a/publicodes/source/mecanisms/arrondi.tsx b/publicodes/source/mecanisms/arrondi.tsx index bb527f808..0490ba20d 100644 --- a/publicodes/source/mecanisms/arrondi.tsx +++ b/publicodes/source/mecanisms/arrondi.tsx @@ -5,11 +5,10 @@ import { InfixMecanism } from '../components/mecanisms/common' import { defaultNode, evaluateNode, mergeAllMissing } from '../evaluation' import { simplifyNodeUnit } from '../nodeUnits' import { mapTemporal, pureTemporal, temporalAverage } from '../temporal' -import { EvaluatedNode, EvaluatedRule, Evaluation } from '../types' +import { EvaluatedNode, EvaluatedRule } from '../types' import { serializeUnit } from '../units' type MecanismRoundProps = { - nodeValue: Evaluation explanation: ArrondiExplanation } @@ -18,7 +17,7 @@ type ArrondiExplanation = { decimals: EvaluatedNode } -function MecanismRound({ nodeValue, explanation }: MecanismRoundProps) { +function MecanismRound({ explanation }: MecanismRoundProps) { return ( {explanation.decimals.nodeValue !== false && @@ -75,7 +74,7 @@ function evaluate( } } -export default (recurse, k, v) => { +export default (recurse, v) => { const explanation = { value: has('valeur', v) ? recurse(v['valeur']) : recurse(v), decimals: has('décimales', v) ? recurse(v['décimales']) : defaultNode(0) diff --git a/publicodes/source/mecanisms/barème.ts b/publicodes/source/mecanisms/barème.ts index a4aa3e646..e3d76a59d 100644 --- a/publicodes/source/mecanisms/barème.ts +++ b/publicodes/source/mecanisms/barème.ts @@ -12,19 +12,9 @@ import { evaluatePlafondUntilActiveTranche, parseTranches } from './trancheUtils' -import { decompose } from './utils' -import variations from './variations' -export default function parse(parse, k, v) { - // Barème en taux marginaux. - - if (v.composantes) { - //mécanisme de composantes. Voir mécanismes.md/composantes - return decompose(parse, k, v) - } - if (v.variations) { - return variations(parse, k, v, true) - } +// Barème en taux marginaux. +export default function parse(parse, v) { const explanation = { assiette: parse(v.assiette), multiplicateur: v.multiplicateur ? parse(v.multiplicateur) : defaultNode(1), diff --git a/publicodes/source/mecanisms/condition-allof.tsx b/publicodes/source/mecanisms/condition-allof.tsx index 9118e7972..ec13b6640 100644 --- a/publicodes/source/mecanisms/condition-allof.tsx +++ b/publicodes/source/mecanisms/condition-allof.tsx @@ -16,7 +16,7 @@ const evaluate = (cache, situation, parsedRules, node) => { return { ...node, nodeValue, explanation, missingVariables } } -export const mecanismAllOf = (recurse, k, v) => { +export const mecanismAllOf = (recurse, v) => { if (!is(Array, v)) throw new Error('should be array') const explanation = map(recurse, v) const jsx = ({ nodeValue, explanation, unit }) => ( diff --git a/publicodes/source/mecanisms/condition-oneof.tsx b/publicodes/source/mecanisms/condition-oneof.tsx index 6ba9c90ac..6b70d99ec 100644 --- a/publicodes/source/mecanisms/condition-oneof.tsx +++ b/publicodes/source/mecanisms/condition-oneof.tsx @@ -26,7 +26,7 @@ const evaluate = (cache, situation, parsedRules, node) => { return { ...node, nodeValue, explanation, missingVariables } } -export const mecanismOneOf = (recurse, k, v) => { +export const mecanismOneOf = (recurse, v) => { if (!is(Array, v)) throw new Error('should be array') const explanation = map(recurse, v) const jsx = ({ nodeValue, explanation, unit }) => ( diff --git a/publicodes/source/mecanisms/durée.tsx b/publicodes/source/mecanisms/durée.tsx index ca3e8fffa..2492858a2 100644 --- a/publicodes/source/mecanisms/durée.tsx +++ b/publicodes/source/mecanisms/durée.tsx @@ -69,7 +69,7 @@ const evaluate = (cache, situation, parsedRules, node) => { } } -export default (recurse, k, v) => { +export default (recurse, v) => { const explanation = parseObject(recurse, objectShape, v) return { diff --git a/publicodes/source/mecanisms/encadrement.tsx b/publicodes/source/mecanisms/encadrement.tsx index a7ab07aa2..b19ab57ef 100644 --- a/publicodes/source/mecanisms/encadrement.tsx +++ b/publicodes/source/mecanisms/encadrement.tsx @@ -82,7 +82,7 @@ const evaluate = evaluateObject( } ) -export default (recurse, k, v) => { +export default (recurse, v) => { const explanation = parseObject(recurse, objectShape, v) return { diff --git a/publicodes/source/mecanisms/grille.ts b/publicodes/source/mecanisms/grille.ts index cedc5c939..3faa115cd 100644 --- a/publicodes/source/mecanisms/grille.ts +++ b/publicodes/source/mecanisms/grille.ts @@ -1,8 +1,6 @@ import { lensPath, over } from 'ramda' import grille from '../components/mecanisms/Grille' import { defaultNode, evaluateNode, mergeAllMissing } from '../evaluation' -import { decompose } from '../mecanisms/utils' -import variations from '../mecanisms/variations' import { liftTemporal2, liftTemporalNode, @@ -15,14 +13,7 @@ import { parseTranches } from './trancheUtils' -export default function parse(parse, k, v) { - if (v.composantes) { - //mécanisme de composantes. Voir mécanismes.md/composantes - return decompose(parse, k, v) - } - if (v.variations) { - return variations(parse, k, v, true) - } +export default function parse(parse, v) { const defaultUnit = v['unité'] && parseUnit(v['unité']) const explanation = { assiette: parse(v.assiette), diff --git a/publicodes/source/mecanisms/inversion.ts b/publicodes/source/mecanisms/inversion.ts index d6fe7283c..7d46f3ceb 100644 --- a/publicodes/source/mecanisms/inversion.ts +++ b/publicodes/source/mecanisms/inversion.ts @@ -86,7 +86,7 @@ export const evaluateInversion = (oldCache, situation, parsedRules, node) => { } } -export const mecanismInversion = dottedName => (recurse, k, v) => { +export const mecanismInversion = dottedName => (recurse, v) => { if (!v.avec) { throw new Error( "Une formule d'inversion doit préciser _avec_ quoi on peut inverser la variable" diff --git a/publicodes/source/mecanisms/max.tsx b/publicodes/source/mecanisms/max.tsx index ec5d1f1d6..0f11d5c73 100644 --- a/publicodes/source/mecanisms/max.tsx +++ b/publicodes/source/mecanisms/max.tsx @@ -2,7 +2,7 @@ import React from 'react' import { Mecanism } from '../components/mecanisms/common' import { evaluateArray, makeJsx } from '../evaluation' -export const mecanismMax = (recurse, k, v) => { +export const mecanismMax = (recurse, v) => { const explanation = v.map(recurse) const max = (a, b) => { diff --git a/publicodes/source/mecanisms/min.tsx b/publicodes/source/mecanisms/min.tsx index 0a8b9b0fc..fdd985ec4 100644 --- a/publicodes/source/mecanisms/min.tsx +++ b/publicodes/source/mecanisms/min.tsx @@ -3,7 +3,7 @@ import React from 'react' import { Mecanism } from '../components/mecanisms/common' import { evaluateArray, makeJsx } from '../evaluation' -export const mecanismMin = (recurse, k, v) => { +export const mecanismMin = (recurse, v) => { const explanation = v.map(recurse) const evaluate = evaluateArray(min, Infinity) const jsx = ({ nodeValue, explanation, unit }) => ( diff --git a/publicodes/source/mecanisms/one-possibility.tsx b/publicodes/source/mecanisms/one-possibility.tsx index 353629014..2e00a1816 100644 --- a/publicodes/source/mecanisms/one-possibility.tsx +++ b/publicodes/source/mecanisms/one-possibility.tsx @@ -1,5 +1,5 @@ // TODO : This isn't a real mecanism, cf. #963 -export const mecanismOnePossibility = dottedName => (recurse, k, v) => ({ +export const mecanismOnePossibility = dottedName => (recurse, v) => ({ ...v, 'une possibilité': 'oui', evaluate: (cache, situation, parsedRules, node) => ({ diff --git a/publicodes/source/mecanisms/operation.tsx b/publicodes/source/mecanisms/operation.tsx index 15517cd00..1a48a979c 100644 --- a/publicodes/source/mecanisms/operation.tsx +++ b/publicodes/source/mecanisms/operation.tsx @@ -8,7 +8,7 @@ import { inferUnit, serializeUnit } from '../units' import { curry, map } from 'ramda' import React from 'react' -export default (k, operatorFunction, symbol) => (recurse, k, v) => { +export default (k, operatorFunction, symbol) => (recurse, v) => { const evaluate = (cache, situation, parsedRules, node) => { const explanation = map( curry(evaluateNode)(cache, situation, parsedRules), diff --git a/publicodes/source/mecanisms/product.tsx b/publicodes/source/mecanisms/product.tsx index e7a96ceb1..2ef5d01d1 100644 --- a/publicodes/source/mecanisms/product.tsx +++ b/publicodes/source/mecanisms/product.tsx @@ -1,19 +1,10 @@ import Product from '../components/mecanisms/Product' import { typeWarning } from '../error' import { defaultNode, evaluateObject, parseObject } from '../evaluation' -import { decompose } from './utils' -import variations from './variations' import { convertNodeToUnit } from '../nodeUnits' import { areUnitConvertible, convertUnit, inferUnit } from '../units' -export const mecanismProduct = (recurse, k, v) => { - if (v.composantes) { - //mécanisme de composantes. Voir mécanismes.md/composantes - return decompose(recurse, k, v) - } - if (v.variations) { - return variations(recurse, k, v, true) - } +export const mecanismProduct = (recurse, v) => { const objectShape = { assiette: false, taux: defaultNode(1), diff --git a/publicodes/source/mecanisms/recalcul.ts b/publicodes/source/mecanisms/recalcul.ts index bfd983284..4cace26b9 100644 --- a/publicodes/source/mecanisms/recalcul.ts +++ b/publicodes/source/mecanisms/recalcul.ts @@ -45,7 +45,7 @@ const evaluateRecalcul = (cache, situation, parsedRules, node) => { } } -export const mecanismRecalcul = dottedNameContext => (recurse, k, v) => { +export const mecanismRecalcul = dottedNameContext => (recurse, v) => { const amendedSituation = Object.keys(v.avec).map(dottedName => [ recurse(dottedName), recurse(v.avec[dottedName]) diff --git a/publicodes/source/mecanisms/reduction.ts b/publicodes/source/mecanisms/reduction.ts index 1d54848a0..238a3efed 100644 --- a/publicodes/source/mecanisms/reduction.ts +++ b/publicodes/source/mecanisms/reduction.ts @@ -5,7 +5,7 @@ import { defaultNode, evaluateObject, parseObject } from '../evaluation' import { convertNodeToUnit } from '../nodeUnits' import { parseUnit, serializeUnit } from '../units' -export const mecanismReduction = (recurse, k, v) => { +export const mecanismReduction = (recurse, v) => { const objectShape = { assiette: false, abattement: defaultNode(0), diff --git a/publicodes/source/mecanisms/régularisation.ts b/publicodes/source/mecanisms/régularisation.ts index a6db5006f..783ad1423 100644 --- a/publicodes/source/mecanisms/régularisation.ts +++ b/publicodes/source/mecanisms/régularisation.ts @@ -20,7 +20,7 @@ function stripTemporalTransform(node) { } return stripTemporalTransform(node.explanation.value) } -export default function parse(parse, k, v) { +export default function parse(parse, v) { const rule = parse(v.règle) if (!v['valeurs cumulées']) { throw new Error( diff --git a/publicodes/source/mecanisms/sum.tsx b/publicodes/source/mecanisms/sum.tsx index 12080892b..f6bf4bf7c 100644 --- a/publicodes/source/mecanisms/sum.tsx +++ b/publicodes/source/mecanisms/sum.tsx @@ -7,7 +7,7 @@ const evaluate = evaluateArray( false ) -export const mecanismSum = (recurse, k, v) => { +export const mecanismSum = (recurse, v) => { const explanation = v.map(recurse) return { evaluate, diff --git a/publicodes/source/mecanisms/synchronisation.tsx b/publicodes/source/mecanisms/synchronisation.tsx index 3da9cc752..033b37502 100644 --- a/publicodes/source/mecanisms/synchronisation.tsx +++ b/publicodes/source/mecanisms/synchronisation.tsx @@ -33,7 +33,7 @@ const evaluate = (cache, situation, parsedRules, node) => { return { ...node, nodeValue: safeNodeValue, explanation, missingVariables } } -export const mecanismSynchronisation = (recurse, k, v) => { +export const mecanismSynchronisation = (recurse, v) => { return { explanation: { ...v, API: recurse(v.API) }, evaluate, diff --git a/publicodes/source/mecanisms/tauxProgressif.ts b/publicodes/source/mecanisms/tauxProgressif.ts index ace9738d2..287bafb1e 100644 --- a/publicodes/source/mecanisms/tauxProgressif.ts +++ b/publicodes/source/mecanisms/tauxProgressif.ts @@ -1,6 +1,4 @@ import { defaultNode, evaluateNode, mergeAllMissing } from '../evaluation' -import { decompose } from './utils' -import variations from './variations' import tauxProgressif from '../components/mecanisms/TauxProgressif' import { convertNodeToUnit } from '../nodeUnits' import { parseUnit } from '../units' @@ -9,15 +7,7 @@ import { parseTranches } from './trancheUtils' -export default function parse(parse, k, v) { - if (v.composantes) { - //mécanisme de composantes. Voir mécanismes.md/composantes - return decompose(parse, k, v) - } - if (v.variations) { - return variations(parse, k, v, true) - } - +export default function parse(parse, v) { const explanation = { assiette: parse(v.assiette), multiplicateur: v.multiplicateur ? parse(v.multiplicateur) : defaultNode(1), diff --git a/publicodes/source/mecanisms/variableTemporelle.ts b/publicodes/source/mecanisms/variableTemporelle.ts index b1a315af0..9a4398c8b 100644 --- a/publicodes/source/mecanisms/variableTemporelle.ts +++ b/publicodes/source/mecanisms/variableTemporelle.ts @@ -46,7 +46,7 @@ function evaluate( } } -export default function parseVariableTemporelle(parse, __, v: any) { +export default function parseVariableTemporelle(parse, v) { const explanation = parse(v.explanation) return { evaluate, diff --git a/publicodes/source/mecanisms/variations.ts b/publicodes/source/mecanisms/variations.ts index e854fa5b3..1754f8137 100644 --- a/publicodes/source/mecanisms/variations.ts +++ b/publicodes/source/mecanisms/variations.ts @@ -12,15 +12,12 @@ import { import { inferUnit } from '../units' import { mergeAllMissing } from './../evaluation' -/* @devariate = true => This function will produce variations of a same mecanism (e.g. product) that share some common properties */ -export default function parse(recurse, k, v, devariate) { - const explanation = devariate - ? devariateExplanation(recurse, k, v) - : v.map(({ si, alors, sinon }) => - sinon !== undefined - ? { consequence: recurse(sinon), condition: defaultNode(true) } - : { consequence: recurse(alors), condition: recurse(si) } - ) +export default function parse(recurse, v) { + const explanation = v.map(({ si, alors, sinon }) => + sinon !== undefined + ? { consequence: recurse(sinon), condition: defaultNode(true) } + : { consequence: recurse(alors), condition: recurse(si) } + ) // TODO - find an appropriate representation return { @@ -36,6 +33,23 @@ export default function parse(recurse, k, v, devariate) { ) } } + +export function devariate(recurse, k, v) { + const explanation = devariateExplanation(recurse, k, v) + return { + explanation, + evaluate, + jsx: Variations, + category: 'mecanism', + name: 'variations', + type: 'numeric', + unit: inferUnit( + '+', + explanation.map(r => r.consequence.unit) + ) + } +} + type Variation = | { si: any @@ -44,7 +58,7 @@ type Variation = | { sinon: object } -export const devariateExplanation = ( +const devariateExplanation = ( recurse, mecanismKey, v: { variations: Array } diff --git a/publicodes/source/parse.tsx b/publicodes/source/parse.tsx index 6c3fe1042..968336d59 100644 --- a/publicodes/source/parse.tsx +++ b/publicodes/source/parse.tsx @@ -1,7 +1,6 @@ // This should be the new way to implement mecanisms // In a specific file // TODO import them automatically -// TODO convert the legacy functions to new files import mecanismRound, { unchainRoundMecanism } from './mecanisms/arrondi' import barème from './mecanisms/barème' import durée from './mecanisms/durée' @@ -11,7 +10,7 @@ import operation from './mecanisms/operation' import régularisation from './mecanisms/régularisation' import tauxProgressif from './mecanisms/tauxProgressif' import variableTemporelle from './mecanisms/variableTemporelle' -import variations from './mecanisms/variations' +import variations, { devariate } from './mecanisms/variations' import { Grammar, Parser } from 'nearley' import { add, @@ -43,6 +42,7 @@ import { mecanismSynchronisation } from './mecanisms/synchronisation' import { mecanismRecalcul } from './mecanisms/recalcul' import { parseReferenceTransforms } from './parseReference' import { EvaluatedRule } from './types' +import { decompose } from './mecanisms/utils' export const parse = (rules, rule, parsedRules) => rawNode => { if (rawNode == null) { @@ -146,6 +146,7 @@ Cela vient probablement d'une erreur dans l'indentation } const parseFn = parseFunctions[mecanismName] + if (!parseFn) { syntaxError( rule.dottedName, @@ -155,7 +156,15 @@ Vérifiez qu'il n'y ait pas d'erreur dans l'orthographe du nom.` ) } try { - return parseFn(parse(rules, rule, parsedRules), mecanismName, values) + const recurse = parse(rules, rule, parsedRules) + // Mécanisme de composantes. Voir mécanismes.md/composantes + if (values?.composantes) { + return decompose(recurse, mecanismName, values) + } + if (values?.variations) { + return devariate(recurse, mecanismName, values) + } + return parseFn(recurse, values) } catch (e) { if (e instanceof EngineError) { throw e @@ -232,8 +241,8 @@ const statelessParseFunction = { allègement: mecanismReduction, variations, synchronisation: mecanismSynchronisation, - valeur: (recurse, __, v) => recurse(v), - constant: (_, __, v) => ({ + valeur: (recurse, v) => recurse(v), + constant: (_, v) => ({ type: v.type, constant: true, nodeValue: v.nodeValue,