@@ -42,6 +42,7 @@ import qualified Elm.Details as Details
42
42
import qualified Elm.Docs as Docs
43
43
import qualified Elm.Interface as I
44
44
import qualified Elm.ModuleName as ModuleName
45
+ import qualified Elm.Outline as Outline
45
46
import qualified Elm.Package as Pkg
46
47
import qualified File
47
48
import qualified Json.Encode as E
@@ -65,21 +66,46 @@ data Env =
65
66
{ _key :: Reporting. BKey
66
67
, _root :: FilePath
67
68
, _project :: Parse. ProjectType
68
- , _srcDirs :: [FilePath ]
69
+ , _srcDirs :: [AbsoluteSrcDir ]
69
70
, _buildID :: Details. BuildID
70
71
, _locals :: Map. Map ModuleName. Raw Details. Local
71
72
, _foreigns :: Map. Map ModuleName. Raw Details. Foreign
72
73
}
73
74
74
75
75
- makeEnv :: Reporting. BKey -> FilePath -> Details. Details -> Env
76
+ makeEnv :: Reporting. BKey -> FilePath -> Details. Details -> IO Env
76
77
makeEnv key root (Details. Details _ validOutline buildID locals foreigns _) =
77
78
case validOutline of
78
- Details. ValidApp srcDirs ->
79
- Env key root Parse. Application (NE. toList srcDirs) buildID locals foreigns
79
+ Details. ValidApp givenSrcDirs ->
80
+ do srcDirs <- traverse (toAbsoluteSrcDir root) (NE. toList givenSrcDirs)
81
+ return $ Env key root Parse. Application srcDirs buildID locals foreigns
80
82
81
83
Details. ValidPkg pkg _ _ ->
82
- Env key root (Parse. Package pkg) [" src" ] buildID locals foreigns
84
+ do srcDir <- toAbsoluteSrcDir root (Outline. RelativeSrcDir " src" )
85
+ return $ Env key root (Parse. Package pkg) [srcDir] buildID locals foreigns
86
+
87
+
88
+
89
+ -- SOURCE DIRECTORY
90
+
91
+
92
+ newtype AbsoluteSrcDir =
93
+ AbsoluteSrcDir FilePath
94
+
95
+
96
+ toAbsoluteSrcDir :: FilePath -> Outline. SrcDir -> IO AbsoluteSrcDir
97
+ toAbsoluteSrcDir root srcDir =
98
+ AbsoluteSrcDir <$> Dir. canonicalizePath
99
+ (
100
+ case srcDir of
101
+ Outline. AbsoluteSrcDir dir -> dir
102
+ Outline. RelativeSrcDir dir -> root </> dir
103
+ )
104
+
105
+
106
+ addRelative :: AbsoluteSrcDir -> FilePath -> FilePath
107
+ addRelative (AbsoluteSrcDir srcDir) path =
108
+ srcDir </> path
83
109
84
110
85
111
@@ -110,7 +136,7 @@ forkWithKey func dict =
110
136
fromExposed :: Reporting. Style -> FilePath -> Details. Details -> DocsGoal docs -> NE. List ModuleName. Raw -> IO (Either Exit. BuildProblem docs )
111
137
fromExposed style root details docsGoal exposed@ (NE. List e es) =
112
138
Reporting. trackBuild style $ \ key ->
113
- do let env = makeEnv key root details
139
+ do env <- makeEnv key root details
114
140
dmvar <- Details. loadInterfaces root details
115
141
116
142
-- crawl
@@ -161,7 +187,7 @@ type Dependencies =
161
187
fromMains :: Reporting. Style -> FilePath -> Details. Details -> NE. List FilePath -> IO (Either Exit. BuildProblem Artifacts )
162
188
fromMains style root details paths =
163
189
Reporting. trackBuild style $ \ key ->
164
- do let env = makeEnv key root details
190
+ do env <- makeEnv key root details
165
191
166
192
elmains <- findMains env paths
167
193
case elmains of
@@ -241,9 +267,8 @@ crawlDeps env mvar deps blockedValue =
241
267
crawlModule :: Env -> MVar StatusDict -> DocsNeed -> ModuleName. Raw -> IO Status
242
268
crawlModule env@ (Env _ root projectType srcDirs buildID locals foreigns) mvar docsNeed name =
243
269
do let fileName = ModuleName. toFilePath name <.> " elm"
244
- let inRoot path = File. exists (root </> path)
245
270
246
- paths <- filterM inRoot (map (</> fileName) srcDirs)
271
+ paths <- filterM File. exists (map (`addRelative` fileName) srcDirs)
247
272
248
273
case paths of
249
274
[path] ->
@@ -263,7 +288,7 @@ crawlModule env@(Env _ root projectType srcDirs buildID locals foreigns) mvar do
263
288
else crawlDeps env mvar deps (SCached local)
264
289
265
290
p1: p2: ps ->
266
- return $ SBadImport $ Import. AmbiguousLocal p1 p2 ps
291
+ return $ SBadImport $ Import. AmbiguousLocal ( FP. makeRelative root p1) ( FP. makeRelative root p2) ( map ( FP. makeRelative root) ps)
267
292
268
293
[] ->
269
294
case Map. lookup name foreigns of
@@ -856,35 +881,33 @@ data ReplArtifacts =
856
881
857
882
fromRepl :: FilePath -> Details. Details -> B. ByteString -> IO (Either Exit. Repl ReplArtifacts )
858
883
fromRepl root details source =
859
- let
860
- env@ (Env _ _ projectType _ _ _ _) = makeEnv Reporting. ignorer root details
861
- in
862
- case Parse. fromByteString projectType source of
863
- Left syntaxError ->
864
- return $ Left $ Exit. ReplBadInput source $ Error. BadSyntax syntaxError
884
+ do env@ (Env _ _ projectType _ _ _ _) <- makeEnv Reporting. ignorer root details
885
+ case Parse. fromByteString projectType source of
886
+ Left syntaxError ->
887
+ return $ Left $ Exit. ReplBadInput source $ Error. BadSyntax syntaxError
865
888
866
- Right modul@ (Src. Module _ _ _ imports _ _ _ _ _) ->
867
- do dmvar <- Details. loadInterfaces root details
889
+ Right modul@ (Src. Module _ _ _ imports _ _ _ _ _) ->
890
+ do dmvar <- Details. loadInterfaces root details
868
891
869
- let deps = map Src. getImportName imports
870
- mvar <- newMVar Map. empty
871
- crawlDeps env mvar deps ()
892
+ let deps = map Src. getImportName imports
893
+ mvar <- newMVar Map. empty
894
+ crawlDeps env mvar deps ()
872
895
873
- statuses <- traverse readMVar =<< readMVar mvar
874
- midpoint <- checkMidpoint dmvar statuses
896
+ statuses <- traverse readMVar =<< readMVar mvar
897
+ midpoint <- checkMidpoint dmvar statuses
875
898
876
- case midpoint of
877
- Left problem ->
878
- return $ Left $ Exit. ReplProjectProblem problem
899
+ case midpoint of
900
+ Left problem ->
901
+ return $ Left $ Exit. ReplProjectProblem problem
879
902
880
- Right foreigns ->
881
- do rmvar <- newEmptyMVar
882
- resultMVars <- forkWithKey (checkModule env foreigns rmvar) statuses
883
- putMVar rmvar resultMVars
884
- results <- traverse readMVar resultMVars
885
- writeDetails root details results
886
- depsStatus <- checkDeps root resultMVars deps 0
887
- finalizeReplArtifacts env source modul depsStatus resultMVars results
903
+ Right foreigns ->
904
+ do rmvar <- newEmptyMVar
905
+ resultMVars <- forkWithKey (checkModule env foreigns rmvar) statuses
906
+ putMVar rmvar resultMVars
907
+ results <- traverse readMVar resultMVars
908
+ writeDetails root details results
909
+ depsStatus <- checkDeps root resultMVars deps 0
910
+ finalizeReplArtifacts env source modul depsStatus resultMVars results
888
911
889
912
890
913
finalizeReplArtifacts :: Env -> B. ByteString -> Src. Module -> DepsStatus -> ResultDict -> Map. Map ModuleName. Raw Result -> IO (Either Exit. Repl ReplArtifacts )
@@ -997,45 +1020,39 @@ findLoc (Env _ root _ srcDirs _ _ _) path absolutePath =
997
1020
return $ Left $ Exit. BP_WithBadExtension path
998
1021
else
999
1022
let
1000
- roots = FP. splitDirectories root
1001
- segments = FP. splitDirectories dirs ++ [final]
1023
+ absoluteSegments = FP. splitDirectories dirs ++ [final]
1002
1024
in
1003
- case dropPrefix roots segments of
1004
- Nothing ->
1025
+ case Maybe. mapMaybe (isInsideSrcDirByPath absoluteSegments) srcDirs of
1026
+ [] ->
1005
1027
return $ Right $ Location absolutePath path (LOutside path)
1006
1028
1007
- Just relativeSegments ->
1008
- case Maybe. mapMaybe (isInsideSrcDirByPath relativeSegments) srcDirs of
1009
- [] ->
1010
- return $ Right $ Location absolutePath path (LOutside path)
1011
-
1012
- [(_, Right names)] ->
1013
- do let name = Name. fromChars (List. intercalate " ." names)
1014
- matchingDirs <- filterM (isInsideSrcDirByName root names) srcDirs
1015
- case matchingDirs of
1016
- d1: d2: _ ->
1017
- do let p1 = d1 </> FP. joinPath names <.> " elm"
1018
- let p2 = d2 </> FP. joinPath names <.> " elm"
1019
- return $ Left $ Exit. BP_MainNameDuplicate name p1 p2
1029
+ [(_, Right names)] ->
1030
+ do let name = Name. fromChars (List. intercalate " ." names)
1031
+ matchingDirs <- filterM (isInsideSrcDirByName names) srcDirs
1032
+ case matchingDirs of
1033
+ d1: d2: _ ->
1034
+ do let p1 = addRelative d1 (FP. joinPath names <.> " elm" )
1035
+ let p2 = addRelative d2 (FP. joinPath names <.> " elm" )
1036
+ return $ Left $ Exit. BP_MainNameDuplicate name p1 p2
1020
1037
1021
- _ ->
1022
- return $ Right $ Location absolutePath path (LInside name)
1038
+ _ ->
1039
+ return $ Right $ Location absolutePath path (LInside name)
1023
1040
1024
- [(s, Left names)] ->
1025
- return $ Left $ Exit. BP_MainNameInvalid path s names
1041
+ [(s, Left names)] ->
1042
+ return $ Left $ Exit. BP_MainNameInvalid path s names
1026
1043
1027
- (s1,_): (s2,_): _ ->
1028
- return $ Left $ Exit. BP_WithAmbiguousSrcDir path s1 s2
1044
+ (s1,_): (s2,_): _ ->
1045
+ return $ Left $ Exit. BP_WithAmbiguousSrcDir path s1 s2
1029
1046
1030
1047
1031
1048
1032
- isInsideSrcDirByName :: FilePath -> [String ] -> FilePath -> IO Bool
1033
- isInsideSrcDirByName root names srcDir =
1034
- File. exists (root </> srcDir </> FP. joinPath names <.> " elm" )
1049
+ isInsideSrcDirByName :: [String ] -> AbsoluteSrcDir -> IO Bool
1050
+ isInsideSrcDirByName names srcDir =
1051
+ File. exists (addRelative srcDir ( FP. joinPath names <.> " elm" ) )
1035
1052
1036
1053
1037
- isInsideSrcDirByPath :: [String ] -> FilePath -> Maybe (FilePath , Either [String ] [String ])
1038
- isInsideSrcDirByPath segments srcDir =
1054
+ isInsideSrcDirByPath :: [String ] -> AbsoluteSrcDir -> Maybe (FilePath , Either [String ] [String ])
1055
+ isInsideSrcDirByPath segments ( AbsoluteSrcDir srcDir) =
1039
1056
case dropPrefix (FP. splitDirectories srcDir) segments of
1040
1057
Nothing ->
1041
1058
Nothing
@@ -1056,20 +1073,18 @@ isGoodName name =
1056
1073
Char. isUpper char && all (\ c -> Char. isAlphaNum c || c == ' _' ) chars
1057
1074
1058
1075
1076
+ -- INVARIANT: Dir.canonicalizePath has been run on both inputs
1077
+ --
1059
1078
dropPrefix :: [FilePath ] -> [FilePath ] -> Maybe [FilePath ]
1060
1079
dropPrefix roots paths =
1061
1080
case roots of
1062
1081
[] ->
1063
1082
Just paths
1064
1083
1065
- " ." : rs ->
1066
- dropPrefix rs paths
1067
-
1068
1084
r: rs ->
1069
1085
case paths of
1070
- [] -> Nothing
1071
- " ." : ps -> dropPrefix roots ps
1072
- p: ps -> if r == p then dropPrefix rs ps else Nothing
1086
+ [] -> Nothing
1087
+ p: ps -> if r == p then dropPrefix rs ps else Nothing
1073
1088
1074
1089
1075
1090
0 commit comments