Skip to content

Commit 9f06733

Browse files
committed
Update Haskell SymbolId handling
1 parent 76d050e commit 9f06733

File tree

2 files changed

+105
-68
lines changed

2 files changed

+105
-68
lines changed

glean/glass/Glean/Glass/Search/Haskell.hs

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,70 @@ module Glean.Glass.Search.Haskell
1515

1616
import Data.Text ( Text )
1717
import qualified Data.Text as Text ( intercalate )
18+
import Util.Text
1819

1920
import Glean.Angle as Angle
2021

2122
import Glean.Glass.Search.Class
22-
import Glean.Glass.Query ( entityLocation )
2323

2424
import qualified Glean.Schema.CodeHs.Types as Haskell
2525
import qualified Glean.Schema.CodemarkupTypes.Types as Code
26-
import qualified Glean.Schema.SearchHs.Types as Haskell
27-
import qualified Glean.Schema.Src.Types as Src
26+
import qualified Glean.Schema.Hs.Types as Hs
2827

2928
instance Search (ResultLocation Haskell.Entity) where
3029
symbolSearch [] = return $ None "Haskell.symbolSearch: empty"
31-
symbolSearch toks = do
32-
searchSymbolId toks $ searchByName $ Text.intercalate "." toks
33-
34-
-- code.hs:searchByName
35-
searchByName :: Text -> Angle (ResultLocation Haskell.Entity)
36-
searchByName sym =
37-
vars $ \(ent :: Angle Haskell.Entity) (file :: Angle Src.File)
38-
(rangespan :: Angle Code.RangeSpan) (lname :: Angle Text) ->
39-
tuple (ent, file, rangespan, lname) `where_` [
40-
wild .= predicate @Haskell.SearchByName (
41-
rec $
42-
field @"name" (string sym) $
43-
field @"entity" ent
44-
end),
45-
entityLocation (alt @"hs" ent) file rangespan lname
46-
]
30+
symbolSearch toks@(pkg : rest) = do
31+
case reverse rest of
32+
end : start : ident : namespace : mod
33+
| Right e <- textToInt end,
34+
Right s <- textToInt start,
35+
Just ns <- fromNamespace namespace ->
36+
searchSymbolId toks $
37+
symbolIdQuery pkg (Text.intercalate "." (reverse mod)) ident ns
38+
(Just (s,e))
39+
ident : namespace : mod
40+
| Just ns <- fromNamespace namespace ->
41+
searchSymbolId toks $
42+
symbolIdQuery pkg (Text.intercalate "." (reverse mod)) ident ns
43+
Nothing
44+
_ -> return $ None "Haskell.symbolSearch: empty"
45+
where
46+
fromNamespace "var" = Just Hs.Namespace_var_
47+
fromNamespace "ty" = Just Hs.Namespace_tycon
48+
fromNamespace "con" = Just Hs.Namespace_datacon
49+
fromNamespace "tyvar" = Just Hs.Namespace_tyvar
50+
fromNamespace _ = Nothing
51+
52+
53+
symbolIdQuery
54+
:: Text -- ^ package (ignored (TODO))
55+
-> Text -- ^ module name
56+
-> Text -- ^ identifier
57+
-> Hs.Namespace -- ^ namespace (var, datacon, tycon, tyvar)
58+
-> Maybe (Int, Int) -- ^ span, for local names
59+
-> Angle (ResultLocation Haskell.Entity)
60+
symbolIdQuery _pkg mod ident ns sort =
61+
vars $ \name file span ->
62+
tuple (name, file, sig (alt @"span" span :: Angle Code.RangeSpan), string ident)
63+
`where_` [
64+
name .= predicate @Hs.Name (
65+
rec $
66+
field @"occ" (rec $
67+
field @"name" (string ident) $
68+
field @"namespace_" (enum ns) end) $
69+
field @"mod" (rec $
70+
field @"name" (string mod) end) $
71+
field @"sort" (
72+
case sort of
73+
Nothing -> alt @"external" wild
74+
Just (s,l) -> alt @"internal" (rec $
75+
field @"start" (nat (fromIntegral s)) $
76+
field @"length" (nat (fromIntegral l)) end)
77+
) end),
78+
stmt $ predicate @Hs.DeclarationLocation (
79+
rec $
80+
field @"name" (asPredicate name) $
81+
field @"file" (asPredicate file) $
82+
field @"span" span end
83+
)
84+
]

glean/glass/Glean/Glass/SymbolId/Hs.hs

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,70 +10,69 @@
1010

1111
module Glean.Glass.SymbolId.Hs ({- instances -}) where
1212

13-
import Data.Text (Text)
13+
import Data.Char
1414
import qualified Data.Text as Text
15+
import TextShow
1516

1617
import Glean.Glass.SymbolId.Class
1718
import Glean.Glass.Types (Name(..))
18-
import Glean.Schema.CodeHs.Types as Hs (Entity (..))
19+
import Glean.Schema.CodeHs.Types as Hs (Entity)
1920
import qualified Glean
2021
import qualified Glean.Schema.Hs.Types as Hs
2122
import qualified Glean.Schema.Src.Types as Src
2223

