json_dumper.rs 13.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::io::Write;

use rustc_serialize::json::as_json;

15
use rls_data::{self, Id, Analysis, Import, ImportKind, Def, DefKind, Ref, RefKind, MacroRef,
N
Nick Cameron 已提交
16
               Relation, RelationKind, CratePreludeData};
17
use rls_span::{Column, Row};
18

19
use external_data::*;
N
Nick Cameron 已提交
20
use data::VariableKind;
21
use dump::Dump;
N
Nick Cameron 已提交
22
use id_from_def_id;
23

24
pub struct JsonDumper<O: DumpOutput> {
25
    result: Analysis,
26
    output: O,
27 28
}

29 30
pub trait DumpOutput {
    fn dump(&mut self, result: &Analysis);
31 32
}

33 34 35 36 37 38 39
pub struct WriteOutput<'b, W: Write + 'b> {
    output: &'b mut W,
}

impl<'b, W: Write> DumpOutput for WriteOutput<'b, W> {
    fn dump(&mut self, result: &Analysis) {
        if let Err(_) = write!(self.output, "{}", as_json(&result)) {
40 41
            error!("Error writing output");
        }
42 43 44
    }
}

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
pub struct CallbackOutput<'b> {
    callback: &'b mut FnMut(&Analysis),
}

impl<'b> DumpOutput for CallbackOutput<'b> {
    fn dump(&mut self, result: &Analysis) {
        (self.callback)(result)
    }
}

impl<'b, W: Write> JsonDumper<WriteOutput<'b, W>> {
    pub fn new(writer: &'b mut W) -> JsonDumper<WriteOutput<'b, W>> {
        JsonDumper { output: WriteOutput { output: writer }, result: Analysis::new() }
    }
}

impl<'b> JsonDumper<CallbackOutput<'b>> {
    pub fn with_callback(callback: &'b mut FnMut(&Analysis)) -> JsonDumper<CallbackOutput<'b>> {
        JsonDumper { output: CallbackOutput { callback: callback }, result: Analysis::new() }
    }
}

impl<O: DumpOutput> Drop for JsonDumper<O> {
    fn drop(&mut self) {
        self.output.dump(&self.result);
    }
}

73
macro_rules! impl_fn {
74
    ($fn_name: ident, $data_type: ident, $bucket: ident) => {
75
        fn $fn_name(&mut self, data: $data_type) {
76
            self.result.$bucket.push(data.into());
77
        }
78 79 80
    }
}

81
impl<'b, O: DumpOutput + 'b> Dump for JsonDumper<O> {
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
    fn crate_prelude(&mut self, data: CratePreludeData) {
        self.result.prelude = Some(data)
    }

    impl_fn!(extern_crate, ExternCrateData, imports);
    impl_fn!(use_data, UseData, imports);
    impl_fn!(use_glob, UseGlobData, imports);

    impl_fn!(enum_data, EnumData, defs);
    impl_fn!(tuple_variant, TupleVariantData, defs);
    impl_fn!(struct_variant, StructVariantData, defs);
    impl_fn!(struct_data, StructData, defs);
    impl_fn!(trait_data, TraitData, defs);
    impl_fn!(function, FunctionData, defs);
    impl_fn!(method, MethodData, defs);
    impl_fn!(macro_data, MacroData, defs);
    impl_fn!(typedef, TypeDefData, defs);
    impl_fn!(variable, VariableData, defs);

    impl_fn!(function_ref, FunctionRefData, refs);
    impl_fn!(function_call, FunctionCallData, refs);
    impl_fn!(method_call, MethodCallData, refs);
    impl_fn!(mod_ref, ModRefData, refs);
    impl_fn!(type_ref, TypeRefData, refs);
    impl_fn!(variable_ref, VariableRefData, refs);

