git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #2016 from hdgarrood/fix-2011

Better error for invalid FFI identifiers, #2011

commit83896db8fcc752b609654c91da84cd84ad788af5 authorPhil Freeman <paf31@cantab.net> dateThu 14 Apr 2016, 12:31 (11 years ago) parent6cb50ee23b6160
2 files changed+29−6
src/Language/PureScript/Errors.hs+9 src/Language/PureScript/Make.hs+20−6
src/Language/PureScript/Errors.hs+9
@@ -46,6 +46,7 @@ data SimpleErrorMessage
4646 | UnnecessaryFFIModule ModuleName FilePath
4747 | MissingFFIImplementations ModuleName [Ident]
4848 | UnusedFFIImplementations ModuleName [Ident]
49+ | InvalidFFIIdentifier ModuleName String
4950 | CannotGetFileInfo FilePath
5051 | CannotReadFile FilePath
5152 | CannotWriteFile FilePath
@@ -229,6 +230,7 @@ errorCode em = case unwrapErrorMessage em of
229230 UnnecessaryFFIModule{} -> "UnnecessaryFFIModule"
230231 MissingFFIImplementations{} -> "MissingFFIImplementations"
231232 UnusedFFIImplementations{} -> "UnusedFFIImplementations"
233+ InvalidFFIIdentifier{} -> "InvalidFFIIdentifier"
232234 CannotGetFileInfo{} -> "CannotGetFileInfo"
233235 CannotReadFile{} -> "CannotReadFile"
234236 CannotWriteFile{} -> "CannotWriteFile"
@@ -552,6 +554,13 @@ prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap
552554 paras [ line $ "The following definitions in the foreign module for module " ++ runModuleName mn ++ " are unused: "
553555 , indent . paras $ map (line . runIdent) idents
554556 ]
557+ renderSimpleErrorMessage (InvalidFFIIdentifier mn ident) =
558+ paras [ line $ "In the FFI module for " ++ runModuleName mn ++ ":"
559+ , indent . paras $
560+ [ line $ "The identifier `" ++ ident ++ "` is not valid in PureScript."
561+ , line "Note that exported identifiers in FFI modules must be valid PureScript identifiers."
562+ ]
563+ ]
555564 renderSimpleErrorMessage (MultipleFFIModules mn paths) =
556565 paras [ line $ "Multiple foreign module implementations have been provided for module " ++ runModuleName mn ++ ": "
557566 , indent . paras $ map line paths
src/Language/PureScript/Make.hs+20−6
@@ -42,6 +42,7 @@ import Control.Concurrent.Lifted as C
4242
4343import Data.List (foldl', sort)
4444import Data.Maybe (fromMaybe, catMaybes, isJust)
45+import Data.Either (partitionEithers)
4546import Data.Time.Clock
4647import Data.String (fromString)
4748import Data.Foldable (for_)
@@ -417,11 +418,10 @@ checkForeignDecls m path = do
417418 js <- either (errorParsingModule . Bundle.UnableToParseModule) pure $ JS.parse jsStr path
418419
419420 foreignIdentsStrs <- either errorParsingModule pure $ getExps js
420− let foreignIdents =
421− either
422− (internalError . ("checkForeignDecls: unexpected idents: " ++) . show)
423− S.fromList
424− (traverse parseIdent foreignIdentsStrs)
421+ foreignIdents <- either
422+ errorInvalidForeignIdentifiers
423+ (pure . S.fromList)
424+ (parseIdents foreignIdentsStrs)
425425 let importedIdents = S.fromList $ map fst (CF.moduleForeign m)
426426
427427 let unusedFFI = foreignIdents S.\\ importedIdents
@@ -443,10 +443,24 @@ checkForeignDecls m path = do
443443 getExps :: JS.JSAST -> Either Bundle.ErrorMessage [String]
444444 getExps = Bundle.getExportedIdentifiers (runModuleName mname)
445445
446+ errorInvalidForeignIdentifiers :: [String] -> SupplyT Make a
447+ errorInvalidForeignIdentifiers =
448+ throwError . mconcat . map (errorMessage . InvalidFFIIdentifier mname)
449+
450+ parseIdents :: [String] -> Either [String] [Ident]
451+ parseIdents strs =
452+ case partitionEithers (map parseIdent strs) of
453+ ([], idents) ->
454+ Right idents
455+ (errs, _) ->
456+ Left errs
457+
446458 -- TODO: Handling for parenthesised operators should be removed after 0.9.
459+ -- We ignore the error message here, just being told it's an invalid
460+ -- identifier should be enough.
447461 parseIdent :: String -> Either String Ident
448462 parseIdent str = try str <|> try ("(" ++ str ++ ")")
449463 where
450− try s = either (Left . show) Right $ do
464+ try s = either (const (Left str)) Right $ do
451465 ts <- PSParser.lex "" s
452466 PSParser.runTokenParser "" (PSParser.parseIdent <* Parsec.eof) ts