Skip to content

Commit 46a87be

Browse files
authored
Merge pull request #194 from devraymondsh/rs_loader
Refactor and make the project cdylib
2 parents f5de249 + aa9ec51 commit 46a87be

File tree

16 files changed

+275
-187
lines changed

16 files changed

+275
-187
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/target
2+
Cargo.lock
3+

source/loaders/rs_loader/Cargo.lock

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
[package]
2-
name = "compiler"
2+
name = "rs_loader"
33
version = "0.1.0"
44
edition = "2018"
55

6+
[lib]
7+
name = "rs_loader"
8+
crate-type = ["cdylib"] # Creates dynamic lib
9+
# crate-type = ["staticlib"] # Creates static lib
10+
611
[package.metadata.rust-analyzer]
712
rustc_private = true
813

914
[profile.release]
10-
opt-level="z"
15+
opt-level = "z"
16+
17+
[workspace]
18+
members = ["functions_extractor"]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "functions_extractor"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
[package.metadata.rust-analyzer]
7+
rustc_private = true
8+
9+
[dependencies]
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
use rustc_ast::ast::ItemKind::Fn;
2+
use rustc_ast::Crate;
3+
use rustc_ast::FnKind;
4+
use rustc_ast::FnRetTy::Ty;
5+
use rustc_ast::PatKind::Ident;
6+
use rustc_ast::TyKind::Path;
7+
use rustc_span::symbol::Ident as TypeIdent;
8+
use std::borrow::Borrow;
9+
10+
#[derive(Debug)]
11+
pub enum ParsedRustFunctionReturnType {
12+
TypeIdent(TypeIdent),
13+
Void,
14+
}
15+
#[derive(Debug)]
16+
pub enum ParsedRustFunctionArgumentType {
17+
TypeIdent(TypeIdent),
18+
Void,
19+
}
20+
#[derive(Debug)]
21+
pub struct ParsedRustFunctionArguments {
22+
name: String,
23+
order_number: usize,
24+
value_type: ParsedRustFunctionArgumentType,
25+
}
26+
#[derive(Debug)]
27+
pub struct ParsedRustFunction {
28+
name: String,
29+
asyncness: rustc_ast::Async,
30+
return_type: ParsedRustFunctionReturnType,
31+
arguments_length: usize,
32+
arguments: Vec<ParsedRustFunctionArguments>,
33+
}
34+
35+
pub fn functions_extractor(parse_source: Crate) -> Vec<ParsedRustFunction> {
36+
let mut parsed_rust_functions: Vec<ParsedRustFunction> = Vec::new();
37+
38+
for parsed_item in parse_source.items.iter() {
39+
if let Fn(function) = parsed_item.kind.borrow() {
40+
match function.borrow() {
41+
FnKind(_the_final, function_signature, _generic, _some) => {
42+
let mut arguments: Vec<ParsedRustFunctionArguments> = Vec::new();
43+
44+
let mut i: usize = 0;
45+
for function_input in function_signature.decl.inputs.iter() {
46+
arguments.push(ParsedRustFunctionArguments {
47+
order_number: i,
48+
name: match function_input.pat.kind {
49+
Ident(_by_value, name, _) => name.to_string(),
50+
_ => String::new(),
51+
},
52+
value_type: match &function_input.borrow().ty.kind {
53+
Path(_, path) => ParsedRustFunctionArgumentType::TypeIdent(
54+
path.segments[0].ident,
55+
),
56+
_ => ParsedRustFunctionArgumentType::Void,
57+
},
58+
});
59+
60+
i += 1;
61+
}
62+
63+
let return_type = match function_signature.decl.output.borrow() {
64+
Ty(ty) => {
65+
if let Path(_, path) = &ty.borrow().kind {
66+
ParsedRustFunctionReturnType::TypeIdent(path.segments[0].ident)
67+
} else {
68+
ParsedRustFunctionReturnType::Void
69+
}
70+
}
71+
_ => ParsedRustFunctionReturnType::Void,
72+
};
73+
74+
parsed_rust_functions.push(ParsedRustFunction {
75+
arguments,
76+
return_type,
77+
name: parsed_item.ident.to_string(),
78+
asyncness: function_signature.header.asyncness,
79+
arguments_length: function_signature.decl.inputs.len(),
80+
});
81+
}
82+
}
83+
}
84+
}
85+
86+
parsed_rust_functions
87+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#![feature(rustc_private)]
2+
extern crate rustc_ast;
3+
extern crate rustc_driver;
4+
extern crate rustc_error_codes;
5+
extern crate rustc_errors;
6+
extern crate rustc_hash;
7+
extern crate rustc_hir;
8+
extern crate rustc_interface;
9+
extern crate rustc_session;
10+
extern crate rustc_span;
11+
12+
use rustc_errors::registry;
13+
use rustc_hash::{FxHashMap, FxHashSet};
14+
use rustc_session::config;
15+
use rustc_session::config::CrateType;
16+
use rustc_span::source_map;
17+
use std::rc::Rc;
18+
use std::sync::Mutex;
19+
20+
mod funtions_extractor;
21+
22+
pub struct Source {
23+
code: String,
24+
filename: String,
25+
}
26+
impl Source {
27+
pub fn new(code: String, filename: String) -> Source {
28+
Source { code, filename }
29+
}
30+
}
31+
32+
pub fn extract_functions(source: Source) {
33+
let Source { code, filename } = source;
34+
35+
let config = rustc_interface::Config {
36+
// Command line options
37+
opts: config::Options {
38+
crate_types: vec![CrateType::Cdylib],
39+
..config::Options::default()
40+
},
41+
// cfg! configuration in addition to the default ones
42+
crate_cfg: FxHashSet::default(), // FxHashSet<(String, Option<String>)>
43+
input: config::Input::Str {
44+
name: source_map::FileName::Custom(filename.clone()),
45+
input: code.clone(),
46+
},
47+
input_path: None, // Option<PathBuf>
48+
output_dir: None, // Option<PathBuf>
49+
output_file: None, // Option<PathBuf>
50+
file_loader: None, // Option<Box<dyn FileLoader + Send + Sync>>
51+
diagnostic_output: rustc_session::DiagnosticOutput::Default,
52+
// Set to capture stderr output during compiler execution
53+
stderr: None, // Option<Arc<Mutex<Vec<u8>>>>
54+
lint_caps: FxHashMap::default(), // FxHashMap<lint::LintId, lint::Level>
55+
// This is a callback from the driver that is called when [`ParseSess`] is created.
56+
parse_sess_created: None, //Option<Box<dyn FnOnce(&mut ParseSess) + Send>>
57+
// This is a callback from the driver that is called when we're registering lints;
58+
// it is called during plugin registration when we have the LintStore in a non-shared state.
59+
//
60+
// Note that if you find a Some here you probably want to call that function in the new
61+
// function being registered.
62+
register_lints: None, // Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>
63+
// This is a callback from the driver that is called just after we have populated
64+
// the list of queries.
65+
//
66+
// The second parameter is local providers and the third parameter is external providers.
67+
override_queries: None, // Option<fn(&Session, &mut ty::query::Providers<'_>, &mut ty::query::Providers<'_>)>
68+
// Registry of diagnostics codes.
69+
registry: registry::Registry::new(&rustc_error_codes::DIAGNOSTICS),
70+
make_codegen_backend: None,
71+
};
72+
73+
let rc = Rc::new(Mutex::new<Option<Vec<funtions_extractor::ParsedRustFunction>>>(None));
74+
75+
let rc_compiler = Rc::clone(&rc);
76+
77+
rustc_interface::run_compiler(config, move |compiler| {
78+
compiler.enter(move |queries| {
79+
// Parse the program and print the syntax tree.
80+
let parsed_source: rustc_ast::Crate = queries.parse().unwrap().take();
81+
82+
let extracted_functions = rc_compiler.lock().unwrap();
83+
84+
extracted_functions = funtions_extractor::functionss_extractor(parsed_source)
85+
86+
// tx.send(extracted_functions).unwrap();
87+
})
88+
});
89+
}

0 commit comments

Comments
 (0)