Skip to content

Commit edf4695

Browse files
Create a parse context and parse file context
1 parent 7d873dd commit edf4695

File tree

8 files changed

+78
-56
lines changed

8 files changed

+78
-56
lines changed

cli/src/main.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rayon::iter::ParallelBridge;
2323
#[cfg(feature = "go")]
2424
use typeshare_core::language::Go;
2525
use typeshare_core::{
26+
context::ParseContext,
2627
language::{
2728
CrateName, GenericConstraints, Kotlin, Language, Scala, SupportedLanguage, Swift,
2829
TypeScript,
@@ -127,9 +128,13 @@ fn main() -> anyhow::Result<()> {
127128

128129
let multi_file = matches!(destination, Output::Folder(_));
129130
let target_os = config.target_os.clone();
130-
131131
let mut lang = language(language_type, config, multi_file);
132-
let ignored_types = lang.ignored_reference_types();
132+
133+
let parse_context = ParseContext {
134+
ignored_types: lang.ignored_reference_types(),
135+
multi_file,
136+
target_os,
137+
};
133138

134139
// The walker ignores directories that are git-ignored. If you need
135140
// a git-ignored directory to be processed, add the specific directory to
@@ -141,9 +146,7 @@ fn main() -> anyhow::Result<()> {
141146
// https://docs.rs/ignore/latest/ignore/struct.WalkParallel.html
142147
let crate_parsed_data = parse_input(
143148
parser_inputs(walker_builder, language_type, multi_file).par_bridge(),
144-
&ignored_types,
145-
multi_file,
146-
&target_os,
149+
&parse_context,
147150
)?;
148151

149152
// Collect all the types into a map of the file name they

cli/src/parse.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::{
77
path::PathBuf,
88
};
99
use typeshare_core::{
10+
context::ParseContext,
1011
language::{CrateName, CrateTypes, SupportedLanguage, SINGLE_FILE_CRATE_NAME},
1112
parser::ParsedData,
1213
RenameExt,
@@ -89,9 +90,7 @@ pub fn all_types(file_mappings: &BTreeMap<CrateName, ParsedData>) -> CrateTypes
8990
/// Collect all the parsed sources into a mapping of crate name to parsed data.
9091
pub fn parse_input(
9192
inputs: impl ParallelIterator<Item = ParserInput>,
92-
ignored_types: &[&str],
93-
multi_file: bool,
94-
target_os: &[String],
93+
parse_context: &ParseContext,
9594
) -> anyhow::Result<BTreeMap<CrateName, ParsedData>> {
9695
inputs
9796
.into_par_iter()
@@ -109,9 +108,7 @@ pub fn parse_input(
109108
crate_name.clone(),
110109
file_name.clone(),
111110
file_path,
112-
ignored_types,
113-
multi_file,
114-
target_os,
111+
parse_context,
115112
)
116113
.with_context(|| format!("Failed to parse: {file_name}"))?;
117114

core/src/context.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::path::PathBuf;
2+
3+
use crate::language::CrateName;
4+
5+
/// Context for parsing rust source files.
6+
#[derive(Default)]
7+
pub struct ParseContext<'a> {
8+
/// Types to ignore
9+
pub ignored_types: Vec<&'a str>,
10+
/// Multi file output enabled.
11+
pub multi_file: bool,
12+
/// `target_os` filtering.
13+
pub target_os: Vec<String>,
14+
}
15+
16+
/// Parsing context for a single rust source file.
17+
pub struct ParseFileContext<'a> {
18+
pub source_code: &'a str,
19+
pub crate_name: CrateName,
20+
pub file_name: String,
21+
pub file_path: PathBuf,
22+
}

core/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
//! The core library for typeshare.
22
//! Contains the parser and language converters.
3-
43
use thiserror::Error;
54

6-
mod rename;
7-
5+
pub mod context;
86
/// Implementations for each language converter
97
pub mod language;
108
/// Parsing Rust code into a format the `language` modules can understand
119
pub mod parser;
10+
mod rename;
1211
/// Codifying Rust types and how they convert to various languages.
1312
pub mod rust_types;
1413
mod target_os_check;

core/src/parser.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{
2+
context::ParseContext,
23
language::{CrateName, SupportedLanguage},
34
rename::RenameExt,
45
rust_types::{
@@ -166,9 +167,7 @@ pub fn parse(
166167
crate_name: CrateName,
167168
file_name: String,
168169
file_path: PathBuf,
169-
ignored_types: &[&str],
170-
mult_file: bool,
171-
target_os: &[String],
170+
parse_context: &ParseContext,
172171
) -> Result<Option<ParsedData>, ParseError> {
173172
// We will only produce output for files that contain the `#[typeshare]`
174173
// attribute, so this is a quick and easy performance win
@@ -179,14 +178,7 @@ pub fn parse(
179178
debug!("parsing {file_name}");
180179
// Parse and process the input, ensuring we parse only items marked with
181180
// `#[typeshare]`
182-
let mut import_visitor = TypeShareVisitor::new(
183-
crate_name,
184-
file_name,
185-
file_path,
186-
ignored_types,
187-
mult_file,
188-
target_os,
189-
);
181+
let mut import_visitor = TypeShareVisitor::new(crate_name, file_name, file_path, parse_context);
190182
import_visitor.visit_file(&syn::parse_file(source_code)?);
191183

192184
Ok(import_visitor.parsed_data())

core/src/visitors.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Visitors to collect various items from the AST.
22
use crate::{
3+
context::ParseContext,
34
language::CrateName,
45
parser::{
56
has_typeshare_annotation, parse_enum, parse_struct, parse_type_alias, ErrorInfo,
@@ -46,12 +47,11 @@ const IGNORED_TYPES: &[&str] = &["Option", "String", "Vec", "HashMap", "T", "I54
4647

4748
/// An import visitor that collects all use or
4849
/// qualified referenced items.
49-
#[derive(Default)]
50+
// #[derive(Default)]
5051
pub struct TypeShareVisitor<'a> {
5152
parsed_data: ParsedData,
5253
file_path: PathBuf,
53-
ignored_types: &'a [&'a str],
54-
target_os: &'a [String],
54+
parse_context: &'a ParseContext<'a>,
5555
}
5656

5757
impl<'a> TypeShareVisitor<'a> {
@@ -60,15 +60,12 @@ impl<'a> TypeShareVisitor<'a> {
6060
crate_name: CrateName,
6161
file_name: String,
6262
file_path: PathBuf,
63-
ignored_types: &'a [&'a str],
64-
multi_file: bool,
65-
target_os: &'a [String],
63+
parse_context: &'a ParseContext<'a>,
6664
) -> Self {
6765
Self {
68-
parsed_data: ParsedData::new(crate_name, file_name, multi_file),
66+
parsed_data: ParsedData::new(crate_name, file_name, parse_context.multi_file),
6967
file_path,
70-
ignored_types,
71-
target_os,
68+
parse_context,
7269
}
7370
}
7471

@@ -193,7 +190,7 @@ impl<'a> TypeShareVisitor<'a> {
193190
/// not match `--target-os` argument?
194191
#[inline(always)]
195192
fn target_os_accepted(&self, attrs: &[Attribute]) -> bool {
196-
accept_target_os(attrs, self.target_os)
193+
accept_target_os(attrs, &self.parse_context.target_os)
197194
}
198195
}
199196

@@ -224,7 +221,10 @@ impl<'ast, 'a> Visit<'ast> for TypeShareVisitor<'a> {
224221

225222
(accept_crate(&crate_candidate)
226223
&& accept_type(&type_candidate)
227-
&& !self.ignored_types.contains(&type_candidate.as_str())
224+
&& !self
225+
.parse_context
226+
.ignored_types
227+
.contains(&type_candidate.as_str())
228228
&& crate_candidate != type_candidate)
229229
.then(|| {
230230
// resolve crate and super aliases into the crate name.
@@ -254,10 +254,14 @@ impl<'ast, 'a> Visit<'ast> for TypeShareVisitor<'a> {
254254
if !self.parsed_data.multi_file {
255255
return;
256256
}
257-
self.parsed_data.import_types.extend(
258-
parse_import(i, &self.parsed_data.crate_name)
259-
.filter(|imp| !self.ignored_types.contains(&imp.type_name.as_str())),
260-
);
257+
self.parsed_data
258+
.import_types
259+
.extend(parse_import(i, &self.parsed_data.crate_name).filter(|imp| {
260+
!self
261+
.parse_context
262+
.ignored_types
263+
.contains(&imp.type_name.as_str())
264+
}));
261265
syn::visit::visit_item_use(self, i);
262266
}
263267

@@ -266,7 +270,7 @@ impl<'ast, 'a> Visit<'ast> for TypeShareVisitor<'a> {
266270
debug!("Visiting {}", i.ident);
267271
if has_typeshare_annotation(&i.attrs) && self.target_os_accepted(&i.attrs) {
268272
debug!("\tParsing {}", i.ident);
269-
self.collect_result(parse_struct(i, self.target_os));
273+
self.collect_result(parse_struct(i, &self.parse_context.target_os));
270274
}
271275

272276
syn::visit::visit_item_struct(self, i);
@@ -277,7 +281,7 @@ impl<'ast, 'a> Visit<'ast> for TypeShareVisitor<'a> {
277281
debug!("Visiting {}", i.ident);
278282
if has_typeshare_annotation(&i.attrs) && self.target_os_accepted(&i.attrs) {
279283
debug!("\tParsing {}", i.ident);
280-
self.collect_result(parse_enum(i, self.target_os));
284+
self.collect_result(parse_enum(i, &self.parse_context.target_os));
281285
}
282286

283287
syn::visit::visit_item_enum(self, i);
@@ -432,7 +436,7 @@ fn parse_import<'a>(
432436
#[cfg(test)]
433437
mod test {
434438
use super::{parse_import, TypeShareVisitor};
435-
use crate::visitors::ImportedType;
439+
use crate::{context::ParseContext, visitors::ImportedType};
436440
use cool_asserts::assert_matches;
437441
use itertools::Itertools;
438442
use syn::{visit::Visit, File};
@@ -603,14 +607,18 @@ mod test {
603607
}
604608
";
605609

610+
let parse_context = ParseContext {
611+
ignored_types: Vec::new(),
612+
multi_file: true,
613+
target_os: Vec::new(),
614+
};
615+
606616
let file: File = syn::parse_str(rust_code).unwrap();
607617
let mut visitor = TypeShareVisitor::new(
608618
"my_crate".into(),
609619
"my_file".into(),
610620
"file_path".into(),
611-
&[],
612-
true,
613-
&[],
621+
&parse_context,
614622
);
615623
visitor.visit_file(&file);
616624

core/tests/agnostic_tests.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::io::Write;
22
use typeshare_core::{
3+
context::ParseContext,
34
language::{CrateTypes, Language, TypeScript},
45
parser::{self, ParseError},
56
rust_types::RustTypeParseError,
@@ -12,14 +13,14 @@ pub fn process_input(
1213
imports: &CrateTypes,
1314
out: &mut dyn Write,
1415
) -> Result<(), ProcessInputError> {
16+
let parse_context = ParseContext::default();
17+
1518
let mut parsed_data = parser::parse(
1619
input,
1720
"default_name".into(),
1821
"file_name".into(),
1922
"file_path".into(),
20-
&[],
21-
false,
22-
&[],
23+
&parse_context,
2324
)?
2425
.unwrap();
2526

core/tests/snapshot_tests.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::{
1010
path::{Path, PathBuf},
1111
sync::Once,
1212
};
13-
use typeshare_core::language::Language;
13+
use typeshare_core::{context::ParseContext, language::Language};
1414

1515
static TESTS_FOLDER_PATH: Lazy<PathBuf> =
1616
Lazy::new(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("data/tests"));
@@ -97,17 +97,17 @@ fn check(
9797
)?;
9898

9999
let mut typeshare_output: Vec<u8> = Vec::new();
100+
let parse_context = ParseContext {
101+
target_os: target_os.iter().map(ToString::to_string).collect(),
102+
..Default::default()
103+
};
104+
100105
let parsed_data = typeshare_core::parser::parse(
101106
&rust_input,
102107
"default_crate".into(),
103108
"file_name".into(),
104109
"file_path".into(),
105-
&[],
106-
false,
107-
&target_os
108-
.iter()
109-
.map(ToString::to_string)
110-
.collect::<Vec<_>>(),
110+
&parse_context,
111111
)?
112112
.unwrap();
113113
lang.generate_types(&mut typeshare_output, &HashMap::new(), parsed_data)?;

0 commit comments

Comments
 (0)