Skip to main content

lisette_semantics/
diagnostics.rs

1use deps::{BindgenFailure, DeclarationStatus, TypedefLocatorResult};
2use diagnostics::LocalSink;
3use stdlib::Target;
4use syntax::ast::Span;
5
6pub fn emit_for_locator_result(
7    result: &TypedefLocatorResult,
8    import_name: &str,
9    go_pkg: &str,
10    name_span: Option<Span>,
11    target: Target,
12    standalone_mode: bool,
13    sink: &LocalSink,
14) -> bool {
15    let span = name_span.unwrap_or_else(|| Span::new(0, 0, 0));
16    match result {
17        TypedefLocatorResult::Found { .. } => return true,
18        TypedefLocatorResult::UnknownStdlib => {
19            emit_unknown_stdlib(import_name, go_pkg, span, target, standalone_mode, sink);
20        }
21        TypedefLocatorResult::UndeclaredImport => {
22            emit_undeclared(import_name, go_pkg, span, standalone_mode, sink);
23        }
24        TypedefLocatorResult::MissingTypedef { module, version } => {
25            sink.push(diagnostics::module_graph::missing_go_typedef(
26                go_pkg, module, version, span,
27            ));
28        }
29        TypedefLocatorResult::UnreadableTypedef { path, error } => {
30            sink.push(diagnostics::module_graph::unreadable_go_typedef(
31                path, error, span,
32            ));
33        }
34        TypedefLocatorResult::BindgenFailed {
35            module,
36            version,
37            kind,
38            ..
39        } => match kind {
40            BindgenFailure::GoToolchainMissing => {
41                sink.push(diagnostics::module_graph::go_toolchain_missing(
42                    go_pkg, span,
43                ));
44            }
45            BindgenFailure::InvocationFailed { stderr } => {
46                sink.push(diagnostics::module_graph::bindgen_failed(
47                    go_pkg, module, version, stderr, span,
48                ));
49            }
50        },
51    }
52    false
53}
54
55/// Emit a diagnostic for a non-OK `DeclarationStatus`; returns `true` if OK.
56pub fn emit_for_declaration_status(
57    status: &DeclarationStatus,
58    import_name: &str,
59    go_pkg: &str,
60    name_span: Span,
61    target: Target,
62    standalone_mode: bool,
63    sink: &LocalSink,
64) -> bool {
65    match status {
66        DeclarationStatus::Stdlib | DeclarationStatus::DeclaredThirdParty { .. } => true,
67        DeclarationStatus::UnknownStdlib => {
68            emit_unknown_stdlib(
69                import_name,
70                go_pkg,
71                name_span,
72                target,
73                standalone_mode,
74                sink,
75            );
76            false
77        }
78        DeclarationStatus::UndeclaredImport => {
79            emit_undeclared(import_name, go_pkg, name_span, standalone_mode, sink);
80            false
81        }
82    }
83}
84
85fn emit_unknown_stdlib(
86    import_name: &str,
87    go_pkg: &str,
88    span: Span,
89    target: Target,
90    standalone_mode: bool,
91    sink: &LocalSink,
92) {
93    if let Some(targets) = stdlib::get_go_stdlib_package_targets(go_pkg) {
94        sink.push(diagnostics::module_graph::go_stdlib_unavailable_on_target(
95            go_pkg,
96            &target.to_string(),
97            &stdlib::format_targets(targets),
98            span,
99        ));
100    } else {
101        sink.push(diagnostics::module_graph::module_not_found(
102            import_name,
103            span,
104            false,
105            standalone_mode,
106            None,
107        ));
108    }
109}
110
111fn emit_undeclared(
112    import_name: &str,
113    go_pkg: &str,
114    span: Span,
115    standalone_mode: bool,
116    sink: &LocalSink,
117) {
118    if standalone_mode {
119        sink.push(diagnostics::module_graph::module_not_found(
120            import_name,
121            span,
122            false,
123            true,
124            None,
125        ));
126    } else {
127        sink.push(diagnostics::module_graph::undeclared_go_import(
128            go_pkg, span,
129        ));
130    }
131}