Skip to content

Commit bbbca4f

Browse files
authored
Resolve #9098: Add LexBraces lexer warning (#9099)
1 parent d363088 commit bbbca4f

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

Cabal-syntax/src/Distribution/Fields/LexerMonad.hs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ data LexWarningType
6969
LexWarningTab
7070
| -- | indentation decreases
7171
LexInconsistentIndentation
72+
| -- | Brace syntax used
73+
LexBraces
7274
deriving (Eq, Ord, Show)
7375

7476
data LexWarning
@@ -79,19 +81,22 @@ data LexWarning
7981

8082
toPWarnings :: [LexWarning] -> [PWarning]
8183
toPWarnings =
82-
map (uncurry toWarning)
84+
mapMaybe (uncurry toWarning)
8385
. Map.toList
8486
. Map.fromListWith (flip (<>)) -- fromListWith gives existing element first.
8587
. map (\(LexWarning t p) -> (t, pure p))
8688
where
8789
toWarning LexWarningBOM poss =
88-
PWarning PWTLexBOM (NE.head poss) "Byte-order mark found at the beginning of the file"
90+
Just $ PWarning PWTLexBOM (NE.head poss) "Byte-order mark found at the beginning of the file"
8991
toWarning LexWarningNBSP poss =
90-
PWarning PWTLexNBSP (NE.head poss) $ "Non breaking spaces at " ++ intercalate ", " (NE.toList $ fmap showPos poss)
92+
Just $ PWarning PWTLexNBSP (NE.head poss) $ "Non breaking spaces at " ++ intercalate ", " (NE.toList $ fmap showPos poss)
9193
toWarning LexWarningTab poss =
92-
PWarning PWTLexTab (NE.head poss) $ "Tabs used as indentation at " ++ intercalate ", " (NE.toList $ fmap showPos poss)
94+
Just $ PWarning PWTLexTab (NE.head poss) $ "Tabs used as indentation at " ++ intercalate ", " (NE.toList $ fmap showPos poss)
9395
toWarning LexInconsistentIndentation poss =
94-
PWarning PWTInconsistentIndentation (NE.head poss) $ "Inconsistent indentation. Indentation jumps at lines " ++ intercalate ", " (NE.toList $ fmap (show . positionRow) poss)
96+
Just $ PWarning PWTInconsistentIndentation (NE.head poss) $ "Inconsistent indentation. Indentation jumps at lines " ++ intercalate ", " (NE.toList $ fmap (show . positionRow) poss)
97+
-- LexBraces warning about using { } delimeters is not reported as parser warning.
98+
toWarning LexBraces _ =
99+
Nothing
95100

96101
{- FOURMOLU_DISABLE -}
97102
data LexState = LexState

Cabal-syntax/src/Distribution/Fields/Parser.hs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ getLexerWarnings = do
8686
LexState' (LexState{warnings = ws}) _ <- getInput
8787
return ws
8888

89+
addLexerWarning :: LexWarning -> Parser ()
90+
addLexerWarning w = do
91+
LexState' ls@LexState{warnings = ws} _ <- getInput
92+
setInput $! mkLexState' ls{warnings = w : ws}
93+
8994
-- | Set Alex code i.e. the mode "state" lexer is in.
9095
setLexerMode :: Int -> Parser ()
9196
setLexerMode code = do
@@ -118,15 +123,16 @@ describeToken t = case t of
118123
tokSym :: Parser (Name Position)
119124
tokSym', tokStr, tokOther :: Parser (SectionArg Position)
120125
tokIndent :: Parser Int
121-
tokColon, tokOpenBrace, tokCloseBrace :: Parser ()
126+
tokColon, tokCloseBrace :: Parser ()
127+
tokOpenBrace :: Parser Position
122128
tokFieldLine :: Parser (FieldLine Position)
123129
tokSym = getTokenWithPos $ \t -> case t of L pos (TokSym x) -> Just (mkName pos x); _ -> Nothing
124130
tokSym' = getTokenWithPos $ \t -> case t of L pos (TokSym x) -> Just (SecArgName pos x); _ -> Nothing
125131
tokStr = getTokenWithPos $ \t -> case t of L pos (TokStr x) -> Just (SecArgStr pos x); _ -> Nothing
126132
tokOther = getTokenWithPos $ \t -> case t of L pos (TokOther x) -> Just (SecArgOther pos x); _ -> Nothing
127133
tokIndent = getToken $ \t -> case t of Indent x -> Just x; _ -> Nothing
128134
tokColon = getToken $ \t -> case t of Colon -> Just (); _ -> Nothing
129-
tokOpenBrace = getToken $ \t -> case t of OpenBrace -> Just (); _ -> Nothing
135+
tokOpenBrace = getTokenWithPos $ \t -> case t of L pos OpenBrace -> Just pos; _ -> Nothing
130136
tokCloseBrace = getToken $ \t -> case t of CloseBrace -> Just (); _ -> Nothing
131137
tokFieldLine = getTokenWithPos $ \t -> case t of L pos (TokFieldLine s) -> Just (FieldLine pos s); _ -> Nothing
132138

@@ -138,7 +144,9 @@ fieldSecName :: Parser (Name Position)
138144
fieldSecName = tokSym <?> "field or section name"
139145

140146
colon = tokColon <?> "\":\""
141-
openBrace = tokOpenBrace <?> "\"{\""
147+
openBrace = do
148+
pos <- tokOpenBrace <?> "\"{\""
149+
addLexerWarning (LexWarning LexBraces pos)
142150
closeBrace = tokCloseBrace <?> "\"}\""
143151

144152
fieldContent :: Parser (FieldLine Position)

changelog.d/issue-9098-lexbraces

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
synopsis: Add LexBraces lexer warning
2+
packages: Cabal-syntax
3+
issues: #8577
4+
5+
description: {
6+
7+
LexBraces warning is issued when brace delimiting syntax is used.
8+
This way, using `readFields'`, a low-lever consumer may decide
9+
whether braces were used.
10+
11+
(Looking for a brace character in the input is imprecise, as braces can occur inside field content).
12+
13+
This warning is not propagated to parser warnings,
14+
so e.g. readGenericPackageDescription doesn't warn about it.
15+
This is because all parser warnings prevent uploads to Hackage,
16+
and using braces (or not) is opinionated choice.
17+
18+
}

0 commit comments

Comments
 (0)