packages feed

glean-0.1.0.0: glean/glass/Glean/Glass/Search/Python.hs

{-
  Copyright (c) Meta Platforms, Inc. and affiliates.
  All rights reserved.

  This source code is licensed under the BSD-style license found in the
  LICENSE file in the root directory of this source tree.
-}

{-# OPTIONS_GHC -Wno-orphans #-}
{-# LANGUAGE TypeApplications #-}

module Glean.Glass.Search.Python
  ( {- instances -}
  ) where

import Glean.Angle as Angle
    ( AngleVars(vars),
      AngleStatement,
      Angle,
      predicate,
      where_,
      (.=),
      string,
      stringPrefix,
      tuple,
      rec,
      alt,
      field,
      end,
      wild )

import Glean.Glass.Search.Class
import Glean.Glass.Query ( entityLocation )

import qualified Glean.Schema.CodePython.Types as Py
import qualified Glean.Schema.CodemarkupTypes.Types as Code
import qualified Glean.Schema.Python.Types as Py
import qualified Glean.Schema.Src.Types as Src
import Data.Text (Text)

instance Search (ResultLocation Py.Entity) where
  symbolSearch params =
    fmap (mapResultLocation Py.Entity_decl) <$> symbolSearch params

instance Search (ResultLocation Py.Declaration) where
  symbolSearch t@[fqname] = searchSymbolId t $
    findByFQName fqname Nothing
  symbolSearch t@[loc, fqname] = searchSymbolId t $
    findByFQName fqname (Just loc)
  symbolSearch _ = return $
    None "Python.symbolSearch: invalid query"

findByFQName
  :: Text -> Maybe Text
  -> Angle (ResultLocation Py.Declaration)
findByFQName = searchByFQName False

searchByFQName
  :: Bool -> Text -> Maybe Text
  -> Angle (ResultLocation Py.Declaration)
searchByFQName isPrefix fqname mloc =
  vars $ \decl (file :: Angle Src.File) (rangespan :: Angle Code.RangeSpan)
      (lname :: Angle Text) ->
    tuple (decl, file, rangespan, lname) `where_` ([
        wild .= predicate @Py.DeclarationWithName (
          rec $
              field @"name" (stringOrPrefix fqname) $
              field @"declaration" decl
          end),
        entityLocation (alt @"python" (alt @"decl" decl)) file rangespan lname
      ] <> location file)
  where
    location :: Angle Src.File -> [AngleStatement]
    location file
      | Just "." <- mloc
      = []
      | Just loc <- mloc
      = [file .= predicate @Src.File (stringPrefix loc)]
      | otherwise
      = []
    stringOrPrefix = if isPrefix then stringPrefix else string