-
Notifications
You must be signed in to change notification settings - Fork 68
/
Copy pathTypes.hs
289 lines (255 loc) · 11.5 KB
/
Types.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Language.Haskell.Brittany.Internal.Config.Types
where
#include "prelude.inc"
import Data.Yaml
import qualified Data.Aeson.Types as Aeson
import GHC.Generics
import Data.Data ( Data )
import Data.Coerce ( Coercible, coerce )
import Data.Semigroup.Generic
import Data.Semigroup ( Last, Option )
import Data.CZipWith
confUnpack :: Coercible a b => Identity a -> b
confUnpack (Identity x) = coerce x
data CDebugConfig f = DebugConfig
{ _dconf_dump_config :: f (Semigroup.Last Bool)
, _dconf_dump_annotations :: f (Semigroup.Last Bool)
, _dconf_dump_ast_unknown :: f (Semigroup.Last Bool)
, _dconf_dump_ast_full :: f (Semigroup.Last Bool)
, _dconf_dump_bridoc_raw :: f (Semigroup.Last Bool)
, _dconf_dump_bridoc_simpl_alt :: f (Semigroup.Last Bool)
, _dconf_dump_bridoc_simpl_floating :: f (Semigroup.Last Bool)
, _dconf_dump_bridoc_simpl_par :: f (Semigroup.Last Bool)
, _dconf_dump_bridoc_simpl_columns :: f (Semigroup.Last Bool)
, _dconf_dump_bridoc_simpl_indent :: f (Semigroup.Last Bool)
, _dconf_dump_bridoc_final :: f (Semigroup.Last Bool)
, _dconf_roundtrip_exactprint_only :: f (Semigroup.Last Bool)
}
deriving (Generic)
data CLayoutConfig f = LayoutConfig
{ _lconfig_cols :: f (Last Int) -- the thing that has default 80.
, _lconfig_indentPolicy :: f (Last IndentPolicy)
, _lconfig_indentAmount :: f (Last Int)
, _lconfig_indentWhereSpecial :: f (Last Bool) -- indent where only 1 sometimes (TODO).
, _lconfig_indentListSpecial :: f (Last Bool) -- use some special indentation for ","
-- when creating zero-indentation
-- multi-line list literals.
, _lconfig_importColumn :: f (Last Int)
-- ^ for import statement layouting, column at which to align the
-- elements to be imported from a module.
-- It is expected that importAsColumn >= importCol.
, _lconfig_importAsColumn :: f (Last Int)
-- ^ for import statement layouting, column at which put the module's
-- "as" name (which also affects the positioning of the "as" keyword).
-- It is expected that importAsColumn >= importCol.
, _lconfig_altChooser :: f (Last AltChooser)
, _lconfig_columnAlignMode :: f (Last ColumnAlignMode)
, _lconfig_alignmentLimit :: f (Last Int)
-- roughly speaking, this sets an upper bound to the number of spaces
-- inserted to create horizontal alignment.
-- More specifically, if 'xs' are the widths of the columns in some
-- alignment-block, then the block will be aligned with the width
-- maximum [ x | x <- xs, x < minimum xs + alignmentLimit ].
, _lconfig_alignmentBreakOnMultiline :: f (Last Bool)
-- stops alignment between items that are not layouted as a single line.
-- e.g. for single-line alignment, things remain unchanged:
-- do
-- short <- stuff
-- loooooooong <- stuff
-- but not in cases such as:
-- do
-- short <- some more stuff
-- that requires two lines
-- loooooooong <- stuff
, _lconfig_hangingTypeSignature :: f (Last Bool)
-- Do not put "::" in a new line, and use hanging indentation for the
-- signature, i.e.:
-- func :: SomeLongStuff
-- -> SomeLongStuff
-- instead of the usual
-- func
-- :: SomeLongStuff
-- -> SomeLongStuff
-- As usual for hanging indentation, the result will be
-- context-sensitive (in the function name).
, _lconfig_reformatModulePreamble :: f (Last Bool)
-- whether the module preamble/header (module keyword, name, export list,
-- import statements) are reformatted. If false, only the elements of the
-- module (everything past the "where") are reformatted.
, _lconfig_allowSingleLineExportList :: f (Last Bool)
-- if true, and it fits in a single line, and there are no comments in the
-- export list, the following layout will be used:
-- > module MyModule (abc, def) where
-- > [stuff]
-- otherwise, the multi-line version is used:
-- > module MyModule
-- > ( abc
-- > , def
-- > )
-- > where
}
deriving (Generic)
data CForwardOptions f = ForwardOptions
{ _options_ghc :: f [String]
}
deriving (Generic)
data CErrorHandlingConfig f = ErrorHandlingConfig
{ _econf_produceOutputOnErrors :: f (Semigroup.Last Bool)
, _econf_Werror :: f (Semigroup.Last Bool)
, _econf_ExactPrintFallback :: f (Semigroup.Last ExactPrintFallbackMode)
-- ^ Determines when to fall back on the exactprint'ed output when
-- syntactical constructs are encountered which are not yet handled by
-- brittany.
-- Note that the "risky" setting is risky because even with the check of
-- the syntactic validity of the brittany output, at least in theory there
-- may be cases where the output is syntactically/semantically valid but
-- has different semantics than the code pre-transformation.
, _econf_omit_output_valid_check :: f (Semigroup.Last Bool)
}
deriving (Generic)
data CPreProcessorConfig f = PreProcessorConfig
{ _ppconf_CPPMode :: f (Semigroup.Last CPPMode)
, _ppconf_hackAroundIncludes :: f (Semigroup.Last Bool)
}
deriving (Generic)
data CConfig f = Config
{ _conf_version :: f (Semigroup.Last Int)
, _conf_debug :: CDebugConfig f
, _conf_layout :: CLayoutConfig f
, _conf_errorHandling :: CErrorHandlingConfig f
, _conf_forward :: CForwardOptions f
, _conf_preprocessor :: CPreProcessorConfig f
}
deriving (Generic)
type DebugConfig = CDebugConfig Identity
type LayoutConfig = CLayoutConfig Identity
type ForwardOptions = CForwardOptions Identity
type ErrorHandlingConfig = CErrorHandlingConfig Identity
type Config = CConfig Identity
-- i wonder if any Show1 stuff could be leveraged.
deriving instance Show (CDebugConfig Identity)
deriving instance Show (CLayoutConfig Identity)
deriving instance Show (CErrorHandlingConfig Identity)
deriving instance Show (CForwardOptions Identity)
deriving instance Show (CPreProcessorConfig Identity)
deriving instance Show (CConfig Identity)
deriving instance Show (CDebugConfig Option)
deriving instance Show (CLayoutConfig Option)
deriving instance Show (CErrorHandlingConfig Option)
deriving instance Show (CForwardOptions Option)
deriving instance Show (CPreProcessorConfig Option)
deriving instance Show (CConfig Option)
deriving instance Data (CDebugConfig Identity)
deriving instance Data (CLayoutConfig Identity)
deriving instance Data (CErrorHandlingConfig Identity)
deriving instance Data (CForwardOptions Identity)
deriving instance Data (CPreProcessorConfig Identity)
deriving instance Data (CConfig Identity)
instance Semigroup.Semigroup (CDebugConfig Option) where
(<>) = gmappend
instance Semigroup.Semigroup (CLayoutConfig Option) where
(<>) = gmappend
instance Semigroup.Semigroup (CErrorHandlingConfig Option) where
(<>) = gmappend
instance Semigroup.Semigroup (CForwardOptions Option) where
(<>) = gmappend
instance Semigroup.Semigroup (CPreProcessorConfig Option) where
(<>) = gmappend
instance Semigroup.Semigroup (CConfig Option) where
(<>) = gmappend
instance Semigroup.Semigroup (CDebugConfig Identity) where
(<>) = gmappend
instance Semigroup.Semigroup (CLayoutConfig Identity) where
(<>) = gmappend
instance Semigroup.Semigroup (CErrorHandlingConfig Identity) where
(<>) = gmappend
instance Semigroup.Semigroup (CForwardOptions Identity) where
(<>) = gmappend
instance Semigroup.Semigroup (CPreProcessorConfig Identity) where
(<>) = gmappend
instance Semigroup.Semigroup (CConfig Identity) where
(<>) = gmappend
instance Monoid (CDebugConfig Option) where
mempty = gmempty
mappend = gmappend
instance Monoid (CLayoutConfig Option) where
mempty = gmempty
mappend = gmappend
instance Monoid (CErrorHandlingConfig Option) where
mempty = gmempty
mappend = gmappend
instance Monoid (CForwardOptions Option) where
mempty = gmempty
mappend = gmappend
instance Monoid (CPreProcessorConfig Option) where
mempty = gmempty
mappend = gmappend
instance Monoid (CConfig Option) where
mempty = gmempty
mappend = gmappend
data IndentPolicy = IndentPolicyLeft -- never create a new indentation at more
-- than old indentation + amount
| IndentPolicyFree -- can create new indentations whereever
| IndentPolicyMultiple -- can create indentations only
-- at any n * amount.
deriving (Eq, Show, Generic, Data)
data AltChooser = AltChooserSimpleQuick -- always choose last alternative.
-- leads to tons of sparsely filled
-- lines.
| AltChooserShallowBest -- choose the first matching alternative
-- using the simplest spacing
-- information for the children.
| AltChooserBoundedSearch Int
-- choose the first matching alternative
-- using a bounded list of recursive
-- options having sufficient space.
deriving (Show, Generic, Data)
data ColumnAlignMode
= ColumnAlignModeDisabled
-- ^ Make no column alignments whatsoever
| ColumnAlignModeUnanimously
-- ^ Make column alignments only if it does not cause overflow for any of
-- the affected lines.
| ColumnAlignModeMajority Float
-- ^ If at least (ratio::Float) of the aligned elements have sufficient
-- space for the alignment, act like ColumnAlignModeAnimously; otherwise
-- act like ColumnAlignModeDisabled.
| ColumnAlignModeAnimouslyScale Int
-- ^ Scale back columns to some degree if their sum leads to overflow.
-- This is done in a linear fashion.
-- The Int specifies additional columns to be added to column maximum for
-- scaling calculation purposes.
| ColumnAlignModeAnimously
-- ^ Decide on a case-by-case basis if alignment would cause overflow.
-- If it does, cancel all alignments for this (nested) column description.
-- ColumnAlignModeAnimouslySome -- potentially to implement
| ColumnAlignModeAlways
-- ^ Always respect column alignments, even if it makes stuff overflow.
deriving (Show, Generic, Data)
data CPPMode = CPPModeAbort -- abort program on seeing -XCPP
| CPPModeWarn -- warn about CPP and non-roundtripping in its
-- presence.
| CPPModeNowarn -- silently allow CPP, if possible (i.e. input is
-- file.)
deriving (Show, Generic, Data)
data ExactPrintFallbackMode
= ExactPrintFallbackModeNever -- never fall back on exactprinting
| ExactPrintFallbackModeInline -- fall back only if there are no newlines in
-- the exactprint'ed output.
| ExactPrintFallbackModeRisky -- fall back even in the presence of newlines.
-- THIS MAY THEORETICALLY CHANGE SEMANTICS OF
-- A PROGRAM BY TRANSFORMING IT.
deriving (Show, Generic, Data)
cMap :: CZipWith k => (forall a . f a -> g a) -> k f -> k g
cMap f c = cZipWith (\_ -> f) c c
deriveCZipWith ''CDebugConfig
deriveCZipWith ''CLayoutConfig
deriveCZipWith ''CErrorHandlingConfig
deriveCZipWith ''CForwardOptions
deriveCZipWith ''CPreProcessorConfig
deriveCZipWith ''CConfig