From bc4e3383e9edad95cf8d5efc8b1e8a1c9e86fe80 Mon Sep 17 00:00:00 2001 From: Philippe Bidinger Date: Tue, 26 Nov 2024 02:33:44 -0800 Subject: [PATCH] Uses FileXRefsGenericEntities to compute xrefs Summary: Use new predicates introduced in D66079681 to compute xrefs. This allows generalization of the computation of xlang xrefs. Before, glass was relying on the assumption that xlang references where the result of a mapping "generated entity <-> idlEntity". In this diff, glass uses FileXRefsGenericEntities to compute all xrefs (plain or xlang). The xlang entities may be generated from a entity <-> idlEntity (as is the case for Hack), but this isn't mandatory. For Hack it's done in Codemarkup. Note that the C++ handler is unchanged and still relies on the "entity <-> idlEntity" mapping. Reviewed By: nhawkes Differential Revision: D66128389 fbshipit-source-id: 8210052f0af20a4b8a6dbe4f939b27d380c43e5e --- glean/glass/Glean/Glass/Handler.hs | 6 +-- glean/glass/Glean/Glass/Query.hs | 60 ++++++------------------------ glean/glass/Glean/Glass/XRefs.hs | 20 +++++----- 3 files changed, 25 insertions(+), 61 deletions(-) diff --git a/glean/glass/Glean/Glass/Handler.hs b/glean/glass/Glean/Glass/Handler.hs index 430234012..464e51e9c 100644 --- a/glean/glass/Glean/Glass/Handler.hs +++ b/glean/glass/Glean/Glass/Handler.hs @@ -103,7 +103,7 @@ import Glean.Glass.NameSearch ( ) import qualified Glean.Glass.Query.Cxx as Cxx import Glean.Glass.XRefs - ( GenXRef(..), XRef, resolveEntitiesRange, splitXRefs ) + ( GenXRef(..), XRef, resolveEntitiesRange, buildGenXRefs ) import Glean.Glass.SymbolMap ( toSymbolIndex ) import Glean.Glass.Search as Search ( CodeEntityLocation(..), @@ -1169,11 +1169,11 @@ documentSymbolsForLanguage documentSymbolsForLanguage mlimit _ ExtraSymbolOpts{..} fileId = do (xrefs, trunc1) <- if oIncludeRefs then searchRecursiveWithLimit mlimit $ - Query.fileEntityXRefLocations fileId oIncludeXlangRefs + Query.fileEntityXRefsGenEntities fileId oIncludeXlangRefs else return ([], False) (defns, trunc2) <- searchRecursiveWithLimit mlimit $ Query.fileEntityLocations fileId - return (splitXRefs xrefs, defns, trunc1 || trunc2) + return (mapMaybe buildGenXRefs xrefs, defns, trunc1 || trunc2) -- And build a line-indexed map of symbols, resolved to spans -- With extra attributes loaded from any associated attr db diff --git a/glean/glass/Glean/Glass/Query.hs b/glean/glass/Glean/Glass/Query.hs index b88944599..28351bcbb 100644 --- a/glean/glass/Glean/Glass/Query.hs +++ b/glean/glass/Glean/Glass/Query.hs @@ -17,7 +17,7 @@ module Glean.Glass.Query -- * Working with XRefs , fileEntityLocations - , fileEntityXRefLocations + , fileEntityXRefsGenEntities -- * Finding refernces to declarations , findReferenceRangeSpan @@ -116,55 +116,19 @@ fileEntityLocations fileid = end) ] --- | Find xrefs from this file, and their associated entities --- and idl entities --- --- > www> src.File "www/flib/intern/glean/Glean.php" --- > { "id": 2688993, "key": "www/flib/intern/glean/Glean.php" } --- --- > www> {X, E, MI} where --- > codemarkup.FileEntityXRefLocations {file = $2688993, xref = X, entity = E}; --- > MI = if (codemarkup.EntityIdl { E, I }) then ({ just = I }) else (nothing) --- -fileEntityXRefLocations - :: Glean.IdOf Src.File - -> Bool - -> Angle (Code.XRefLocation, Code.Entity, Maybe Code.IdlEntity) -fileEntityXRefLocations fileid True = - vars $ \(xref :: Angle Code.XRefLocation) - (entity :: Angle Code.Entity) - (mIdlEntity :: Angle (Maybe Code.IdlEntity)) - (idlEntity :: Angle Code.IdlEntity) -> - tuple (xref,entity,mIdlEntity) `where_` [ - stmt $ predicate @Code.FileEntityXRefLocations ( +-- | Find all "generic" xrefs from this file, regular and xlang +fileEntityXRefsGenEntities + :: Glean.IdOf Src.File + -> Bool + -> Angle Code.GenericEntity +fileEntityXRefsGenEntities fileid includeXRefs = + vars $ \(genEntity :: Angle Code.GenericEntity) -> + genEntity `where_` ( + stmt (predicate @Code.FileXRefsGenericEntities ( rec $ field @"file" (asPredicate (factId fileid)) $ - field @"xref" xref $ - field @"entity" entity - end), - mIdlEntity .= - if_ (predicate @Code.EntityIdl ( - rec $ - field @"entity" entity $ - field @"idlEntity" idlEntity - end)) - (just idlEntity) - nothing - ] - -fileEntityXRefLocations fileid False = - vars $ \(xref :: Angle Code.XRefLocation) - (entity :: Angle Code.Entity) - (mIdlEntity :: Angle (Maybe Code.IdlEntity)) -> - tuple (xref,entity,mIdlEntity) `where_` [ - stmt $ predicate @Code.FileEntityXRefLocations ( - rec $ - field @"file" (asPredicate (factId fileid)) $ - field @"xref" xref $ - field @"entity" entity - end), - nothing .= mIdlEntity - ] + field @"genEntity" genEntity + end)) : [genEntity .= alt @"plainEntity" wild | not includeXRefs]) -- | Entity-based find-references returning native range or bytespan findReferenceRangeSpan diff --git a/glean/glass/Glean/Glass/XRefs.hs b/glean/glass/Glean/Glass/XRefs.hs index 3eeab59b9..07d8f5512 100644 --- a/glean/glass/Glean/Glass/XRefs.hs +++ b/glean/glass/Glean/Glass/XRefs.hs @@ -13,7 +13,7 @@ module Glean.Glass.XRefs GenXRef(..), XRef, resolveEntitiesRange, - splitXRefs, + buildGenXRefs, fetchCxxIdlXRefs ) where @@ -31,10 +31,10 @@ import Glean.Glass.Range ( rangeSpanToLocationRange ) import Glean.Glass.Utils import Glean.Glass.Types ( LocationRange, RepoName(..) ) import qualified Glean.Schema.CodemarkupTypes.Types as Code +import qualified Glean.Schema.Codemarkup.Types as Code import qualified Glean.Schema.Code.Types as Code import qualified Glean.Schema.Cxx1.Types as Cxx import qualified Glean.Schema.CodemarkupCxx.Types as Code -import qualified Glean.Schema.Codemarkup.Types as Code import qualified Glean.Schema.Src.Types as Src import Data.Maybe (catMaybes) @@ -42,15 +42,15 @@ type XRef = (Code.XRefLocation, Code.Entity) type IdlXRef = (Code.RangeSpan, Code.IdlEntity) data GenXRef = PlainXRef XRef | IdlXRef IdlXRef -type EntityIdlMap = Map Code.Entity Code.IdlEntity +buildGenXRefs :: Code.GenericEntity -> Maybe GenXRef +buildGenXRefs genEntity = case genEntity of + Code.GenericEntity_xlangEntity (Code.GenericEntity_xlangEntity_ source entity) + -> Just $ IdlXRef (source, entity) + Code.GenericEntity_plainEntity (Code.GenericEntity_plainEntity_ xref entity) + -> Just $ PlainXRef (xref, entity) + Code.GenericEntity_EMPTY -> Nothing --- | Split xrefs (target ent + optional idl ent) into plain and idl entities -splitXRefs - :: [(Code.XRefLocation, Code.Entity, Maybe Code.IdlEntity)] -> [GenXRef] -splitXRefs xrefs = concat - [ PlainXRef (loc, ent) : - [IdlXRef (Code.xRefLocation_source loc, idl) | Just idl <- [mb_idl]] - | (loc, ent, mb_idl) <- xrefs] +type EntityIdlMap = Map Code.Entity Code.IdlEntity -- | extract idl xrefs from the regular ones extractIdlXRefs