/src/librustc_save_analysis/json_dumper.rs

https://gitlab.com/alx741/rust · Rust · 651 lines · 542 code · 82 blank · 27 comment · 32 complexity · 03c09b38cdf0b57e1b2b0e053f12989f MD5 · raw file

  1. // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // http://rust-lang.org/COPYRIGHT.
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. use std::io::Write;
  11. use rustc_serialize::json::as_json;
  12. use syntax::codemap::CodeMap;
  13. use syntax::ast::CrateNum;
  14. use super::data::{self, SpanData};
  15. use super::dump::Dump;
  16. pub struct JsonDumper<'a, 'b, W: Write + 'b> {
  17. output: &'b mut W,
  18. codemap: &'a CodeMap,
  19. first: bool,
  20. }
  21. impl<'a, 'b, W: Write> JsonDumper<'a, 'b, W> {
  22. pub fn new(writer: &'b mut W, codemap: &'a CodeMap) -> JsonDumper<'a, 'b, W> {
  23. if let Err(_) = write!(writer, "[") {
  24. error!("Error writing output");
  25. }
  26. JsonDumper { output: writer, codemap:codemap, first: true }
  27. }
  28. }
  29. impl<'a, 'b, W: Write> Drop for JsonDumper<'a, 'b, W> {
  30. fn drop(&mut self) {
  31. if let Err(_) = write!(self.output, "]") {
  32. error!("Error writing output");
  33. }
  34. }
  35. }
  36. macro_rules! impl_fn {
  37. ($fn_name: ident, $data_type: ident) => {
  38. fn $fn_name(&mut self, data: data::$data_type) {
  39. if self.first {
  40. self.first = false;
  41. } else {
  42. if let Err(_) = write!(self.output, ",") {
  43. error!("Error writing output");
  44. }
  45. }
  46. let data = data.lower(self.codemap);
  47. if let Err(_) = write!(self.output, "{}", as_json(&data)) {
  48. error!("Error writing output '{}'", as_json(&data));
  49. }
  50. }
  51. }
  52. }
  53. impl<'a, 'b, W: Write + 'b> Dump for JsonDumper<'a, 'b, W> {
  54. impl_fn!(crate_prelude, CratePreludeData);
  55. impl_fn!(enum_data, EnumData);
  56. impl_fn!(extern_crate, ExternCrateData);
  57. impl_fn!(impl_data, ImplData);
  58. impl_fn!(inheritance, InheritanceData);
  59. impl_fn!(function, FunctionData);
  60. impl_fn!(function_ref, FunctionRefData);
  61. impl_fn!(function_call, FunctionCallData);
  62. impl_fn!(method, MethodData);
  63. impl_fn!(method_call, MethodCallData);
  64. impl_fn!(macro_data, MacroData);
  65. impl_fn!(macro_use, MacroUseData);
  66. impl_fn!(mod_data, ModData);
  67. impl_fn!(mod_ref, ModRefData);
  68. impl_fn!(struct_data, StructData);
  69. impl_fn!(struct_variant, StructVariantData);
  70. impl_fn!(trait_data, TraitData);
  71. impl_fn!(tuple_variant, TupleVariantData);
  72. impl_fn!(type_ref, TypeRefData);
  73. impl_fn!(typedef, TypedefData);
  74. impl_fn!(use_data, UseData);
  75. impl_fn!(use_glob, UseGlobData);
  76. impl_fn!(variable, VariableData);
  77. impl_fn!(variable_ref, VariableRefData);
  78. }
  79. trait Lower {
  80. type Target;
  81. fn lower(self, cm: &CodeMap) -> Self::Target;
  82. }
  83. pub type Id = u32;
  84. #[derive(Debug, RustcEncodable)]
  85. pub struct CratePreludeData {
  86. pub crate_name: String,
  87. pub crate_root: String,
  88. pub external_crates: Vec<data::ExternalCrateData>,
  89. pub span: SpanData,
  90. }
  91. impl Lower for data::CratePreludeData {
  92. type Target = CratePreludeData;
  93. fn lower(self, cm: &CodeMap) -> CratePreludeData {
  94. CratePreludeData {
  95. crate_name: self.crate_name,
  96. crate_root: self.crate_root,
  97. external_crates: self.external_crates,
  98. span: SpanData::from_span(self.span, cm),
  99. }
  100. }
  101. }
  102. /// Data for enum declarations.
  103. #[derive(Clone, Debug, RustcEncodable)]
  104. pub struct EnumData {
  105. pub id: Id,
  106. pub value: String,
  107. pub qualname: String,
  108. pub span: SpanData,
  109. pub scope: Id,
  110. }
  111. impl Lower for data::EnumData {
  112. type Target = EnumData;
  113. fn lower(self, cm: &CodeMap) -> EnumData {
  114. EnumData {
  115. id: self.id,
  116. value: self.value,
  117. qualname: self.qualname,
  118. span: SpanData::from_span(self.span, cm),
  119. scope: self.scope,
  120. }
  121. }
  122. }
  123. /// Data for extern crates.
  124. #[derive(Debug, RustcEncodable)]
  125. pub struct ExternCrateData {
  126. pub id: Id,
  127. pub name: String,
  128. pub crate_num: CrateNum,
  129. pub location: String,
  130. pub span: SpanData,
  131. pub scope: Id,
  132. }
  133. impl Lower for data::ExternCrateData {
  134. type Target = ExternCrateData;
  135. fn lower(self, cm: &CodeMap) -> ExternCrateData {
  136. ExternCrateData {
  137. id: self.id,
  138. name: self.name,
  139. crate_num: self.crate_num,
  140. location: self.location,
  141. span: SpanData::from_span(self.span, cm),
  142. scope: self.scope,
  143. }
  144. }
  145. }
  146. /// Data about a function call.
  147. #[derive(Debug, RustcEncodable)]
  148. pub struct FunctionCallData {
  149. pub span: SpanData,
  150. pub scope: Id,
  151. pub ref_id: Id,
  152. }
  153. impl Lower for data::FunctionCallData {
  154. type Target = FunctionCallData;
  155. fn lower(self, cm: &CodeMap) -> FunctionCallData {
  156. FunctionCallData {
  157. span: SpanData::from_span(self.span, cm),
  158. scope: self.scope,
  159. ref_id: self.ref_id.index.as_u32(),
  160. }
  161. }
  162. }
  163. /// Data for all kinds of functions and methods.
  164. #[derive(Clone, Debug, RustcEncodable)]
  165. pub struct FunctionData {
  166. pub id: Id,
  167. pub name: String,
  168. pub qualname: String,
  169. pub declaration: Option<Id>,
  170. pub span: SpanData,
  171. pub scope: Id,
  172. }
  173. impl Lower for data::FunctionData {
  174. type Target = FunctionData;
  175. fn lower(self, cm: &CodeMap) -> FunctionData {
  176. FunctionData {
  177. id: self.id,
  178. name: self.name,
  179. qualname: self.qualname,
  180. declaration: self.declaration.map(|id| id.index.as_u32()),
  181. span: SpanData::from_span(self.span, cm),
  182. scope: self.scope,
  183. }
  184. }
  185. }
  186. /// Data about a function call.
  187. #[derive(Debug, RustcEncodable)]
  188. pub struct FunctionRefData {
  189. pub span: SpanData,
  190. pub scope: Id,
  191. pub ref_id: Id,
  192. }
  193. impl Lower for data::FunctionRefData {
  194. type Target = FunctionRefData;
  195. fn lower(self, cm: &CodeMap) -> FunctionRefData {
  196. FunctionRefData {
  197. span: SpanData::from_span(self.span, cm),
  198. scope: self.scope,
  199. ref_id: self.ref_id.index.as_u32(),
  200. }
  201. }
  202. }
  203. #[derive(Debug, RustcEncodable)]
  204. pub struct ImplData {
  205. pub id: Id,
  206. pub span: SpanData,
  207. pub scope: Id,
  208. pub trait_ref: Option<Id>,
  209. pub self_ref: Option<Id>,
  210. }
  211. impl Lower for data::ImplData {
  212. type Target = ImplData;
  213. fn lower(self, cm: &CodeMap) -> ImplData {
  214. ImplData {
  215. id: self.id,
  216. span: SpanData::from_span(self.span, cm),
  217. scope: self.scope,
  218. trait_ref: self.trait_ref.map(|id| id.index.as_u32()),
  219. self_ref: self.self_ref.map(|id| id.index.as_u32()),
  220. }
  221. }
  222. }
  223. #[derive(Debug, RustcEncodable)]
  224. pub struct InheritanceData {
  225. pub span: SpanData,
  226. pub base_id: Id,
  227. pub deriv_id: Id
  228. }
  229. impl Lower for data::InheritanceData {
  230. type Target = InheritanceData;
  231. fn lower(self, cm: &CodeMap) -> InheritanceData {
  232. InheritanceData {
  233. span: SpanData::from_span(self.span, cm),
  234. base_id: self.base_id.index.as_u32(),
  235. deriv_id: self.deriv_id
  236. }
  237. }
  238. }
  239. /// Data about a macro declaration.
  240. #[derive(Debug, RustcEncodable)]
  241. pub struct MacroData {
  242. pub span: SpanData,
  243. pub name: String,
  244. pub qualname: String,
  245. }
  246. impl Lower for data::MacroData {
  247. type Target = MacroData;
  248. fn lower(self, cm: &CodeMap) -> MacroData {
  249. MacroData {
  250. span: SpanData::from_span(self.span, cm),
  251. name: self.name,
  252. qualname: self.qualname,
  253. }
  254. }
  255. }
  256. /// Data about a macro use.
  257. #[derive(Debug, RustcEncodable)]
  258. pub struct MacroUseData {
  259. pub span: SpanData,
  260. pub name: String,
  261. pub qualname: String,
  262. // Because macro expansion happens before ref-ids are determined,
  263. // we use the callee span to reference the associated macro definition.
  264. pub callee_span: SpanData,
  265. pub scope: Id,
  266. pub imported: bool,
  267. }
  268. impl Lower for data::MacroUseData {
  269. type Target = MacroUseData;
  270. fn lower(self, cm: &CodeMap) -> MacroUseData {
  271. MacroUseData {
  272. span: SpanData::from_span(self.span, cm),
  273. name: self.name,
  274. qualname: self.qualname,
  275. callee_span: SpanData::from_span(self.callee_span, cm),
  276. scope: self.scope,
  277. imported: self.imported,
  278. }
  279. }
  280. }
  281. /// Data about a method call.
  282. #[derive(Debug, RustcEncodable)]
  283. pub struct MethodCallData {
  284. pub span: SpanData,
  285. pub scope: Id,
  286. pub ref_id: Option<Id>,
  287. pub decl_id: Option<Id>,
  288. }
  289. impl Lower for data::MethodCallData {
  290. type Target = MethodCallData;
  291. fn lower(self, cm: &CodeMap) -> MethodCallData {
  292. MethodCallData {
  293. span: SpanData::from_span(self.span, cm),
  294. scope: self.scope,
  295. ref_id: self.ref_id.map(|id| id.index.as_u32()),
  296. decl_id: self.decl_id.map(|id| id.index.as_u32()),
  297. }
  298. }
  299. }
  300. /// Data for method declarations (methods with a body are treated as functions).
  301. #[derive(Clone, Debug, RustcEncodable)]
  302. pub struct MethodData {
  303. pub id: Id,
  304. pub qualname: String,
  305. pub span: SpanData,
  306. pub scope: Id,
  307. }
  308. impl Lower for data::MethodData {
  309. type Target = MethodData;
  310. fn lower(self, cm: &CodeMap) -> MethodData {
  311. MethodData {
  312. span: SpanData::from_span(self.span, cm),
  313. scope: self.scope,
  314. id: self.id,
  315. qualname: self.qualname,
  316. }
  317. }
  318. }
  319. /// Data for modules.
  320. #[derive(Debug, RustcEncodable)]
  321. pub struct ModData {
  322. pub id: Id,
  323. pub name: String,
  324. pub qualname: String,
  325. pub span: SpanData,
  326. pub scope: Id,
  327. pub filename: String,
  328. }
  329. impl Lower for data::ModData {
  330. type Target = ModData;
  331. fn lower(self, cm: &CodeMap) -> ModData {
  332. ModData {
  333. id: self.id,
  334. name: self.name,
  335. qualname: self.qualname,
  336. span: SpanData::from_span(self.span, cm),
  337. scope: self.scope,
  338. filename: self.filename,
  339. }
  340. }
  341. }
  342. /// Data for a reference to a module.
  343. #[derive(Debug, RustcEncodable)]
  344. pub struct ModRefData {
  345. pub span: SpanData,
  346. pub scope: Id,
  347. pub ref_id: Option<Id>,
  348. pub qualname: String
  349. }
  350. impl Lower for data::ModRefData {
  351. type Target = ModRefData;
  352. fn lower(self, cm: &CodeMap) -> ModRefData {
  353. ModRefData {
  354. span: SpanData::from_span(self.span, cm),
  355. scope: self.scope,
  356. ref_id: self.ref_id.map(|id| id.index.as_u32()),
  357. qualname: self.qualname,
  358. }
  359. }
  360. }
  361. #[derive(Debug, RustcEncodable)]
  362. pub struct StructData {
  363. pub span: SpanData,
  364. pub id: Id,
  365. pub ctor_id: Id,
  366. pub qualname: String,
  367. pub scope: Id,
  368. pub value: String
  369. }
  370. impl Lower for data::StructData {
  371. type Target = StructData;
  372. fn lower(self, cm: &CodeMap) -> StructData {
  373. StructData {
  374. span: SpanData::from_span(self.span, cm),
  375. id: self.id,
  376. ctor_id: self.ctor_id,
  377. qualname: self.qualname,
  378. scope: self.scope,
  379. value: self.value
  380. }
  381. }
  382. }
  383. #[derive(Debug, RustcEncodable)]
  384. pub struct StructVariantData {
  385. pub span: SpanData,
  386. pub id: Id,
  387. pub qualname: String,
  388. pub type_value: String,
  389. pub value: String,
  390. pub scope: Id
  391. }
  392. impl Lower for data::StructVariantData {
  393. type Target = StructVariantData;
  394. fn lower(self, cm: &CodeMap) -> StructVariantData {
  395. StructVariantData {
  396. span: SpanData::from_span(self.span, cm),
  397. id: self.id,
  398. qualname: self.qualname,
  399. type_value: self.type_value,
  400. value: self.value,
  401. scope: self.scope,
  402. }
  403. }
  404. }
  405. #[derive(Debug, RustcEncodable)]
  406. pub struct TraitData {
  407. pub span: SpanData,
  408. pub id: Id,
  409. pub qualname: String,
  410. pub scope: Id,
  411. pub value: String
  412. }
  413. impl Lower for data::TraitData {
  414. type Target = TraitData;
  415. fn lower(self, cm: &CodeMap) -> TraitData {
  416. TraitData {
  417. span: SpanData::from_span(self.span, cm),
  418. id: self.id,
  419. qualname: self.qualname,
  420. scope: self.scope,
  421. value: self.value,
  422. }
  423. }
  424. }
  425. #[derive(Debug, RustcEncodable)]
  426. pub struct TupleVariantData {
  427. pub span: SpanData,
  428. pub id: Id,
  429. pub name: String,
  430. pub qualname: String,
  431. pub type_value: String,
  432. pub value: String,
  433. pub scope: Id,
  434. }
  435. impl Lower for data::TupleVariantData {
  436. type Target = TupleVariantData;
  437. fn lower(self, cm: &CodeMap) -> TupleVariantData {
  438. TupleVariantData {
  439. span: SpanData::from_span(self.span, cm),
  440. id: self.id,
  441. name: self.name,
  442. qualname: self.qualname,
  443. type_value: self.type_value,
  444. value: self.value,
  445. scope: self.scope,
  446. }
  447. }
  448. }
  449. /// Data for a typedef.
  450. #[derive(Debug, RustcEncodable)]
  451. pub struct TypedefData {
  452. pub id: Id,
  453. pub span: SpanData,
  454. pub qualname: String,
  455. pub value: String,
  456. }
  457. impl Lower for data::TypedefData {
  458. type Target = TypedefData;
  459. fn lower(self, cm: &CodeMap) -> TypedefData {
  460. TypedefData {
  461. id: self.id,
  462. span: SpanData::from_span(self.span, cm),
  463. qualname: self.qualname,
  464. value: self.value,
  465. }
  466. }
  467. }
  468. /// Data for a reference to a type or trait.
  469. #[derive(Clone, Debug, RustcEncodable)]
  470. pub struct TypeRefData {
  471. pub span: SpanData,
  472. pub scope: Id,
  473. pub ref_id: Option<Id>,
  474. pub qualname: String,
  475. }
  476. impl Lower for data::TypeRefData {
  477. type Target = TypeRefData;
  478. fn lower(self, cm: &CodeMap) -> TypeRefData {
  479. TypeRefData {
  480. span: SpanData::from_span(self.span, cm),
  481. scope: self.scope,
  482. ref_id: self.ref_id.map(|id| id.index.as_u32()),
  483. qualname: self.qualname,
  484. }
  485. }
  486. }
  487. #[derive(Debug, RustcEncodable)]
  488. pub struct UseData {
  489. pub id: Id,
  490. pub span: SpanData,
  491. pub name: String,
  492. pub mod_id: Option<Id>,
  493. pub scope: Id
  494. }
  495. impl Lower for data::UseData {
  496. type Target = UseData;
  497. fn lower(self, cm: &CodeMap) -> UseData {
  498. UseData {
  499. id: self.id,
  500. span: SpanData::from_span(self.span, cm),
  501. name: self.name,
  502. mod_id: self.mod_id.map(|id| id.index.as_u32()),
  503. scope: self.scope,
  504. }
  505. }
  506. }
  507. #[derive(Debug, RustcEncodable)]
  508. pub struct UseGlobData {
  509. pub id: Id,
  510. pub span: SpanData,
  511. pub names: Vec<String>,
  512. pub scope: Id
  513. }
  514. impl Lower for data::UseGlobData {
  515. type Target = UseGlobData;
  516. fn lower(self, cm: &CodeMap) -> UseGlobData {
  517. UseGlobData {
  518. id: self.id,
  519. span: SpanData::from_span(self.span, cm),
  520. names: self.names,
  521. scope: self.scope,
  522. }
  523. }
  524. }
  525. /// Data for local and global variables (consts and statics).
  526. #[derive(Debug, RustcEncodable)]
  527. pub struct VariableData {
  528. pub id: Id,
  529. pub name: String,
  530. pub qualname: String,
  531. pub span: SpanData,
  532. pub scope: Id,
  533. pub value: String,
  534. pub type_value: String,
  535. }
  536. impl Lower for data::VariableData {
  537. type Target = VariableData;
  538. fn lower(self, cm: &CodeMap) -> VariableData {
  539. VariableData {
  540. id: self.id,
  541. name: self.name,
  542. qualname: self.qualname,
  543. span: SpanData::from_span(self.span, cm),
  544. scope: self.scope,
  545. value: self.value,
  546. type_value: self.type_value,
  547. }
  548. }
  549. }
  550. /// Data for the use of some item (e.g., the use of a local variable, which
  551. /// will refer to that variables declaration (by ref_id)).
  552. #[derive(Debug, RustcEncodable)]
  553. pub struct VariableRefData {
  554. pub name: String,
  555. pub span: SpanData,
  556. pub scope: Id,
  557. pub ref_id: Id,
  558. }
  559. impl Lower for data::VariableRefData {
  560. type Target = VariableRefData;
  561. fn lower(self, cm: &CodeMap) -> VariableRefData {
  562. VariableRefData {
  563. name: self.name,
  564. span: SpanData::from_span(self.span, cm),
  565. scope: self.scope,
  566. ref_id: self.ref_id.index.as_u32(),
  567. }
  568. }
  569. }