Skip to content

Commit ef4cf6f

Browse files
simonmarmeta-codesync[bot]
authored andcommitted
Add --prefix and --unit options (facebookincubator#626)
Summary: Most indexers have a `--prefix` for getting the file paths right. `--unit` is useful for stacking DBs when the unit names don't match exactly... I'll leave this as undocumented for now until the workflow is more polished. Pull Request resolved: facebookincubator#626 Reviewed By: jjuliamolin Differential Revision: D88849435 Pulled By: phlalx fbshipit-source-id: 28a0d38803fc56b7c35960de5341557024a7f102
1 parent 297f701 commit ef4cf6f

3 files changed

Lines changed: 75 additions & 17 deletions

File tree

glean/lang/haskell/HieIndexer/Index.hs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ import qualified GHC.Types.Var as GHC (ForAllTyFlag(..), Specificity(..))
5858
#else
5959
import qualified GHC.Types.Var as GHC (ArgFlag(..), Specificity(..))
6060
#endif
61-
import GHC.Unit.Types (unitFS)
61+
import qualified GHC.Unit.Types as GHC
62+
import qualified GHC.Types.Unique.Set as GHC (mkUniqSet, elementOfUniqSet)
6263
#if !MIN_VERSION_ghc(9,6,0)
6364
import qualified GHC.Unit.Module.Name as GHC (moduleNameFS)
6465
#endif
@@ -71,6 +72,7 @@ import Glean.Impl.ConfigProvider ()
7172
import qualified Glean.Schema.Hs.Types as Hs
7273
import qualified Glean.Schema.Src.Types as Src
7374
import Glean.Util.Range
75+
import HieIndexer.Options
7476

7577
{- TODO
7678
@@ -96,6 +98,12 @@ import Glean.Util.Range
9698
Haddock's Interface type has all the ASTs for the declarations
9799
in addition to the Hie.
98100
101+
- imports
102+
- import refs contain only ModuleName, not Module. This means we can't
103+
resolve imports to the correct file for module names that occur in
104+
multiple packages.
105+
- modules in the export list should be refs
106+
99107
- map Name to exportedness?
100108
101109
- exclude generated names in a cleaner way
@@ -108,15 +116,31 @@ import Glean.Util.Range
108116
- Haddock docs for symbol
109117
-}
110118

111-
mkModule :: Glean.NewFact m => GHC.Module -> m Hs.Module
112-
mkModule mod = do
119+
mkModule :: Glean.NewFact m => GHC.Module -> UnitName -> m Hs.Module
120+
mkModule mod unit = do
113121
modname <- Glean.makeFact @Hs.ModuleName $
114122
fsToText (GHC.moduleNameFS (GHC.moduleName mod))
115123
unitname <- Glean.makeFact @Hs.UnitName $
116-
fsToText (unitFS (GHC.moduleUnit mod))
124+
toUnitName unit $ GHC.moduleUnit mod
117125
Glean.makeFact @Hs.Module $
118126
Hs.Module_key modname unitname
119127

128+
toUnitName :: UnitName -> GHC.Unit -> Text
129+
toUnitName unitName u = case unitName of
130+
UnitKey -> t
131+
UnitId
132+
| isWiredInUnit u -> t
133+
| (id, _) <- Text.breakOnEnd "-" t, not (Text.null id) -> Text.init id
134+
| otherwise -> t
135+
-- TODO: this is not right for local libraries, which have names like
136+
-- aeson-pretty-0.8.9-inplace-aeson
137+
where t = fsToText $ GHC.unitFS u
138+
139+
isWiredInUnit :: GHC.Unit -> Bool
140+
isWiredInUnit = \u -> GHC.toUnitId u `GHC.elementOfUniqSet` wiredInUnitIds
141+
where
142+
wiredInUnitIds = GHC.mkUniqSet GHC.wiredInUnitIds
143+
120144
mkName :: Glean.NewFact m => GHC.Name -> Hs.Module -> Hs.NameSort -> m Hs.Name
121145
mkName name mod sort = do
122146
let occ = nameOccName name
@@ -254,9 +278,10 @@ nat = Glean.toNat . fromIntegral
254278

255279
indexTypes
256280
:: forall m . (MonadFail m, Monad m, Glean.NewFact m)
257-
=> A.Array TypeIndex HieTypeFlat
281+
=> UnitName
282+
-> A.Array TypeIndex HieTypeFlat
258283
-> m (IntMap Hs.Type)
259-
indexTypes typeArr = foldM go IntMap.empty (A.assocs typeArr)
284+
indexTypes unit typeArr = foldM go IntMap.empty (A.assocs typeArr)
260285
where
261286
go tymap (n,ty) = do
262287
fact <- mkTy ty
@@ -314,7 +339,7 @@ indexTypes typeArr = foldM go IntMap.empty (A.assocs typeArr)
314339
tcname <- case nameModule_maybe name of
315340
Nothing -> fail "HTyConApp: internal name"
316341
Just mod -> do
317-
namemod <- mkModule mod
342+
namemod <- mkModule mod unit
318343
mkName name namemod (Hs.NameSort_external def)
319344
let sort = case GHC.ifaceTyConSort info of
320345
GHC.IfaceNormalTyCon -> Hs.TyConSort_normal def
@@ -347,25 +372,28 @@ indexTypes typeArr = foldM go IntMap.empty (A.assocs typeArr)
347372
indexHieFile
348373
:: Glean.Writer
349374
-> NonEmpty Text
375+
-> Maybe Text
376+
-> UnitName
350377
-> FilePath
351378
-> HieFile
352379
-> IO ()
353-
indexHieFile writer srcPaths path hie = do
380+
indexHieFile writer srcPaths srcPrefix unit path hie = do
354381
srcFile <- findSourceFile srcPaths (hie_module hie) (hie_hs_file hie)
355382
logInfo $ "Indexing: " <> path <> " (" <> srcFile <> ")"
356383
Glean.writeFacts writer $ do
357-
modfact <- mkModule smod
384+
modfact <- mkModule smod unit
358385

359386
let offs = getLineOffsets (hie_hs_src hie)
360387
let hsFileFS = GHC.mkFastString $ hie_hs_file hie
361-
filefact <- Glean.makeFact @Src.File (Text.pack srcFile)
388+
let file = maybe id (\p f -> (p <> "/" <> f)) srcPrefix (Text.pack srcFile)
389+
filefact <- Glean.makeFact @Src.File file
362390
let fileLines = mkFileLines filefact offs
363391
Glean.makeFact_ @Src.FileLines fileLines
364392

365393
Glean.makeFact_ @Hs.ModuleSource $
366394
Hs.ModuleSource_key modfact filefact
367395

368-
typeMap <- indexTypes (hie_types hie)
396+
typeMap <- indexTypes unit (hie_types hie)
369397

370398
let toByteRange = srcRangeToByteRange fileLines (hie_hs_src hie)
371399
toByteSpan sp
@@ -413,7 +441,7 @@ indexHieFile writer srcPaths path hie = do
413441
-- But it does happen, so let's not crash.
414442
return Nothing
415443
Just m -> do
416-
mod <- if m == smod then return modfact else mkModule m
444+
mod <- if m == smod then return modfact else mkModule m unit
417445
Just <$> mkName name mod (Hs.NameSort_external def)
418446

419447
sigMap <- produceDeclInfo filefact toByteSpan getName declInfo
@@ -512,7 +540,7 @@ findSourceFile srcPaths mod src = do
512540
return src
513541
Just f -> return f
514542
where
515-
pkg = fsToText (unitFS (GHC.moduleUnit mod))
543+
pkg = fsToText (GHC.unitFS (GHC.moduleUnit mod))
516544
isVer = Text.all (\c -> isDigit c || c == '.')
517545
pkgNameAndVersion = case break isVer (Text.splitOn "-" pkg) of
518546
(before, after) -> Text.intercalate "-" (before <> take 1 after)

glean/lang/haskell/HieIndexer/Main.hs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ defaultMain cfg repo backend = do
8787

8888
Glean.withSender backend repo allPredicates def $ \sender -> do
8989
Glean.withWriter sender def $
90-
indexHieFiles paths (srcPaths cfg)
90+
indexHieFiles paths (srcPaths cfg) (srcPrefix cfg) (unitName cfg)
9191

9292
predicates <-
9393
Glean.schemaInfo_predicateIds
@@ -119,20 +119,22 @@ outputMain cfg out schema_id backend = do
119119
paths <- getHieFilesIn (NonEmpty.toList (hiePaths cfg))
120120
((), batch) <-
121121
Glean.withBatchWriter backend schema_id Nothing def $
122-
indexHieFiles paths (srcPaths cfg)
122+
indexHieFiles paths (srcPaths cfg) (srcPrefix cfg) (unitName cfg)
123123
BS.writeFile out (Thrift.Protocol.Compact.serializeCompact batch)
124124

125125
indexHieFiles
126126
:: HashSet.HashSet FilePath
127127
-> NonEmpty Text
128+
-> Maybe Text
129+
-> UnitName
128130
-> Glean.Writer
129131
-> IO ()
130-
indexHieFiles paths srcs writer =
132+
indexHieFiles paths srcs srcPrefix unitName writer =
131133
forM_ (HashSet.toList paths) $ \f -> do
132134
nc <- newIORef =<< makeNc
133135
runDbM nc $ do
134136
withHieFile f $ \h ->
135-
liftIO $ indexHieFile writer srcs f h
137+
liftIO $ indexHieFile writer srcs srcPrefix unitName f h
136138

137139
{- | Recursively search for @.hie@ and @.hie-boot@ files in given directory
138140
avoiding loops due to symlinks

glean/lang/haskell/HieIndexer/Options.hs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
module HieIndexer.Options (
1212
HieIndexerOptions(..),
1313
Mode(..),
14+
UnitName(..),
1415
options,
1516
) where
1617

@@ -31,9 +32,24 @@ data HieIndexerOptions = HieIndexerOptions
3132
-- ^ Paths to look for source files. May include the string
3233
-- @$PACKAGE@ which will be replaced by the package name
3334
-- (@<pkg>-<version>@).
35+
, srcPrefix :: Maybe Text
36+
-- ^ Prefix to add to source paths
37+
, unitName :: UnitName
38+
-- ^ How to handle unit names
3439
, verbosity :: Int
3540
}
3641

42+
data UnitName = UnitKey | UnitId
43+
44+
parseUnit :: String -> Maybe UnitName
45+
parseUnit "key" = Just UnitKey
46+
parseUnit "id" = Just UnitId
47+
parseUnit _ = Nothing
48+
49+
showUnit :: UnitName -> String
50+
showUnit UnitKey = "key"
51+
showUnit UnitId = "id"
52+
3753
data Mode
3854
= WriteMode {
3955
repo :: Repo
@@ -61,6 +77,18 @@ options = info (helper <*> parser) fullDesc
6177
"Path to search for source files. The string \"$PACKAGE\" is " <>
6278
"replaced by the package name, e.g. text-2.0.2")))
6379

80+
srcPrefix <- optional (textOption (
81+
long "prefix" <>
82+
metavar "PATH" <>
83+
help "Prefix to add to source paths in the DB"))
84+
85+
unitName <- option (maybeReader parseUnit) (
86+
long "unit" <>
87+
metavar "key|id" <>
88+
value UnitKey <>
89+
showDefaultWith showUnit <>
90+
help "Whether to store the full unit key (key) or just name-version (id)")
91+
6492
verbosity <-
6593
option
6694
auto

0 commit comments

Comments
 (0)