1 // Copyright (c) Facebook, Inc. and its affiliates.
3 // This source code is licensed under the MIT license found in the
4 // LICENSE file in the "hack" directory of this source tree.
7 use pos::{ConstName, FunName, MethodName, PropName, TypeName};
10 pub type Result<T, E = Error> = std::result::Result<T, E>;
12 #[derive(thiserror::Error, Debug)]
15 // Implementations of `FoldedDeclProvider` need to be able to record
16 // dependencies (if needed). We do this by having the functions of this
17 // trait take a "who's asking?" symbol of this type.
18 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
25 impl From<FunName> for DeclName {
26 fn from(name: FunName) -> Self {
31 impl From<ConstName> for DeclName {
32 fn from(name: ConstName) -> Self {
37 impl From<TypeName> for DeclName {
38 fn from(name: TypeName) -> Self {
43 // nb(sf, 2022-03-15): c.f. ` Typing_deps.Dep.variant`
44 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
45 /// A node in the dependency graph that, when changed, must recheck all of its
47 pub enum DependencyName {
48 /// Represents another class depending on a class via an inheritance-like
49 /// mechanism (`extends`, `implements`, `use`, `require extends`, `require
50 /// implements`, etc.)
52 /// Represents something depending on a class constant.
54 /// Represents something depending on a class constructor.
55 Constructor(TypeName),
56 /// Represents something depending on a class's instance property.
57 Prop(TypeName, PropName),
58 /// Represents something depending on a class's static property.
59 StaticProp(TypeName, PropName),
60 /// Represents something depending on a class's instance method.
61 Method(TypeName, MethodName),
62 /// Represents something depending on a class's static method.
63 StaticMethod(TypeName, MethodName),
64 /// Represents something depending on all members of a class. Particularly
65 /// useful for switch exhaustiveness-checking. We establish a dependency on
66 /// all members of an enum in that case.
68 /// Represents something depending on a global constant.
70 /// Represents something depending on a global function.
72 /// Represents something depending on a class/typedef/trait/interface
76 /// Organize and administer dependency records.
77 pub trait DepGraphWriter: Debug + Send + Sync {
78 /// Record a dependency.
79 // e.g. If class B extends A {} then A <- B (B depends on A). So here,
80 // dependent is B and dependency is A.
81 fn add_dependency(&self, dependent: DeclName, dependency: DependencyName) -> Result<()>;
84 /// Query dependency records.
85 pub trait DepGraphReader: Debug + Send + Sync {
86 /// Retrieve dependents of a name.
87 fn get_dependents(&self, dependency: DependencyName) -> Box<dyn Iterator<Item = Dep>>;
90 /// A no-op implementation of the `DepGraphReader` & `DepGraphWriter` traits.
91 /// All registered edges are thrown away.
92 #[derive(Debug, Clone)]
93 pub struct NoDepGraph(());
96 pub fn new() -> Self {
101 impl DepGraphWriter for NoDepGraph {
102 fn add_dependency(&self, _dependent: DeclName, _dependency: DependencyName) -> Result<()> {
107 impl DepGraphReader for NoDepGraph {
108 fn get_dependents(&self, _dependency: DependencyName) -> Box<dyn Iterator<Item = Dep>> {
109 Box::new(std::iter::empty())
113 /// Read & write dependency records.
114 pub trait DepGraph: DepGraphReader + DepGraphWriter {}
115 impl<T: DepGraphReader + DepGraphWriter> DepGraph for T {}