git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Enhancements to import linting
d9d397eGary Burgess
src/Language/PureScript/AST/Declarations.hs+4
@@ -146,6 +146,10 @@ isImplicit :: ImportDeclarationType -> Bool
146isImplicit Implicit = True
146isImplicit Implicit = True
147isImplicit _ = False
147isImplicit _ = False
148
148
149+isExplicit :: ImportDeclarationType -> Bool
150+isExplicit (Explicit _) = True
151+isExplicit _ = False
152+
149-- |
153-- |
150-- The data type of declarations
154-- The data type of declarations
151--
155--
src/Language/PureScript/Errors.hs+15
@@ -138,7 +138,9 @@ data SimpleErrorMessage
138 | DuplicateExportRef String
138 | DuplicateExportRef String
139 | IntOutOfRange Integer String Integer Integer
139 | IntOutOfRange Integer String Integer Integer
140 | RedundantEmptyHidingImport ModuleName
140 | RedundantEmptyHidingImport ModuleName
141+ | ImplicitQualifiedImport ModuleName ModuleName [DeclarationRef]
141 | ImplicitImport ModuleName [DeclarationRef]
142 | ImplicitImport ModuleName [DeclarationRef]
143+ | HidingImport ModuleName [DeclarationRef]
142 | CaseBinderLengthDiffers Int [Binder]
144 | CaseBinderLengthDiffers Int [Binder]
143 deriving (Show)
145 deriving (Show)
144
146
@@ -309,7 +311,9 @@ errorCode em = case unwrapErrorMessage em of
309 DuplicateExportRef{} -> "DuplicateExportRef"
311 DuplicateExportRef{} -> "DuplicateExportRef"
310 IntOutOfRange{} -> "IntOutOfRange"
312 IntOutOfRange{} -> "IntOutOfRange"
311 RedundantEmptyHidingImport{} -> "RedundantEmptyHidingImport"
313 RedundantEmptyHidingImport{} -> "RedundantEmptyHidingImport"
314+ ImplicitQualifiedImport{} -> "ImplicitQualifiedImport"
312 ImplicitImport{} -> "ImplicitImport"
315 ImplicitImport{} -> "ImplicitImport"
316+ HidingImport{} -> "HidingImport"
313 CaseBinderLengthDiffers{} -> "CaseBinderLengthDiffers"
317 CaseBinderLengthDiffers{} -> "CaseBinderLengthDiffers"
314
318
315-- |
319-- |
@@ -858,11 +862,22 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
858 renderSimpleErrorMessage (RedundantEmptyHidingImport mn) =
862 renderSimpleErrorMessage (RedundantEmptyHidingImport mn) =
859 line $ "The import for module " ++ runModuleName mn ++ " is redundant as all members have been explicitly hidden."
863 line $ "The import for module " ++ runModuleName mn ++ " is redundant as all members have been explicitly hidden."
860
864
865+ renderSimpleErrorMessage (ImplicitQualifiedImport importedModule asModule refs) =
866+ paras [ line $ "Module " ++ runModuleName importedModule ++ " was imported as " ++ runModuleName asModule ++ " with unspecified imports."
867+ , line $ "As there are multiple modules being imported as " ++ runModuleName asModule ++ ", consider using the explicit form:"
868+ , indent $ line $ "import " ++ runModuleName importedModule ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ") as " ++ runModuleName asModule
869+ ]
870+
861 renderSimpleErrorMessage (ImplicitImport mn refs) =
871 renderSimpleErrorMessage (ImplicitImport mn refs) =
862 paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
872 paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
863 , indent $ line $ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
873 , indent $ line $ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
864 ]
874 ]
865
875
876+ renderSimpleErrorMessage (HidingImport mn refs) =
877+ paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the inclusive form: "
878+ , indent $ line $ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
879+ ]
880+
866 renderSimpleErrorMessage (CaseBinderLengthDiffers l bs) =
881 renderSimpleErrorMessage (CaseBinderLengthDiffers l bs) =
867 paras $ [ line $ "Binder list length differs in case alternative:"
882 paras $ [ line $ "Binder list length differs in case alternative:"
868 , indent $ line $ intercalate ", " $ fmap prettyPrintBinderAtom bs
883 , indent $ line $ intercalate ", " $ fmap prettyPrintBinderAtom bs
src/Language/PureScript/Linter/Imports.hs+229−87
@@ -1,18 +1,23 @@
1{-# LANGUAGE ScopedTypeVariables #-}
1{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3
3
4−module Language.PureScript.Linter.Imports (findUnusedImports, Name(..), UsedImports()) where
4+module Language.PureScript.Linter.Imports
5+ ( lintImports
6+ , Name(..)
7+ , UsedImports()
8+ ) where
5
9
6import Prelude ()
10import Prelude ()
7import Prelude.Compat
11import Prelude.Compat
8
12
9−import qualified Data.Map as M
13+import Control.Monad (unless, when)
10−import Data.Maybe (mapMaybe, isNothing)
11−import Data.List ((\\), find, intersect, nub)
12import Control.Monad.Error.Class (MonadError(..))
14import Control.Monad.Error.Class (MonadError(..))
13import Control.Monad.Writer.Class
15import Control.Monad.Writer.Class
14−import Control.Monad (unless,when)
16+
15import Data.Foldable (forM_)
17import Data.Foldable (forM_)
18+import Data.List ((\\), find, intersect, nub)
19+import Data.Maybe (mapMaybe)
20+import qualified Data.Map as M
16
21
17import Language.PureScript.AST.Declarations
22import Language.PureScript.AST.Declarations
18import Language.PureScript.AST.SourcePos
23import Language.PureScript.AST.SourcePos
@@ -31,118 +36,247 @@ data Name
31 | TyName (Qualified (ProperName 'TypeName))
36 | TyName (Qualified (ProperName 'TypeName))
32 | DctorName (Qualified (ProperName 'ConstructorName))
37 | DctorName (Qualified (ProperName 'ConstructorName))
33 | TyClassName (Qualified (ProperName 'ClassName))
38 | TyClassName (Qualified (ProperName 'ClassName))
34− deriving (Eq)
39+ deriving (Eq, Show)
35
40
36−getIdentName :: Name -> Maybe Ident
41+getIdentName :: Maybe ModuleName -> Name -> Maybe Ident
37−getIdentName (IdentName (Qualified _ name)) = Just name
42+getIdentName q (IdentName (Qualified q' name)) | q == q' = Just name
38−getIdentName _ = Nothing
43+getIdentName _ _ = Nothing
39
44
40−getTypeName :: Name -> Maybe (ProperName 'TypeName)
45+getTypeName :: Maybe ModuleName -> Name -> Maybe (ProperName 'TypeName)
41−getTypeName (TyName (Qualified _ name)) = Just name
46+getTypeName q (TyName (Qualified q' name)) | q == q' = Just name
42−getTypeName _ = Nothing
47+getTypeName _ _ = Nothing
43
48
44−getClassName :: Name -> Maybe (ProperName 'ClassName)
49+getClassName :: Maybe ModuleName -> Name -> Maybe (ProperName 'ClassName)
45−getClassName (TyClassName (Qualified _ name)) = Just name
50+getClassName q (TyClassName (Qualified q' name)) | q == q' = Just name
46−getClassName _ = Nothing
51+getClassName _ _ = Nothing
47
52
48-- | Map of module name to list of imported names from that module which have been used.
53-- | Map of module name to list of imported names from that module which have been used.
49type UsedImports = M.Map ModuleName [Name]
54type UsedImports = M.Map ModuleName [Name]
50
55
51-- |
56-- |
57+-- Find and warn on:
58+--
52−-- Find and warn on any unused import statements (qualified or unqualified)
59+-- * Unused import statements (qualified or unqualified)
60+--
53−-- or references in an explicit import list.
61+-- * Unused references in an explicit import list
54--
62--
63+-- * Implicit imports of modules
64+--
65+-- * Implicit imports into a virtual module (unless the virtual module only has
66+-- members from one module imported)
67+--
68+-- * Imports using `hiding` (this is another form of implicit importing)
69+--
70+lintImports
71+ :: forall m
55−findUnusedImports :: forall m. (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Module -> Env -> UsedImports -> m ()
72+ . (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
73+ => Module
74+ -> Env
75+ -> UsedImports
76+ -> m ()
56−findUnusedImports (Module _ _ _ mdecls mexports) env usedImps = do
77+lintImports (Module _ _ mn mdecls mexports) env usedImps = do
78+
79+ let scope = maybe nullImports (\(_, imps, _) -> imps) (M.lookup mn env)
80+ usedImps' = foldr (elaborateUsed scope) usedImps exportedModules
81+
57− imps <- findImports mdecls
82+ imps <- M.toAscList <$> findImports mdecls
83+
58− forM_ (M.toAscList imps) $ \(mni, decls) -> unless (mni `elem` alwaysUsedModules) $
84+ forM_ imps $ \(mni, decls) ->
85+ unless (isPrim mni) $ do
59− forM_ decls $ \(ss, declType, qualifierName) ->
86+ forM_ decls $ \(ss, declType, qualifierName) ->
60− censor (onErrorMessages $ addModuleLocError ss) $ unless (qnameUsed qualifierName) $
87+ censor (onErrorMessages $ addModuleLocError ss) $ do
61− let names = nub $ M.findWithDefault [] mni usedImps
88+ let names = nub $ M.findWithDefault [] mni usedImps'
62− usedNames = mapMaybe (matchName (typeForDCtor mni) qualifierName) names
89+ lintImportDecl env mni qualifierName names declType
63− usedDctors = mapMaybe (matchDctor qualifierName) names
90+
64− in case declType of
91+ forM_ (M.toAscList (byQual imps)) $ \(mnq, entries) -> do
65− Implicit | isNothing qualifierName ->
92+ let mnis = nub $ map (\(_, _, mni) -> mni) entries
66− let classRefs = TypeClassRef <$> mapMaybe getClassName names
93+ unless (length mnis == 1) $ do
67− valueRefs = ValueRef <$> mapMaybe getIdentName names
94+ let implicits = filter (\(_, declType, _) -> not $ isExplicit declType) entries
68− types = mapMaybe getTypeName names
95+ forM_ implicits $ \(ss, _, mni) ->
69− typesWithDctors = reconstructTypeRefs mni usedDctors
96+ censor (onErrorMessages $ addModuleLocError ss) $ do
70− typesWithoutDctors = filter (`M.notMember` typesWithDctors) types
97+ let names = nub $ M.findWithDefault [] mni usedImps'
71− typesRefs
98+ usedRefs = findUsedRefs env mni (Just mnq) names
72− = map (flip TypeRef (Just [])) typesWithoutDctors
99+ unless (null usedRefs) $
73− ++ map (\(ty, ds) -> TypeRef ty (Just ds)) (M.toList typesWithDctors)
100+ tell $ errorMessage $ ImplicitQualifiedImport mni mnq usedRefs
74− allRefs = classRefs ++ typesRefs ++ valueRefs
101+
75− in tell $ errorMessage $
76− if null allRefs
77− then UnusedImport mni
78− else ImplicitImport mni allRefs
79− Explicit [] -> tell $ errorMessage $ UnusedImport mni
80− Explicit declrefs -> do
81− let idents = nub (mapMaybe runDeclRef declrefs)
82− let diff = idents \\ usedNames
83− case (length diff, length idents) of
84− (0, _) -> return ()
85− (n, m) | n == m -> tell $ errorMessage $ UnusedImport mni
86− _ -> tell $ errorMessage $ UnusedExplicitImport mni diff
87−
88− -- If we've not already warned a type is unused, check its data constructors
89− forM_ (mapMaybe getTypeRef declrefs) $ \(tn, c) -> do
90− let allCtors = dctorsForType mni tn
91− when (runProperName tn `elem` usedNames) $ case (c, usedDctors `intersect` allCtors) of
92− (_, []) | c /= Just [] ->
93− tell $ errorMessage $ UnusedDctorImport tn
94− (Just ctors, usedDctors') ->
95− let ddiff = ctors \\ usedDctors'
96− in unless (null ddiff) $ tell $ errorMessage $ UnusedDctorExplicitImport tn ddiff
97− _ -> return ()
98−
99− return ()
102+ return ()
100−
103+
101− _ -> return ()
102 where
104 where
103− reconstructTypeRefs :: ModuleName -> [ProperName 'ConstructorName] -> M.Map (ProperName 'TypeName) [ProperName 'ConstructorName]
104− reconstructTypeRefs mni = foldr accumDctors M.empty
105− where
106− accumDctors dctor = M.alter (Just . maybe [dctor] (dctor :)) (findTypeForDctor mni dctor)
107
105
108− findTypeForDctor :: ModuleName -> ProperName 'ConstructorName -> ProperName 'TypeName
106+ -- Checks whether a module is the Prim module - used to suppress any checks
109− findTypeForDctor mn dctor =
107+ -- made, as Prim is always implicitly imported.
110− case mn `M.lookup` env of
108+ isPrim :: ModuleName -> Bool
111− Just (_, _, exps) ->
109+ isPrim = (== ModuleName [ProperName C.prim])
112− case find (elem dctor . snd . fst) (exportedTypes exps) of
110+
113− Just ((ty, _), _) -> ty
111+ -- Creates a map of virtual modules mapped to all the declarations that
114− Nothing -> internalError $ "missing type for data constructor " ++ runProperName dctor ++ " in findTypeForDctor"
112+ -- import to that module, with the corresponding source span, import type,
115− Nothing -> internalError $ "missing module " ++ runModuleName mn ++ " in findTypeForDctor"
113+ -- and module being imported
114+ byQual
115+ :: [(ModuleName, [(Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)])]
116+ -> M.Map ModuleName [(Maybe SourceSpan, ImportDeclarationType, ModuleName)]
117+ byQual = foldr goImp M.empty
118+ where
119+ goImp (mni, xs) acc = foldr (goDecl mni) acc xs
120+ goDecl mni (ss, declType, Just qmn) acc =
121+ let entry = (ss, declType, mni)
122+ in M.alter (Just . maybe [entry] (entry :)) qmn acc
123+ goDecl _ _ acc = acc
116
124
117− -- rely on exports being elaborated by this point
125+ -- The list of modules that are being re-exported by the current module. Any
118− alwaysUsedModules :: [ ModuleName ]
126+ -- module that appears in this list is always considered to be used.
127+ exportedModules :: [ModuleName]
119− alwaysUsedModules = ModuleName [ProperName C.prim] : maybe [] (mapMaybe extractModule) mexports
128+ exportedModules = nub $ maybe [] (mapMaybe extractModule) mexports
120 where
129 where
121 extractModule (PositionedDeclarationRef _ _ r) = extractModule r
130 extractModule (PositionedDeclarationRef _ _ r) = extractModule r
122− extractModule (ModuleRef mn) = Just mn
131+ extractModule (ModuleRef mne) = Just mne
123 extractModule _ = Nothing
132 extractModule _ = Nothing
124
133
125− qnameUsed :: Maybe ModuleName -> Bool
134+ -- Elaborates the UsedImports to include values from modules that are being
126− qnameUsed (Just qn) = qn `elem` alwaysUsedModules
135+ -- re-exported. This ensures explicit export hints are printed for modules
136+ -- that are implicitly exported and then re-exported.
137+ elaborateUsed :: Imports -> ModuleName -> UsedImports -> UsedImports
138+ elaborateUsed scope mne used =
139+ let classes = extractByQual mne (importedTypeClasses scope) TyClassName
140+ types = extractByQual mne (importedTypes scope) TyName
141+ dctors = extractByQual mne (importedDataConstructors scope) DctorName
142+ values = extractByQual mne (importedValues scope) IdentName
143+ in foldr go used (classes ++ types ++ dctors ++ values)
144+ where
145+ go :: (ModuleName, Name) -> UsedImports -> UsedImports
146+ go (q, name) acc = M.alter (Just . maybe [name] (name :)) q acc
147+
148+ extractByQual
149+ :: (Eq a)
150+ => ModuleName
151+ -> M.Map (Qualified a) [(Qualified a, ModuleName)]
152+ -> (Qualified a -> Name)
153+ -> [(ModuleName, Name)]
154+ extractByQual k m toName = mapMaybe go (M.toList m)
155+ where
156+ go (q@(Qualified mnq _), is) | isUnqualified q || isQualifiedWith k q =
157+ case fst (head is) of
158+ Qualified (Just mn') name -> Just (mn', toName $ Qualified mnq name)
159+ _ -> internalError "unqualified name in extractByQual"
127− qnameUsed Nothing = False
160+ go _ = Nothing
128
161
162+lintImportDecl
163+ :: forall m
164+ . (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
165+ => Env
166+ -> ModuleName
167+ -> Maybe ModuleName
168+ -> [Name]
169+ -> ImportDeclarationType
170+ -> m ()
171+lintImportDecl env mni qualifierName names declType =
172+ case declType of
173+ Implicit -> case qualifierName of
174+ Nothing -> checkImplicit ImplicitImport
175+ Just q ->
176+ let usedModuleNames = mapMaybe extractQualName names
177+ in unless (q `elem` usedModuleNames) unused
178+ Hiding _ -> checkImplicit HidingImport
179+ Explicit [] -> unused
180+ Explicit declrefs -> checkExplicit declrefs
181+
182+ where
183+
184+ checkImplicit
185+ :: (ModuleName -> [DeclarationRef] -> SimpleErrorMessage)
186+ -> m ()
187+ checkImplicit warning =
188+ let allRefs = findUsedRefs env mni qualifierName names
189+ in if null allRefs
190+ then unused
191+ else tell $ errorMessage $ warning mni allRefs
192+
193+ checkExplicit
194+ :: [DeclarationRef]
195+ -> m ()
196+ checkExplicit declrefs = do
197+ let idents = nub (mapMaybe runDeclRef declrefs)
198+ dctors = mapMaybe (matchDctor qualifierName) names
199+ usedNames = mapMaybe (matchName (typeForDCtor mni) qualifierName) names
200+ diff = idents \\ usedNames
201+ case (length diff, length idents) of
202+ (0, _) -> return ()
203+ (n, m) | n == m -> unused
204+ _ -> tell $ errorMessage $ UnusedExplicitImport mni diff
205+
206+ -- If we've not already warned a type is unused, check its data constructors
207+ forM_ (mapMaybe getTypeRef declrefs) $ \(tn, c) -> do
208+ let allCtors = dctorsForType mni tn
209+ when (runProperName tn `elem` usedNames) $ case (c, dctors `intersect` allCtors) of
210+ (_, []) | c /= Just [] ->
211+ tell $ errorMessage $ UnusedDctorImport tn
212+ (Just ctors, dctors') ->
213+ let ddiff = ctors \\ dctors'
214+ in unless (null ddiff) $ tell $ errorMessage $ UnusedDctorExplicitImport tn ddiff
215+ _ -> return ()
216+ return ()
217+
218+ unused :: m ()
219+ unused = tell $ errorMessage $ UnusedImport mni
220+
221+ dtys
222+ :: ModuleName
129− dtys :: ModuleName -> [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
223+ -> [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
130 dtys mn = maybe [] exportedTypes $ envModuleExports <$> mn `M.lookup` env
224 dtys mn = maybe [] exportedTypes $ envModuleExports <$> mn `M.lookup` env
131
225
226+ dctorsForType
227+ :: ModuleName
228+ -> ProperName 'TypeName
132− dctorsForType :: ModuleName -> ProperName 'TypeName -> [ProperName 'ConstructorName]
229+ -> [ProperName 'ConstructorName]
133 dctorsForType mn tn =
230 dctorsForType mn tn =
134 maybe [] getDctors (find matches $ dtys mn)
231 maybe [] getDctors (find matches $ dtys mn)
135 where
232 where
136 matches ((ty, _),_) = ty == tn
233 matches ((ty, _),_) = ty == tn
137 getDctors ((_,ctors),_) = ctors
234 getDctors ((_,ctors),_) = ctors
138
235
236+ typeForDCtor
237+ :: ModuleName
139− typeForDCtor :: ModuleName -> ProperName 'ConstructorName -> Maybe (ProperName 'TypeName)
238+ -> ProperName 'ConstructorName
239+ -> Maybe (ProperName 'TypeName)
140 typeForDCtor mn pn =
240 typeForDCtor mn pn =
141 getTy <$> find matches (dtys mn)
241 getTy <$> find matches (dtys mn)
142 where
242 where
143 matches ((_, ctors), _) = pn `elem` ctors
243 matches ((_, ctors), _) = pn `elem` ctors
144 getTy ((ty, _), _) = ty
244 getTy ((ty, _), _) = ty
145
245
246+findUsedRefs :: Env -> ModuleName -> Maybe ModuleName -> [Name] -> [DeclarationRef]
247+findUsedRefs env mni qualifierName names =
248+ let
249+ classRefs = TypeClassRef <$> mapMaybe (getClassName qualifierName) names
250+ valueRefs = ValueRef <$> mapMaybe (getIdentName qualifierName) names
251+ types = mapMaybe (getTypeName qualifierName) names
252+ dctors = mapMaybe (matchDctor qualifierName) names
253+ typesWithDctors = reconstructTypeRefs dctors
254+ typesWithoutDctors = filter (`M.notMember` typesWithDctors) types
255+ typesRefs
256+ = map (flip TypeRef (Just [])) typesWithoutDctors
257+ ++ map (\(ty, ds) -> TypeRef ty (Just ds)) (M.toList typesWithDctors)
258+ in classRefs ++ typesRefs ++ valueRefs
259+
260+ where
261+
262+ reconstructTypeRefs
263+ :: [ProperName 'ConstructorName]
264+ -> M.Map (ProperName 'TypeName) [ProperName 'ConstructorName]
265+ reconstructTypeRefs = foldr accumDctors M.empty
266+ where
267+ accumDctors dctor = M.alter (Just . maybe [dctor] (dctor :)) (findTypeForDctor mni dctor)
268+
269+ findTypeForDctor
270+ :: ModuleName
271+ -> ProperName 'ConstructorName
272+ -> ProperName 'TypeName
273+ findTypeForDctor mn dctor =
274+ case mn `M.lookup` env of
275+ Just (_, _, exps) ->
276+ case find (elem dctor . snd . fst) (exportedTypes exps) of
277+ Just ((ty, _), _) -> ty
278+ Nothing -> internalError $ "missing type for data constructor " ++ runProperName dctor ++ " in findTypeForDctor"
279+ Nothing -> internalError $ "missing module " ++ runModuleName mn ++ " in findTypeForDctor"
146
280
147matchName
281matchName
148 :: (ProperName 'ConstructorName -> Maybe (ProperName 'TypeName))
282 :: (ProperName 'ConstructorName -> Maybe (ProperName 'TypeName))
@@ -155,6 +289,12 @@ matchName _ qual (TyClassName (Qualified q x)) | q == qual = Just $ runProperNam
155matchName lookupDc qual (DctorName (Qualified q x)) | q == qual = runProperName <$> lookupDc x
289matchName lookupDc qual (DctorName (Qualified q x)) | q == qual = runProperName <$> lookupDc x
156matchName _ _ _ = Nothing
290matchName _ _ _ = Nothing
157
291
292+extractQualName :: Name -> Maybe ModuleName
293+extractQualName (IdentName (Qualified q _)) = q
294+extractQualName (TyName (Qualified q _)) = q
295+extractQualName (TyClassName (Qualified q _)) = q
296+extractQualName (DctorName (Qualified q _)) = q
297+
158matchDctor :: Maybe ModuleName -> Name -> Maybe (ProperName 'ConstructorName)
298matchDctor :: Maybe ModuleName -> Name -> Maybe (ProperName 'ConstructorName)
159matchDctor qual (DctorName (Qualified q x)) | q == qual = Just x
299matchDctor qual (DctorName (Qualified q x)) | q == qual = Just x
160matchDctor _ _ = Nothing
300matchDctor _ _ = Nothing
@@ -166,7 +306,9 @@ runDeclRef (TypeRef pn _) = Just $ runProperName pn
166runDeclRef (TypeClassRef pn) = Just $ runProperName pn
306runDeclRef (TypeClassRef pn) = Just $ runProperName pn
167runDeclRef _ = Nothing
307runDeclRef _ = Nothing
168
308
309+getTypeRef
310+ :: DeclarationRef
169−getTypeRef :: DeclarationRef -> Maybe (ProperName 'TypeName, Maybe [ProperName 'ConstructorName])
311+ -> Maybe (ProperName 'TypeName, Maybe [ProperName 'ConstructorName])
170getTypeRef (PositionedDeclarationRef _ _ ref) = getTypeRef ref
312getTypeRef (PositionedDeclarationRef _ _ ref) = getTypeRef ref
171getTypeRef (TypeRef pn x) = Just (pn, x)
313getTypeRef (TypeRef pn x) = Just (pn, x)
172getTypeRef _ = Nothing
314getTypeRef _ = Nothing
src/Language/PureScript/Sugar/Names.hs+1−1
@@ -95,7 +95,7 @@ desugarImports externs modules = do
95 warnAndRethrow (addHint (ErrorInModule mn)) $ do
95 warnAndRethrow (addHint (ErrorInModule mn)) $ do
96 let (_, imps, exps) = fromMaybe (internalError "Module is missing in renameInModule'") $ M.lookup mn env
96 let (_, imps, exps) = fromMaybe (internalError "Module is missing in renameInModule'") $ M.lookup mn env
97 (m', used) <- flip runStateT M.empty $ renameInModule env imps (elaborateExports exps m)
97 (m', used) <- flip runStateT M.empty $ renameInModule env imps (elaborateExports exps m)
98− findUnusedImports m env used
98+ lintImports m env used
99 return m'
99 return m'
100
100
101-- |
101-- |