24+
-- REPO/hs/containers/Data/Map/{var|datacon|tyvar|tycon}/toList[/START/END]
25+
2326
instance Symbol Hs.Entity where
24-
toSymbol (Hs.Entity_definition d) = toSymbolPredicate d
25-
toSymbol (Hs.Entity_function_ d) = toSymbolPredicate d
26-
toSymbol (Hs.Entity_class_ d) = toSymbolPredicate d
27-
toSymbol Hs.Entity_EMPTY = return []
27+
toSymbol = toSymbolPredicate
2828

29-
instance Symbol Hs.Definition_key where
30-
toSymbol (Hs.Definition_key name _) = do
31-
n <- Glean.keyOf name
32-
return (Text.splitOn "." n)
29+
instance Symbol Hs.Name_key where
30+
toSymbol (Hs.Name_key occ mod sort) = do
31+
m <- toSymbol mod
32+
o <- toSymbol occ
33+
s <- toSymbol sort
34+
return $ m <> o <> s
3335

34-
instance Symbol Hs.FunctionDefinition_key where
35-
toSymbol (Hs.FunctionDefinition_key fnName Src.Range{..}) = do
36-
name <- Glean.keyOf fnName
37-
fname <- Glean.keyOf range_file
38-
return (fname : Text.splitOn "." name)
36+
instance Symbol Hs.Module where
37+
toSymbol = toSymbolPredicate
3938

40-
instance Symbol Hs.Class_key where
41-
toSymbol (Hs.Class_key clsName Src.Range{..}) = do
42-
name <- Glean.keyOf clsName
43-
fname <- Glean.keyOf range_file
44-
return (fname : Text.splitOn "." name)
39+
instance Symbol Hs.OccName where
40+
toSymbol = toSymbolPredicate
4541

46-
instance ToQName Hs.Entity where
47-
toQName (Hs.Entity_definition d) = Glean.keyOf d >>= toQName
48-
toQName (Hs.Entity_function_ d) = Glean.keyOf d >>= toQName
49-
toQName (Hs.Entity_class_ d) = Glean.keyOf d >>= toQName
50-
toQName Hs.Entity_EMPTY =
51-
return $ Left "toQName: Haskell: empty qname"
52-
53-
instance ToQName Hs.Definition_key where
54-
toQName (Hs.Definition_key name _) = do
42+
instance Symbol Hs.Module_key where
43+
toSymbol (Hs.Module_key name unit) = do
44+
u <- Glean.keyOf unit
5545
n <- Glean.keyOf name
56-
return $ case reverse (Text.splitOn "." n) of
57-
[] -> Left "toQName: Haskell: empty function qname"
58-
[x] -> Right (Name x, Name "")
59-
(x:xs) -> Right (Name x, joinDotted xs)
46+
-- unit names are things like glean-0.1.0.0-inplace-core
47+
-- let's strip the version and everything after it
48+
let pkg = Text.intercalate "-" (fst (break isVer (Text.splitOn "-" u)))
49+
return (pkg : Text.splitOn "." n)
50+
where
51+
isVer t
52+
| Just (d, _) <- Text.uncons t = isDigit d
53+
| otherwise = False
6054

61-
instance ToQName Hs.FunctionDefinition_key where
62-
toQName (Hs.FunctionDefinition_key fnName _) = do
63-
name <- Glean.keyOf fnName
64-
return $ case reverse (Text.splitOn "." name) of
65-
[] -> Left "toQName: Haskell: empty function qname"
66-
[x] -> Right (Name x, Name "")
67-
(x:xs) -> Right (Name x, joinDotted xs)
55+
instance Symbol Hs.OccName_key where
56+
toSymbol (Hs.OccName_key name namespace) = do
57+
let sp = case namespace of
58+
Hs.Namespace_var_ -> "var"
59+
Hs.Namespace_datacon -> "con"
60+
Hs.Namespace_tyvar -> "tyvar"
61+
Hs.Namespace_tycon -> "ty"
62+
_ -> error "namespace"
63+
return [sp,name]
6864

65+
instance Symbol Hs.NameSort where
66+
toSymbol Hs.NameSort_external{} = return []
67+
toSymbol (Hs.NameSort_internal (Src.ByteSpan start end)) =
68+
return [showt (Glean.fromNat start), showt (Glean.fromNat end)]
6969

70-
instance ToQName Hs.Class_key where
71-
toQName (Hs.Class_key clsName _) = do
72-
name <- Glean.keyOf clsName
73-
return $ case reverse (Text.splitOn "." name) of
74-
[] -> Left "toQName: Haskell: empty class qname"
75-
[x] -> Right (Name x, Name "")
76-
(x:xs) -> Right (Name x, joinDotted xs)
70+
instance ToQName Hs.Entity where
71+
toQName n = Glean.keyOf n >>= toQName
7772

78-
joinDotted :: [Text] -> Name
79-
joinDotted = Name . Text.intercalate "." . reverse
73+
instance ToQName Hs.Name_key where
74+
toQName (Hs.Name_key occ mod sort) = do
75+
Hs.Module_key m _ <- Glean.keyOf mod
76+
modname <- Glean.keyOf m
77+
Hs.OccName_key n _ <- Glean.keyOf occ
78+
return $ Right (Name modname, Name n)

0 commit comments

Comments
 (0)