Skip to content

Commit 2f48e37

Browse files
authored
Merge branch 'master' into patch-2
2 parents fc33654 + 98e9fb9 commit 2f48e37

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2792
-601
lines changed

builder/src/Build.hs

Lines changed: 156 additions & 100 deletions
Large diffs are not rendered by default.

builder/src/Elm/Details.hs

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{-# LANGUAGE BangPatterns, OverloadedStrings #-}
33
module Elm.Details
44
( Details(..)
5+
, BuildID
56
, ValidOutline(..)
67
, Local(..)
78
, Foreign(..)
@@ -15,7 +16,7 @@ module Elm.Details
1516

1617
import Control.Concurrent (forkIO)
1718
import Control.Concurrent.MVar (MVar, newEmptyMVar, newMVar, putMVar, readMVar, takeMVar)
18-
import Control.Monad (liftM, liftM2, liftM3, liftM4)
19+
import Control.Monad (liftM, liftM2, liftM3)
1920
import Data.Binary (Binary, get, put, getWord8, putWord8)
2021
import qualified Data.Either as Either
2122
import qualified Data.Map as Map
@@ -27,6 +28,7 @@ import qualified Data.NonEmptyList as NE
2728
import qualified Data.OneOrMore as OneOrMore
2829
import qualified Data.Set as Set
2930
import qualified Data.Utf8 as Utf8
31+
import Data.Word (Word64)
3032
import qualified System.Directory as Dir
3133
import System.FilePath ((</>), (<.>))
3234

@@ -66,23 +68,42 @@ data Details =
6668
Details
6769
{ _outlineTime :: File.Time
6870
, _outline :: ValidOutline
71+
, _buildID :: BuildID
6972
, _locals :: Map.Map ModuleName.Raw Local
7073
, _foreigns :: Map.Map ModuleName.Raw Foreign
7174
, _extras :: Extras
7275
}
7376

7477

78+
type BuildID = Word64
79+
80+
7581
data ValidOutline
7682
= ValidApp (NE.List FilePath)
7783
| ValidPkg Pkg.Name [ModuleName.Raw] (Map.Map Pkg.Name V.Version {- for docs in reactor -})
7884

7985

86+
-- NOTE: we need two ways to detect if a file must be recompiled:
87+
--
88+
-- (1) _time is the modification time from the last time we compiled the file.
89+
-- By checking EQUALITY with the current modification time, we can detect file
90+
-- saves and `git checkout` of previous versions. Both need a recompile.
91+
--
92+
-- (2) _lastChange is the BuildID from the last time a new interface file was
93+
-- generated, and _lastCompile is the BuildID from the last time the file was
94+
-- compiled. These may be different if a file is recompiled but the interface
95+
-- stayed the same. When the _lastCompile is LESS THAN the _lastChange of any
96+
-- imports, we need to recompile. This can happen when a project has multiple
97+
-- entrypoints and some modules are compiled less often than their imports.
98+
--
8099
data Local =
81100
Local
82101
{ _path :: FilePath
83102
, _time :: File.Time
84103
, _deps :: [ModuleName.Raw]
85104
, _main :: Bool
105+
, _lastChange :: BuildID
106+
, _lastCompile :: BuildID
86107
}
87108

88109

@@ -104,14 +125,14 @@ type Interfaces =
104125

105126

106127
loadObjects :: FilePath -> Details -> IO (MVar (Maybe Opt.GlobalGraph))
107-
loadObjects root (Details _ _ _ _ extras) =
128+
loadObjects root (Details _ _ _ _ _ extras) =
108129
case extras of
109130
ArtifactsFresh _ o -> newMVar (Just o)
110131
ArtifactsCached -> fork (File.readBinary (Stuff.objects root))
111132

112133

113134
loadInterfaces :: FilePath -> Details -> IO (MVar (Maybe Interfaces))
114-
loadInterfaces root (Details _ _ _ _ extras) =
135+
loadInterfaces root (Details _ _ _ _ _ extras) =
115136
case extras of
116137
ArtifactsFresh i _ -> newMVar (Just i)
117138
ArtifactsCached -> fork (File.readBinary (Stuff.interfaces root))
@@ -143,9 +164,9 @@ load style scope root =
143164
Nothing ->
144165
generate style scope root newTime
145166

146-
Just details@(Details oldTime _ _ _ _) ->
167+
Just details@(Details oldTime _ buildID _ _ _) ->
147168
if oldTime == newTime
148-
then return (Right details)
169+
then return (Right details { _buildID = buildID + 1 })
149170
else generate style scope root newTime
150171

151172

@@ -309,8 +330,8 @@ verifyDependencies env@(Env key scope root cache _ _ _) time outline solution di
309330
let
310331
objs = Map.foldr addObjects Opt.empty artifacts
311332
ifaces = Map.foldrWithKey (addInterfaces directDeps) Map.empty artifacts
312-
foreigns = Map.map (OneOrMore.destruct Foreign) $ Map.foldrWithKey gatherForeigns Map.empty artifacts
313-
details = Details time outline Map.empty foreigns (ArtifactsFresh ifaces objs)
333+
foreigns = Map.map (OneOrMore.destruct Foreign) $ Map.foldrWithKey gatherForeigns Map.empty $ Map.intersection artifacts directDeps
334+
details = Details time outline 0 Map.empty foreigns (ArtifactsFresh ifaces objs)
314335
in
315336
do BW.writeBinary scope (Stuff.objects root) objs
316337
BW.writeBinary scope (Stuff.interfaces root) ifaces
@@ -574,7 +595,7 @@ crawlModule foreignDeps mvar pkg src docsStatus name =
574595
crawlFile :: Map.Map ModuleName.Raw ForeignInterface -> MVar StatusDict -> Pkg.Name -> FilePath -> DocsStatus -> ModuleName.Raw -> FilePath -> IO (Maybe Status)
575596
crawlFile foreignDeps mvar pkg src docsStatus expectedName path =
576597
do bytes <- File.readUtf8 path
577-
case Parse.fromByteString pkg bytes of
598+
case Parse.fromByteString (Parse.Package pkg) bytes of
578599
Right modul@(Src.Module (Just (A.At _ actualName)) _ _ imports _ _ _ _ _) | expectedName == actualName ->
579600
do deps <- crawlImports foreignDeps mvar pkg src imports
580601
return (Just (SLocal docsStatus deps modul))
@@ -761,8 +782,14 @@ endpointDecoder =
761782

762783

763784
instance Binary Details where
764-
get = do { a <- get; b <- get; c <- get; d <- get; return (Details a b c d ArtifactsCached) }
765-
put (Details a b c d _) = put a >> put b >> put c >> put d
785+
put (Details a b c d e _) = put a >> put b >> put c >> put d >> put e
786+
get =
787+
do a <- get
788+
b <- get
789+
c <- get
790+
d <- get
791+
e <- get
792+
return (Details a b c d e ArtifactsCached)
766793

767794

768795
instance Binary ValidOutline where
@@ -780,8 +807,15 @@ instance Binary ValidOutline where
780807

781808

782809
instance Binary Local where
783-
get = liftM4 Local get get get get
784-
put (Local a b c d) = put a >> put b >> put c >> put d
810+
put (Local a b c d e f) = put a >> put b >> put c >> put d >> put e >> put f
811+
get =
812+
do a <- get
813+
b <- get
814+
c <- get
815+
d <- get
816+
e <- get
817+
f <- get
818+
return (Local a b c d e f)
785819

786820

787821
instance Binary Foreign where

builder/src/File.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,11 @@ writeEntry destination root entry =
190190
let
191191
path = drop root (Zip.eRelativePath entry)
192192
in
193-
if path == "LICENSE" || List.isPrefixOf "src/" path then
193+
if List.isPrefixOf "src/" path
194+
|| path == "LICENSE"
195+
|| path == "README.md"
196+
|| path == "elm.json"
197+
then
194198
if not (null path) && last path == '/'
195199
then Dir.createDirectoryIfMissing True (destination </> path)
196200
else LBS.writeFile (destination </> path) (Zip.fromEntry entry)

builder/src/Reporting/Exit.hs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ module Reporting.Exit
3131

3232

3333
import qualified Data.ByteString as BS
34-
import qualified Data.ByteString.Builder as B
35-
import qualified Data.ByteString.Char8 as BSC
36-
import qualified Data.ByteString.Lazy as LBS
3734
import qualified Data.ByteString.UTF8 as BS_UTF8
3835
import qualified Data.List as List
3936
import qualified Data.Map as Map
@@ -178,7 +175,7 @@ diffToReport diff =
178175
\ with packages. That way there are previously published versions of the API to\
179176
\ diff against!"
180177
[ D.reflow $ "If you are just curious to see a diff, try running this command:"
181-
, D.indent 4 $ D.dullyellow $ "elm diff elm/http 1.0.0 2.0.0"
178+
, D.indent 4 $ D.dullyellow $ "elm diff elm/json 1.0.0 1.1.2"
182179
]
183180

184181
DiffNoExposed ->
@@ -751,7 +748,7 @@ data Install
751748
| InstallHadSolverTrouble Solver
752749
| InstallUnknownPackageOnline Pkg.Name [Pkg.Name]
753750
| InstallUnknownPackageOffline Pkg.Name [Pkg.Name]
754-
| InstallHasBadDetails Pkg.Name Encode.Value
751+
| InstallBadDetails Details
755752

756753

757754
installToReport :: Install -> Help.Report
@@ -895,20 +892,8 @@ installToReport exit =
895892
, D.reflow $ "Maybe you want one of these instead?"
896893
]
897894

898-
InstallHasBadDetails pkg outline ->
899-
Help.report "INSTALL PROBLEM" Nothing
900-
(
901-
"I found a version of " ++ Pkg.toChars pkg ++ " that claims to be compatible with\
902-
\ your existing dependencies, but I ran into an error when I tried to build it locally."
903-
)
904-
[ D.reflow $
905-
"Here is an elm.json that should reproduce the error with a bit more information:"
906-
, D.indent 4 $ D.dullyellow $ D.vcat $ map D.fromChars $
907-
map BS_UTF8.toString $ BSC.lines $ LBS.toStrict $ B.toLazyByteString $
908-
Encode.encode outline
909-
, D.reflow $
910-
"Maybe that can help figure out what is going on here."
911-
]
895+
InstallBadDetails details ->
896+
toDetailsReport details
912897

913898

914899

@@ -1168,10 +1153,16 @@ toOutlineProblemReport path source _ region problem =
11681153
toSnippet "HEADER TOO LONG" Nothing
11691154
( D.reflow $
11701155
"I got stuck while reading your elm.json file. This section header is too long:"
1171-
, D.fillSep
1172-
["I","need","it","to","be"
1173-
,D.green "under",D.green "20",D.green "characters"
1174-
,"so","it","renders","nicely","on","the","package","website!"
1156+
, D.stack
1157+
[ D.fillSep
1158+
["I","need","it","to","be"
1159+
,D.green "under",D.green "20",D.green "bytes"
1160+
,"so","it","renders","nicely","on","the","package","website!"
1161+
]
1162+
, D.toSimpleNote
1163+
"I count the length in bytes, so using non-ASCII characters costs extra.\
1164+
\ Please report your case at https://github.com/elm/compiler/issues if this seems\
1165+
\ overly restrictive for your needs."
11751166
]
11761167
)
11771168

@@ -1216,10 +1207,16 @@ toOutlineProblemReport path source _ region problem =
12161207
toSnippet "SUMMARY TOO LONG" Nothing
12171208
( D.reflow $
12181209
"I got stuck while reading your elm.json file. Your \"summary\" is too long:"
1219-
, D.fillSep
1220-
["I","need","it","to","be"
1221-
,D.green "under",D.green "80",D.green "characters"
1222-
,"so","it","renders","nicely","on","the","package","website!"
1210+
, D.stack
1211+
[ D.fillSep
1212+
["I","need","it","to","be"
1213+
,D.green "under",D.green "80",D.green "bytes"
1214+
,"so","it","renders","nicely","on","the","package","website!"
1215+
]
1216+
, D.toSimpleNote
1217+
"I count the length in bytes, so using non-ASCII characters costs extra.\
1218+
\ Please report your case at https://github.com/elm/compiler/issues if this seems\
1219+
\ overly restrictive for your needs."
12231220
]
12241221
)
12251222

@@ -1334,7 +1331,7 @@ toDetailsReport details =
13341331
"I need the list of published packages to verify your dependencies"
13351332

13361333
DetailsBadDeps cacheDir deps ->
1337-
case deps of
1334+
case List.sortOn toBadDepRank deps of
13381335
[] ->
13391336
Help.report "PROBLEM BUILDING DEPENDENCIES" Nothing
13401337
"I am not sure what is going wrong though."
@@ -1374,6 +1371,13 @@ toDetailsReport details =
13741371
]
13751372

13761373

1374+
toBadDepRank :: DetailsBadDep -> Int -- lower is better
1375+
toBadDepRank badDep =
1376+
case badDep of
1377+
BD_BadDownload _ _ _ -> 0
1378+
BD_BadBuild _ _ _ -> 1
1379+
1380+
13771381

13781382
-- PACKAGE PROBLEM
13791383

builder/src/Stuff.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ prepublishDir root =
6262

6363
compilerVersion :: FilePath
6464
compilerVersion =
65-
V.toChars V.compiler ++ "-alpha-1"
65+
V.toChars V.compiler ++ "-alpha-4"
6666

6767

6868

compiler/src/AST/Utils/Shader.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,11 @@ escape chars =
7474
[]
7575

7676
c:cs
77+
| c == '\r' -> escape cs
7778
| c == '\n' -> '\\' : 'n' : escape cs
7879
| c == '\"' -> '\\' : '"' : escape cs
7980
| c == '\'' -> '\\' : '\'' : escape cs
81+
| c == '\\' -> '\\' : '\\' : escape cs
8082
| otherwise -> c : escape cs
8183

8284

compiler/src/Data/Name.hs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -288,42 +288,51 @@ fromTypeVariableScheme scheme =
288288

289289

290290
-- FROM MANY NAMES
291+
--
292+
-- Creating a unique name by combining all the subnames can create names
293+
-- longer than 256 bytes relatively easily. So instead, the first given name
294+
-- (e.g. foo) is prefixed chars that are valid in JS but not Elm (e.g. _M$foo)
295+
--
296+
-- This should be a unique name since 0.19 disallows shadowing. It would not
297+
-- be possible for multiple top-level cycles to include values with the same
298+
-- name, so the important thing is to make the cycle name distinct from the
299+
-- normal name. Same logic for destructuring patterns like (x,y)
291300

292301

293302
fromManyNames :: [Name] -> Name
294303
fromManyNames names =
295-
let
296-
!(I# size#) = sum (map (\(Utf8.Utf8 ba#) -> I# (sizeofByteArray# ba# +# 1#)) names)
297-
in
298-
runST
299-
(
300-
ST $ \s ->
301-
case newByteArray# size# s of
302-
(# s, mba# #) ->
303-
case writeNames mba# 0# names s of
304-
s ->
305-
case unsafeFreezeByteArray# mba# s of
306-
(# s, ba# #) -> (# s, Utf8.Utf8 ba# #)
307-
)
308-
309-
310-
writeNames :: MutableByteArray# s -> Int# -> [Name] -> State# s -> State# s
311-
writeNames mba# !offset# names s =
312304
case names of
313305
[] ->
314-
s
315-
316-
(Utf8.Utf8 ba#) : names ->
317-
case writeWord8Array# mba# offset# 0x24## {- $ -} s of
318-
s ->
319-
let
320-
!offset1# = offset# +# 1#
321-
!len# = sizeofByteArray# ba#
322-
!newOffset# = offset1# +# len#
323-
in
324-
case copyByteArray# ba# 0# mba# offset1# len# s of
325-
s ->
326-
writeNames mba# newOffset# names s
306+
blank
307+
-- this case is needed for (let _ = Debug.log "x" x in ...)
308+
-- but maybe unused patterns should be stripped out instead
309+
310+
Utf8.Utf8 ba# : _ ->
311+
let
312+
len# = sizeofByteArray# ba#
313+
in
314+
runST
315+
(
316+
ST $ \s ->
317+
case newByteArray# (len# +# 3#) s of
318+
(# s, mba# #) ->
319+
case writeWord8Array# mba# 0# 0x5F## {-_-} s of
320+
s ->
321+
case writeWord8Array# mba# 1# 0x4D## {-M-} s of
322+
s ->
323+
case writeWord8Array# mba# 2# 0x24## {-$-} s of
324+
s ->
325+
case copyByteArray# ba# 0# mba# 3# len# s of
326+
s ->
327+
case unsafeFreezeByteArray# mba# s of
328+
(# s, ba# #) -> (# s, Utf8.Utf8 ba# #)
329+
)
330+
331+
332+
{-# NOINLINE blank #-}
333+
blank :: Name
334+
blank =
335+
fromWords [0x5F,0x4D,0x24] {-_M$-}
327336

328337

329338

0 commit comments

Comments
 (0)