@@ -124,7 +124,7 @@ data SimpleErrorMessage
124 | MisleadingEmptyTypeImport ModuleName (ProperName 'TypeName)
124 | MisleadingEmptyTypeImport ModuleName (ProperName 'TypeName)
125 | ImportHidingModule ModuleName
125 | ImportHidingModule ModuleName
126 | UnusedImport ModuleName
126 | UnusedImport ModuleName
127− | UnusedExplicitImport ModuleName [String]
127+ | UnusedExplicitImport ModuleName [String] (Maybe ModuleName) [DeclarationRef]
128 | UnusedDctorImport (ProperName 'TypeName)
128 | UnusedDctorImport (ProperName 'TypeName)
129 | UnusedDctorExplicitImport (ProperName 'TypeName) [ProperName 'ConstructorName]
129 | UnusedDctorExplicitImport (ProperName 'TypeName) [ProperName 'ConstructorName]
130 | DeprecatedOperatorDecl String
130 | DeprecatedOperatorDecl String
@@ -179,6 +179,8 @@ data HintCategory
180data ErrorMessage = ErrorMessage [ErrorMessageHint] SimpleErrorMessage deriving (Show)
180data ErrorMessage = ErrorMessage [ErrorMessageHint] SimpleErrorMessage deriving (Show)
182+newtype ErrorSuggestion = ErrorSuggestion String
182-- | Get the source span for an error
184-- | Get the source span for an error
183errorSpan :: ErrorMessage -> Maybe SourceSpan
185errorSpan :: ErrorMessage -> Maybe SourceSpan
184errorSpan = findHint matchSpan
186errorSpan = findHint matchSpan
@@ -419,6 +421,40 @@ onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse
419wikiUri :: ErrorMessage -> String
421wikiUri :: ErrorMessage -> String
420wikiUri e = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
422wikiUri e = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
424+-- TODO Other possible suggestions:
425+-- WildcardInferredType - source span not small enough
426+-- DuplicateSelectiveImport - would require 2 ranges to remove and 1 insert
427+-- DeprecatedClassExport, DeprecatedClassImport, would want to replace smaller span?
428+errorSuggestion :: SimpleErrorMessage -> Maybe ErrorSuggestion
429+errorSuggestion err = case err of
430+ UnusedImport{} -> emptySuggestion
431+ RedundantEmptyHidingImport{} -> emptySuggestion
432+ DuplicateImport{} -> emptySuggestion
433+ RedundantUnqualifiedImport{} -> emptySuggestion
434+ DeprecatedQualifiedSyntax name qualName -> suggest $
435+ "import " ++ runModuleName name ++ " as " ++ runModuleName qualName
436+ UnusedExplicitImport mn _ qual refs -> suggest $ importSuggestion mn refs qual
437+ ImplicitImport mn refs -> suggest $ importSuggestion mn refs Nothing
438+ ImplicitQualifiedImport mn asModule refs -> suggest $ importSuggestion mn refs (Just asModule)
442+ emptySuggestion = Just $ ErrorSuggestion ""
443+ suggest = Just . ErrorSuggestion
445+ importSuggestion :: ModuleName -> [ DeclarationRef ] -> Maybe ModuleName -> String
446+ importSuggestion mn refs qual =
447+ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")" ++ qstr qual
449+ qstr :: Maybe ModuleName -> String
450+ qstr (Just mn) = " as " ++ runModuleName mn
453+showSuggestion :: SimpleErrorMessage -> String
454+showSuggestion suggestion = case errorSuggestion suggestion of
455+ Just (ErrorSuggestion x) -> x
423-- Pretty print a single error, simplifying if necessary
459-- Pretty print a single error, simplifying if necessary
@@ -796,9 +832,11 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
796 renderSimpleErrorMessage (UnusedImport name) =
832 renderSimpleErrorMessage (UnusedImport name) =
797 line $ "The import of module " ++ runModuleName name ++ " is redundant"
833 line $ "The import of module " ++ runModuleName name ++ " is redundant"
799− renderSimpleErrorMessage (UnusedExplicitImport name names) =
835+ renderSimpleErrorMessage msg@(UnusedExplicitImport mn names _ _) =
800− paras [ line $ "The import of module " ++ runModuleName name ++ " contains the following unused references:"
836+ paras [ line $ "The import of module " ++ runModuleName mn ++ " contains the following unused references:"
801− , indent $ paras $ map line names ]
837+ , indent $ paras $ map line names
838+ , line $ "It could be replaced with:"
839+ , indent $ line $ showSuggestion msg ]
803 renderSimpleErrorMessage (UnusedDctorImport name) =
841 renderSimpleErrorMessage (UnusedDctorImport name) =
804 line $ "The import of type " ++ runProperName name ++ " includes data constructors but only the type is used"
842 line $ "The import of type " ++ runProperName name ++ " includes data constructors but only the type is used"
@@ -860,15 +898,15 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
860 renderSimpleErrorMessage (RedundantEmptyHidingImport mn) =
898 renderSimpleErrorMessage (RedundantEmptyHidingImport mn) =
861 line $ "The import for module " ++ runModuleName mn ++ " is redundant as all members have been explicitly hidden."
899 line $ "The import for module " ++ runModuleName mn ++ " is redundant as all members have been explicitly hidden."
863− renderSimpleErrorMessage (ImplicitQualifiedImport importedModule asModule refs) =
901+ renderSimpleErrorMessage msg@(ImplicitQualifiedImport importedModule asModule _) =
864 paras [ line $ "Module " ++ runModuleName importedModule ++ " was imported as " ++ runModuleName asModule ++ " with unspecified imports."
902 paras [ line $ "Module " ++ runModuleName importedModule ++ " was imported as " ++ runModuleName asModule ++ " with unspecified imports."
865 , line $ "As there are multiple modules being imported as " ++ runModuleName asModule ++ ", consider using the explicit form:"
903 , line $ "As there are multiple modules being imported as " ++ runModuleName asModule ++ ", consider using the explicit form:"
866− , indent $ line $ "import " ++ runModuleName importedModule ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ") as " ++ runModuleName asModule
904+ , indent $ line $ showSuggestion msg
869− renderSimpleErrorMessage (ImplicitImport mn refs) =
907+ renderSimpleErrorMessage msg@(ImplicitImport mn _) =
870 paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
908 paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
871− , indent $ line $ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
909+ , indent $ line $ showSuggestion msg
874 renderSimpleErrorMessage (HidingImport mn refs) =
912 renderSimpleErrorMessage (HidingImport mn refs) =
@@ -1009,30 +1047,6 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1009 paras :: [Box.Box] -> Box.Box
1047 paras :: [Box.Box] -> Box.Box
1010 paras = Box.vcat Box.left
1048 paras = Box.vcat Box.left
1012− -- Pretty print and export declaration
1013− prettyPrintExport :: DeclarationRef -> String
1014− prettyPrintExport (TypeRef pn _) = runProperName pn
1015− prettyPrintExport ref = prettyPrintRef ref
1017− prettyPrintRef :: DeclarationRef -> String
1018− prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
1019− prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
1020− prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1021− prettyPrintRef (ValueRef ident) = showIdent ident
1022− prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
1023− prettyPrintRef (ProperRef name) = name
1024− prettyPrintRef (TypeInstanceRef ident) = showIdent ident
1025− prettyPrintRef (ModuleRef name) = "module " ++ runModuleName name
1026− prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
1028− prettyPrintImport :: ModuleName -> ImportDeclarationType -> Maybe ModuleName -> String
1029− prettyPrintImport mn idt qual =
1030− let i = case idt of
1031− Implicit -> runModuleName mn
1032− Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
1033− Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (map prettyPrintRef refs) ++ ")"
1034− in i ++ maybe "" (\q -> " as " ++ runModuleName q) qual
1036 -- | Simplify an error message
1050 -- | Simplify an error message
1037 simplifyErrorMessage :: ErrorMessage -> ErrorMessage
1051 simplifyErrorMessage :: ErrorMessage -> ErrorMessage
1038 simplifyErrorMessage (ErrorMessage hints simple) = ErrorMessage (simplifyHints hints) simple
1052 simplifyErrorMessage (ErrorMessage hints simple) = ErrorMessage (simplifyHints hints) simple
@@ -1084,6 +1098,30 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
1084 hintCategory PositionedError{} = PositionHint
1098 hintCategory PositionedError{} = PositionHint
1085 hintCategory _ = OtherHint
1099 hintCategory _ = OtherHint
1101+-- Pretty print and export declaration
1102+prettyPrintExport :: DeclarationRef -> String
1103+prettyPrintExport (TypeRef pn _) = runProperName pn
1104+prettyPrintExport ref = prettyPrintRef ref
1106+prettyPrintImport :: ModuleName -> ImportDeclarationType -> Maybe ModuleName -> String
1107+prettyPrintImport mn idt qual =
1108+ let i = case idt of
1109+ Implicit -> runModuleName mn
1110+ Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
1111+ Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (map prettyPrintRef refs) ++ ")"
1112+ in i ++ maybe "" (\q -> " as " ++ runModuleName q) qual
1114+prettyPrintRef :: DeclarationRef -> String
1115+prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
1116+prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
1117+prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1118+prettyPrintRef (ValueRef ident) = showIdent ident
1119+prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
1120+prettyPrintRef (ProperRef name) = name
1121+prettyPrintRef (TypeInstanceRef ident) = showIdent ident
1122+prettyPrintRef (ModuleRef name) = "module " ++ runModuleName name
1123+prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
1088-- Pretty print multiple errors
1126-- Pretty print multiple errors