git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge branch 'master' into pure11
commit1235127d2b5f5a84a0852c13f845bdf5eb0cb199 authorAndy Arvanitis <andyarvanitis@gmail.com> dateMon 30 Jan 2017, 19:40 (10 years ago) parentcab7795ada063f
30 files changed+303−258
.travis.yml+7−7 CONTRIBUTORS.md+3 examples/failing/2601.purs+7 examples/passing/NestedRecordUpdate.purs+6−5 examples/passing/NestedRecordUpdateWildcards.purs+1−1 examples/passing/ParseNamedBinder.purs−9 psc-package/Main.hs+35−32 purescript.cabal+8−8 src/Language/PureScript/AST/Declarations.hs+37−3 src/Language/PureScript/AST/Traversals.hs+7−7 src/Language/PureScript/Crash.hs+27−11 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+4−4 src/Language/PureScript/Ide/Imports.hs+6−6 src/Language/PureScript/Ide/Rebuild.hs+6−6 src/Language/PureScript/Ide/SourceFile.hs+7−4 src/Language/PureScript/Ide/Types.hs+4−4 src/Language/PureScript/Ide/Util.hs+15 src/Language/PureScript/Parser/Declarations.hs+23−13 src/Language/PureScript/Pretty/JS.hs+15−9 src/Language/PureScript/Pretty/Values.hs+8−10 src/Language/PureScript/Sugar/ObjectWildcards.hs+26−88 stack-ghc-8.0.yaml+2 stack.yaml+2 tests/Language/PureScript/Ide/ImportsSpec.hs+1−1 tests/Language/PureScript/Ide/SourceFileSpec.hs+28−2 tests/Language/PureScript/Ide/Test.hs+2−2 tests/support/pscide/src/SourceFileSpec.purs−10
.travis.yml+7−7
@@ -39,13 +39,13 @@ matrix:
3939 sudo: required
4040 env: BUILD_TYPE=haddock
4141
42− - compiler: cc-osx-lts-normal
43− os: osx
44− env: BUILD_TYPE=normal DEPLOY=true
45−
46− - compiler: cc-osx-lts-sdist
47− os: osx
48− env: BUILD_TYPE=sdist
42+ # - compiler: cc-osx-lts-normal
43+ # os: osx
44+ # env: BUILD_TYPE=normal DEPLOY=true
45+
46+ # - compiler: cc-osx-lts-sdist
47+ # os: osx
48+ # env: BUILD_TYPE=sdist
4949addons:
5050 apt:
5151 packages:
CONTRIBUTORS.md+3
@@ -76,6 +76,7 @@ This file lists the contributors to the PureScript compiler project, and the ter
7676- [@sharkdp](https://github.com/sharkdp) (David Peter) My existing contributions and all future contributions until further notice are Copyright David Peter, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
7777- [@soupi](https://github.com/soupi) (Gil Mizrahi) My existing contributions and all future contributions until further notice are Copyright Gil Mizrahi, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
7878- [@sztupi](https://github.com/sztupi) (Attila Sztupak) My existing contributions and all future contributions until further notice are Copyright Attila Sztupak, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
79+- [@taktoa](https://github.com/taktoa) (Remy Goldschmidt) My existing contributions and all future contributions until further notice are Copyright Remy Goldschmidt, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
7980- [@taku0](https://github.com/taku0) - My existing contributions and all future contributions until further notice are Copyright taku0, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
8081- [@tfausak](https://github.com/tfausak) (Taylor Fausak) My existing contributions and all future contributions until further notice are Copyright Taylor Fausak, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
8182- [@tmcgilchrist](https://github.com/tmcgilchrist) (Tim McGilchrist) My existing contributions and all future contributions until further notice are Copyright Tim McGilchrist, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
@@ -87,6 +88,8 @@ This file lists the contributors to the PureScript compiler project, and the ter
8788- [@bbqbaron](https://github.com/bbqbaron) (Eric Loren) My existing contributions and all future contributions until further notice are Copyright Eric Loren, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
8889- [@RyanGlScott](https://github.com/RyanGlScott) (Ryan Scott) My existing contributions and all future contributions until further notice are Copyright Ryan Scott, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
8990- [@seungha-kim](https://github.com/seungha-kim) (Seungha Kim) My existing contributions and all future contributions until further notice are Copyright Seungha Kim, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
91+- [@matthewleon](https://github.com/matthewleon) (Matthew Leon) My existing contributions and all future contributions until further notice are Copyright Matthew Leon, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
92+- [@alexbiehl](https://github.com/alexbiehl) (Alexander Biehl) My existing contributions and all future contributions until further notice are Copyright Alexander Biehl, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT).
9093
9194### Companies
9295
examples/failing/2601.pursnew file+7
@@ -0,0 +1,7 @@
1+-- @shouldFailWith KindsDoNotUnify
2+module Main where
3+
4+type Syn (a :: * -> *) = String
5+
6+val :: Syn Int
7+val = "bad"
examples/passing/NestedRecordUpdate.purs+6−5
@@ -3,21 +3,22 @@ module Main where
33import Prelude
44import Control.Monad.Eff.Console
55
6−type T = { foo :: Int, bar :: { baz :: Int, qux :: Int } }
6+type T = { foo :: Int, bar :: { baz :: Int, qux :: { lhs :: Int, rhs :: Int } } }
77
88init :: T
9−init = { foo: 1, bar: { baz: 2, qux: 3 } }
9+init = { foo: 1, bar: { baz: 2, qux: { lhs: 3, rhs: 4 } } }
1010
1111updated :: T
12−updated = init { foo = 10, bar.baz = 20, bar.qux = 30 }
12+updated = init { foo = 10, bar { baz = 20, qux { lhs = 30, rhs = 40 } } }
1313
1414expected :: T
15−expected = { foo: 10, bar: { baz: 20, qux: 30 } }
15+expected = { foo: 10, bar: { baz: 20, qux: { lhs: 30, rhs: 40 } } }
1616
1717check l r =
1818 l.foo == r.foo &&
1919 l.bar.baz == r.bar.baz &&
20− l.bar.qux == r.bar.qux
20+ l.bar.qux.lhs == r.bar.qux.lhs &&
21+ l.bar.qux.rhs == r.bar.qux.rhs
2122
2223main = do
2324 when (check updated expected) $ log "Done"
examples/passing/NestedRecordUpdateWildcards.purs+1−1
@@ -3,7 +3,7 @@ module Main where
33import Prelude
44import Control.Monad.Eff.Console
55
6−update = _ { foo = _, bar.baz = _, bar.qux = _ }
6+update = _ { foo = _, bar { baz = _, qux = _ } }
77
88init = { foo: 1, bar: { baz: 2, qux: 3 } }
99
examples/passing/ParseNamedBinder.pursdeleted−9
@@ -1,9 +0,0 @@
1−module Main where
2−
3−import Control.Monad.Eff.Console (log)
4−
5−data X = X
6−
7−f a@X X = a
8−
9−main = log "Done"
psc-package/Main.hs+35−32
@@ -28,9 +28,12 @@ import GHC.Generics (Generic)
2828import qualified Options.Applicative as Opts
2929import qualified Paths_purescript as Paths
3030import qualified System.IO as IO
31−import Turtle hiding (fold, s, x)
31+import Turtle hiding (echo, fold, s, x)
3232import qualified Turtle
3333
34+echoT :: Text -> IO ()
35+echoT = Turtle.printf (Turtle.s % "\n")
36+
3437packageFile :: Path.FilePath
3538packageFile = "psc-package.json"
3639
@@ -56,12 +59,12 @@ readPackageFile :: IO PackageConfig
5659readPackageFile = do
5760 exists <- testfile packageFile
5861 unless exists $ do
59− echo "psc-package.json does not exist"
62+ echoT "psc-package.json does not exist"
6063 exit (ExitFailure 1)
6164 mpkg <- Aeson.decodeStrict . encodeUtf8 <$> readTextFile packageFile
6265 case mpkg of
6366 Nothing -> do
64− echo "Unable to parse psc-package.json"
67+ echoT "Unable to parse psc-package.json"
6568 exit (ExitFailure 1)
6669 Just pkg -> return pkg
6770
@@ -124,13 +127,13 @@ listRemoteTags
124127 :: Text
125128 -- ^ repo
126129 -> Turtle.Shell Text
127−listRemoteTags from =
128− inproc "git"
129− [ "ls-remote"
130− , "-q"
131− , "-t"
132− , from
133− ] empty
130+listRemoteTags from = let gitProc = inproc "git"
131+ [ "ls-remote"
132+ , "-q"
133+ , "-t"
134+ , from
135+ ] empty
136+ in lineToText <$> gitProc
134137
135138getPackageSet :: PackageConfig -> IO ()
136139getPackageSet PackageConfig{ source, set } = do
@@ -143,12 +146,12 @@ readPackageSet PackageConfig{ set } = do
143146 let dbFile = ".psc-package" </> fromText set </> ".set" </> "packages.json"
144147 exists <- testfile dbFile
145148 unless exists $ do
146− echo $ format (fp%" does not exist") dbFile
149+ echoT $ format (fp%" does not exist") dbFile
147150 exit (ExitFailure 1)
148151 mdb <- Aeson.decodeStrict . encodeUtf8 <$> readTextFile dbFile
149152 case mdb of
150153 Nothing -> do
151− echo "Unable to parse packages.json"
154+ echoT "Unable to parse packages.json"
152155 exit (ExitFailure 1)
153156 Just db -> return db
154157
@@ -159,7 +162,7 @@ writePackageSet PackageConfig{ set } =
159162
160163installOrUpdate :: Text -> Text -> PackageInfo -> IO Turtle.FilePath
161164installOrUpdate set pkgName PackageInfo{ repo, version } = do
162− echo ("Updating " <> pkgName)
165+ echoT ("Updating " <> pkgName)
163166 let pkgDir = ".psc-package" </> fromText set </> fromText pkgName </> fromText version
164167 exists <- testdir pkgDir
165168 unless exists . void $ cloneShallow repo version pkgDir
@@ -170,7 +173,7 @@ getTransitiveDeps db depends = do
170173 pkgs <- for depends $ \pkg ->
171174 case Map.lookup pkg db of
172175 Nothing -> do
173− echo ("Package " <> pkg <> " does not exist in package set")
176+ echoT ("Package " <> pkg <> " does not exist in package set")
174177 exit (ExitFailure 1)
175178 Just PackageInfo{ dependencies } -> return (pkg : dependencies)
176179 let unique = Set.toList (foldMap Set.fromList pkgs)
@@ -181,16 +184,16 @@ updateImpl config@PackageConfig{ depends } = do
181184 getPackageSet config
182185 db <- readPackageSet config
183186 trans <- getTransitiveDeps db depends
184− echo ("Updating " <> pack (show (length trans)) <> " packages...")
187+ echoT ("Updating " <> pack (show (length trans)) <> " packages...")
185188 for_ trans $ \(pkgName, pkg) -> installOrUpdate (set config) pkgName pkg
186189
187190initialize :: IO ()
188191initialize = do
189192 exists <- testfile "psc-package.json"
190193 when exists $ do
191− echo "psc-package.json already exists"
194+ echoT "psc-package.json already exists"
192195 exit (ExitFailure 1)
193− echo "Initializing new project in current directory"
196+ echoT "Initializing new project in current directory"
194197 pkgName <- pathToTextUnsafe . Path.filename <$> pwd
195198 let pkg = defaultPackage pkgName
196199 writePackageFile pkg
@@ -200,7 +203,7 @@ update :: IO ()
200203update = do
201204 pkg <- readPackageFile
202205 updateImpl pkg
203− echo "Update complete"
206+ echoT "Update complete"
204207
205208install :: String -> IO ()
206209install pkgName = do
@@ -208,7 +211,7 @@ install pkgName = do
208211 let pkg' = pkg { depends = nub (pack pkgName : depends pkg) }
209212 updateImpl pkg'
210213 writePackageFile pkg'
211− echo "psc-package.json file was updated"
214+ echoT "psc-package.json file was updated"
212215
213216uninstall :: String -> IO ()
214217uninstall pkgName = do
@@ -216,20 +219,20 @@ uninstall pkgName = do
216219 let pkg' = pkg { depends = filter (/= pack pkgName) $ depends pkg }
217220 updateImpl pkg'
218221 writePackageFile pkg'
219− echo "psc-package.json file was updated"
222+ echoT "psc-package.json file was updated"
220223
221224listDependencies :: IO ()
222225listDependencies = do
223226 pkg@PackageConfig{ depends } <- readPackageFile
224227 db <- readPackageSet pkg
225228 trans <- getTransitiveDeps db depends
226− traverse_ (echo . fst) trans
229+ traverse_ (echoT . fst) trans
227230
228231listPackages :: IO ()
229232listPackages = do
230233 pkg <- readPackageFile
231234 db <- readPackageSet pkg
232− traverse_ echo (fmt <$> Map.assocs db)
235+ traverse_ echoT (fmt <$> Map.assocs db)
233236 where
234237 fmt :: (Text, PackageInfo) -> Text
235238 fmt (name, PackageInfo{ version }) = name <> " (" <> version <> ")"
@@ -251,7 +254,7 @@ listSourcePaths = do
251254 pkg@PackageConfig{ depends } <- readPackageFile
252255 db <- readPackageSet pkg
253256 paths <- getSourcePaths pkg db depends
254− traverse_ (echo . pathToTextUnsafe) paths
257+ traverse_ (echoT . pathToTextUnsafe) paths
255258
256259exec :: Text -> IO ()
257260exec exeName = do
@@ -267,11 +270,11 @@ checkForUpdates applyMinorUpdates applyMajorUpdates = do
267270 pkg <- readPackageFile
268271 db <- readPackageSet pkg
269272
270− echo ("Checking " <> pack (show (Map.size db)) <> " packages for updates.")
271− echo "Warning: this could take some time!"
273+ echoT ("Checking " <> pack (show (Map.size db)) <> " packages for updates.")
274+ echoT "Warning: this could take some time!"
272275
273276 newDb <- Map.fromList <$> (for (Map.toList db) $ \(name, p@PackageInfo{ repo, version }) -> do
274− echo ("Checking package " <> name)
277+ echoT ("Checking package " <> name)
275278 tagLines <- Turtle.fold (listRemoteTags repo) Foldl.list
276279 let tags = mapMaybe parseTag tagLines
277280 newVersion <- case parseVersion version of
@@ -280,7 +283,7 @@ checkForUpdates applyMinorUpdates applyMajorUpdates = do
280283 case filter (isMinorReleaseFrom parts) tags of
281284 [] -> pure version
282285 minorReleases -> do
283− echo ("New minor release available")
286+ echoT ("New minor release available")
284287 case applyMinorUpdates of
285288 True -> do
286289 let latestMinorRelease = maximum minorReleases
@@ -290,7 +293,7 @@ checkForUpdates applyMinorUpdates applyMajorUpdates = do
290293 case filter (isMajorReleaseFrom parts) tags of
291294 [] -> applyMinor
292295 newReleases -> do
293− echo ("New major release available")
296+ echoT ("New major release available")
294297 case applyMajorUpdates of
295298 True -> do
296299 let latestRelease = maximum newReleases
@@ -298,7 +301,7 @@ checkForUpdates applyMinorUpdates applyMajorUpdates = do
298301 False -> applyMinor
299302 in applyMajor
300303 _ -> do
301− echo "Unable to parse version string"
304+ echoT "Unable to parse version string"
302305 pure version
303306 pure (name, p { version = newVersion }))
304307
@@ -345,15 +348,15 @@ verifyPackageSet = do
345348 pkg <- readPackageFile
346349 db <- readPackageSet pkg
347350
348− echo ("Verifying " <> pack (show (Map.size db)) <> " packages.")
349− echo "Warning: this could take some time!"
351+ echoT ("Verifying " <> pack (show (Map.size db)) <> " packages.")
352+ echoT "Warning: this could take some time!"
350353
351354 let installOrUpdate' (name, pkgInfo) = (name, ) <$> installOrUpdate (set pkg) name pkgInfo
352355 paths <- Map.fromList <$> traverse installOrUpdate' (Map.toList db)
353356
354357 for_ (Map.toList db) $ \(name, PackageInfo{..}) -> do
355358 let dirFor = fromMaybe (error "verifyPackageSet: no directory") . (`Map.lookup` paths)
356− echo ("Verifying package " <> name)
359+ echoT ("Verifying package " <> name)
357360 let srcGlobs = map (pathToTextUnsafe . (</> ("src" </> "**" </> "*.purs")) . dirFor) (name : dependencies)
358361 procs "psc" srcGlobs empty
359362
purescript.cabal+8−8
@@ -374,7 +374,7 @@ executable psc
374374 filepath -any,
375375 Glob >= 0.7 && < 0.8,
376376 mtl -any,
377− optparse-applicative >= 0.12.1,
377+ optparse-applicative >= 0.13.0,
378378 parsec -any,
379379 text -any,
380380 time -any,
@@ -401,7 +401,7 @@ executable psci
401401 haskeline >= 0.7.0.0,
402402 http-types == 0.9.*,
403403 mtl -any,
404− optparse-applicative >= 0.12.1,
404+ optparse-applicative >= 0.13.0,
405405 parsec -any,
406406 process -any,
407407 stm >= 0.2.4.0,
@@ -427,7 +427,7 @@ executable psc-docs
427427 filepath -any,
428428 Glob -any,
429429 mtl -any,
430− optparse-applicative >= 0.12.1,
430+ optparse-applicative >= 0.13.0,
431431 process -any,
432432 split -any,
433433 text -any,
@@ -465,7 +465,7 @@ executable psc-package
465465 optparse-applicative -any,
466466 system-filepath -any,
467467 text -any,
468− turtle <1.3
468+ turtle ==1.3.*
469469 main-is: Main.hs
470470 other-modules: Paths_purescript
471471 buildable: True
@@ -479,7 +479,7 @@ executable psc-hierarchy
479479 filepath -any,
480480 Glob -any,
481481 mtl -any,
482− optparse-applicative >= 0.12.1,
482+ optparse-applicative >= 0.13.0,
483483 parsec -any,
484484 process -any,
485485 text -any
@@ -502,7 +502,7 @@ executable psc-bundle
502502 filepath -any,
503503 Glob -any,
504504 mtl -any,
505− optparse-applicative >= 0.12.1,
505+ optparse-applicative >= 0.13.0,
506506 sourcemap >= 0.1.6,
507507 transformers -any,
508508 transformers-compat -any,
@@ -524,7 +524,7 @@ executable psc-ide-server
524524 monad-logger -any,
525525 mtl -any,
526526 network -any,
527− optparse-applicative >= 0.12.1,
527+ optparse-applicative >= 0.13.0,
528528 protolude >= 0.1.6,
529529 stm -any,
530530 text -any,
@@ -541,7 +541,7 @@ executable psc-ide-client
541541 bytestring -any,
542542 mtl -any,
543543 network -any,
544− optparse-applicative >= 0.12.1,
544+ optparse-applicative >= 0.13.0,
545545 text -any
546546 ghc-options: -Wall -O2
547547 hs-source-dirs: psc-ide-client
src/Language/PureScript/AST/Declarations.hs+37−3
@@ -1,4 +1,6 @@
11{-# LANGUAGE TemplateHaskell #-}
2+{-# LANGUAGE DeriveFoldable #-}
3+{-# LANGUAGE DeriveTraversable #-}
24
35-- |
46-- Data types for modules and declarations
@@ -12,7 +14,6 @@ import Control.Monad.Identity
1214import Data.Aeson.TH
1315import qualified Data.Map as M
1416import Data.Text (Text)
15−import Data.List.NonEmpty (NonEmpty(..))
1617
1718import Language.PureScript.AST.Binders
1819import Language.PureScript.AST.Literals
@@ -587,10 +588,10 @@ data Expr
587588 --
588589 | ObjectUpdate Expr [(PSString, Expr)]
589590 -- |
590− -- Object updates with nested support: `x { foo.bar = e }`
591+ -- Object updates with nested support: `x { foo { bar = e } }`
591592 -- Replaced during desugaring into a `Let` and nested `ObjectUpdate`s
592593 --
593− | ObjectUpdateNested Expr [(NonEmpty PSString, Expr)]
594+ | ObjectUpdateNested Expr (PathTree Expr)
594595 -- |
595596 -- Function introduction
596597 --
@@ -706,5 +707,38 @@ data DoNotationElement
706707 | PositionedDoNotationElement SourceSpan [Comment] DoNotationElement
707708 deriving (Show)
708709
710+
711+-- For a record update such as:
712+--
713+-- x { foo = 0
714+-- , bar { baz = 1
715+-- , qux = 2 } }
716+--
717+-- We represent the updates as the `PathTree`:
718+--
719+-- [ ("foo", Leaf 3)
720+-- , ("bar", Branch [ ("baz", Leaf 1)
721+-- , ("qux", Leaf 2) ]) ]
722+--
723+-- Which we then convert to an expression representing the following:
724+--
725+-- let x' = x
726+-- in x' { foo = 0
727+-- , bar = x'.bar { baz = 1
728+-- , qux = 2 } }
729+--
730+-- The `let` here is required to prevent re-evaluating the object expression `x`.
731+-- However we don't generate this when using an anonymous argument for the object.
732+--
733+
734+newtype PathTree t = PathTree (AssocList PSString (PathNode t))
735+ deriving (Show, Eq, Ord, Functor, Foldable, Traversable)
736+
737+data PathNode t = Leaf t | Branch (PathTree t)
738+ deriving (Show, Eq, Ord, Functor, Foldable, Traversable)
739+
740+newtype AssocList k t = AssocList { runAssocList :: [(k, t)] }
741+ deriving (Show, Eq, Ord, Foldable, Functor, Traversable)
742+
709743$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''DeclarationRef)
710744$(deriveJSON (defaultOptions { sumEncoding = ObjectWithSingleField }) ''ImportDeclarationType)
src/Language/PureScript/AST/Traversals.hs+7−7
@@ -48,7 +48,7 @@ everywhereOnValues f g h = (f', g', h')
4848 g' (TypeClassDictionaryConstructorApp name v) = g (TypeClassDictionaryConstructorApp name (g' v))
4949 g' (Accessor prop v) = g (Accessor prop (g' v))
5050 g' (ObjectUpdate obj vs) = g (ObjectUpdate (g' obj) (map (fmap g') vs))
51− g' (ObjectUpdateNested obj vs) = g (ObjectUpdateNested (g' obj) (map (fmap g') vs))
51+ g' (ObjectUpdateNested obj vs) = g (ObjectUpdateNested (g' obj) (fmap g' vs))
5252 g' (Abs name v) = g (Abs name (g' v))
5353 g' (App v1 v2) = g (App (g' v1) (g' v2))
5454 g' (IfThenElse v1 v2 v3) = g (IfThenElse (g' v1) (g' v2) (g' v3))
@@ -116,7 +116,7 @@ everywhereOnValuesTopDownM f g h = (f' <=< f, g' <=< g, h' <=< h)
116116 g' (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> (g v >>= g')
117117 g' (Accessor prop v) = Accessor prop <$> (g v >>= g')
118118 g' (ObjectUpdate obj vs) = ObjectUpdate <$> (g obj >>= g') <*> traverse (sndM (g' <=< g)) vs
119− g' (ObjectUpdateNested obj vs) = ObjectUpdateNested <$> (g obj >>= g') <*> traverse (sndM (g' <=< g)) vs
119+ g' (ObjectUpdateNested obj vs) = ObjectUpdateNested <$> (g obj >>= g') <*> traverse (g' <=< g) vs
120120 g' (Abs name v) = Abs name <$> (g v >>= g')
121121 g' (App v1 v2) = App <$> (g v1 >>= g') <*> (g v2 >>= g')
122122 g' (IfThenElse v1 v2 v3) = IfThenElse <$> (g v1 >>= g') <*> (g v2 >>= g') <*> (g v3 >>= g')
@@ -184,7 +184,7 @@ everywhereOnValuesM f g h = (f', g', h')
184184 g' (TypeClassDictionaryConstructorApp name v) = (TypeClassDictionaryConstructorApp name <$> g' v) >>= g
185185 g' (Accessor prop v) = (Accessor prop <$> g' v) >>= g
186186 g' (ObjectUpdate obj vs) = (ObjectUpdate <$> g' obj <*> traverse (sndM g') vs) >>= g
187− g' (ObjectUpdateNested obj vs) = (ObjectUpdateNested <$> g' obj <*> traverse (sndM g') vs) >>= g
187+ g' (ObjectUpdateNested obj vs) = (ObjectUpdateNested <$> g' obj <*> traverse g' vs) >>= g
188188 g' (Abs name v) = (Abs name <$> g' v) >>= g
189189 g' (App v1 v2) = (App <$> g' v1 <*> g' v2) >>= g
190190 g' (IfThenElse v1 v2 v3) = (IfThenElse <$> g' v1 <*> g' v2 <*> g' v3) >>= g
@@ -257,7 +257,7 @@ everythingOnValues (<>) f g h i j = (f', g', h', i', j')
257257 g' v@(TypeClassDictionaryConstructorApp _ v1) = g v <> g' v1
258258 g' v@(Accessor _ v1) = g v <> g' v1
259259 g' v@(ObjectUpdate obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)
260− g' v@(ObjectUpdateNested obj vs) = foldl (<>) (g v <> g' obj) (map (g' . snd) vs)
260+ g' v@(ObjectUpdateNested obj vs) = foldl (<>) (g v <> g' obj) (fmap g' vs)
261261 g' v@(Abs _ v1) = g v <> g' v1
262262 g' v@(App v1 v2) = g v <> g' v1 <> g' v2
263263 g' v@(IfThenElse v1 v2 v3) = g v <> g' v1 <> g' v2 <> g' v3
@@ -335,7 +335,7 @@ everythingWithContextOnValues s0 r0 (<>) f g h i j = (f'' s0, g'' s0, h'' s0, i'
335335 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
336336 g' s (Accessor _ v1) = g'' s v1
337337 g' s (ObjectUpdate obj vs) = foldl (<>) (g'' s obj) (map (g'' s . snd) vs)
338− g' s (ObjectUpdateNested obj vs) = foldl (<>) (g'' s obj) (map (g'' s . snd) vs)
338+ g' s (ObjectUpdateNested obj vs) = foldl (<>) (g'' s obj) (fmap (g'' s) vs)
339339 g' s (Abs _ v1) = g'' s v1
340340 g' s (App v1 v2) = g'' s v1 <> g'' s v2
341341 g' s (IfThenElse v1 v2 v3) = g'' s v1 <> g'' s v2 <> g'' s v3
@@ -415,7 +415,7 @@ everywhereWithContextOnValuesM s0 f g h i j = (f'' s0, g'' s0, h'' s0, i'' s0, j
415415 g' s (TypeClassDictionaryConstructorApp name v) = TypeClassDictionaryConstructorApp name <$> g'' s v
416416 g' s (Accessor prop v) = Accessor prop <$> g'' s v
417417 g' s (ObjectUpdate obj vs) = ObjectUpdate <$> g'' s obj <*> traverse (sndM (g'' s)) vs
418− g' s (ObjectUpdateNested obj vs) = ObjectUpdateNested <$> g'' s obj <*> traverse (sndM (g'' s)) vs
418+ g' s (ObjectUpdateNested obj vs) = ObjectUpdateNested <$> g'' s obj <*> traverse (g'' s) vs
419419 g' s (Abs name v) = Abs name <$> g'' s v
420420 g' s (App v1 v2) = App <$> g'' s v1 <*> g'' s v2
421421 g' s (IfThenElse v1 v2 v3) = IfThenElse <$> g'' s v1 <*> g'' s v2 <*> g'' s v3
@@ -506,7 +506,7 @@ everythingWithScope f g h i j = (f'', g'', h'', i'', \s -> snd . j'' s)
506506 g' s (TypeClassDictionaryConstructorApp _ v1) = g'' s v1
507507 g' s (Accessor _ v1) = g'' s v1
508508 g' s (ObjectUpdate obj vs) = g'' s obj <> foldMap (g'' s . snd) vs
509− g' s (ObjectUpdateNested obj vs) = g'' s obj <> foldMap (g'' s . snd) vs
509+ g' s (ObjectUpdateNested obj vs) = g'' s obj <> foldMap (g'' s) vs
510510 g' s (Abs (Left name) v1) =
511511 let s' = S.insert name s
512512 in g'' s' v1
src/Language/PureScript/Crash.hs+27−11
@@ -1,11 +1,27 @@
1−module Language.PureScript.Crash where
2−
3−import Prelude.Compat
4−
5−-- | Exit with an error message and a crash report link.
6−internalError :: String -> a
7−internalError =
8− error
9− . ("An internal error occurred during compilation: " ++)
10− . (++ "\nPlease report this at https://github.com/purescript/purescript/issues")
11− . show
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE ImplicitParams #-}
3+
4+module Language.PureScript.Crash where
5+
6+import Prelude.Compat
7+
8+import qualified GHC.Stack
9+
10+-- | A compatibility wrapper for the @GHC.Stack.HasCallStack@ constraint.
11+#if __GLASGOW_HASKELL__ >= 800
12+type HasCallStack = GHC.Stack.HasCallStack
13+#elif MIN_VERSION_GLASGOW_HASKELL(7,10,2,0)
14+type HasCallStack = (?callStack :: GHC.Stack.CallStack)
15+#else
16+import GHC.Exts (Constraint)
17+-- CallStack wasn't present in GHC 7.10.1
18+type HasCallStack = (() :: Constraint)
19+#endif
20+
21+-- | Exit with an error message and a crash report link.
22+internalError :: HasCallStack => String -> a
23+internalError =
24+ error
25+ . ("An internal error occurred during compilation: " ++)
26+ . (++ "\nPlease report this at https://github.com/purescript/purescript/issues")
27+ . show
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+4−4
@@ -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)
@@ -138,9 +138,9 @@ annotateModule (defs, types) decls =
138138 IdeDeclTypeClass tc ->
139139 annotateType (tc ^. ideTCName . properNameT) (IdeDeclTypeClass tc)
140140 IdeDeclValueOperator op ->
141− annotateValue (op ^. ideValueOpAlias & valueOperatorAliasT) (IdeDeclValueOperator op)
141+ annotateValue (op ^. ideValueOpName . opNameT) (IdeDeclValueOperator op)
142142 IdeDeclTypeOperator op ->
143− annotateType (op ^. ideTypeOpAlias & typeOperatorAliasT) (IdeDeclTypeOperator op)
143+ annotateType (op ^. ideTypeOpName . opNameT) (IdeDeclTypeOperator op)
144144 IdeDeclKind i ->
145145 annotateKind (i ^. properNameT) (IdeDeclKind i)
146146 where
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+7−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
@@ -106,6 +105,10 @@ extractSpans ss d = case d of
106105 P.DataDeclaration _ name _ ctors ->
107106 (IdeNSType (P.runProperName name), ss)
108107 : map (\(cname, _) -> (IdeNSValue (P.runProperName cname), ss)) ctors
108+ P.FixityDeclaration (Left (P.ValueFixity _ _ opName)) ->
109+ [(IdeNSValue (P.runOpName opName), ss)]
110+ P.FixityDeclaration (Right (P.TypeFixity _ _ opName)) ->
111+ [(IdeNSType (P.runOpName opName), ss)]
109112 P.ExternDeclaration ident _ ->
110113 [(IdeNSValue (P.runIdent ident), ss)]
111114 P.ExternDataDeclaration name _ ->
src/Language/PureScript/Ide/Types.hs+4−4
@@ -145,7 +145,7 @@ data IdeState = IdeState
145145 { ideStage1 :: Stage1
146146 , ideStage2 :: Stage2
147147 , ideStage3 :: Stage3
148− }
148+ } deriving (Show)
149149
150150emptyIdeState :: IdeState
151151emptyIdeState = IdeState emptyStage1 emptyStage2 emptyStage3
@@ -162,16 +162,16 @@ emptyStage3 = Stage3 M.empty Nothing
162162data Stage1 = Stage1
163163 { s1Externs :: ModuleMap P.ExternsFile
164164 , s1Modules :: ModuleMap (P.Module, FilePath)
165− }
165+ } deriving (Show)
166166
167167data Stage2 = Stage2
168168 { s2AstData :: AstData P.SourceSpan
169− }
169+ } deriving (Show, Eq)
170170
171171data Stage3 = Stage3
172172 { s3Declarations :: ModuleMap [IdeDeclarationAnn]
173173 , s3CachedRebuild :: Maybe (P.ModuleName, P.ExternsFile)
174− }
174+ } deriving (Show)
175175
176176newtype Match a = Match (P.ModuleName, a)
177177 deriving (Show, Eq, Functor)
src/Language/PureScript/Ide/Util.hs+15
@@ -27,6 +27,8 @@ module Language.PureScript.Ide.Util
2727 , prettyTypeT
2828 , properNameT
2929 , identT
30+ , opNameT
31+ , ideReadFile
3032 , module Language.PureScript.Ide.Logging
3133 ) where
3234
@@ -39,8 +41,10 @@ import qualified Data.Text as T
3941import qualified Data.Text.Lazy as TL
4042import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)
4143import qualified Language.PureScript as P
44+import Language.PureScript.Ide.Error
4245import Language.PureScript.Ide.Logging
4346import Language.PureScript.Ide.Types
47+import System.IO.UTF8 (readUTF8FileT)
4448
4549identifierFromIdeDeclaration :: IdeDeclaration -> Text
4650identifierFromIdeDeclaration d = case d of
@@ -123,6 +127,17 @@ properNameT = iso P.runProperName P.ProperName
123127identT :: Iso' P.Ident Text
124128identT = iso P.runIdent P.Ident
125129
130+opNameT :: Iso' (P.OpName a) Text
131+opNameT = iso P.runOpName P.OpName
132+
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+
126141prettyTypeT :: P.Type -> Text
127142prettyTypeT =
128143 T.unwords
src/Language/PureScript/Parser/Declarations.hs+23−13
@@ -17,13 +17,12 @@ import Prelude hiding (lex)
1717
1818import Control.Applicative
1919import Control.Arrow ((+++))
20+import Control.Monad (foldM)
2021import Control.Monad.Error.Class (MonadError(..))
2122import Control.Parallel.Strategies (withStrategy, parList, rseq)
22−import Data.Bifunctor (first)
2323import Data.Functor (($>))
24−import Data.List.NonEmpty (NonEmpty(..))
25−import qualified Data.List.NonEmpty as N
2624import Data.Maybe (fromMaybe)
25+import qualified Data.Set as S
2726import Data.Text (Text)
2827import Language.PureScript.AST
2928import Language.PureScript.Environment
@@ -399,13 +398,17 @@ parseInfixExpr
399398parseHole :: TokenParser Expr
400399parseHole = Hole <$> holeLit
401400
402−parsePropertyUpdate :: TokenParser (NonEmpty PSString, Expr)
401+parsePropertyUpdate :: TokenParser (PSString, PathNode Expr)
403402parsePropertyUpdate = do
404403 name <- parseLabel
405− rest <- P.many (indented *> dot *> indented *> parseLabel)
406− _ <- indented *> equals
407− value <- indented *> parseValue
408− return (name :| rest, value)
404+ updates <- parseShallowUpdate <|> parseNestedUpdate
405+ return (name, updates)
406+ where
407+ parseShallowUpdate :: TokenParser (PathNode Expr)
408+ parseShallowUpdate = Leaf <$> (indented *> equals *> indented *> parseValue)
409+
410+ parseNestedUpdate :: TokenParser (PathNode Expr)
411+ parseNestedUpdate = Branch <$> parseUpdaterBodyFields
409412
410413parseAccessor :: Expr -> TokenParser Expr
411414parseAccessor (Constructor _) = P.unexpected "constructor"
@@ -455,11 +458,18 @@ parseValue = withSourceSpan PositionedValue
455458 ]
456459 ]
457460
458−parseUpdaterBody :: Expr -> TokenParser Expr
459−parseUpdaterBody v = objectUpdate <$> (indented *> braces (commaSep1 (indented *> parsePropertyUpdate)))
461+parseUpdaterBodyFields :: TokenParser (PathTree Expr)
462+parseUpdaterBodyFields = do
463+ updates <- indented *> braces (commaSep1 (indented *> parsePropertyUpdate))
464+ (_, tree) <- foldM insertUpdate (S.empty, []) updates
465+ return (PathTree (AssocList (reverse tree)))
460466 where
461− objectUpdate xs | all (null . N.tail . fst) xs = ObjectUpdate v (map (first N.head) xs)
462− | otherwise = ObjectUpdateNested v xs
467+ insertUpdate (seen, xs) (key, node)
468+ | S.member key seen = P.unexpected ("Duplicate key in record update: " ++ show key)
469+ | otherwise = return (S.insert key seen, (key, node) : xs)
470+
471+parseUpdaterBody :: Expr -> TokenParser Expr
472+parseUpdaterBody v = ObjectUpdateNested v <$> parseUpdaterBodyFields
463473
464474parseAnonymousArgument :: TokenParser Expr
465475parseAnonymousArgument = underscore *> pure AnonymousArgument
@@ -487,7 +497,7 @@ parseArrayBinder = LiteralBinder <$> parseArrayLiteral (indented *> parseBinder)
487497parseVarOrNamedBinder :: TokenParser Binder
488498parseVarOrNamedBinder = do
489499 name <- parseIdent
490− let parseNamedBinder = NamedBinder name <$> (at *> indented *> parseBinderNoParens)
500+ let parseNamedBinder = NamedBinder name <$> (at *> indented *> parseBinderAtom)
491501 parseNamedBinder <|> return (VarBinder name)
492502
493503parseNullBinder :: TokenParser Binder
src/Language/PureScript/Pretty/JS.hs+15−9
@@ -122,22 +122,30 @@ literals = mkPattern' match'
122122 [ return $ emit $ lbl <> ": "
123123 , prettyPrintJS' js
124124 ]
125− match (JSComment _ com js) = fmap mconcat $ sequence $
125+ match (JSComment _ com js) = mconcat <$> sequence
126+ [ mconcat <$> forM com comment
127+ , prettyPrintJS' js
128+ ]
129+ match (JSRaw _ js) = return $ emit js
130+ match _ = mzero
131+
132+ comment :: (Emit gen) => Comment -> StateT PrinterState Maybe gen
133+ comment (LineComment com) = fmap mconcat $ sequence $
134+ [ return $ emit "\n"
135+ , currentIndent
136+ , return $ emit "//" <> emit com <> emit "\n"
137+ ]
138+ comment (BlockComment com) = fmap mconcat $ sequence $
126139 [ return $ emit "\n"
127140 , currentIndent
128141 , return $ emit "/**\n"
129142 ] ++
130− map asLine (concatMap commentLines com) ++
143+ map asLine (T.lines com) ++
131144 [ currentIndent
132145 , return $ emit " */\n"
133146 , currentIndent
134− , prettyPrintJS' js
135147 ]
136148 where
137− commentLines :: Comment -> [Text]
138− commentLines (LineComment s) = [s]
139− commentLines (BlockComment s) = T.lines s
140−
141149 asLine :: (Emit gen) => Text -> StateT PrinterState Maybe gen
142150 asLine s = do
143151 i <- currentIndent
@@ -150,8 +158,6 @@ literals = mkPattern' match'
150158 Nothing -> case T.uncons t of
151159 Just (x, xs) -> x `T.cons` removeComments xs
152160 Nothing -> ""
153− match (JSRaw _ js) = return $ emit js
154− match _ = mzero
155161
156162conditional :: Pattern PrinterState JS ((Maybe SourceSpan, JS, JS), JS)
157163conditional = mkPattern match
src/Language/PureScript/Pretty/Values.hs+8−10
@@ -12,7 +12,6 @@ import Prelude.Compat
1212import Control.Arrow (second)
1313
1414import qualified Data.Monoid as Monoid ((<>))
15−import Data.List.NonEmpty (NonEmpty(..))
1615
1716import qualified Data.Text as T
1817import Data.Text (Text)
@@ -48,11 +47,8 @@ prettyPrintObject d = list '{' '}' prettyPrintObjectProperty
4847 prettyPrintObjectProperty :: (PSString, Maybe Expr) -> Box
4948 prettyPrintObjectProperty (key, value) = textT (prettyPrintObjectKey key Monoid.<> ": ") <> maybe (text "_") (prettyPrintValue (d - 1)) value
5049
51−prettyPrintObjectUpdate :: forall k. (k -> Box) -> Int -> Expr -> [(k, Expr)] -> Box
52−prettyPrintObjectUpdate printKey d o ps =
53− prettyPrintValueAtom (d - 1) o `beforeWithSpace` list '{' '}' printEntry ps
54− where
55− printEntry (key, val) = printKey key <> text " = " <> prettyPrintValue (d - 1) val
50+prettyPrintUpdateEntry :: Int -> PSString -> Expr -> Box
51+prettyPrintUpdateEntry d key val = textT (prettyPrintObjectKey key) <> text " = " <> prettyPrintValue (d - 1) val
5652
5753-- | Pretty-print an expression
5854prettyPrintValue :: Int -> Expr -> Box
@@ -63,10 +59,12 @@ prettyPrintValue d (IfThenElse cond th el) =
6359 , text "else " <> prettyPrintValueAtom (d - 1) el
6460 ])
6561prettyPrintValue d (Accessor prop val) = prettyPrintValueAtom (d - 1) val `before` textT ("." Monoid.<> prettyPrintObjectKey prop)
66−prettyPrintValue d (ObjectUpdate o ps) = prettyPrintObjectUpdate (textT . prettyPrintObjectKey) d o ps
67−prettyPrintValue d (ObjectUpdateNested o ps) = prettyPrintObjectUpdate printPath d o ps where
68− printPath (hd :| tl) = foldl combine (textT (prettyPrintObjectKey hd)) tl
69− combine acc key = acc <> textT ("." Monoid.<> prettyPrintObjectKey key)
62+prettyPrintValue d (ObjectUpdate o ps) = prettyPrintValueAtom (d - 1) o `beforeWithSpace` list '{' '}' (uncurry (prettyPrintUpdateEntry d)) ps
63+prettyPrintValue d (ObjectUpdateNested o ps) = prettyPrintValueAtom (d - 1) o `beforeWithSpace` prettyPrintUpdate ps
64+ where
65+ prettyPrintUpdate (PathTree tree) = list '{' '}' printNode (runAssocList tree)
66+ printNode (key, Leaf val) = prettyPrintUpdateEntry d key val
67+ printNode (key, Branch val) = textT (prettyPrintObjectKey key) `beforeWithSpace` prettyPrintUpdate val
7068prettyPrintValue d (App val arg) = prettyPrintValueAtom (d - 1) val `beforeWithSpace` prettyPrintValueAtom (d - 1) arg
7169prettyPrintValue d (Abs (Left arg) val) = text ('\\' : T.unpack (showIdent arg) ++ " -> ") // moveRight 2 (prettyPrintValue (d - 1) val)
7270prettyPrintValue d (Abs (Right arg) val) = text ('\\' : T.unpack (prettyPrintBinder arg) ++ " -> ") // moveRight 2 (prettyPrintValue (d - 1) val)
src/Language/PureScript/Sugar/ObjectWildcards.hs+26−88
@@ -5,46 +5,18 @@ module Language.PureScript.Sugar.ObjectWildcards
55
66import Prelude.Compat
77
8−import Control.Monad (forM, foldM)
8+import Control.Monad (forM)
99import Control.Monad.Error.Class (MonadError(..))
1010import Control.Monad.Supply.Class
11−import Data.List (partition)
12−import Data.List.NonEmpty (NonEmpty(..))
13−import Data.Map (Map)
14−import qualified Data.Map as M
11+import Data.Foldable (toList)
12+import Data.List (foldl')
1513import Data.Maybe (catMaybes)
1614import Language.PureScript.AST
1715import Language.PureScript.Environment (NameKind(..))
1816import Language.PureScript.Errors
19−import Language.PureScript.Label (Label(..))
2017import Language.PureScript.Names
2118import Language.PureScript.PSString (PSString)
2219
23−-- `PathNode` and `PathTree` are used as an intermediate form when desugaring a nested object update.
24−-- For an update such as:
25−--
26−-- x { foo = 0
27−-- , bar.baz = 1
28−-- , bar.qux = 2 }
29−--
30−-- We represent the updates as the `PathTree`:
31−--
32−-- M.fromList [ ("foo", Leaf 3)
33−-- , ("bar", Branch (M.fromList [ ("baz", Leaf 1)
34−-- , ("qux", Leaf 2) ]) ])
35−--
36−-- Which we then convert to an expression representing the following:
37−--
38−-- let x' = x
39−-- in x' { foo = 0
40−-- , bar = x'.bar { baz = 1
41−-- , qux = 2 } }
42−--
43−-- The `let` here is required to prevent re-evaluating the object expression `x`.
44−-- However we don't generate this when using an anonymous argument for the object.
45−--
46−type PathTree = Map PSString PathNode
47−data PathNode = Leaf Expr | Branch PathTree
4820
4921desugarObjectConstructors
5022 :: forall m
@@ -70,11 +42,7 @@ desugarDecl other = fn other
7042 , BinaryNoParens op u val <- b'
7143 , isAnonymousArgument u = do arg <- freshIdent'
7244 return $ Abs (Left arg) $ App (App op (Var (Qualified Nothing arg))) val
73− desugarExpr (Literal (ObjectLiteral ps)) = wrapLambda (Literal . ObjectLiteral) ps
74− desugarExpr (ObjectUpdate u ps) | isAnonymousArgument u = do
75− obj <- freshIdent'
76− Abs (Left obj) <$> wrapLambda (ObjectUpdate (argToExpr obj)) ps
77− desugarExpr (ObjectUpdate obj ps) = wrapLambda (ObjectUpdate obj) ps
45+ desugarExpr (Literal (ObjectLiteral ps)) = wrapLambdaAssoc (Literal . ObjectLiteral) ps
7846 desugarExpr (ObjectUpdateNested obj ps) = transformNestedUpdate obj ps
7947 desugarExpr (Accessor prop u)
8048 | Just props <- peelAnonAccessorChain u = do
@@ -92,67 +60,42 @@ desugarDecl other = fn other
9260 return $ foldr (Abs . Left) if_ (catMaybes [u', t', f'])
9361 desugarExpr e = return e
9462
95− transformNestedUpdate :: Expr -> [(NonEmpty PSString, Expr)] -> m Expr
63+ transformNestedUpdate :: Expr -> PathTree Expr -> m Expr
9664 transformNestedUpdate obj ps = do
9765 -- If we don't have an anonymous argument then we need to generate a let wrapper
9866 -- so that the object expression isn't re-evaluated for each nested update.
9967 val <- freshIdent'
68+ let valExpr = argToExpr val
10069 if isAnonymousArgument obj
101− then Abs (Left val) <$> wrapLambdaM (build val) ps
102− else wrapLambdaM (fmap (buildLet val) . build val) ps
70+ then Abs (Left val) <$> wrapLambda (buildUpdates valExpr) ps
71+ else wrapLambda (buildLet val . buildUpdates valExpr) ps
10372 where
104− build val xs = buildUpdates (argToExpr val) <$> foldM buildTree M.empty xs
10573 buildLet val = Let [ValueDeclaration val Public [] (Right obj)]
10674
107− -- Here we build up the intermediate `PathTree` data structure and check that
108− -- the paths are valid relative to each other - for example, the update
109− -- `{ foo.bar = 2, foo = {bar: 3} }` is invalid because there are conflicting
110− -- paths.
111− buildTree
112− :: PathTree
113− -> (NonEmpty PSString, Expr)
114− -> m PathTree
115− buildTree pathTree (path, e) = go pathTree path where
116− go tree (key :| [])
117− -- path already exists
118− | key `M.member` tree = throwError . errorMessage $ DuplicateLabel (Label key) (Just (ObjectUpdateNested obj ps))
119− -- create new path
120− | otherwise = return (M.insert key (Leaf e) tree)
121− go tree (key :| (x : xs)) = do
122− branch <- case M.lookup key tree of
123− -- nothing at this path yet
124− Nothing -> return M.empty
125− -- already a map at this path
126− Just (Branch branch) -> return branch
127− -- sub-path already exists
128− Just (Leaf _) -> throwError . errorMessage $ DuplicateLabel (Label key) (Just (ObjectUpdateNested obj ps))
129− M.insert key . Branch <$> go branch (x :| xs) <*> pure tree
130−
131− -- Now we have a valid collection of updates in the form of a `PathTree`
132− -- we can recursively build up the nested `ObjectUpdate` expressions.
133− buildUpdates :: Expr -> PathTree -> Expr
134− buildUpdates val vs = ObjectUpdate val (goLayer [] <$> M.toList vs) where
135− goLayer :: [PSString] -> (PSString, PathNode) -> (PSString, Expr)
75+ -- recursively build up the nested `ObjectUpdate` expressions
76+ buildUpdates :: Expr -> PathTree Expr -> Expr
77+ buildUpdates val (PathTree vs) = ObjectUpdate val (goLayer [] <$> runAssocList vs) where
78+ goLayer :: [PSString] -> (PSString, PathNode Expr) -> (PSString, Expr)
13679 goLayer _ (key, Leaf expr) = (key, expr)
137− goLayer path (key, Branch branch) =
80+ goLayer path (key, Branch (PathTree branch)) =
13881 let path' = path ++ [key]
139− updates = goLayer path' <$> M.toList branch
140− accessor = foldr Accessor val path'
82+ updates = goLayer path' <$> runAssocList branch
83+ accessor = foldl' (flip Accessor) val path'
14184 objectUpdate = ObjectUpdate accessor updates
14285 in (key, objectUpdate)
14386
144− wrapLambdaM :: forall k. ([(k, Expr)] -> m Expr) -> [(k, Expr)] -> m Expr
145− wrapLambdaM mkVal ps =
146− let (args, props) = partition (isAnonymousArgument . snd) ps
147− in if null args
148− then mkVal props
149− else do
150− (args', ps') <- unzip <$> mapM mkProp ps
151− val <- mkVal ps'
152− return $ foldr (Abs . Left) val (catMaybes args')
87+ wrapLambda :: forall t. Traversable t => (t Expr -> Expr) -> t Expr -> m Expr
88+ wrapLambda mkVal ps = do
89+ args <- traverse processExpr ps
90+ return $ foldr (Abs . Left) (mkVal (snd <$> args)) (catMaybes $ toList (fst <$> args))
91+ where
92+ processExpr :: Expr -> m (Maybe Ident, Expr)
93+ processExpr e = do
94+ arg <- freshIfAnon e
95+ return (arg, maybe e argToExpr arg)
15396
154− wrapLambda :: forall k. ([(k, Expr)] -> Expr) -> [(k, Expr)] -> m Expr
155− wrapLambda mkVal = wrapLambdaM (return . mkVal)
97+ wrapLambdaAssoc :: ([(PSString, Expr)] -> Expr) -> [(PSString, Expr)] -> m Expr
98+ wrapLambdaAssoc mkVal = wrapLambda (mkVal . runAssocList) . AssocList
15699
157100 stripPositionInfo :: Expr -> Expr
158101 stripPositionInfo (PositionedValue _ _ e) = stripPositionInfo e
@@ -169,11 +112,6 @@ desugarDecl other = fn other
169112 isAnonymousArgument (PositionedValue _ _ e) = isAnonymousArgument e
170113 isAnonymousArgument _ = False
171114
172− mkProp :: forall k. (k, Expr) -> m (Maybe Ident, (k, Expr))
173− mkProp (name, e) = do
174− arg <- freshIfAnon e
175− return (arg, (name, maybe e argToExpr arg))
176−
177115 freshIfAnon :: Expr -> m (Maybe Ident)
178116 freshIfAnon u
179117 | isAnonymousArgument u = Just <$> freshIdent'
stack-ghc-8.0.yaml+2
@@ -6,3 +6,5 @@ extra-deps:
66- wai-websockets-3.0.0.9
77- websockets-0.9.6.2
88- bower-json-1.0.0.1
9+- turtle-1.3.1
10+- optparse-applicative-0.13.0.0
stack.yaml+2
@@ -3,3 +3,5 @@ packages:
33- '.'
44extra-deps:
55- bower-json-1.0.0.1
6+- turtle-1.3.1
7+- optparse-applicative-0.13.0.0
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/SourceFileSpec.hs+28−2
@@ -16,7 +16,7 @@ span0 = P.SourceSpan "ModuleLevel" (P.SourcePos 0 0) (P.SourcePos 1 1)
1616span1 = P.SourceSpan "" (P.SourcePos 1 1) (P.SourcePos 2 2)
1717span2 = P.SourceSpan "" (P.SourcePos 2 2) (P.SourcePos 3 3)
1818
19−typeAnnotation1, value1, synonym1, class1, class2, data1, data2, foreign1, foreign2, foreign3, member1 :: P.Declaration
19+typeAnnotation1, value1, synonym1, class1, class2, data1, data2, valueFixity, typeFixity, foreign1, foreign2, foreign3, member1 :: P.Declaration
2020typeAnnotation1 = P.TypeDeclaration (P.Ident "value1") P.REmpty
2121value1 = P.ValueDeclaration (P.Ident "value1") P.Public [] (Left [])
2222synonym1 = P.TypeSynonymDeclaration (P.ProperName "Synonym1") [] P.REmpty
@@ -25,6 +25,16 @@ class2 = P.TypeClassDeclaration (P.ProperName "Class2") [] [] []
2525 [P.PositionedDeclaration span2 [] member1]
2626data1 = P.DataDeclaration P.Newtype (P.ProperName "Data1") [] []
2727data2 = P.DataDeclaration P.Data (P.ProperName "Data2") [] [(P.ProperName "Cons1", [])]
28+valueFixity =
29+ P.ValueFixityDeclaration
30+ (P.Fixity P.Infix 0)
31+ (P.Qualified Nothing (Left (P.Ident "")))
32+ (P.OpName "<$>")
33+typeFixity =
34+ P.TypeFixityDeclaration
35+ (P.Fixity P.Infix 0)
36+ (P.Qualified Nothing (P.ProperName ""))
37+ (P.OpName "~>")
2838foreign1 = P.ExternDeclaration (P.Ident "foreign1") P.REmpty
2939foreign2 = P.ExternDataDeclaration (P.ProperName "Foreign2") P.kindType
3040foreign3 = P.ExternKindDeclaration (P.ProperName "Foreign3")
@@ -45,6 +55,10 @@ spec = do
4555 extractSpans span0 (P.PositionedDeclaration span1 [] data1) `shouldBe` [(IdeNSType "Data1", span1)]
4656 it "extracts spans for a data declaration and its constructors" $
4757 extractSpans span0 (P.PositionedDeclaration span1 [] data2) `shouldBe` [(IdeNSType "Data2", span1), (IdeNSValue "Cons1", span1)]
58+ it "extracts a span for a value operator fixity declaration" $
59+ extractSpans span0 (P.PositionedDeclaration span1 [] valueFixity) `shouldBe` [(IdeNSValue "<$>", span1)]
60+ it "extracts a span for a type operator fixity declaration" $
61+ extractSpans span0 (P.PositionedDeclaration span1 [] typeFixity) `shouldBe` [(IdeNSType "~>", span1)]
4862 it "extracts a span for a foreign declaration" $
4963 extractSpans span0 (P.PositionedDeclaration span1 [] foreign1) `shouldBe` [(IdeNSValue "foreign1", span1)]
5064 it "extracts a span for a data foreign declaration" $
@@ -67,6 +81,12 @@ spec = do
6781 it "finds a class declaration" $ do
6882 Just r <- getLocation "SFClass"
6983 r `shouldBe` classSS
84+ it "finds a value operator declaration" $ do
85+ Just r <- getLocation "<$>"
86+ r `shouldBe` valueOpSS
87+ it "finds a type operator declaration" $ do
88+ Just r <- getLocation "~>"
89+ r `shouldBe` typeOpSS
7090
7191getLocation :: Text -> IO (Maybe P.SourceSpan)
7292getLocation s = do
@@ -83,14 +103,20 @@ getLocation s = do
83103 , ideDtor "SFTwo" "SFData" Nothing `annLoc` typeSS
84104 , ideDtor "SFThree" "SFData" Nothing `annLoc` typeSS
85105 , ideTypeClass "SFClass" [] `annLoc` classSS
106+ , ideValueOp "<$>" (P.Qualified Nothing (Left "")) 0 Nothing Nothing
107+ `annLoc` valueOpSS
108+ , ideTypeOp "~>" (P.Qualified Nothing "") 0 Nothing Nothing
109+ `annLoc` typeOpSS
86110 ])
87111 ]
88112
89−valueSS, synonymSS, typeSS, classSS :: P.SourceSpan
113+valueSS, synonymSS, typeSS, classSS, valueOpSS, typeOpSS :: P.SourceSpan
90114valueSS = ss 3 1
91115synonymSS = ss 5 1
92116typeSS = ss 7 1
93117classSS = ss 8 1
118+valueOpSS = ss 12 1
119+typeOpSS = ss 13 1
94120
95121ss :: Int -> Int -> P.SourceSpan
96122ss x y = P.SourceSpan "Test.purs" (P.SourcePos x y) (P.SourcePos x y)
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
tests/support/pscide/src/SourceFileSpec.pursdeleted−10
@@ -1,10 +0,0 @@
1−module SourceFileSpec where
2−
3−sfValue = "sfValue"
4−
5−type SFType = String
6−
7−data SFData = SFOne | SFTwo | SFThree
8−
9−class SFClass a where
10− sfShow :: a -> String