Rename directory hhbc to hackc
[hiphop-php.git] / hphp / hack / src / hackc / bytecode_printer / context.rs
blob4052fcabc66c1130ba101730507590e6445bb9be
1 // Copyright (c) Facebook, Inc. and its 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 crate::{special_class_resolver::SpecialClassResolver, write::newline};
7 use env::emitter::Emitter;
8 use oxidized::relative_path::RelativePath;
9 use std::collections::BTreeMap;
10 use std::io::{Result, Write};
12 /// Indent is an abstraction of indentation. Configurable indentation
13 /// and perf tweaking will be easier.
14 #[derive(Clone)]
15 struct Indent(usize);
17 impl Indent {
18     fn new() -> Self {
19         Self(0)
20     }
22     fn inc(&mut self) {
23         self.0 += 1;
24     }
26     fn dec(&mut self) {
27         self.0 -= 1;
28     }
30     fn write(&self, w: &mut dyn Write) -> Result<()> {
31         for _ in 0..self.0 {
32             w.write_all(b"  ")?;
33         }
34         Ok(())
35     }
38 #[derive(Clone)]
39 pub struct Context<'a> {
40     pub(crate) special_class_resolver: &'a dyn SpecialClassResolver,
41     pub(crate) path: Option<&'a RelativePath>,
43     dump_symbol_refs: bool,
44     pub(crate) dump_lambdas: bool,
45     indent: Indent,
46     is_system_lib: bool,
48     pub(crate) include_roots: &'a BTreeMap<String, String>,
49     pub(crate) include_search_paths: &'a [String],
50     pub(crate) doc_root: &'a str,
51     pub(crate) array_provenance: bool,
54 impl<'a> Context<'a> {
55     pub fn new<'arena, 'decl>(
56         emitter: &'a Emitter<'arena, 'decl>,
57         path: Option<&'a RelativePath>,
58         dump_symbol_refs: bool,
59         is_system_lib: bool,
60     ) -> Self {
61         let include_roots = emitter.options().hhvm.include_roots.get();
62         let include_search_paths = emitter.options().server.include_search_paths.get();
63         let doc_root = emitter.options().doc_root.get();
64         let array_provenance = emitter.options().array_provenance();
66         Self {
67             special_class_resolver: emitter,
68             path,
69             dump_symbol_refs,
70             dump_lambdas: false,
71             indent: Indent::new(),
72             is_system_lib,
74             include_roots,
75             include_search_paths,
76             doc_root,
77             array_provenance,
78         }
79     }
81     pub(crate) fn dump_symbol_refs(&self) -> bool {
82         self.dump_symbol_refs
83     }
85     /// Insert a newline with indentation
86     pub(crate) fn newline(&self, w: &mut dyn Write) -> Result<()> {
87         newline(w)?;
88         self.indent.write(w)
89     }
91     /// Start a new indented block
92     pub(crate) fn block<F>(&self, w: &mut dyn Write, f: F) -> Result<()>
93     where
94         F: FnOnce(&Self, &mut dyn Write) -> Result<()>,
95     {
96         let mut ctx = self.clone();
97         ctx.indent.inc();
98         f(&ctx, w)
99     }
101     pub(crate) fn unblock<F>(&self, w: &mut dyn Write, f: F) -> Result<()>
102     where
103         F: FnOnce(&Self, &mut dyn Write) -> Result<()>,
104     {
105         let mut ctx = self.clone();
106         ctx.indent.dec();
107         f(&ctx, w)
108     }
110     /// Printing instruction list requies manually control indentation,
111     /// where indent_inc/indent_dec are called
112     pub(crate) fn indent_inc(&mut self) {
113         self.indent.inc();
114     }
116     pub(crate) fn indent_dec(&mut self) {
117         self.indent.dec();
118     }
120     pub(crate) fn is_system_lib(&self) -> bool {
121         self.is_system_lib
122     }