| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 1 | use crate::gen::out::{Content, OutFile}; |
| David Tolnay | 353d98c | 2020-10-28 15:43:35 -0700 | [diff] [blame] | 2 | use crate::syntax::{self, IncludeKind}; |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 3 | use std::ops::{Deref, DerefMut}; |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 4 | |
| David Tolnay | 0e01d64 | 2020-10-16 12:54:44 -0700 | [diff] [blame] | 5 | /// The complete contents of the "rust/cxx.h" header. |
| David Tolnay | 736cbca | 2020-03-11 16:49:18 -0700 | [diff] [blame] | 6 | pub static HEADER: &str = include_str!("include/cxx.h"); |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 7 | |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 8 | /// A header to #include. |
| 9 | /// |
| 10 | /// The cxxbridge tool does not parse or even require the given paths to exist; |
| 11 | /// they simply go into the generated C++ code as #include lines. |
| 12 | #[derive(Clone, PartialEq, Debug)] |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame] | 13 | pub struct Include { |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 14 | /// The header's path, not including the enclosing quotation marks or angle |
| 15 | /// brackets. |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame] | 16 | pub path: String, |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 17 | /// Whether to emit `#include "path"` or `#include <path>`. |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame] | 18 | pub kind: IncludeKind, |
| 19 | } |
| 20 | |
| David Tolnay | 3577d45 | 2020-03-17 21:48:13 -0700 | [diff] [blame] | 21 | #[derive(Default, PartialEq)] |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 22 | pub struct Includes<'a> { |
| David Tolnay | 12af7e4 | 2020-10-31 21:09:23 -0700 | [diff] [blame] | 23 | pub custom: Vec<Include>, |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 24 | pub algorithm: bool, |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 25 | pub array: bool, |
| David Tolnay | 30430f1 | 2020-03-19 20:49:00 -0700 | [diff] [blame] | 26 | pub cstddef: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 27 | pub cstdint: bool, |
| David Tolnay | ebef4a2 | 2020-03-17 15:33:47 -0700 | [diff] [blame] | 28 | pub cstring: bool, |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 29 | pub exception: bool, |
| David Tolnay | 08a03db | 2020-12-09 23:04:36 -0800 | [diff] [blame] | 30 | pub functional: bool, |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 31 | pub initializer_list: bool, |
| David Tolnay | d1df4c7 | 2020-11-25 20:38:05 -0800 | [diff] [blame] | 32 | pub iterator: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 33 | pub memory: bool, |
| David Tolnay | 0ecd05a | 2020-07-29 16:32:03 -0700 | [diff] [blame] | 34 | pub new: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 35 | pub string: bool, |
| 36 | pub type_traits: bool, |
| David Tolnay | 4791f1c | 2020-03-17 21:53:16 -0700 | [diff] [blame] | 37 | pub utility: bool, |
| David Tolnay | 8b7f899 | 2020-04-25 13:06:08 -0700 | [diff] [blame] | 38 | pub vector: bool, |
| David Tolnay | da38b7c | 2020-09-16 11:50:04 -0400 | [diff] [blame] | 39 | pub basetsd: bool, |
| David Tolnay | 74dd66f | 2020-12-12 22:03:47 -0800 | [diff] [blame] | 40 | pub sys_types: bool, |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 41 | pub content: Content<'a>, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 42 | } |
| 43 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 44 | impl<'a> Includes<'a> { |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 45 | pub fn new() -> Self { |
| 46 | Includes::default() |
| 47 | } |
| 48 | |
| David Tolnay | 353d98c | 2020-10-28 15:43:35 -0700 | [diff] [blame] | 49 | pub fn insert(&mut self, include: impl Into<Include>) { |
| 50 | self.custom.push(include.into()); |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 51 | } |
| 52 | } |
| 53 | |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 54 | pub(super) fn write(out: &mut OutFile) { |
| David Tolnay | 58711a9 | 2020-11-01 19:11:37 -0800 | [diff] [blame] | 55 | let header = out.header; |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 56 | let include = &mut out.include; |
| 57 | let out = &mut include.content; |
| 58 | |
| David Tolnay | 58711a9 | 2020-11-01 19:11:37 -0800 | [diff] [blame] | 59 | if header { |
| 60 | writeln!(out, "#pragma once"); |
| 61 | } |
| 62 | |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 63 | for include in &include.custom { |
| 64 | match include.kind { |
| 65 | IncludeKind::Quoted => { |
| 66 | writeln!(out, "#include \"{}\"", include.path.escape_default()); |
| 67 | } |
| 68 | IncludeKind::Bracketed => { |
| 69 | writeln!(out, "#include <{}>", include.path); |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 74 | let Includes { |
| 75 | custom: _, |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 76 | algorithm, |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 77 | array, |
| 78 | cstddef, |
| 79 | cstdint, |
| 80 | cstring, |
| 81 | exception, |
| David Tolnay | 08a03db | 2020-12-09 23:04:36 -0800 | [diff] [blame] | 82 | functional, |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 83 | initializer_list, |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 84 | iterator, |
| 85 | memory, |
| 86 | new, |
| 87 | string, |
| 88 | type_traits, |
| 89 | utility, |
| 90 | vector, |
| 91 | basetsd, |
| David Tolnay | 74dd66f | 2020-12-12 22:03:47 -0800 | [diff] [blame] | 92 | sys_types, |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 93 | content: _, |
| 94 | } = *include; |
| 95 | |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 96 | if algorithm { |
| 97 | writeln!(out, "#include <algorithm>"); |
| 98 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 99 | if array { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 100 | writeln!(out, "#include <array>"); |
| 101 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 102 | if cstddef { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 103 | writeln!(out, "#include <cstddef>"); |
| 104 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 105 | if cstdint { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 106 | writeln!(out, "#include <cstdint>"); |
| 107 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 108 | if cstring { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 109 | writeln!(out, "#include <cstring>"); |
| 110 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 111 | if exception { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 112 | writeln!(out, "#include <exception>"); |
| 113 | } |
| David Tolnay | 08a03db | 2020-12-09 23:04:36 -0800 | [diff] [blame] | 114 | if functional { |
| 115 | writeln!(out, "#include <functional>"); |
| 116 | } |
| David Tolnay | f799b37 | 2020-11-29 23:57:42 -0800 | [diff] [blame] | 117 | if initializer_list { |
| 118 | writeln!(out, "#include <initializer_list>"); |
| 119 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 120 | if iterator { |
| David Tolnay | d1df4c7 | 2020-11-25 20:38:05 -0800 | [diff] [blame] | 121 | writeln!(out, "#include <iterator>"); |
| 122 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 123 | if memory { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 124 | writeln!(out, "#include <memory>"); |
| 125 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 126 | if new { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 127 | writeln!(out, "#include <new>"); |
| 128 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 129 | if string { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 130 | writeln!(out, "#include <string>"); |
| 131 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 132 | if type_traits { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 133 | writeln!(out, "#include <type_traits>"); |
| 134 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 135 | if utility { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 136 | writeln!(out, "#include <utility>"); |
| 137 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 138 | if vector { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 139 | writeln!(out, "#include <vector>"); |
| 140 | } |
| David Tolnay | a829be6 | 2020-11-25 20:41:12 -0800 | [diff] [blame] | 141 | if basetsd { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 142 | writeln!(out, "#if defined(_WIN32)"); |
| 143 | writeln!(out, "#include <basetsd.h>"); |
| David Tolnay | 74dd66f | 2020-12-12 22:03:47 -0800 | [diff] [blame] | 144 | } |
| 145 | if sys_types { |
| 146 | if basetsd { |
| 147 | writeln!(out, "#else"); |
| 148 | } else { |
| 149 | writeln!(out, "#if not defined(_WIN32)"); |
| 150 | } |
| 151 | } |
| 152 | if sys_types { |
| 153 | writeln!(out, "#include <sys/types.h>"); |
| 154 | } |
| 155 | if basetsd || sys_types { |
| David Tolnay | 2f3e90b | 2020-10-31 22:16:51 -0700 | [diff] [blame] | 156 | writeln!(out, "#endif"); |
| 157 | } |
| 158 | } |
| 159 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 160 | impl<'i, 'a> Extend<&'i Include> for Includes<'a> { |
| 161 | fn extend<I: IntoIterator<Item = &'i Include>>(&mut self, iter: I) { |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 162 | self.custom.extend(iter.into_iter().cloned()); |
| David Tolnay | 33d3029 | 2020-03-18 18:02:02 -0700 | [diff] [blame] | 163 | } |
| 164 | } |
| 165 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 166 | impl<'i> From<&'i syntax::Include> for Include { |
| David Tolnay | 353d98c | 2020-10-28 15:43:35 -0700 | [diff] [blame] | 167 | fn from(include: &syntax::Include) -> Self { |
| 168 | Include { |
| 169 | path: include.path.clone(), |
| 170 | kind: include.kind, |
| 171 | } |
| 172 | } |
| 173 | } |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 174 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 175 | impl<'a> Deref for Includes<'a> { |
| 176 | type Target = Content<'a>; |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 177 | |
| 178 | fn deref(&self) -> &Self::Target { |
| 179 | &self.content |
| 180 | } |
| 181 | } |
| 182 | |
| David Tolnay | 97c5b86 | 2020-11-01 14:59:01 -0800 | [diff] [blame] | 183 | impl<'a> DerefMut for Includes<'a> { |
| David Tolnay | 8810a54 | 2020-10-31 21:39:22 -0700 | [diff] [blame] | 184 | fn deref_mut(&mut self) -> &mut Self::Target { |
| 185 | &mut self.content |
| 186 | } |
| 187 | } |