Skip to content

Commit 5109221

Browse files
committed
Initial commit for the rs_loader
1 parent 934b694 commit 5109221

File tree

5 files changed

+214
-0
lines changed

5 files changed

+214
-0
lines changed

source/loaders/rs_loader/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "compiler"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
[package.metadata.rust-analyzer]
7+
rustc_private = true
8+
9+
[profile.release]
10+
opt-level="z"
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
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_ast::ast::ItemKind::Fn;
13+
use rustc_ast::FnKind;
14+
use rustc_ast::FnRetTy::Ty;
15+
use rustc_ast::PatKind::Ident;
16+
use rustc_ast::TyKind::Path;
17+
use rustc_driver::{Callbacks, RunCompiler};
18+
use rustc_errors::registry;
19+
use rustc_hash::{FxHashMap, FxHashSet};
20+
use rustc_session::config;
21+
use rustc_session::config::CrateType;
22+
use rustc_span::source_map;
23+
use rustc_span::symbol::Ident as TypeIdent;
24+
use std::borrow::Borrow;
25+
26+
pub struct Source {
27+
code: String,
28+
filename: String,
29+
}
30+
impl Source {
31+
pub fn new(code: String, filename: String) -> Source {
32+
Source { code, filename }
33+
}
34+
}
35+
36+
#[derive(Debug)]
37+
pub enum ParsedRustFunctionReturnType {
38+
TypeIdent(TypeIdent),
39+
Void,
40+
}
41+
#[derive(Debug)]
42+
pub enum ParsedRustFunctionArgumentType {
43+
TypeIdent(TypeIdent),
44+
Void,
45+
}
46+
#[derive(Debug)]
47+
pub struct ParsedRustFunctionArguments {
48+
name: String,
49+
order_number: usize,
50+
value_type: ParsedRustFunctionArgumentType,
51+
}
52+
#[derive(Debug)]
53+
pub struct ParsedRustFunction {
54+
name: String,
55+
asyncness: rustc_ast::Async,
56+
return_type: ParsedRustFunctionReturnType,
57+
arguments_length: usize,
58+
arguments: Vec<ParsedRustFunctionArguments>,
59+
}
60+
struct Calls;
61+
impl Callbacks for Calls {
62+
fn config(&mut self, _config: &mut rustc_interface::interface::Config) {}
63+
}
64+
65+
pub fn compile(source: Source) {
66+
let Source { code, filename } = source;
67+
68+
let config = rustc_interface::Config {
69+
// Command line options
70+
opts: config::Options {
71+
crate_types: vec![CrateType::Cdylib],
72+
..config::Options::default()
73+
},
74+
// cfg! configuration in addition to the default ones
75+
crate_cfg: FxHashSet::default(), // FxHashSet<(String, Option<String>)>
76+
input: config::Input::Str {
77+
name: source_map::FileName::Custom(filename.clone()),
78+
input: code.clone(),
79+
},
80+
input_path: None, // Option<PathBuf>
81+
output_dir: None, // Option<PathBuf>
82+
output_file: None, // Option<PathBuf>
83+
file_loader: None, // Option<Box<dyn FileLoader + Send + Sync>>
84+
diagnostic_output: rustc_session::DiagnosticOutput::Default,
85+
// Set to capture stderr output during compiler execution
86+
stderr: None, // Option<Arc<Mutex<Vec<u8>>>>
87+
lint_caps: FxHashMap::default(), // FxHashMap<lint::LintId, lint::Level>
88+
// This is a callback from the driver that is called when [`ParseSess`] is created.
89+
parse_sess_created: None, //Option<Box<dyn FnOnce(&mut ParseSess) + Send>>
90+
// This is a callback from the driver that is called when we're registering lints;
91+
// it is called during plugin registration when we have the LintStore in a non-shared state.
92+
//
93+
// Note that if you find a Some here you probably want to call that function in the new
94+
// function being registered.
95+
register_lints: None, // Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>>
96+
// This is a callback from the driver that is called just after we have populated
97+
// the list of queries.
98+
//
99+
// The second parameter is local providers and the third parameter is external providers.
100+
override_queries: None, // Option<fn(&Session, &mut ty::query::Providers<'_>, &mut ty::query::Providers<'_>)>
101+
// Registry of diagnostics codes.
102+
registry: registry::Registry::new(&rustc_error_codes::DIAGNOSTICS),
103+
make_codegen_backend: None,
104+
};
105+
106+
rustc_interface::run_compiler(config, |compiler| {
107+
compiler.enter(|queries| {
108+
// Parse the program and print the syntax tree.
109+
let parse = queries.parse().unwrap().take();
110+
let mut parsed_rust_functions: Vec<ParsedRustFunction> = Vec::new();
111+
112+
{
113+
for parsed_item in parse.items.iter() {
114+
if let Fn(function) = parsed_item.kind.borrow() {
115+
match function.borrow() {
116+
FnKind(_the_final, function_signature, _generic, _some) => {
117+
let mut arguments: Vec<ParsedRustFunctionArguments> = Vec::new();
118+
119+
let mut i: usize = 0;
120+
for function_input in function_signature.decl.inputs.iter() {
121+
arguments.push(ParsedRustFunctionArguments {
122+
order_number: i,
123+
name: match function_input.pat.kind {
124+
Ident(_by_value, name, _) => name.to_string(),
125+
_ => String::new(),
126+
},
127+
value_type: match &function_input.borrow().ty.kind {
128+
Path(_, path) => {
129+
ParsedRustFunctionArgumentType::TypeIdent(
130+
path.segments[0].ident,
131+
)
132+
}
133+
_ => ParsedRustFunctionArgumentType::Void,
134+
},
135+
});
136+
137+
i += 1;
138+
}
139+
140+
let return_type = match function_signature.decl.output.borrow() {
141+
Ty(ty) => {
142+
if let Path(_, path) = &ty.borrow().kind {
143+
ParsedRustFunctionReturnType::TypeIdent(
144+
path.segments[0].ident,
145+
)
146+
} else {
147+
ParsedRustFunctionReturnType::Void
148+
}
149+
}
150+
_ => ParsedRustFunctionReturnType::Void,
151+
};
152+
153+
parsed_rust_functions.push(ParsedRustFunction {
154+
arguments,
155+
return_type,
156+
name: parsed_item.ident.to_string(),
157+
asyncness: function_signature.header.asyncness,
158+
arguments_length: function_signature.decl.inputs.len(),
159+
});
160+
}
161+
}
162+
}
163+
}
164+
165+
println!("Results: {:#?}", parsed_rust_functions);
166+
}
167+
});
168+
});
169+
170+
let args: Vec<_> = std::env::args().collect();
171+
let mut calls = Calls {};
172+
173+
RunCompiler::new(&args, &mut calls).run().unwrap();
174+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use compiler;
2+
use std::fs;
3+
4+
fn main() {
5+
let filename = String::from("test_files/test.rs");
6+
let code = fs::read_to_string(&filename).unwrap();
7+
let source = compiler::Source::new(code, filename);
8+
9+
compiler::compile(source);
10+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use std::ffi::CString;
2+
3+
fn add(num_1: i32, num_2: i32) -> i32 {
4+
num_1 + num_2
5+
}
6+
7+
fn greetings(greeting_word: &str, target: &str) -> CString {
8+
CString::new(greeting_word.to_owned() + target + &add(1, 3).to_string()[..]).unwrap()
9+
}
10+
11+
pub extern "C" fn run() {
12+
println!("Greetings: {:#?}", greetings("Hello", "Para"))
13+
}

0 commit comments

Comments
 (0)