diff --git a/JBFL_DOCS.md b/JBFL_DOCS.md index 05f255c0..52366575 100644 --- a/JBFL_DOCS.md +++ b/JBFL_DOCS.md @@ -74,6 +74,24 @@ Typical use cases include: - `TrailingComma: None` strips trailing commas. `Force` always adds them. `Preserve` (default) keeps whatever the source file had. - `TrailingComma` is resolved at the child level, so `.* { TrailingComma: None; }` also strips the trailing comma in the root object. +### How far a property reaches + +A pattern names one level. Some properties then apply only to what sits exactly +there, and others also apply to everything nested below it, so a rule on `.*` +can still decide how a value five levels down is printed. + +| Reaches | Properties | +|-----------------------------|-------------------------------------------------------------------------------------------------| +| The matched value only | `AutoPad`, `AlignObjectKeys`, `AutoPadSubObjects` | +| The matched value and below | `PadDecimals`, `PadAmount`, `Indent`, `ComplexNewLine`, `TrailingComma`, `PreserveNumberFormat` | + +The three in the first row all describe how one array or object lays out its own +children, so inheriting them would align structures the rule never mentioned. + +This is why `.* { Indent: 2; }` indents the whole file while `.* { AutoPad: true; }` +only pads the root object, and why the shipped `minimal.jbfl` can set +`PadDecimals` on `.*.nodes[*][*]` or on a parent and get the same result. + ## Detailed Rules Examples ### Pattern: `.*.nodes[*][*]` diff --git a/cabal.project.dev b/cabal.project.dev index c083d613..a4d888e0 100644 --- a/cabal.project.dev +++ b/cabal.project.dev @@ -14,7 +14,8 @@ package jbeam-edit ghc-options: -haddock -Wno-invalid-haddock + -XPartialTypeSignatures documentation: False tests: True - flags: +dump-ast +transformation -windows-example-paths + flags: -modern-containers +dump-ast +transformation -windows-example-paths diff --git a/examples/ast/jbfl/complex.hs b/examples/ast/jbfl/complex.hs index 05881d91..459b9b9a 100644 --- a/examples/ast/jbfl/complex.hs +++ b/examples/ast/jbfl/complex.hs @@ -1,364 +1,307 @@ RuleSet - ( fromList - [ - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "beams" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "components" ), Selector - ( ObjectKey "electrics" ), Selector - ( ObjectKey "smoothers" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "flexbodies" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "nodes" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "props" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots2" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "beams" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "flexbodies" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), AnyObjectKey, Selector - ( ObjectKey "off" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 10 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), AnyObjectKey, Selector - ( ObjectKey "on" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 10 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "mainEngine" ), Selector - ( ObjectKey "burnEfficiency" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "mainEngine" ), Selector - ( ObjectKey "torque" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "mainEngine" ), Selector - ( ObjectKey "torqueModIntake" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "mainEngine" ), Selector - ( ObjectKey "torqueModMult" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "nodes" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "nodes" ), AnyArrayIndex, AnyArrayIndex ] ), fromList - [ ( SomeKey PadDecimals, SomeProperty PadDecimals 3 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "props" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots2" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "beams" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "controller" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "flexbodies" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "abs" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "battery" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "chassis_gaugelight_warning" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "checkengine" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "dumptruck_gaugelight_warning" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "hazard" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "highbeam" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "lowfuel" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "lowpressure" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "parkingbrake" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "signal_L" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), Selector - ( ObjectKey "signal_R" ) ] ), fromList - [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "nodes" ), AnyArrayIndex ] ), fromList - [ ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "powertrain" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "props" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "rails" ), AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots2" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "triangles" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "variables" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList [ AnyObjectKey, Selector ( ObjectKey "beams" ) ] ), fromList - [ ( SomeKey AutoPad, SomeProperty AutoPad True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "glowMap" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey AutoPadSubObjects, SomeProperty AutoPadSubObjects True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "information" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "mainEngine" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList [ AnyObjectKey, Selector ( ObjectKey "nodes" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey AutoPad, SomeProperty AutoPad True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "soundConfig" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "soundConfigExhaust" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "sounds" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "triangles" ) ] ), fromList - [ ( SomeKey AutoPad, SomeProperty AutoPad True ) ] ), - ( NodePattern - ( fromList [ AnyObjectKey ] ), fromList + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "beams", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList + [ + ( SomeKey AutoPad, SomeProperty AutoPad True ) ], rsBelow = fromList [] } ), + ( ObjectKey "components", RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "electrics", RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "smoothers", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ) ], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ) ], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "controller", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "flexbodies", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "glowMap", RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "abs", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ), + ( ObjectKey "battery", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ), + ( ObjectKey "chassis_gaugelight_warning", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "checkengine", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ), + ( ObjectKey "dumptruck_gaugelight_warning", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "hazard", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ), + ( ObjectKey "highbeam", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ), + ( ObjectKey "lowfuel", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ), + ( ObjectKey "lowpressure", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ), + ( ObjectKey "parkingbrake", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ), + ( ObjectKey "signal_L", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ), + ( ObjectKey "signal_R", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey PadAmount, SomeProperty PadAmount 20 ) ] } ) ], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "off", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey PadAmount, SomeProperty PadAmount 10 ) ] } ), + ( ObjectKey "on", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey PadAmount, SomeProperty PadAmount 10 ) ] } ) ], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), + ( SomeKey AutoPadSubObjects, SomeProperty AutoPadSubObjects True ) ], rsBelow = fromList [] } ), + ( ObjectKey "information", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "mainEngine", RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "burnEfficiency", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "torque", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "torqueModIntake", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "torqueModMult", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ) ], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "nodes", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey PadDecimals, SomeProperty PadDecimals 3 ) ] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ) ] } ), rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), + ( SomeKey AutoPad, SomeProperty AutoPad True ) ], rsBelow = fromList [] } ), + ( ObjectKey "powertrain", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "props", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "rails", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "slots", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "slots2", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "soundConfig", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "soundConfigExhaust", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "sounds", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "triangles", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList + [ + ( SomeKey AutoPad, SomeProperty AutoPad True ) ], rsBelow = fromList [] } ), + ( ObjectKey "variables", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ) ], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [ ( SomeKey Indent, SomeProperty Indent 2 ), - ( SomeKey TrailingComma, SomeProperty TrailingComma None ) ] ) ] ) \ No newline at end of file + ( SomeKey TrailingComma, SomeProperty TrailingComma None ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } diff --git a/examples/ast/jbfl/minimal.hs b/examples/ast/jbfl/minimal.hs index d2c37cd3..735cc739 100644 --- a/examples/ast/jbfl/minimal.hs +++ b/examples/ast/jbfl/minimal.hs @@ -1,269 +1,249 @@ RuleSet - ( fromList - [ - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "beams" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "components" ), Selector - ( ObjectKey "electrics" ), Selector - ( ObjectKey "smoothers" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "flexbodies" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "nodes" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "props" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots2" ), AnyArrayIndex, AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "beams" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "flexbodies" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "mainEngine" ), Selector - ( ObjectKey "burnEfficiency" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "mainEngine" ), Selector - ( ObjectKey "torque" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "mainEngine" ), Selector - ( ObjectKey "torqueModIntake" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "mainEngine" ), Selector - ( ObjectKey "torqueModMult" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "nodes" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "nodes" ), AnyArrayIndex, AnyArrayIndex ] ), fromList - [ ( SomeKey PadDecimals, SomeProperty PadDecimals 3 ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "props" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots2" ), AnyArrayIndex, AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "beams" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "controller" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "flexbodies" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "glowMap" ), AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "nodes" ), AnyArrayIndex ] ), fromList - [ ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "powertrain" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "props" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "rails" ), AnyObjectKey ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "slots2" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "triangles" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "variables" ), AnyArrayIndex ] ), fromList - [ - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList [ AnyObjectKey, Selector ( ObjectKey "beams" ) ] ), fromList - [ ( SomeKey AutoPad, SomeProperty AutoPad True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "glowMap" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey AutoPadSubObjects, SomeProperty AutoPadSubObjects True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "information" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "mainEngine" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList [ AnyObjectKey, Selector ( ObjectKey "nodes" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey AutoPad, SomeProperty AutoPad True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "soundConfig" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector - ( ObjectKey "soundConfigExhaust" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "sounds" ) ] ), fromList - [ - ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), - ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), - ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] ), - ( NodePattern - ( fromList - [ AnyObjectKey, Selector ( ObjectKey "triangles" ) ] ), fromList - [ ( SomeKey AutoPad, SomeProperty AutoPad True ) ] ) ] ) \ No newline at end of file + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "beams", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList + [ + ( SomeKey AutoPad, SomeProperty AutoPad True ) ], rsBelow = fromList [] } ), + ( ObjectKey "components", RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "electrics", RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "smoothers", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ) ], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ) ], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "controller", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "flexbodies", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "glowMap", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), + ( SomeKey AutoPadSubObjects, SomeProperty AutoPadSubObjects True ) ], rsBelow = fromList [] } ), + ( ObjectKey "information", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "mainEngine", RuleSet + { rsBySelectors = fromList + [ + ( ObjectKey "burnEfficiency", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "torque", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "torqueModIntake", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "torqueModMult", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ) ], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "nodes", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey PadDecimals, SomeProperty PadDecimals 3 ) ] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ) ] } ), rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ), + ( SomeKey AutoPad, SomeProperty AutoPad True ) ], rsBelow = fromList [] } ), + ( ObjectKey "powertrain", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "props", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "rails", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "slots", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "slots2", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ), + ( ObjectKey "soundConfig", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "soundConfigExhaust", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "sounds", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList + [ + ( SomeKey AlignObjectKeys, SomeProperty AlignObjectKeys True ) ], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine Force ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), + ( ObjectKey "triangles", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList + [ + ( SomeKey AutoPad, SomeProperty AutoPad True ) ], rsBelow = fromList [] } ), + ( ObjectKey "variables", RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Just + ( RuleSet + { rsBySelectors = fromList [], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList + [ + ( SomeKey ComplexNewLine, SomeProperty ComplexNewLine None ), + ( SomeKey PreserveNumberFormat, SomeProperty PreserveNumberFormat True ) ] } ), rsHere = fromList [], rsBelow = fromList [] } ) ], rsPrefixes = [], rsAnyObjectKey = Nothing, rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } ), rsAnyArrayIndex = Nothing, rsHere = fromList [], rsBelow = fromList [] } diff --git a/src/JbeamEdit/Core/NodePath.hs b/src/JbeamEdit/Core/NodePath.hs index 342817b3..c6b214bf 100644 --- a/src/JbeamEdit/Core/NodePath.hs +++ b/src/JbeamEdit/Core/NodePath.hs @@ -9,9 +9,10 @@ module JbeamEdit.Core.NodePath ( ) where import Data.Either.Extra (maybeToEither) +import Data.Function (on) import Data.Sequence (Seq (..)) import Data.Text (Text) -import Data.Text qualified as T (isPrefixOf, show) +import Data.Text qualified as T (isPrefixOf, length, show) import Data.Vector (Vector) import Data.Vector qualified as V import GHC.IsList (IsList (..)) @@ -29,7 +30,16 @@ data NodeSelector | ObjectKey Text | ObjectPrefixKey Text | ObjectIndex Int - deriving (Eq, Ord, Read, Show) + deriving (Eq, Read, Show) + +instance Ord NodeSelector where + compare = on compare rank + where + rank :: NodeSelector -> (Int, Int, Text) + rank (ObjectKey key) = (0, 0, key) + rank (ArrayIndex index) = (1, index, "") + rank (ObjectIndex i) = (2, i, "") + rank (ObjectPrefixKey prefix) = (3, negate (T.length prefix), prefix) {- | node path A NodePath is a Sequence of selectors to that point out a certain point in a Node tree, either to point at as something when fetching it from Node or to point to something compare that I at a certain point when doing updates. diff --git a/src/JbeamEdit/Formatting.hs b/src/JbeamEdit/Formatting.hs index 34ebabb2..99c6207e 100644 --- a/src/JbeamEdit/Formatting.hs +++ b/src/JbeamEdit/Formatting.hs @@ -41,13 +41,12 @@ import JbeamEdit.Core.Node ( import JbeamEdit.Core.NodeCursor (newCursor) import JbeamEdit.Core.NodeCursor qualified as NC import JbeamEdit.Formatting.Rules ( - MatchMode (..), PropertyKey (..), RuleSet (..), applyPadLogic, findPropertiesForCursor, + lookupProperty, lookupPropertyForCursor, - lookupRule, ) import JbeamEdit.Formatting.Rules.ComplexNewLine qualified as CNL import JbeamEdit.Formatting.Rules.TrailingComma qualified as TC @@ -238,7 +237,7 @@ addDelimiters rs index rowIdx c complexChildren state acc ns@((node, nodeHadComm ( \childCursor _ -> fromMaybe TC.Preserve - (lookupPropertyForCursor PrefixMatch TrailingComma rs childCursor) + (lookupPropertyForCursor TrailingComma rs childCursor) ) index node @@ -320,17 +319,16 @@ doFormatNode -> Text doFormatNode rs cursor state elems = let nodes = V.map fst elems - prefixProps = findPropertiesForCursor PrefixMatch cursor rs - exactProps = findPropertiesForCursor ExactMatch cursor rs + props = findPropertiesForCursor cursor rs - autoPadEnabled = lookupRule AutoPad exactProps == Just True - alignObjectKeysEnabled = lookupRule AlignObjectKeys exactProps == Just True - autopadSubObjectsEnabled = lookupRule AutoPadSubObjects exactProps == Just True + autoPadEnabled = lookupProperty AutoPad props == Just True + alignObjectKeysEnabled = lookupProperty AlignObjectKeys props == Just True + autopadSubObjectsEnabled = lookupProperty AutoPadSubObjects props == Just True complexChildren = - lookupRule ComplexNewLine prefixProps == Just CNL.Force + lookupProperty ComplexNewLine props == Just CNL.Force || any (liftA2 (||) isSinglelineComment isComplexNode) nodes - && lookupRule ComplexNewLine prefixProps /= Just CNL.None + && lookupProperty ComplexNewLine props /= Just CNL.None (colWidths, formattedCache, headerWasExtracted) = maxColumnLengthsWithCache rs cursor nodes @@ -397,7 +395,7 @@ doFormatNode rs cursor state elems = . V.toList $ elems - indentationAmount = fromMaybe 4 (lookupRule Indent prefixProps) + indentationAmount = fromMaybe 4 (lookupProperty Indent props) in if complexChildren then T.unlines @@ -453,8 +451,8 @@ formatWithCursor rs state cursor (ObjectKey (k, v)) = in paddedKey <> " : " <> valueText formatWithCursor _ _ _ (Comment comment) = formatComment comment formatWithCursor rs _ cursor n = - let ps = findPropertiesForCursor PrefixMatch cursor rs - preserve = (Just True == lookupRule PreserveNumberFormat ps) + let ps = findPropertiesForCursor cursor rs + preserve = (Just True == lookupProperty PreserveNumberFormat ps) in applyPadLogic (formatScalarNode preserve) ps n formatNode :: RuleSet -> Node -> Text diff --git a/src/JbeamEdit/Formatting/Rules.hs b/src/JbeamEdit/Formatting/Rules.hs index cede8c5e..68127bce 100644 --- a/src/JbeamEdit/Formatting/Rules.hs +++ b/src/JbeamEdit/Formatting/Rules.hs @@ -1,13 +1,12 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} +{-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} module JbeamEdit.Formatting.Rules ( - MatchMode (..), NodePatternSelector (..), - NodePattern (..), SomeKey (..), SomeProperty (..), PropertyKey (..), @@ -18,10 +17,11 @@ module JbeamEdit.Formatting.Rules ( lookupKey, allProperties, deprecatedAliases, + prefixProperties, keyName, applyPadLogic, complexNewLine, - lookupRule, + lookupProperty, lookupPropertyForCursor, findPropertiesForCursor, ) where @@ -29,18 +29,17 @@ module JbeamEdit.Formatting.Rules ( import Data.Bool (bool) import Data.Foldable (fold) import Data.Function (on) -import Data.List (find) +import Data.List (find, sortOn) import Data.Map (Map) import Data.Map qualified as M import Data.Ord (Down (..)) import Data.Sequence (Seq (..)) -import Data.Sequence qualified as Seq (length, null) import Data.Text (Text) import Data.Text qualified as T import Data.Type.Equality ((:~:) (Refl)) import JbeamEdit.Core.Node import JbeamEdit.Core.NodeCursor qualified as NC -import JbeamEdit.Core.NodePath (NodeSelector (..)) +import JbeamEdit.Core.NodePath qualified as NP (NodeSelector (..)) import JbeamEdit.Formatting.Rules.ComplexNewLine (ComplexNewLine) import JbeamEdit.Formatting.Rules.ComplexNewLine qualified as CNL import JbeamEdit.Formatting.Rules.TrailingComma (TrailingComma) @@ -49,32 +48,21 @@ import Text.Read qualified as TR data NodePatternSelector = AnyObjectKey | AnyArrayIndex - | Selector NodeSelector - deriving stock (Eq, Read, Show) - -instance Ord NodePatternSelector where - compare a b = compare (rank a) (rank b) - where - rank :: NodePatternSelector -> (Int, Maybe NodeSelector) - rank AnyArrayIndex = (2, Nothing) - rank AnyObjectKey = (1, Nothing) - rank (Selector s) = (0, Just s) - -newtype NodePattern - = NodePattern (Seq NodePatternSelector) + | Selector NP.NodeSelector deriving stock (Eq, Read, Show) instance Monoid RuleSet where - mempty = RuleSet M.empty + mempty = RuleSet M.empty [] mempty mempty M.empty M.empty instance Semigroup RuleSet where - (RuleSet rs1) <> (RuleSet rs2) = RuleSet (M.unionWith M.union rs1 rs2) - -instance Ord NodePattern where - compare (NodePattern a) (NodePattern b) = - case on compare (Down . Seq.length) a b of - EQ -> compare a b - c -> c + (RuleSet rs1 ps1 aok1 aai1 h1 b1) <> (RuleSet rs2 ps2 aok2 aai2 h2 b2) = + RuleSet + (M.unionWith (<>) rs1 rs2) + (mergePrefixes ps1 ps2) + (aok1 <> aok2) + (aai1 <> aai2) + (h1 <> h2) + (b1 <> b2) data PropertyKey a where AutoPad :: PropertyKey Bool @@ -190,6 +178,18 @@ intProperties = map SomeKey [PadAmount, PadDecimals, Indent] allProperties :: [SomeKey] allProperties = boolProperties ++ enumProperties ++ intProperties +mergePrefixes :: [(Text, RuleSet)] -> [(Text, RuleSet)] -> [(Text, RuleSet)] +mergePrefixes ps1 ps2 = + sortOn (Down . T.length . fst) . M.toList . M.fromListWith (flip (<>)) $ + ps1 <> ps2 + +prefixProperties :: [SomeKey] +prefixProperties = + SomeKey ComplexNewLine + : SomeKey TrailingComma + : SomeKey PreserveNumberFormat + : map SomeKey [PadAmount, PadDecimals, Indent] + -- | Maps deprecated property names to (key, value-when-true, value-when-false). deprecatedAliases :: [(Text, (SomeKey, SomeProperty, SomeProperty))] deprecatedAliases = @@ -213,12 +213,19 @@ deprecatedAliases = type Rule = Map SomeKey SomeProperty -newtype RuleSet - = RuleSet (Map NodePattern Rule) +data RuleSet + = RuleSet + { rsBySelectors :: Map NP.NodeSelector RuleSet + , rsPrefixes :: [(Text, RuleSet)] + , rsAnyObjectKey :: Maybe RuleSet + , rsAnyArrayIndex :: Maybe RuleSet + , rsHere :: Rule + , rsBelow :: Rule + } deriving stock (Eq, Read, Show) -lookupProp :: (Eq a, Read a, Show a) => PropertyKey a -> Rule -> Maybe a -lookupProp targetKey m = +lookupProperty :: (Eq a, Read a, Show a) => PropertyKey a -> Rule -> Maybe a +lookupProperty targetKey m = case M.lookup (SomeKey targetKey) m of Just (SomeProperty key val) -> case eqKey key targetKey of @@ -226,9 +233,6 @@ lookupProp targetKey m = Nothing -> Nothing Nothing -> Nothing -lookupRule :: (Eq a, Read a, Show a) => PropertyKey a -> Rule -> Maybe a -lookupRule = lookupProp - applyDecimalPadding :: Int -> Text -> Text applyDecimalPadding padDecimals node | padDecimals /= 0 @@ -240,8 +244,8 @@ applyDecimalPadding padDecimals node applyPadLogic :: (Node -> Text) -> Rule -> Node -> Text applyPadLogic f rs n = - let padAmount = sum $ lookupProp PadAmount rs - padDecimals = sum $ lookupProp PadDecimals rs + let padAmount = sum $ lookupProperty PadAmount rs + padDecimals = sum $ lookupProperty PadDecimals rs decimalPaddedText | isNumberNode n = applyDecimalPadding padDecimals (f n) | otherwise = f n @@ -249,41 +253,34 @@ applyPadLogic f rs n = complexNewLine :: RuleSet -> NC.NodeCursor -> Maybe ComplexNewLine complexNewLine rs cursor = - let ps = findPropertiesForCursor PrefixMatch cursor rs - in lookupProp ComplexNewLine ps - -data MatchMode = PrefixMatch | ExactMatch deriving (Eq, Show) + let ps = findPropertiesForCursor cursor rs + in lookupProperty ComplexNewLine ps lookupPropertyForCursor :: (Eq a, Read a, Show a) - => MatchMode -> PropertyKey a -> RuleSet -> NC.NodeCursor -> Maybe a -lookupPropertyForCursor matchMode key rs cursor = lookupProp key (findPropertiesForCursor matchMode cursor rs) - -comparePC :: NodePatternSelector -> NC.NodeBreadcrumb -> Bool -comparePC AnyObjectKey (NC.ObjectIndexAndKey _ _) = True -comparePC AnyArrayIndex (NC.ArrayIndex _) = True -comparePC (Selector s) bc = NC.compareSB s bc -comparePC _ _ = False - -compareCursorAndPattern :: MatchMode -> NC.NodeCursor -> NodePattern -> Bool -compareCursorAndPattern matchMode (NC.NodeCursor c) (NodePattern p) = sameBy matchMode comparePC p c - -type SelCrumbCompFun = NodePatternSelector -> NC.NodeBreadcrumb -> Bool - -sameBy - :: MatchMode - -> SelCrumbCompFun - -> Seq NodePatternSelector - -> Seq NC.NodeBreadcrumb - -> Bool -sameBy matchMode f = go + => PropertyKey a -> RuleSet -> NC.NodeCursor -> Maybe a +lookupPropertyForCursor key rs cursor = + lookupProperty key (findPropertiesForCursor cursor rs) + +findPropertiesForCursor :: NC.NodeCursor -> RuleSet -> Rule +findPropertiesForCursor (NC.NodeCursor cursor) = go cursor where - go (p :<| ps) (b :<| bs) = - let res = f p b - in res && go ps bs - go ps bs = Seq.null ps && (Seq.null bs || PrefixMatch == matchMode) - --- TODO: migrate to M.filterKeys once the stack snapshot ships containers 0.8 -findPropertiesForCursor :: MatchMode -> NC.NodeCursor -> RuleSet -> Rule -findPropertiesForCursor matchMode cursor (RuleSet rs) = - fold (M.filterWithKey (const . compareCursorAndPattern matchMode cursor) rs) + go Empty rs = rs.rsHere <> rs.rsBelow + go (NC.ObjectIndexAndKey i k :<| bs) rs = + go + bs + ( addBelowProps rs $ + fold (M.lookup (NP.ObjectKey k) rs.rsBySelectors) + <> fold (M.lookup (NP.ObjectIndex i) rs.rsBySelectors) + <> matchingPrefixes k rs.rsPrefixes + <> fold rs.rsAnyObjectKey + ) + go (NC.ArrayIndex i :<| bs) rs = + go + bs + ( addBelowProps rs $ + fold (M.lookup (NP.ArrayIndex i) rs.rsBySelectors) + <> fold rs.rsAnyArrayIndex + ) + addBelowProps rsAbove rs = rs {rsBelow = rs.rsBelow <> rsAbove.rsBelow} + matchingPrefixes k = foldMap snd . filter ((`T.isPrefixOf` k) . fst) diff --git a/src/JbeamEdit/Parsing/DSL.hs b/src/JbeamEdit/Parsing/DSL.hs index 83c70bfe..ff23d204 100644 --- a/src/JbeamEdit/Parsing/DSL.hs +++ b/src/JbeamEdit/Parsing/DSL.hs @@ -13,12 +13,19 @@ import Data.Bifunctor (first) import Data.ByteString qualified as BS import Data.ByteString.Lazy qualified as LBS import Data.Char (isSpace) +import Data.Foldable (fold) import Data.Functor (void, ($>)) import Data.Functor.Identity (Identity (..)) import Data.List.NonEmpty qualified as NE (fromList) import Data.Map (Map) -import Data.Map qualified as M (fromList, fromListWith, union) -import Data.Sequence qualified as Seq (fromList) +import Data.Map qualified as M ( + empty, + fromList, + null, + partitionWithKey, + singleton, + ) +import Data.Monoid (Dual (..)) import Data.Set qualified as S (fromList) import Data.Text (Text) import Data.Text qualified as T (init, isSuffixOf, unpack) @@ -67,7 +74,7 @@ patternSelectorParser = , arrayIndexParser "array index" ] -patternParser :: JbflParser NodePattern +patternParser :: JbflParser [NodePatternSelector] patternParser = do pat <- skipWhiteSpace *> patternSelectors c <- MP.lookAhead B.asciiChar @@ -75,7 +82,7 @@ patternParser = do ',' -> byteChar ',' $> pat _ -> skipWhiteSpace $> pat where - patternSelectors = NodePattern . Seq.fromList <$> MP.some patternSelectorParser + patternSelectors = MP.some patternSelectorParser tryDecodeKey :: [Word8] -> (Text -> Maybe SomeKey) -> Maybe SomeKey tryDecodeKey bs f = @@ -159,7 +166,7 @@ deprecatedBoolPropertyParser sk valTrue valFalse = do separatorParser :: JbflParser () separatorParser = skipWhiteSpace *> void (byteChar ';') <* skipWhiteSpace -ruleParser :: JbflParser ([NodePattern], Map SomeKey SomeProperty) +ruleParser :: JbflParser ([[NodePatternSelector]], Map SomeKey SomeProperty) ruleParser = do pats <- MP.some patternParser skipWhiteSpace @@ -170,11 +177,23 @@ ruleParser = do skipWhiteSpace pure (pats, M.fromList props) -separateRulesets :: [([a], b)] -> [(a, b)] -separateRulesets rs = [(pat, props) | (pats, props) <- rs, pat <- pats] +combineRuleSets + :: ([[NodePatternSelector]], Map SomeKey SomeProperty) -> RuleSet +combineRuleSets (_, props) + | M.null props = mempty +combineRuleSets (pats, props) = fold [fold (go pat) | pat <- pats] + where + go :: [NodePatternSelector] -> Maybe RuleSet + go [] = Just (mempty {rsHere = hereProps, rsBelow = belowProps}) + where + (belowProps, hereProps) = M.partitionWithKey (\k _ -> k `elem` prefixProperties) props + go (AnyObjectKey : pats') = Just (mempty {rsAnyObjectKey = go pats'}) + go (AnyArrayIndex : pats') = Just (mempty {rsAnyArrayIndex = go pats'}) + go (Selector (ObjectPrefixKey p) : pats') = Just (mempty {rsPrefixes = maybe [] (\x -> [(p, x)]) (go pats')}) + go (Selector s : pats') = Just (mempty {rsBySelectors = maybe M.empty (M.singleton s) (go pats')}) ruleSetParser :: JbflParser RuleSet -ruleSetParser = RuleSet . M.fromListWith M.union . separateRulesets <$> MP.some singleRuleSet +ruleSetParser = getDual . foldMap (Dual . combineRuleSets) <$> MP.some singleRuleSet where singleRuleSet = skipComment *> ruleParser <* skipComment diff --git a/test/Formatting/RulesSpec.hs b/test/Formatting/RulesSpec.hs index a40c7565..27e50c1d 100644 --- a/test/Formatting/RulesSpec.hs +++ b/test/Formatting/RulesSpec.hs @@ -1,12 +1,16 @@ module Formatting.RulesSpec (spec) where +import Data.Text qualified as T import GHC.IsList (fromList) +import JbeamEdit.Core.NodeCursor (NodeBreadcrumb (..), NodeCursor (..)) import JbeamEdit.Formatting import JbeamEdit.Formatting.Rules import SpecHelper spec :: Spec spec = do + precedenceSpec + describe "SomeKey & SomeProperty" $ do it "Eq works for same PropertyKey" $ SomeKey PadAmount == SomeKey PadAmount `shouldBe` True @@ -34,3 +38,134 @@ spec = do ] it "applies PadAmount and PadDecimals" $ applyPadLogic (formatScalarNode False) ruleSet fakeNode `shouldBe` "123.50 " + + describe "matching a pattern against a cursor" $ do + let cursorAt crumbs = NodeCursor (fromList crumbs) + nodesCursor = + cursorAt [ObjectIndexAndKey 0 "part", ObjectIndexAndKey 0 "nodes"] + rulesFor pat = rulesFromSource (pat ++ " { PadAmount: 7; AutoPad: true; }") + cascading pat = lookupPropertyForCursor PadAmount (rulesFor pat) + hereOnly pat = lookupPropertyForCursor AutoPad (rulesFor pat) + + it "answers both kinds at the node the pattern names" $ do + cascading ".*.nodes" nodesCursor `shouldBe` Just 7 + hereOnly ".*.nodes" nodesCursor `shouldBe` Just True + + it "carries a cascading property below that node, and nothing else" $ do + cascading ".*" nodesCursor `shouldBe` Just 7 + hereOnly ".*" nodesCursor `shouldBe` Nothing + + it "never answers for a pattern longer than the cursor" $ do + cascading ".*.nodes[*]" nodesCursor `shouldBe` Nothing + hereOnly ".*.nodes[*]" nodesCursor `shouldBe` Nothing + + it "matches a prefix key against the rest of the breadcrumb" $ do + let p k = ".*." ++ k ++ "*" + atDeformGroups = + cursorAt + [ObjectIndexAndKey 0 "part", ObjectIndexAndKey 0 "deformGroups"] + hereOnly (p "deform") atDeformGroups `shouldBe` Just True + hereOnly (p "deformGroups") atDeformGroups `shouldBe` Just True + hereOnly (p "deformGroupsAndMore") atDeformGroups `shouldBe` Nothing + hereOnly (p "eform") atDeformGroups `shouldBe` Nothing + + it "keeps the two wildcards apart" $ do + let atArray = cursorAt [ObjectIndexAndKey 0 "part", ArrayIndex 0] + atKey = cursorAt [ObjectIndexAndKey 0 "part", ObjectIndexAndKey 0 "k"] + hereOnly ".*[*]" atArray `shouldBe` Just True + hereOnly ".*.*" atArray `shouldBe` Nothing + hereOnly ".*.*" atKey `shouldBe` Just True + hereOnly ".*[*]" atKey `shouldBe` Nothing + +precedenceSpec :: Spec +precedenceSpec = do + let cell :: Int -> Node + cell n = Number (mkNumberValue (T.pack (show n)) (fromIntegral n)) + pair a b = mkArray (fromList [mkArray (fromList [a, b]), mkArray (fromList [b, a])]) + topNode = + mkObject + ( fromList + [ ObjectKey + ( String "deformGroups" + , mkArray + ( fromList + [ pair (cell 1) (cell 2) + , pair (cell 3) (cell 4) + ] + ) + ) + ] + ) + rulesFrom = rulesFromSource + formatWith = flip formatNode topNode . rulesFrom + -- Both orders: the first alone passes for a first-parsed-rule lookup. + beats winner loser = do + formatWith (winner <> "\n" <> loser) `shouldBe` formatWith winner + formatWith (loser <> "\n" <> winner) `shouldBe` formatWith winner + formatWith winner `shouldNotBe` formatWith loser + named = ".deformGroups { Indent : 1; }" + positional = ".0 { Indent : 2; }" + longPrefix = ".deform* { Indent : 3; }" + shortPrefix = ".de* { Indent : 5; }" + wildcard = ".* { Indent : 6; }" + + describe "which of several matching patterns supplies a property" $ do + it "prefers a named key over a positional index" $ named `beats` positional + it "prefers a positional index over a prefix key" $ + positional `beats` longPrefix + it "prefers the longer of two prefix keys" $ longPrefix `beats` shortPrefix + + it "takes each property from its own most specific match" $ do + let cur = NodeCursor (fromList [ObjectIndexAndKey 0 "deformGroups"]) + both a b = rulesFromSource (a <> "\n" <> b) + short = ".de* { Indent: 2; PadAmount: 4; }" + long = ".deform* { PadAmount: 8; }" + lookupPropertyForCursor Indent (both short long) cur `shouldBe` Just 2 + lookupPropertyForCursor Indent (both long short) cur `shouldBe` Just 2 + lookupPropertyForCursor PadAmount (both short long) cur `shouldBe` Just 8 + lookupPropertyForCursor PadAmount (both long short) cur `shouldBe` Just 8 + it "prefers a prefix key over a wildcard" $ shortPrefix `beats` wildcard + + it "cascades from a prefix key the same way a named key does" $ do + let byPrefix = formatWith ".deform* { Indent : 1; }" + byPrefix `shouldBe` formatWith ".deformGroups { Indent : 1; }" + byPrefix `shouldNotBe` formatWith ".deformGroups { Indent : 6; }" + + it "settles length before specificity" $ do + let shorter = ".deformGroups { Indent : 7; }" + longer = ".deformGroups[*] { Indent : 1; }" + both = shorter <> "\n" <> longer + formatWith both + `shouldBe` "{\n \"deformGroups\" : [\n [\n [1, 2],\n [2, 1]\n ],\n [\n [3, 4],\n [4, 3]\n ]\n ]\n}\n" + formatWith both `shouldNotBe` formatWith shorter + formatWith both `shouldNotBe` formatWith longer + + it "matches a literal array index and prefers it over the wildcard" $ + ".deformGroups[0] { Indent : 1; }" `beats` ".deformGroups[*] { Indent : 4; }" + + it "still takes properties the winner does not set from the loser" $ do + let winnerOnly = ".deformGroups { Indent : 1; }" + loserOnly = ".de* { TrailingComma : Force; }" + formatWith (winnerOnly <> "\n" <> loserOnly) + `shouldNotBe` formatWith winnerOnly + formatWith (winnerOnly <> "\n" <> loserOnly) + `shouldNotBe` formatWith loserOnly + + describe "two rules with the same pattern" $ do + let twice = rulesFrom ".deformGroups { Indent : 1; }\n.deformGroups { Indent : 2; }" + cur = NodeCursor (fromList [ObjectIndexAndKey 0 "deformGroups"]) + + it "takes the value from the later one" $ + lookupPropertyForCursor Indent twice cur `shouldBe` Just 2 + + describe "combining a user ruleset with the shipped one" $ do + let user = rulesFrom ".deformGroups { Indent : 1; }" + shipped = rulesFrom ".deformGroups { Indent : 7; TrailingComma : Force; }" + format = flip formatNode topNode + + it "takes the user's value and keeps the rest of the shipped one" $ do + let merged = rulesFrom ".deformGroups { Indent : 1; TrailingComma : Force; }" + format (user <> shipped) `shouldBe` format merged + -- Guards the line above: without these the two could be indistinguishable. + format user `shouldNotBe` format shipped + format merged `shouldNotBe` format user diff --git a/test/FormattingSpec.hs b/test/FormattingSpec.hs index 20dd571d..51be4372 100644 --- a/test/FormattingSpec.hs +++ b/test/FormattingSpec.hs @@ -83,9 +83,45 @@ dynamicJbflTests = do expected <- T.pack <$> readFile outFile pure (outFile, formatted, expected) +reachSpec :: Spec +reachSpec = do + let row cells = mkArray (fromList cells) + rows = + row + [ row [String "a_long_name", Number (mkNumberValue "1" 1)] + , row [String "n1", Number (mkNumberValue "2" 2)] + ] + topNode = + mkObject + ( fromList + [ ObjectKey + ( String "part" + , mkObject (fromList [ObjectKey (String "rows", rows)]) + ) + ] + ) + formatWith src = formatNode (rulesFromSource src) topNode + shortPattern prop = ".* { " <> prop <> " }" + exactPattern prop = ".*.rows { " <> prop <> " }" + + wrap body = "{\"part\" : {\n \"rows\" : [\n" <> body <> "\n ]\n}}\n" + baseline = wrap " [\"a_long_name\", 1],\n [\"n1\", 2]" + padded = wrap " [\"a_long_name\", 1],\n [\"n1\", 2]" + + describe "how far down a property reaches" $ do + it "applies AutoPad to the matched value only" $ do + formatWith (exactPattern "AutoPad : true;") `shouldBe` padded + -- Guards the line below: a shortPattern matching nothing passes it too. + formatWith (shortPattern "ComplexNewLine : Force;") `shouldNotBe` baseline + formatWith (shortPattern "AutoPad : true;") `shouldBe` baseline + + it "applies ComplexNewLine below the matched value too" $ + formatWith (shortPattern "ComplexNewLine : Force;") `shouldNotBe` baseline + spec :: Spec spec = do mapM_ formatNodeSpec specs + reachSpec dynamicTests <- runIO dynamicJbflTests forM_ dynamicTests $ \(outFile, formatted, expected) -> diff --git a/test/SpecHelper.hs b/test/SpecHelper.hs index 483f95ef..8b257671 100644 --- a/test/SpecHelper.hs +++ b/test/SpecHelper.hs @@ -1,5 +1,6 @@ module SpecHelper ( textToLazyByteString, + rulesFromSource, applySpecOnInput, works, listFilesInDir, @@ -15,6 +16,8 @@ import Data.List (isPrefixOf, isSuffixOf) import Data.Text qualified as T import Data.Text.Encoding (encodeUtf8) import JbeamEdit.Core.Node +import JbeamEdit.Formatting.Rules (RuleSet) +import JbeamEdit.Parsing.DSL (parseDSL) import System.Directory (getDirectoryContents) import Test.Hspec @@ -45,3 +48,9 @@ works = it "works" textToLazyByteString :: String -> ByteString textToLazyByteString = BS.fromStrict . encodeUtf8 . T.pack + +rulesFromSource :: String -> RuleSet +rulesFromSource src = + case parseDSL (textToLazyByteString src) of + Right rs -> rs + Left err -> error ("bad JBFL in spec: " ++ T.unpack err)