    impl_fn!(macro_use, MacroUseData, macro_refs);

110
    fn mod_data(&mut self, data: ModData) {
111
        let id: Id = id_from_def_id(data.id);
112 113 114
        let mut def = Def {
            kind: DefKind::Mod,
            id: id,
115
            span: data.span.into(),
116 117 118
            name: data.name,
            qualname: data.qualname,
            value: data.filename,
119 120
            parent: None,
            children: data.items.into_iter().map(|id| id_from_def_id(id)).collect(),
121 122
            decl_id: None,
            docs: data.docs,
N
Nick Cameron 已提交
123
            sig: data.sig,
124
            attributes: data.attributes.into_iter().map(|a| a.into()).collect(),
125
        };
126
        if def.span.file_name.to_str().unwrap() != def.value {
127 128 129 130 131 132 133 134 135
            // If the module is an out-of-line defintion, then we'll make the
            // defintion the first character in the module's file and turn the
            // the declaration into a reference to it.
            let rf = Ref {
                kind: RefKind::Mod,
                span: def.span,
                ref_id: id,
            };
            self.result.refs.push(rf);
136 137
            def.span = rls_data::SpanData {
                file_name: def.value.clone().into(),
138 139
                byte_start: 0,
                byte_end: 0,
140 141 142 143
                line_start: Row::new_one_indexed(1),
                line_end: Row::new_one_indexed(1),
                column_start: Column::new_one_indexed(1),
                column_end: Column::new_one_indexed(1),
144 145 146 147 148 149
            }
        }

        self.result.defs.push(def);
    }

150 151
    fn impl_data(&mut self, data: ImplData) {
        if data.self_ref.is_some() {
152
            self.result.relations.push(data.into());
153 154 155
        }
    }
    fn inheritance(&mut self, data: InheritanceData) {
156
        self.result.relations.push(data.into());
157
    }
158 159 160 161 162 163 164 165
}

// FIXME do we want to change ExternalData to this mode? It will break DXR.
// FIXME methods. The defs have information about possible overriding and the
// refs have decl information (e.g., a trait method where we know the required
// method, but not the supplied method). In both cases, we are currently
// ignoring it.

166 167
impl Into<Import> for ExternCrateData {
    fn into(self) -> Import {
168 169
        Import {
            kind: ImportKind::ExternCrate,
170
            ref_id: None,
171 172
            span: self.span,
            name: self.name,
173 174 175 176
            value: String::new(),
        }
    }
}
177 178
impl Into<Import> for UseData {
    fn into(self) -> Import {
179 180
        Import {
            kind: ImportKind::Use,
181 182 183
            ref_id: self.mod_id.map(|id| id_from_def_id(id)),
            span: self.span,
            name: self.name,
184 185 186 187
            value: String::new(),
        }
    }
}
188 189
impl Into<Import> for UseGlobData {
    fn into(self) -> Import {
190 191
        Import {
            kind: ImportKind::GlobUse,
192
            ref_id: None,
193
            span: self.span,
194
            name: "*".to_owned(),
195
            value: self.names.join(", "),
196 197 198 199
        }
    }
}

200 201
impl Into<Def> for EnumData {
    fn into(self) -> Def {
202 203
        Def {
            kind: DefKind::Enum,
204 205 206 207 208 209 210
            id: id_from_def_id(self.id),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
            value: self.value,
            parent: None,
            children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(),
211
            decl_id: None,
212
            docs: self.docs,
N
Nick Cameron 已提交
213
            sig: self.sig,
N
Nick Cameron 已提交
214
            attributes: self.attributes,
215 216 217 218
        }
    }
}

219 220
impl Into<Def> for TupleVariantData {
    fn into(self) -> Def {
221 222
        Def {
            kind: DefKind::Tuple,
223 224 225 226 227 228
            id: id_from_def_id(self.id),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
            value: self.value,
            parent: None,
229
            children: vec![],
230
            decl_id: None,
231
            docs: self.docs,
N
Nick Cameron 已提交
232
            sig: self.sig,
N
Nick Cameron 已提交
233
            attributes: self.attributes,
234 235 236
        }
    }
}
237 238
impl Into<Def> for StructVariantData {
    fn into(self) -> Def {
239 240
        Def {
            kind: DefKind::Struct,
241 242 243 244 245 246
            id: id_from_def_id(self.id),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
            value: self.value,
            parent: None,
247
            children: vec![],
248
            decl_id: None,
249
            docs: self.docs,
N
Nick Cameron 已提交
250
            sig: self.sig,
N
Nick Cameron 已提交
251
            attributes: self.attributes,
252 253 254
        }
    }
}
255 256
impl Into<Def> for StructData {
    fn into(self) -> Def {
257 258
        Def {
            kind: DefKind::Struct,
259 260 261 262 263 264 265
            id: id_from_def_id(self.id),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
            value: self.value,
            parent: None,
            children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(),
266
            decl_id: None,
267
            docs: self.docs,
N
Nick Cameron 已提交
268
            sig: self.sig,
N
Nick Cameron 已提交
269
            attributes: self.attributes,
270 271 272
        }
    }
}
273 274
impl Into<Def> for TraitData {
    fn into(self) -> Def {
275 276
        Def {
            kind: DefKind::Trait,
277 278 279 280 281 282 283
            id: id_from_def_id(self.id),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
            value: self.value,
            parent: None,
            children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
284
            decl_id: None,
285
            docs: self.docs,
N
Nick Cameron 已提交
286
            sig: self.sig,
N
Nick Cameron 已提交
287
            attributes: self.attributes,
288 289 290
        }
    }
}
291 292
impl Into<Def> for FunctionData {
    fn into(self) -> Def {
293 294
        Def {
            kind: DefKind::Function,
295 296 297 298 299 300
            id: id_from_def_id(self.id),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
            value: self.value,
            parent: None,
301
            children: vec![],
302
            decl_id: None,
303
            docs: self.docs,
N
Nick Cameron 已提交
304
            sig: self.sig,
N
Nick Cameron 已提交
305
            attributes: self.attributes,
306 307 308
        }
    }
}
309 310
impl Into<Def> for MethodData {
    fn into(self) -> Def {
311
        Def {
312
            kind: DefKind::Method,
313 314 315 316 317 318
            id: id_from_def_id(self.id),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
            value: self.value,
            parent: None,
319
            children: vec![],
320 321
            decl_id: self.decl_id.map(|id| id_from_def_id(id)),
            docs: self.docs,
N
Nick Cameron 已提交
322
            sig: self.sig,
N
Nick Cameron 已提交
323
            attributes: self.attributes,
324 325 326
        }
    }
}
327 328
impl Into<Def> for MacroData {
    fn into(self) -> Def {
329 330
        Def {
            kind: DefKind::Macro,
331 332 333 334
            id: id_from_def_id(null_def_id()),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
335
            value: String::new(),
336
            parent: None,
337
            children: vec![],
338
            decl_id: None,
339
            docs: self.docs,
340
            sig: None,
341
            attributes: vec![],
342 343 344
        }
    }
}
345 346
impl Into<Def> for TypeDefData {
    fn into(self) -> Def {
347 348
        Def {
            kind: DefKind::Type,
349 350 351 352 353 354
            id: id_from_def_id(self.id),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
            value: self.value,
            parent: None,
355
            children: vec![],
356
            decl_id: None,
N
Nick Cameron 已提交
357
            docs: String::new(),
N
Nick Cameron 已提交
358
            sig: self.sig,
N
Nick Cameron 已提交
359
            attributes: self.attributes,
360 361 362
        }
    }
}
363 364
impl Into<Def> for VariableData {
    fn into(self) -> Def {
365
        Def {
366
            kind: match self.kind {
367 368 369 370 371
                VariableKind::Static => DefKind::Static,
                VariableKind::Const => DefKind::Const,
                VariableKind::Local => DefKind::Local,
                VariableKind::Field => DefKind::Field,
            },
372 373 374 375 376 377
            id: id_from_def_id(self.id),
            span: self.span,
            name: self.name,
            qualname: self.qualname,
            value: self.type_value,
            parent: None,
378
            children: vec![],
379
            decl_id: None,
380
            docs: self.docs,
381
            sig: None,
N
Nick Cameron 已提交
382
            attributes: self.attributes,
383 384 385 386
        }
    }
}

387 388
impl Into<Ref> for FunctionRefData {
    fn into(self) -> Ref {
389 390
        Ref {
            kind: RefKind::Function,
391 392
            span: self.span,
            ref_id: id_from_def_id(self.ref_id),
393 394 395
        }
    }
}
396 397
impl Into<Ref> for FunctionCallData {
    fn into(self) -> Ref {
398 399
        Ref {
            kind: RefKind::Function,
400 401
            span: self.span,
            ref_id: id_from_def_id(self.ref_id),
402 403 404
        }
    }
}
405 406
impl Into<Ref> for MethodCallData {
    fn into(self) -> Ref {
407 408
        Ref {
            kind: RefKind::Function,
409 410
            span: self.span,
            ref_id: id_from_def_id(self.ref_id.or(self.decl_id).unwrap_or(null_def_id())),
411 412 413
        }
    }
}
414 415
impl Into<Ref> for ModRefData {
    fn into(self) -> Ref {
416 417
        Ref {
            kind: RefKind::Mod,
418 419
            span: self.span,
            ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
420 421 422
        }
    }
}
423 424
impl Into<Ref> for TypeRefData {
    fn into(self) -> Ref {
425 426
        Ref {
            kind: RefKind::Type,
427 428
            span: self.span,
            ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
429 430 431
        }
    }
}
432 433
impl Into<Ref> for VariableRefData {
    fn into(self) -> Ref {
434 435
        Ref {
            kind: RefKind::Variable,
436 437
            span: self.span,
            ref_id: id_from_def_id(self.ref_id),
438 439 440 441
        }
    }
}

442 443
impl Into<MacroRef> for MacroUseData {
    fn into(self) -> MacroRef {
444
        MacroRef {
445 446 447
            span: self.span,
            qualname: self.qualname,
            callee_span: self.callee_span.into(),
448 449
        }
    }
450
}
N
Nick Cameron 已提交
451

452 453
impl Into<Relation> for ImplData {
    fn into(self) -> Relation {
454
        Relation {
455
            span: self.span,
456
            kind: RelationKind::Impl,
457 458
            from: id_from_def_id(self.self_ref.unwrap_or(null_def_id())),
            to: id_from_def_id(self.trait_ref.unwrap_or(null_def_id())),
459 460 461 462
        }
    }
}

463 464
impl Into<Relation> for InheritanceData {
    fn into(self) -> Relation {
465
        Relation {
466
            span: self.span,
467
            kind: RelationKind::SuperTrait,
468 469
            from: id_from_def_id(self.base_id),
            to: id_from_def_id(self.deriv_id),
470 471 472
        }
    }
}