git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
[psc-ide] fix 2537 (#2603)

* [psc-ide] rename PscIdeError to IdeError * [psc-ide] Use a safer readFile to prevent crashes * try to read file and handle exception instead

commitde550a1fc85c7831e41476d48c6666fb99ae0c64 authorChristoph Hegemann <kRITZCREEK@users.noreply.github.com> dateSat 28 Jan 2017, 02:17 (10 years ago) parent43c133f
10 files changed+47−37
src/Language/PureScript/Ide.hs+6−6 src/Language/PureScript/Ide/CaseSplit.hs+6−6 src/Language/PureScript/Ide/Error.hs+4−4 src/Language/PureScript/Ide/Externs.hs+2−2 src/Language/PureScript/Ide/Imports.hs+6−6 src/Language/PureScript/Ide/Rebuild.hs+6−6 src/Language/PureScript/Ide/SourceFile.hs+3−4 src/Language/PureScript/Ide/Util.hs+11 tests/Language/PureScript/Ide/ImportsSpec.hs+1−1 tests/Language/PureScript/Ide/Test.hs+2−2
src/Language/PureScript/Ide.hs+6−6
@@ -43,7 +43,7 @@ import System.FilePath.Glob (glob)
4343
4444-- | Accepts a Commmand and runs it against psc-ide's State. This is the main
4545-- entry point for the server.
46−handleCommand :: (Ide m, MonadLogger m, MonadError PscIdeError m) =>
46+handleCommand :: (Ide m, MonadLogger m, MonadError IdeError m) =>
4747 Command -> m Success
4848handleCommand c = case c of
4949 Load [] ->
@@ -131,7 +131,7 @@ listAvailableModules = do
131131 let cleaned = filter (`notElem` [".", ".."]) contents
132132 return (ModuleList (map toS cleaned))
133133
134−caseSplit :: (Ide m, MonadError PscIdeError m) =>
134+caseSplit :: (Ide m, MonadError IdeError m) =>
135135 Text -> Int -> Int -> CS.WildcardAnnotations -> Text -> m Success
136136caseSplit l b e csa t = do
137137 patterns <- CS.makePattern l b e csa <$> CS.caseSplit t
@@ -139,7 +139,7 @@ caseSplit l b e csa t = do
139139
140140-- | Finds all the externs.json files inside the output folder and returns the
141141-- corresponding Modulenames
142−findAvailableExterns :: (Ide m, MonadError PscIdeError m) => m [P.ModuleName]
142+findAvailableExterns :: (Ide m, MonadError IdeError m) => m [P.ModuleName]
143143findAvailableExterns = do
144144 oDir <- outputDirectory
145145 unlessM (liftIO (doesDirectoryExist oDir))
@@ -169,7 +169,7 @@ findAllSourceFiles = do
169169-- inserts their ASTs into the state. Finally kicks off an async worker, which
170170-- populates Stage 2 and 3 of the state.
171171loadModulesAsync
172− :: (Ide m, MonadError PscIdeError m, MonadLogger m)
172+ :: (Ide m, MonadError IdeError m, MonadLogger m)
173173 => [P.ModuleName]
174174 -> m Success
175175loadModulesAsync moduleNames = do
@@ -185,7 +185,7 @@ loadModulesAsync moduleNames = do
185185 pure tr
186186
187187loadModulesSync
188− :: (Ide m, MonadError PscIdeError m, MonadLogger m)
188+ :: (Ide m, MonadError IdeError m, MonadLogger m)
189189 => [P.ModuleName]
190190 -> m Success
191191loadModulesSync moduleNames = do
@@ -194,7 +194,7 @@ loadModulesSync moduleNames = do
194194 pure tr
195195
196196loadModules
197− :: (Ide m, MonadError PscIdeError m, MonadLogger m)
197+ :: (Ide m, MonadError IdeError m, MonadLogger m)
198198 => [P.ModuleName]
199199 -> m Success
200200loadModules moduleNames = do
src/Language/PureScript/Ide/CaseSplit.hs+6−6
@@ -45,7 +45,7 @@ explicitAnnotations = WildcardAnnotations True
4545noAnnotations :: WildcardAnnotations
4646noAnnotations = WildcardAnnotations False
4747
48−caseSplit :: (Ide m, MonadError PscIdeError m) =>
48+caseSplit :: (Ide m, MonadError IdeError m) =>
4949 Text -> m [Constructor]
5050caseSplit q = do
5151 type' <- parseType' q
@@ -55,7 +55,7 @@ caseSplit q = do
5555 let appliedCtors = map (second (map applyTypeVars)) ctors
5656 pure appliedCtors
5757
58−findTypeDeclaration :: (Ide m, MonadError PscIdeError m) =>
58+findTypeDeclaration :: (Ide m, MonadError IdeError m) =>
5959 P.ProperName 'P.TypeName -> m ExternsDeclaration
6060findTypeDeclaration q = do
6161 efs <- getExternFiles
@@ -73,7 +73,7 @@ findTypeDeclaration' t ExternsFile{..} =
7373 EDType tn _ _ -> tn == t
7474 _ -> False) efDeclarations
7575
76−splitTypeConstructor :: (MonadError PscIdeError m) =>
76+splitTypeConstructor :: (MonadError IdeError m) =>
7777 P.Type -> m (P.ProperName 'P.TypeName, [P.Type])
7878splitTypeConstructor = go []
7979 where
@@ -105,7 +105,7 @@ makePattern t x y wsa = makePattern' (T.take x t) (T.drop y t)
105105 where
106106 makePattern' lhs rhs = map (\ctor -> lhs <> prettyCtor wsa ctor <> rhs)
107107
108−addClause :: (MonadError PscIdeError m) => Text -> WildcardAnnotations -> m [Text]
108+addClause :: (MonadError IdeError m) => Text -> WildcardAnnotations -> m [Text]
109109addClause s wca = do
110110 (fName, fType) <- parseTypeDeclaration' s
111111 let args = splitFunctionType fType
@@ -114,7 +114,7 @@ addClause s wca = do
114114 " = ?" <> (T.strip . P.runIdent $ fName)
115115 pure [s, template]
116116
117−parseType' :: (MonadError PscIdeError m) =>
117+parseType' :: (MonadError IdeError m) =>
118118 Text -> m P.Type
119119parseType' s =
120120 case P.lex "<psc-ide>" (toS s) >>= P.runTokenParser "<psc-ide>" (P.parseType <* Parsec.eof) of
@@ -123,7 +123,7 @@ parseType' s =
123123 throwError (GeneralError ("Parsing the splittype failed with:"
124124 <> show err))
125125
126−parseTypeDeclaration' :: (MonadError PscIdeError m) => Text -> m (P.Ident, P.Type)
126+parseTypeDeclaration' :: (MonadError IdeError m) => Text -> m (P.Ident, P.Type)
127127parseTypeDeclaration' s =
128128 let x = do
129129 ts <- P.lex "" (toS s)
src/Language/PureScript/Ide/Error.hs+4−4
@@ -13,7 +13,7 @@
1313-----------------------------------------------------------------------------
1414
1515module Language.PureScript.Ide.Error
16− ( PscIdeError(..)
16+ ( IdeError(..)
1717 ) where
1818
1919import Data.Aeson
@@ -22,7 +22,7 @@ import Language.PureScript.Ide.Types (ModuleIdent)
2222import Protolude
2323import qualified Text.Parsec.Error as P
2424
25−data PscIdeError
25+data IdeError
2626 = GeneralError Text
2727 | NotFound Text
2828 | ModuleNotFound ModuleIdent
@@ -31,7 +31,7 @@ data PscIdeError
3131 | RebuildError [JSONError]
3232 deriving (Show, Eq)
3333
34−instance ToJSON PscIdeError where
34+instance ToJSON IdeError where
3535 toJSON (RebuildError errs) = object
3636 [ "resultType" .= ("error" :: Text)
3737 , "result" .= errs
@@ -41,7 +41,7 @@ instance ToJSON PscIdeError where
4141 , "result" .= textError err
4242 ]
4343
44−textError :: PscIdeError -> Text
44+textError :: IdeError -> Text
4545textError (GeneralError msg) = msg
4646textError (NotFound ident) = "Symbol '" <> ident <> "' not found."
4747textError (ModuleNotFound ident) = "Module '" <> ident <> "' not found."
src/Language/PureScript/Ide/Externs.hs+2−2
@@ -28,13 +28,13 @@ import Data.Aeson (decodeStrict)
2828import qualified Data.ByteString as BS
2929import qualified Data.Map as Map
3030import Data.Version (showVersion)
31−import Language.PureScript.Ide.Error (PscIdeError (..))
31+import Language.PureScript.Ide.Error (IdeError (..))
3232import Language.PureScript.Ide.Types
3333import Language.PureScript.Ide.Util
3434
3535import qualified Language.PureScript as P
3636
37−readExternFile :: (MonadIO m, MonadError PscIdeError m, MonadLogger m) =>
37+readExternFile :: (MonadIO m, MonadError IdeError m, MonadLogger m) =>
3838 FilePath -> m P.ExternsFile
3939readExternFile fp = do
4040 parseResult <- liftIO (decodeStrict <$> BS.readFile fp)
src/Language/PureScript/Ide/Imports.hs+6−6
@@ -39,7 +39,7 @@ import Language.PureScript.Ide.Filter
3939import Language.PureScript.Ide.State
4040import Language.PureScript.Ide.Types
4141import Language.PureScript.Ide.Util
42−import System.IO.UTF8 (readUTF8FileT, writeUTF8FileT)
42+import System.IO.UTF8 (writeUTF8FileT)
4343
4444data Import = Import P.ModuleName P.ImportDeclarationType (Maybe P.ModuleName)
4545 deriving (Eq, Show)
@@ -67,10 +67,10 @@ compImport (Import n i q) (Import n' i' q')
6767
6868-- | Reads a file and returns the (lines before the imports, the imports, the
6969-- lines after the imports)
70−parseImportsFromFile :: (MonadIO m, MonadError PscIdeError m) =>
70+parseImportsFromFile :: (MonadIO m, MonadError IdeError m) =>
7171 FilePath -> m (P.ModuleName, [Text], [Import], [Text])
7272parseImportsFromFile fp = do
73− file <- liftIO (readUTF8FileT fp)
73+ file <- ideReadFile fp
7474 case sliceImportSection (T.lines file) of
7575 Right res -> pure res
7676 Left err -> throwError (GeneralError err)
@@ -147,7 +147,7 @@ moduleParse t = first show $ do
147147 P.runTokenParser "<psc-ide>" P.parseModule tokens
148148
149149-- | Adds an implicit import like @import Prelude@ to a Sourcefile.
150−addImplicitImport :: (MonadIO m, MonadError PscIdeError m)
150+addImplicitImport :: (MonadIO m, MonadError IdeError m)
151151 => FilePath -- ^ The Sourcefile read from
152152 -> P.ModuleName -- ^ The module to import
153153 -> m [Text]
@@ -170,7 +170,7 @@ addImplicitImport' imports mn =
170170-- So @addExplicitImport "/File.purs" "bind" "Prelude"@ with an already existing
171171-- @import Prelude (bind)@ in the file File.purs returns @["import Prelude
172172-- (bind, unit)"]@
173−addExplicitImport :: (MonadIO m, MonadError PscIdeError m) =>
173+addExplicitImport :: (MonadIO m, MonadError IdeError m) =>
174174 FilePath -> IdeDeclaration -> P.ModuleName -> m [Text]
175175addExplicitImport fp decl moduleName = do
176176 (mn, pre, imports, post) <- parseImportsFromFile fp
@@ -249,7 +249,7 @@ updateAtFirstOrPrepend p t d l =
249249--
250250-- * If more than one possible imports are found, reports the possibilities as a
251251-- list of completions.
252−addImportForIdentifier :: (Ide m, MonadError PscIdeError m)
252+addImportForIdentifier :: (Ide m, MonadError IdeError m)
253253 => FilePath -- ^ The Sourcefile to read from
254254 -> Text -- ^ The identifier to import
255255 -> [Filter] -- ^ Filters to apply before searching for
src/Language/PureScript/Ide/Rebuild.hs+6−6
@@ -20,7 +20,7 @@ import Language.PureScript.Ide.Error
2020import Language.PureScript.Ide.Logging
2121import Language.PureScript.Ide.State
2222import Language.PureScript.Ide.Types
23−import System.IO.UTF8 (readUTF8FileT)
23+import Language.PureScript.Ide.Util
2424
2525-- | Given a filepath performs the following steps:
2626--
@@ -38,7 +38,7 @@ import System.IO.UTF8 (readUTF8FileT)
3838-- warnings, and if rebuilding fails, returns a @RebuildError@ with the
3939-- generated errors.
4040rebuildFile
41− :: (Ide m, MonadLogger m, MonadError PscIdeError m)
41+ :: (Ide m, MonadLogger m, MonadError IdeError m)
4242 => FilePath
4343 -- ^ The file to rebuild
4444 -> (ReaderT IdeEnvironment (LoggingT IO) () -> m ())
@@ -46,7 +46,7 @@ rebuildFile
4646 -> m Success
4747rebuildFile path runOpenBuild = do
4848
49− input <- liftIO (readUTF8FileT path)
49+ input <- ideReadFile path
5050
5151 m <- case snd <$> P.parseModuleFromFile identity (path, input) of
5252 Left parseError -> throwError
@@ -80,7 +80,7 @@ rebuildFile path runOpenBuild = do
8080 pure (RebuildSuccess (toJSONErrors False P.Warning warnings))
8181
8282rebuildFileAsync
83− :: forall m. (Ide m, MonadLogger m, MonadError PscIdeError m)
83+ :: forall m. (Ide m, MonadLogger m, MonadError IdeError m)
8484 => FilePath -> m Success
8585rebuildFileAsync fp = rebuildFile fp asyncRun
8686 where
@@ -91,7 +91,7 @@ rebuildFileAsync fp = rebuildFile fp asyncRun
9191 void (liftIO (async (runLogger ll (runReaderT action env))))
9292
9393rebuildFileSync
94− :: forall m. (Ide m, MonadLogger m, MonadError PscIdeError m)
94+ :: forall m. (Ide m, MonadLogger m, MonadError IdeError m)
9595 => FilePath -> m Success
9696rebuildFileSync fp = rebuildFile fp syncRun
9797 where
@@ -158,7 +158,7 @@ shushCodegen ma MakeActionsEnv{..} =
158158-- module. Throws an error if there is a cyclic dependency within the
159159-- ExternsFiles
160160sortExterns
161− :: (Ide m, MonadError PscIdeError m)
161+ :: (Ide m, MonadError IdeError m)
162162 => P.Module
163163 -> ModuleMap P.ExternsFile
164164 -> m [P.ExternsFile]
src/Language/PureScript/Ide/SourceFile.hs+3−4
@@ -28,14 +28,13 @@ import qualified Language.PureScript as P
2828import Language.PureScript.Ide.Error
2929import Language.PureScript.Ide.Types
3030import Language.PureScript.Ide.Util
31−import System.IO.UTF8 (readUTF8FileT)
3231
3332parseModule
34− :: (MonadIO m)
33+ :: (MonadIO m, MonadError IdeError m)
3534 => FilePath
3635 -> m (Either FilePath (FilePath, P.Module))
3736parseModule path = do
38− contents <- liftIO (readUTF8FileT path)
37+ contents <- ideReadFile path
3938 case P.parseModuleFromFile identity (path, contents) of
4039 Left _ -> pure (Left path)
4140 Right m -> pure (Right m)
@@ -47,7 +46,7 @@ getImports (P.Module _ _ _ declarations _) =
4746 isImport (P.PositionedDeclaration _ _ (P.ImportDeclaration a b c)) = Just (a, b, c)
4847 isImport _ = Nothing
4948
50−getImportsForFile :: (MonadIO m, MonadError PscIdeError m) =>
49+getImportsForFile :: (MonadIO m, MonadError IdeError m) =>
5150 FilePath -> m [ModuleImport]
5251getImportsForFile fp = do
5352 moduleE <- parseModule fp
src/Language/PureScript/Ide/Util.hs+11
@@ -28,6 +28,7 @@ module Language.PureScript.Ide.Util
2828 , properNameT
2929 , identT
3030 , opNameT
31+ , ideReadFile
3132 , module Language.PureScript.Ide.Logging
3233 ) where
3334
@@ -40,8 +41,10 @@ import qualified Data.Text as T
4041import qualified Data.Text.Lazy as TL
4142import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)
4243import qualified Language.PureScript as P
44+import Language.PureScript.Ide.Error
4345import Language.PureScript.Ide.Logging
4446import Language.PureScript.Ide.Types
47+import System.IO.UTF8 (readUTF8FileT)
4548
4649identifierFromIdeDeclaration :: IdeDeclaration -> Text
4750identifierFromIdeDeclaration d = case d of
@@ -127,6 +130,14 @@ identT = iso P.runIdent P.Ident
127130opNameT :: Iso' (P.OpName a) Text
128131opNameT = iso P.runOpName P.OpName
129132
133+ideReadFile :: (MonadIO m, MonadError IdeError m) => FilePath -> m Text
134+ideReadFile fp = do
135+ contents :: Either IOException Text <- liftIO (try (readUTF8FileT fp))
136+ either
137+ (\_ -> throwError (GeneralError ("Couldn't find file at: " <> T.pack fp)))
138+ pure
139+ contents
140+
130141prettyTypeT :: P.Type -> Text
131142prettyTypeT =
132143 T.unwords
tests/Language/PureScript/Ide/ImportsSpec.hs+1−1
@@ -190,7 +190,7 @@ importShouldBe :: [Text] -> [Text] -> Expectation
190190importShouldBe res importSection =
191191 res `shouldBe` [ "module ImportsSpec where" , ""] ++ importSection ++ [ "" , "myId x = x"]
192192
193−runIdeLoaded :: Command -> IO (Either PscIdeError Success)
193+runIdeLoaded :: Command -> IO (Either IdeError Success)
194194runIdeLoaded c = do
195195 ([_, result], _) <- Test.inProject $ Test.runIde [Command.LoadSync [] , c]
196196 pure result
tests/Language/PureScript/Ide/Test.hs+2−2
@@ -24,7 +24,7 @@ defConfig =
2424 , confGlobs = ["src/*.purs"]
2525 }
2626
27−runIde' :: Configuration -> IdeState -> [Command] -> IO ([Either PscIdeError Success], IdeState)
27+runIde' :: Configuration -> IdeState -> [Command] -> IO ([Either IdeError Success], IdeState)
2828runIde' conf s cs = do
2929 stateVar <- newTVarIO s
3030 let env' = IdeEnvironment {ideStateVar = stateVar, ideConfiguration = conf}
@@ -32,7 +32,7 @@ runIde' conf s cs = do
3232 newState <- readTVarIO stateVar
3333 pure (r, newState)
3434
35−runIde :: [Command] -> IO ([Either PscIdeError Success], IdeState)
35+runIde :: [Command] -> IO ([Either IdeError Success], IdeState)
3636runIde = runIde' defConfig emptyIdeState
3737
3838s3 :: IdeState -> [(Text, [IdeDeclarationAnn])] -> IdeState