Implement naming table functionality in hackrs_provider_backend
[hiphop-php.git] / hphp / hack / src / rupro / naming_provider / naming_provider.rs
blob5fda1581103024e55d2c6b866ad1479b2bbd4098
1 // Copyright (c) Meta Platforms, Inc. and affiliates.
2 //
3 // This source code is licensed under the MIT license found in the
4 // LICENSE file in the "hack" directory of this source tree.
6 use hh24_types::ToplevelSymbolHash;
7 use oxidized::file_info::NameType;
8 use parking_lot::Mutex;
9 use pos::{ConstName, FunName, RelativePath, TypeName};
10 use std::fmt::{self, Debug};
11 use std::path::Path;
13 /// An abstraction over the global symbol table. Should be used by
14 /// `LazyShallowDeclProvider` only, since folding and typechecking logic should
15 /// have no need for a `NamingProvider`.
16 pub trait NamingProvider: Debug + Send + Sync {
17     fn get_type_path(&self, name: TypeName) -> Result<Option<RelativePath>>;
18     fn get_fun_path(&self, name: FunName) -> Result<Option<RelativePath>>;
19     fn get_const_path(&self, name: ConstName) -> Result<Option<RelativePath>>;
22 pub type Result<T, E = Error> = std::result::Result<T, E>;
24 #[derive(thiserror::Error, Debug)]
25 pub enum Error {
26     #[error("Failed to read SQLite naming table: {0}")]
27     Sqlite(#[from] rusqlite::Error),
30 /// A naming table in a SQLite database (with the same database schema as
31 /// hh_server's SQLite saved states).
32 pub struct SqliteNamingTable {
33     names: Mutex<names::Names>,
36 impl SqliteNamingTable {
37     pub fn new(path: impl AsRef<Path>) -> rusqlite::Result<Self> {
38         Ok(Self {
39             names: Mutex::new(names::Names::from_file(path)?),
40         })
41     }
43     pub fn get_type_path_and_kind(
44         &self,
45         name: TypeName,
46     ) -> Result<Option<(RelativePath, NameType)>> {
47         let path_opt = self
48             .names
49             .lock()
50             .get_filename(ToplevelSymbolHash::from_type(name.as_str()))?;
51         Ok(path_opt.map(|(path, kind)| (RelativePath::from(&path), kind)))
52     }
55 impl NamingProvider for SqliteNamingTable {
56     fn get_type_path(&self, name: TypeName) -> Result<Option<RelativePath>> {
57         let path_opt = self
58             .names
59             .lock()
60             .get_path_by_symbol_hash(ToplevelSymbolHash::from_type(name.as_str()))?;
61         Ok(path_opt.map(|path| RelativePath::new(path.prefix(), path.path())))
62     }
63     fn get_fun_path(&self, name: FunName) -> Result<Option<RelativePath>> {
64         let path_opt = self
65             .names
66             .lock()
67             .get_path_by_symbol_hash(ToplevelSymbolHash::from_fun(name.as_str()))?;
68         Ok(path_opt.map(|path| RelativePath::new(path.prefix(), path.path())))
69     }
70     fn get_const_path(&self, name: ConstName) -> Result<Option<RelativePath>> {
71         let path_opt = self
72             .names
73             .lock()
74             .get_path_by_symbol_hash(ToplevelSymbolHash::from_const(name.as_str()))?;
75         Ok(path_opt.map(|path| RelativePath::new(path.prefix(), path.path())))
76     }
79 impl Debug for SqliteNamingTable {
80     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81         write!(f, "SqliteNamingTable")
82     }