Skip to content

Commit

Permalink
Implement support for fractional precedence
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkkrp committed Sep 13, 2024
1 parent 392b2bc commit 3864287
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

* Format multiple files in parallel. [Issue
1128](https://github.com/tweag/ormolu/issues/1128).
* Fractional precedences are now allowed in `.ormolu` files for more precise
control over formatting of complex operator chains. [Issue
1106](https://github.com/tweag/ormolu/issues/1106).

## Ormolu 0.7.7.0

Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,16 @@ infixl 1 >>, >>=
infixr 1 =<<
infixr 0 $, $!
infixl 4 <*>, <*, *>, <**>

infixr 3 >~<
infixr 3.3 |~|
infixr 3.7 <~>
```

It uses exactly the same syntax as usual Haskell fixity declarations to make
it easier for Haskellers to edit and maintain.
it easier for Haskellers to edit and maintain. Since Ormolu 0.7.8.0
fractional precedences are supported for more precise control over
formatting of complex operator chains.

As of Ormolu 0.7.0.0, `.ormolu` files can also contain instructions about
module re-exports that Ormolu should be aware of. This might be desirable
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
startFormTok |~| messageTag
>~< startMessageTok |~| name
>~< p' |~| endMessageTok |~| endFormTok
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
startFormTok |~| messageTag
>~< startMessageTok |~| name
>~< p' |~| endMessageTok |~| endFormTok
Binary file modified extract-hackage-info/hackage-info.bin
Binary file not shown.
6 changes: 3 additions & 3 deletions src/Ormolu/Fixity/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ data FixityInfo = FixityInfo
{ -- | Fixity direction
fiDirection :: FixityDirection,
-- | Precedence
fiPrecedence :: Int
fiPrecedence :: Double
}
deriving stock (Eq, Ord, Show, Generic)
deriving anyclass (Binary, NFData)
Expand All @@ -116,10 +116,10 @@ data FixityApproximation = FixityApproximation
faDirection :: Maybe FixityDirection,
-- | Minimum precedence level found in the (maybe conflicting)
-- definitions for the operator (inclusive)
faMinPrecedence :: Int,
faMinPrecedence :: Double,
-- | Maximum precedence level found in the (maybe conflicting)
-- definitions for the operator (inclusive)
faMaxPrecedence :: Int
faMaxPrecedence :: Double
}
deriving stock (Eq, Ord, Show, Generic)
deriving anyclass (Binary, NFData)
Expand Down
4 changes: 3 additions & 1 deletion src/Ormolu/Fixity/Parser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ pFixity = do
fiDirection <- pFixityDirection
hidden hspace1
offsetAtPrecedence <- getOffset
fiPrecedence <- L.decimal
fiPrecedence <-
try L.float
<|> (fromIntegral <$> (L.decimal :: Parser Integer))
when (fiPrecedence > 9) $
region
(setErrorOffset offsetAtPrecedence)
Expand Down
12 changes: 11 additions & 1 deletion src/Ormolu/Fixity/Printer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Data.Text.Lazy qualified as TL
import Data.Text.Lazy.Builder (Builder)
import Data.Text.Lazy.Builder qualified as B
import Data.Text.Lazy.Builder.Int qualified as B
import Data.Text.Lazy.Builder.RealFloat qualified as B
import Distribution.ModuleName (ModuleName)
import Distribution.ModuleName qualified as ModuleName
import Distribution.Types.PackageName
Expand All @@ -44,7 +45,7 @@ renderSingleFixityOverride (OpName operator, FixityInfo {..}) =
InfixR -> "infixr"
InfixN -> "infix",
" ",
B.decimal fiPrecedence,
renderPrecedence fiPrecedence,
" ",
if isTickedOperator operator
then "`" <> B.fromText operator <> "`"
Expand Down Expand Up @@ -75,3 +76,12 @@ renderSingleModuleReexport (exportingModule, exports) =

renderModuleName :: ModuleName -> Builder
renderModuleName = B.fromString . intercalate "." . ModuleName.components

-- | Render precedence using integer representation for whole numbers.
renderPrecedence :: Double -> Builder
renderPrecedence x =
let (n :: Int, fraction :: Double) = properFraction x
isWholeEnough = fraction < 0.0001
in if isWholeEnough
then B.decimal n
else B.realFloat x
22 changes: 22 additions & 0 deletions tests/Ormolu/Fixity/ParserSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ spec = do
`shouldParse` ( exampleFixityOverrides,
ModuleReexports Map.empty
)
it "accepts fractional operator precedences" $
parseDotOrmolu
""
( T.unlines
[ "infixr 3 >~<",
"infixr 3.3 |~|",
"infixr 3.7 <~>"
]
)
`shouldParse` ( fractionalFixityOverrides,
ModuleReexports Map.empty
)
it "combines conflicting fixity declarations correctly" $
parseDotOrmolu
""
Expand Down Expand Up @@ -231,6 +243,16 @@ exampleFixityOverrides =
]
)

fractionalFixityOverrides :: FixityOverrides
fractionalFixityOverrides =
FixityOverrides
( Map.fromList
[ (">~<", FixityInfo InfixR 3),
("|~|", FixityInfo InfixR 3.3),
("<~>", FixityInfo InfixR 3.7)
]
)

exampleModuleReexports :: ModuleReexports
exampleModuleReexports =
ModuleReexports . Map.fromList $
Expand Down
7 changes: 6 additions & 1 deletion tests/Ormolu/Fixity/PrinterSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ instance Arbitrary FixityOverrides where
InfixR,
InfixN
]
fiPrecedence <- chooseInt (0, 9)
precedenceWholePart <- fromIntegral <$> chooseInt (0, 9)
precedenceFractionalPart <-
if precedenceWholePart < 9.0
then (* 0.1) . fromIntegral <$> chooseInt (0, 1)
else return 0
let fiPrecedence = precedenceWholePart + precedenceFractionalPart
return FixityInfo {..}

instance Arbitrary ModuleReexports where
Expand Down
5 changes: 4 additions & 1 deletion tests/Ormolu/PrinterSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ testsuiteOverrides =
FixityOverrides
( Map.fromList
[ (".=", FixityInfo InfixR 8),
("#", FixityInfo InfixR 5)
("#", FixityInfo InfixR 5),
(">~<", FixityInfo InfixR 3),
("|~|", FixityInfo InfixR 3.3),
("<~>", FixityInfo InfixR 3.7)
]
)

Expand Down

0 comments on commit 3864287

Please sign in to comment.