# Copyright (c) Meta Platforms, Inc. and affiliates. schema search.code.16 { import buck.4 import code import code.cxx import code.hack import code.java import code.python import codemarkup.lsif import codemarkup.types import csharp import cxx1 import erlang import fbthrift import flow import graphql import hack import hs import javakotlin.alpha import lsif import pp1 import python import search.anglelang import search.cxx import search.erlang import search.flow import search.hack import search.hs import search.java import search.kind.cxx import search.kotlin import search.python import scip # # public API # # global symbol search with language constraint # migrate these to kind-based search so that the union of them covers each # language once predicate SearchByNameAndLanguage: { name: string, language: code.Language, entity: code.Entity, } { Name, Language, Entity } where # see SearchByNameKindAndLanguage for C++, PreProcessor, Python, Hack ( Java = Language; JavaSearchByName { Name, Entity } ) | ( Kotlin = Language; KotlinSearchByName { Name, Entity } ) | ( Haskell = Language; HsSearchByName { Name, Entity } ) | ( Erlang = Language; ErlangSearchByName { Name, Entity } ) | ( Thrift = Language; ThriftSearchByName { Name, Entity } ) | ( Buck = Language; BuckSearchByName { Name, Entity } ) | ( CSharp = Language; CSharpSearchByName { Name, Entity } ) | ( GraphQL = Language; GraphQLSearchByName { Name, Entity } ) | ( Angle = Language; AngleSearchByName { Name, Entity } ); code.EntityLanguage { Entity, Language }; # double check the entity lang # global symbol search normalized to lower case predicate SearchByLowerCaseNameAndLanguage: { name: string, language: code.Language, entity: code.Entity, } { Name, Language, Entity } where # See SearchByLowerCaseNameKindAndLanguage ( Java = Language; JavaSearchByLowerCaseName { Name, Entity } ) | ( Kotlin = Language; KotlinSearchByLowerCaseName { Name, Entity } ) | ( Haskell = Language; HsSearchByLowerCaseName { Name, Entity } ) | ( Erlang = Language; ErlangSearchByLowerCaseName { Name, Entity } ) | ( Thrift = Language; ThriftSearchByLowerCaseName { Name, Entity } ) | ( Buck = Language; BuckSearchByLowerCaseName { Name, Entity } ) | ( CSharp = Language; CSharpSearchByLowerCaseName { Name, Entity } ) | ( GraphQL = Language; GraphQLSearchByLowerCaseName { Name, Entity } ) | ( Angle = Language; AngleSearchByLowerCaseName { Name, Entity } ); code.EntityLanguage { Entity, Language }; # double check the entity lang # Kind-optimized search. predicate SearchByNameKindAndLanguage: { name: string, language: code.Language, kinds: maybe codemarkup.types.SymbolKind, # `nothing` indicates unknown kind entity: code.Entity } { NameStr, Language, Kinds, Entity } where ( Cpp = Language; CxxSearchByNameKindAndScopeFact { NameStr, _, Kinds, Entity } ) | ( PreProcessor = Language; PpSearchByNameKind { NameStr, Kinds, Entity } ) | ( Python = Language; PythonSearchByNameKindAndScopeFact { NameStr, _, Kinds, Entity } ) | ( JavaScript = Language; FlowSearchByNameKindAndScopeFact { NameStr, _, Kinds, Entity } ) | ( Hack = Language; HackSearchByNameAndKind { NameStr, Kinds, Entity } ) | ( Rust = Language; RustSearchByNameAndKind { NameStr, Kinds, Entity } ) # Kind-optimized search, case insensitive. predicate SearchByLowerCaseNameKindAndLanguage: { name: string, language: code.Language, kinds: maybe codemarkup.types.SymbolKind, # `nothing` indicates unknown kind entity: code.Entity } { NameStr, Language, Kinds, Entity } where ( Cpp = Language; CxxSearchByLowerCaseNameKindAndScopeFact { NameStr, _, Kinds, Entity } ) | ( PreProcessor = Language; PpSearchByLowerCaseNameKind { NameStr, Kinds, Entity } ) | ( Python = Language; PythonSearchByLowerCaseNameKindAndScopeFact { NameStr, _, Kinds, Entity } ) | ( JavaScript = Language; FlowSearchByLowerCaseNameKindAndScopeFact { NameStr, _, Kinds, Entity } ) | ( Hack = Language; HackSearchByLowerCaseNameAndKind { NameStr, Kinds, Entity } ) # scoped search predicate SearchByScope: { name: string, scope: [string], language: code.Language, entity: code.Entity, } { Name, Scope, Language, Entity } where # See SearchByScopeAndKind for C++ ( Java = Language; JavaSearchByScope { Name, Scope, Entity } ) | ( Kotlin = Language; KotlinSearchByScope { Name, Scope, Entity } ); code.EntityLanguage { Entity, Language }; # lower case by scope predicate SearchByLowerCaseScope: { name: string, scope: [string], language: code.Language, entity: code.Entity, } { Name, Scope, Language, Entity } where # See SearchByLowerCaseScopeAndKind for C++ ( Java = Language; JavaSearchByLowerCaseScope { Name, Scope, Entity}) | ( Kotlin = Language; KotlinSearchByLowerCaseScope { Name, Scope, Entity}); code.EntityLanguage { Entity, Language }; # name and scope search, kind-optimized predicate SearchByScopeAndKind: { name: string, scope: [string], language: code.Language, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { Name, Scope, Language, Kinds, Entity } where ( Cpp = Language; CxxSearchByScopeAndKind { Name, Scope, Kinds, Entity }; ) | ( Python = Language; PythonSearchByScopeAndKind { Name, Scope, Kinds, Entity }; ) | ( JavaScript = Language; FlowSearchByScopeAndKind { Name, Scope, Kinds, Entity }; ) | ( Hack = Language; HackSearchByScopeAndKind { Name, Scope, Kinds, Entity } ) # lower case by scope predicate SearchByLowerCaseScopeAndKind: { name: string, scope: [string], language: code.Language, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { Name, Scope, Language, Kinds, Entity } where ( Cpp = Language; CxxSearchByLowerCaseScopeAndKind { Name, Scope, Kinds, Entity } ) | ( Python = Language; PythonSearchByLowerCaseScopeAndKind { Name, Scope, Kinds, Entity }; ) | ( JavaScript = Language; FlowSearchByLowerCaseScopeAndKind { Name, Scope, Kinds, Entity } ) | ( Hack = Language; HackSearchByLowerCaseScopeAndKind { Name, Scope, Kinds, Entity } ) # # Language-specific identifier search # predicate HackSearchByScopeAndKind: { name: string, scope: [string], kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Query, Kinds, Entity } where Insensitive = false; HackSearchByScopeWithNameKinds { NameStr, Insensitive, Query, Kinds, Entity } predicate HackSearchByLowerCaseScopeAndKind: { name: string, scope: [string], kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Query, Kinds, Entity} where HackNameLowerCase { NameStr, Kinds, Name }; Insensitive = true; HackSearchByScopeWithNameKinds { Name, Insensitive, Query, Kinds, Entity } # # by always using the matched namespace we make prevent scope wildcards # e.g. C\count won't match Test\C\count # we could try to interpret prefix mode this way though # predicate HackSearchByScopeWithNameKinds: { name: string, insensitive : bool, scope: [string], kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Insensitive, Scope, Kinds, Entity } where if ( [] = Scope; true | false = Insensitive ) then ( ( # exactly and specifically global declarations # these will get ranked higher by glass HackSearchByNameKindWithNamespace { NameStr, nothing, Kinds, Entity } ) | ( # or global namespace alias children ("FlibSL\Vec" or "C" work) { just = Namespace } = Kinds; hack.GlobalNamespaceAlias { hack.Name NameStr, NSQName }; hack.NamespaceDeclaration { name = NSQName } = NSDecl; { hack = { decl = { namespace_ = NSDecl } } } = Entity ) | ( { just = Module } = Kinds; hack.SearchModuleByName { NameStr, Decl }; { hack = { decl = Decl } } = Entity ) | ( # and check if NameStr is something in HH (i.e. auto-imported). Equiv # to having the HH namespace as parent. And specifically not another # namespace under HH. Has to be direct child of HH HH = hack.NamespaceQName { name = hack.Name "HH", parent = nothing }; HackSearchByNameKindWithNamespace { NameStr, { just = HH }, Kinds, Entity } ) ) else ( # search within specific context search.hack.QueryToScopeCase { Scope, Insensitive, ScopeName, ScopeNS }; HackSearchByNameKindWithQName { NameStr, ScopeName, ScopeNS, Kinds, Entity } | HackSearchByNameKindWithNamespace { NameStr, { just = { ScopeName, ScopeNS } }, Kinds, Entity }; ); # # string-based search # predicate RustSearchByNameAndKind: { name: string, kind: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Kinds, Entity } where scip.SearchByNameKind { NameStr, Ks, { rust = { defn = D } } }; Kinds = if (Ks = { just = K }) then (codemarkup.lsif.LsifKindToKind { K, Kind }; { just = Kind }) else nothing; { scip = { rust = { defn = D } } } = Entity predicate HackSearchByNameAndKind: { name: string, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Kinds, Entity } where HackSearchByNameKindWithQName { NameStr, _, _, Kinds, Entity } | HackSearchByNameKindWithNamespace { NameStr, _, Kinds, Entity } | # module is special as it has no scope term ever ( { just = Module } = Kinds; hack.SearchModuleByName { NameStr, Decl }; { hack = { decl = Decl } } = Entity ) predicate HackSearchByLowerCaseNameAndKind: { name: string, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Kinds, Entity } where HackNameLowerCase { NameStr, Kinds, Name }; HackSearchByNameAndKind { Name, Kinds, Entity } # arity-2 scope. Those that require a parent and an optional namespace. i.e. at # least one non-empty scope term or all empty predicate HackSearchByNameKindWithQName: { name: string, scope : hack.Name, scopeNamespace : maybe hack.NamespaceQName, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Scope, ScopeNS, Kinds, Entity } where { just = Kind } = Kinds; ( Method = Kind; hack.SearchMethodByName { NameStr, { Scope, ScopeNS }, Decl } ) | ( Property = Kind; hack.SearchPropertyByName { NameStr, { Scope, ScopeNS }, Decl } ) | ( Field = Kind; hack.SearchEnumeratorByName { NameStr, { Scope, ScopeNS }, Decl } ) | ( Constant = Kind; hack.SearchClassConstByName { NameStr, { Scope, ScopeNS }, Decl } ) | ( Type = Kind; hack.SearchTypeConstByName { NameStr, { Scope, ScopeNS }, Decl } ); { hack = { decl = Decl } } = Entity # arity-1 scope: those that require a maybe namespace scope term # # With namespace_ of nothing, this searches for top-level declarations (global # items without a context) # predicate HackSearchByNameKindWithNamespace: { name: string, scope: maybe hack.NamespaceQName, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity } { NameStr, Scope, Kinds, Entity } where { just = Kind } = Kinds; ( Class_ = Kind; hack.SearchClassByName { NameStr, Scope, Decl } ) | ( Interface = Kind; hack.SearchInterfaceByName { NameStr, Scope, Decl } ) | ( Trait = Kind; hack.SearchTraitByName { NameStr, Scope, Decl } ) | ( Enum_ = Kind; hack.SearchEnumByName { NameStr, Scope, Decl } ) | ( Namespace = Kind; hack.SearchNamespaceByName { NameStr, Scope, Decl } ) | ( Function = Kind; hack.SearchFunctionByName { NameStr, Scope, Decl } ) | ( Constant = Kind; hack.SearchGlobalConstByName { NameStr, Scope, Decl } ) | ( Type = Kind; hack.SearchTypedefByName { NameStr, Scope, Decl } ); { hack = { decl = Decl } } = Entity predicate HackNameLowerCase : { nameLowercase : string, kinds: maybe codemarkup.types.SymbolKind, name : string, } { NameStr, Kinds, Name } where { just = Kind } = Kinds; ( Class_ = Kind; hack.SearchClassByLowerCaseName { NameStr, Name } ) | ( Interface = Kind; hack.SearchInterfaceByLowerCaseName { NameStr, Name } ) | ( Trait = Kind; hack.SearchTraitByLowerCaseName { NameStr, Name } ) | ( Enum_ = Kind; hack.SearchEnumByLowerCaseName { NameStr, Name } ) | ( Namespace = Kind; hack.SearchNamespaceByLowerCaseName { NameStr, Name } ) | ( Function = Kind; hack.SearchFunctionByLowerCaseName { NameStr, Name } ) | ( Method = Kind; hack.SearchMethodByLowerCaseName { NameStr, Name } ) | ( Constant = Kind; hack.SearchClassConstByLowerCaseName { NameStr, Name } | hack.SearchGlobalConstByLowerCaseName { NameStr, Name } ) | ( Property = Kind; hack.SearchPropertyByLowerCaseName { NameStr, Name } ) | ( Field = Kind; hack.SearchEnumeratorByLowerCaseName { NameStr, Name } ) | ( Type = Kind; hack.SearchTypeConstByLowerCaseName { NameStr, Name } | hack.SearchTypedefByLowerCaseName { NameStr, Name } ) | ( Module = Kind; hack.SearchModuleByLowerCaseName { NameStr, Name } ); predicate PythonSearchByScopeAndKind: { name: string, scope: [string], kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Scope, Kinds, Entity } where Insensitive = false; search.python.QueryToScopeCase { Scope, Insensitive, MSName }; PythonSearchByNameKindAndScopeFact { NameStr, MSName, Kinds, Entity } predicate PythonSearchByLowerCaseScopeAndKind: { name: string, scope: [string], kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Scope, Kinds, Entity } where Insensitive = true; search.python.QueryToScopeCase { Scope, Insensitive, MSName }; PythonSearchByLowerCaseNameKindAndScopeFact { NameStr, MSName, Kinds, Entity } predicate PythonSearchByLowerCaseNameKindAndScopeFact: { name: string, scope: maybe python.SName, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity } { NameStr, Scope, Kinds, Entity } where PythonNameLowerCase { NameStr, Kinds, Name }; PythonSearchByNameKindAndScopeFact { Name, Scope, Kinds, Entity } # with a bare string name and a known scope, search by kind predicate PythonSearchByNameKindAndScopeFact: { name: string, scope: maybe python.SName, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity } { NameStr, Scope, Kinds, Entity } where # n.b no un-kinded entities in Python, so we ignore the `nothing` case { just = Kind } = Kinds; ( Class_ = Kind; python.SearchClassByName { NameStr, Scope, CDecl }; { cls = CDecl } = Decl ) | ( Module = Kind; python.SearchModuleByName { NameStr, Scope, MDecl }; { module = MDecl } = Decl ) | ( Function = Kind; python.SearchFunctionByName { NameStr, Scope, FDecl }; { func = FDecl } = Decl ) | ( Method = Kind; python.SearchMethodByName { NameStr, Scope, MDecl }; { func = MDecl } = Decl ) | ( Field = Kind; python.SearchFieldByName { NameStr, Scope, FDecl }; { variable = FDecl } = Decl ) | ( Variable = Kind; python.SearchVariableByName { NameStr, Scope, VDecl }; { variable = VDecl } = Decl ); { python = { decl = Decl } } = Entity predicate PythonNameLowerCase : { nameLowercase : string, kinds: maybe codemarkup.types.SymbolKind, name : string, } { NameLower, Kinds, Name } where { just = Kind } = Kinds; ( Class_ = Kind; python.SearchClassByLowerCaseName { NameLower, Name } ) | ( Module = Kind; python.SearchModuleByLowerCaseName { NameLower, Name } ) | ( Function = Kind; python.SearchFunctionByLowerCaseName { NameLower, Name } ) | ( Method = Kind; python.SearchMethodByLowerCaseName { NameLower, Name }; ) | ( Field = Kind; python.SearchFieldByLowerCaseName { NameLower, Name } ) | ( Variable = Kind; python.SearchVariableByLowerCaseName { NameLower, Name } ); predicate FlowSearchByScopeAndKind: { name: string, scope: [string], kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Query, Kinds, Entity } where Insensitive = false; search.flow.QueryToScopeCase { Query, Insensitive, Scope }; FlowSearchByNameKindAndScopeFact { NameStr, Scope, Kinds, Entity } predicate FlowSearchByLowerCaseScopeAndKind: { name: string, scope: [string], kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Query, Kinds, Entity } where Insensitive = true; search.flow.QueryToScopeCase { Query, Insensitive, Scope }; FlowSearchByLowerCaseNameKindAndScopeFact { NameStr, Scope, Kinds, Entity }; predicate FlowSearchByLowerCaseNameKindAndScopeFact: { name: string, scope: maybe flow.Module, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity } { NameStr, Scope, Kinds, Entity } where FlowNameLowerCase { NameStr, Kinds, Name }; FlowSearchByNameKindAndScopeFact { Name, Scope, Kinds, Entity } # with a bare string name and a known scope, search by kind predicate FlowSearchByNameKindAndScopeFact: { name: string, scope: maybe flow.Module, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity } { NameStr, MScope, Kinds, Entity } where # n.b no un-kinded entities in Flow, so we ignore the `nothing` case # the kinds are a bit inaccurate (i.e. no classes, all values are objects) { just = Kind } = Kinds; ( { just = Scope } = MScope; # nothing would imply these are global ( Object_ = Kind; flow.SearchDeclarationByName { NameStr, Scope, ODecl }; # we need to carefully remove import occurences as they're spammy !flow.ImportDeclaration { declaration = ODecl }; { localDecl = ODecl } = Decl; ) | ( Property = Kind; flow.SearchMemberDeclarationByName { NameStr, Scope, MDecl }; { memberDecl = MDecl } = Decl ) | ( Type = Kind; flow.SearchTypeDeclarationByName { NameStr, Scope, TDecl }; # and filter out forms of type import declarations !flow.TypeImportDeclaration { typeDeclaration = TDecl }; !(search.flow.TypeDeclarationAsDeclaration { TDecl, DeclImport }; flow.ImportDeclaration { declaration = DeclImport }); { typeDecl = TDecl } = Decl ); { flow = { decl = Decl } } = Entity ) | ( Module = Kind; nothing = MScope; # check its not scoped flow.SearchByModuleName { NameStr, Mod }; { flow = { module_ = Mod } } = Entity ) # Maps lower-case strings to normal Names, for case-insensitive search predicate FlowNameLowerCase : { nameLowercase : string, kinds: maybe codemarkup.types.SymbolKind, name : string, } { NameStr, Kinds, Name } where { just = Kind } = Kinds; ( Object_ = Kind; flow.SearchDeclarationByLowerCaseName { NameStr, Name } ) | ( Property = Kind; flow.SearchMemberDeclarationByLowerCaseName { NameStr, Name } ) | ( Type = Kind; flow.SearchTypeDeclarationByLowerCaseName { NameStr, Name } ) | ( Module = Kind; flow.SearchModuleByLowerCaseName { NameStr, Name } ) predicate JavaSearchByName: { name: string, entity: code.Entity, } { NameStr, Entity } where Name = javakotlin.alpha.Name NameStr; QName = javakotlin.alpha.QName { name = Name }; JavaSearchByNameWithFact { QName, Entity } predicate JavaSearchByLowerCaseName: { name: string, entity: code.Entity, } { NameStr, Entity } where javakotlin.alpha.NameLowerCase { NameStr, Name }; QName = javakotlin.alpha.QName { name = Name }; JavaSearchByNameWithFact { QName, Entity } predicate JavaSearchByNameWithFact: { name: javakotlin.alpha.QName, entity: code.Entity } { QName, { java = { decl = Decl } } } where search.java.SearchByQName { QName, Decl }; predicate JavaSearchByScope: { name: string, scope: [string], entity: code.Entity } { NameStr, Query, Entity } where Name = javakotlin.alpha.Name NameStr; Insensitive = false; JavaSearchByScopeWithName { Name, Insensitive, Query, Entity } predicate JavaSearchByLowerCaseScope: { name: string, scope: [string], entity: code.Entity, } { NameStr, Query, Entity } where javakotlin.alpha.NameLowerCase { NameStr, Name }; Insensitive = true; JavaSearchByScopeWithName { Name, Insensitive, Query, Entity } predicate JavaSearchByScopeWithName: { name: javakotlin.alpha.Name, insensitive : bool, scope: [string], entity: code.Entity, } { Name, Insensitive, Query, Entity } where search.java.QueryToScopeCase { Query, Insensitive, Path }; QName = javakotlin.alpha.QName { name = Name, context = Path }; search.java.SearchByQName { QName, Decl }; { java = { decl = Decl } } = Entity; predicate KotlinSearchByName: { name: string, entity: code.Entity, } { NameStr, Entity } where Name = javakotlin.alpha.Name NameStr; QName = javakotlin.alpha.QName { name = Name }; KotlinSearchByNameWithFact { QName, Entity } predicate KotlinSearchByLowerCaseName: { name: string, entity: code.Entity, } { NameStr, Entity } where javakotlin.alpha.NameLowerCase { NameStr, Name }; QName = javakotlin.alpha.QName { name = Name }; KotlinSearchByNameWithFact { QName, Entity } predicate KotlinSearchByNameWithFact: { name: javakotlin.alpha.QName, entity: code.Entity } { QName, { kotlin = { decl = Decl } } } where search.kotlin.SearchByQName { QName, Decl }; predicate KotlinSearchByScope: { name: string, scope: [string], entity: code.Entity } { NameStr, Query, Entity } where Name = javakotlin.alpha.Name NameStr; Insensitive = false; KotlinSearchByScopeWithName { Name, Insensitive, Query, Entity } predicate KotlinSearchByLowerCaseScope: { name: string, scope: [string], entity: code.Entity, } { NameStr, Query, Entity } where javakotlin.alpha.NameLowerCase { NameStr, Name }; Insensitive = true; KotlinSearchByScopeWithName { Name, Insensitive, Query, Entity } predicate KotlinSearchByScopeWithName: { name: javakotlin.alpha.Name, insensitive : bool, scope: [string], entity: code.Entity, } { Name, Insensitive, Query, Entity } where search.java.QueryToScopeCase { Query, Insensitive, Path }; # n.b. java QName = javakotlin.alpha.QName { name = Name, context = Path }; search.kotlin.SearchByQName { QName, Decl }; { kotlin = { decl = Decl } } = Entity; predicate CSharpSearchByName: { name: string, entity: code.Entity, } { NameStr, Entity } where Name = csharp.Name NameStr; csharp.SearchByName { Name, Defn }; { csharp = { decl = Defn } } = Entity predicate CSharpSearchByLowerCaseName: { name: string, entity: code.Entity, } { NameStr, Entity } where csharp.NameLowerCase { NameStr, Name }; csharp.SearchByName { Name, Defn }; { csharp = { decl = Defn } } = Entity predicate CxxSearchByScopeAndKind: { name: string, scope: [string], kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Query, Kinds, Entity } where search.cxx.QueryToScopeCase { Query, false, Scope }; CxxSearchByNameKindAndScopeFact { NameStr, Scope, Kinds, Entity } predicate CxxSearchByLowerCaseScopeAndKind: { name: string, scope: [string], kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity, } { NameStr, Query, Kinds, Entity } where search.cxx.QueryToScopeCase { Query, true, Scope }; CxxSearchByLowerCaseNameKindAndScopeFact { NameStr, Scope, Kinds, Entity }; # Maps lower-case strings to normal Names, for case-insensitive search predicate CxxNameLowerCase : { nameLowercase : string, kinds: maybe codemarkup.types.SymbolKind, name : string, } { NameLower, Kinds, Name } where { just = Kind } = Kinds; ( Namespace = Kind; cxx1.NamespaceLowerCase { NameLower, Name } ) | ( Class_ = Kind; cxx1.RecordClassLowerCase { NameLower, Name } ) | ( Struct = Kind; cxx1.RecordStructLowerCase { NameLower, Name } ) | ( Union = Kind; cxx1.RecordUnionLowerCase { NameLower, Name } ) | ( Enum_ = Kind; cxx1.EnumLowerCase { NameLower, Name } ) | ( Function = Kind; cxx1.FunctionLowerCase { NameLower, Name } ) | ( Variable = Kind; cxx1.VariableLowerCase { NameLower, Name }; ) | ( Enumerator = Kind; cxx1.EnumeratorLowerCase { NameLower, Name }; ) | ( Type = Kind; cxx1.TypeAliasLowerCase { NameLower, Name }; ) | ( Interface = Kind; cxx1.ObjcContainerInterfaceLowerCase { NameLower, Name }; ); # with a bare string name and a known scope, search by kind predicate CxxSearchByNameKindAndScopeFact: { name: string, scope : cxx1.Scope, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity } { NameStr, Scope, Kinds, Entity } where # n.b no un-kinded entities in C++, so we ignore the `nothing` case { just = Kind } = Kinds; ( Namespace = Kind; search.kind.cxx.SearchNamespace { NameStr, Scope, Ent }; ) | ( Class_ = Kind; search.kind.cxx.SearchClass { NameStr, Scope, Ent }; ) | ( Struct = Kind; search.kind.cxx.SearchStruct { NameStr, Scope, Ent }; ) | ( Union = Kind; search.kind.cxx.SearchUnion { NameStr, Scope, Ent }; ) | ( Enum_ = Kind; search.kind.cxx.SearchEnum { NameStr, Scope, Ent }; ) | ( Function = Kind; search.kind.cxx.SearchFunction { NameStr, Scope, Ent }; ) | ( Variable = Kind; search.kind.cxx.SearchVariable { NameStr, Scope, Ent }; ) | ( Enumerator = Kind; search.kind.cxx.SearchEnumerator { NameStr, Scope, Ent }; ) | ( Type = Kind; # type alias or using decl is a "Type" kind search.kind.cxx.SearchTypeAlias { NameStr, Scope, Ent }; ) | ( Interface = Kind; { global_ = {} } = Scope; # objc containers have global scope search.kind.cxx.SearchObjcInterface { NameStr, Ent }; ); CxxPreferDefinitions { Ent, OutEnt }; { cxx = OutEnt } = Entity; # lower case form predicate CxxSearchByLowerCaseNameKindAndScopeFact: { name: string, scope : cxx1.Scope, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity } { NameStr, Scope, Kinds, Entity } where CxxNameLowerCase { NameStr, Kinds, Name }; CxxSearchByNameKindAndScopeFact { Name, Scope, Kinds, Entity } # Helper for C++ to prefer definitions over declaration spam predicate CxxPreferDefinitions: { from: code.cxx.Entity , to : code.cxx.Entity } { InEnt, OutEnt } where if ({ decl = Decl } = InEnt) then ( # avoid returning all members of decl families if (search.cxx.DeclIsDefn { Decl, Defn }) then ({ defn = Defn } = OutEnt) else ({ decl = Decl } = OutEnt) ) else ( InEnt = OutEnt ); # already a defn (or enumerator) predicate PpSearchByNameKind: { name: string, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity } { NameStr, Kinds, { pp = { define = Define } } } where { just = Macro } = Kinds; # this avoids unnecessary #define searches pp1.Macro NameStr = Macro; pp1.Define { macro = Macro } = Define predicate PpSearchByLowerCaseNameKind: { name: string, kinds: maybe codemarkup.types.SymbolKind, entity: code.Entity } { NameStr, Kinds, { pp = { define = Define } } } where { just = Macro } = Kinds; # this avoids unnecessary #define searches pp1.DefineLowerCase { NameStr, Define } predicate ThriftSearchByName: { name: string, entity: code.Entity } { Name, Entity } where ( Ident = fbthrift.Identifier Name; FbthriftSearchByNameFact { Ident, Entity } ) predicate ThriftSearchByLowerCaseName: { name: string, entity: code.Entity } { NameStr, Entity } where ( fbthrift.NameLowerCase { NameStr, Ident }; FbthriftSearchByNameFact { Ident, Entity } ) predicate FbthriftSearchByNameFact: { name: fbthrift.Identifier, entity: code.Entity } { Ident, { fbthrift = { decl = Decl } }} where fbthrift.SearchByName { Ident, QName }; fbthrift.DeclarationName { QName, Decl } predicate BuckSearchByName: { name: string, entity: code.Entity, } { NameStr, Entity } where LocalName = buck.LocalName NameStr; BuckSearchByLocalNameFact { LocalName, Entity } predicate BuckSearchByLowerCaseName: { name: string, entity: code.Entity, } { NameStr, Entity } where buck.LocalNameLowerCase { NameStr, LocalName }; BuckSearchByLocalNameFact { LocalName, Entity } # helper to avoid repeatedly doing string search predicate BuckSearchByLocalNameFact: { name: buck.LocalName, entity: code.Entity, } { LocalName, { buck = Decl }} where buck.SearchByLocalName { LocalName, Decl } predicate AngleSearchByName: { name: string, entity: code.Entity, } { Name, { angle = E } } where search.anglelang.SearchByName { name = Name : string, entity = E } predicate AngleSearchByLowerCaseName: { name: string, entity: code.Entity, } { Name, { angle = Entity } } where search.anglelang.NameLowerCase { Name, NameCase }; search.anglelang.SearchByName { NameCase, Entity } predicate HsSearchByName: { name: string, entity: code.Entity, } { Name, { hs = E } } where search.hs.SearchByName { name = Name, entity = E } predicate HsSearchByLowerCaseName: { name: string, entity: code.Entity, } { Name, { hs = E } } where search.hs.SearchByLowerCaseName { name = Name, entity = E } predicate ErlangSearchByName: { name: string, entity: code.Entity, } { Name, { erlang = E } } where search.erlang.SearchByName { name = Name, entity = E } predicate ErlangSearchByLowerCaseName: { name: string, entity: code.Entity, } { Name, Entity } where erlang.NameLowerCase { Name, NameCase }; ErlangSearchByName { NameCase, Entity } predicate LsifSearchByName: { name: string, entity: code.Entity, } { Name, { lsif = Entity } } where lsif.SearchByName { lsif.Name Name, Entity } predicate LsifSearchByLowerCaseName: { name: string, entity: code.Entity, } { Name, { lsif = Entity } } where lsif.NameLowerCase { Name, NameCase }; lsif.SearchByName { NameCase, Entity } predicate GraphQLSearchByName: { name: string, entity: code.Entity, } { NameStr, Entity } where Name = graphql.Value NameStr; graphql.SearchByName { Name, Decl }; { graphql = { decl = Decl } } = Entity predicate GraphQLSearchByLowerCaseName: { name: string, entity: code.Entity, } { NameStr, Entity } where graphql.NameLowerCase { NameStr, Name }; graphql.SearchByName { Name, Decl }; { graphql = { decl = Decl } } = Entity }