Support constructor func calls, more integration tests
This commit is contained in:
parent
69b5d76a9b
commit
08eb97cf38
|
@ -24,4 +24,4 @@ debug = true
|
|||
opt-level = 3
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
opt-level = 0
|
|
@ -20,7 +20,7 @@ fn integration_add_function() {
|
|||
return a + b;
|
||||
}";
|
||||
let lexed_tokens = lex(script, &mut panic_on_error);
|
||||
println!("{}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
let expected_tokens: Vec<LexToken> =
|
||||
serde_json::from_str(r#"[
|
||||
{
|
||||
|
@ -254,7 +254,7 @@ fn integration_add_function() {
|
|||
assert_eq!(lexed_tokens, expected_tokens);
|
||||
|
||||
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
|
||||
println!("{}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
let expected_tree: Box<ParsedStatement> =
|
||||
serde_json::from_str(r#"{
|
||||
"Script": {
|
||||
|
@ -264,6 +264,7 @@ fn integration_add_function() {
|
|||
"modifiers": 0,
|
||||
"field_mod": null,
|
||||
"is_destructor": false,
|
||||
"is_constructor": false,
|
||||
"returns_reference": false,
|
||||
"return_type": {
|
||||
"Type": {
|
||||
|
|
|
@ -68,7 +68,7 @@ fn panic_on_error(msg: Message, _: Span) {{
|
|||
fn integration_{name}() {{
|
||||
let script = "{script}";
|
||||
let lexed_tokens = lex(script, &mut panic_on_error);
|
||||
println!("{{}}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
println!("Lexed tokens JSON: {{}}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
"#,
|
||||
name = test_name,
|
||||
script = script.as_str()
|
||||
|
@ -94,7 +94,7 @@ fn integration_{name}() {{
|
|||
testfile,
|
||||
r##"
|
||||
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
|
||||
println!("{{}}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
println!("Parsed Tree JSON: {{}}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
"##
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
////////////////////////////
|
||||
// Automatically Generated//
|
||||
////////////////////////////
|
||||
use crate::logger::messages::Message;
|
||||
use crate::parsing::lexer::lex;
|
||||
use crate::parsing::lexer::lex_tokens::LexToken;
|
||||
use crate::parsing::parser::parse;
|
||||
use crate::parsing::parser::parsed_statement::ParsedStatement;
|
||||
use crate::span::Span;
|
||||
|
||||
fn ignore_error(_msg: Message, _: Span) {
|
||||
}
|
||||
|
||||
fn panic_on_error(msg: Message, _: Span) {
|
||||
std::panic::panic_any(msg.stringify());
|
||||
}
|
||||
#[test]
|
||||
fn integration_class_with_many_statements() {
|
||||
let script = "final shared class Foobar {
|
||||
int _a;
|
||||
int _b;
|
||||
|
||||
Foobar(int a, int b) {
|
||||
_a = a;
|
||||
_b = b;
|
||||
}
|
||||
|
||||
int GetA(){
|
||||
return _a;
|
||||
}
|
||||
|
||||
int Add() {
|
||||
return _a + _b;
|
||||
}
|
||||
|
||||
class Inner {
|
||||
int a;
|
||||
}
|
||||
}";
|
||||
let lexed_tokens = lex(script, &mut panic_on_error);
|
||||
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
|
||||
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
|
||||
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
}
|
||||
// A substring of a script should never panic, even though it might be completely invalid.
|
||||
#[test]
|
||||
fn integration_class_with_many_statements_substring() {
|
||||
let mut script = "final shared class Foobar {
|
||||
int _a;
|
||||
int _b;
|
||||
|
||||
Foobar(int a, int b) {
|
||||
_a = a;
|
||||
_b = b;
|
||||
}
|
||||
|
||||
int GetA(){
|
||||
return _a;
|
||||
}
|
||||
|
||||
int Add() {
|
||||
return _a + _b;
|
||||
}
|
||||
|
||||
class Inner {
|
||||
int a;
|
||||
}
|
||||
}".to_string();
|
||||
for _ in 0..script.len() {
|
||||
script.pop();
|
||||
let lexed_tokens = lex(script.as_str(), &mut ignore_error);
|
||||
let _parsed_tree = parse(lexed_tokens, &mut ignore_error);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ fn panic_on_error(msg: Message, _: Span) {
|
|||
fn integration_empty_class_declaration() {
|
||||
let script = "class Foo {}";
|
||||
let lexed_tokens = lex(script, &mut panic_on_error);
|
||||
println!("{}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
let expected_tokens: Vec<LexToken> =
|
||||
serde_json::from_str(r#"[
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ fn integration_empty_class_declaration() {
|
|||
assert_eq!(lexed_tokens, expected_tokens);
|
||||
|
||||
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
|
||||
println!("{}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
let expected_tree: Box<ParsedStatement> =
|
||||
serde_json::from_str(r#"{
|
||||
"Script": {
|
||||
|
|
|
@ -24,7 +24,7 @@ fn integration_enum_definition() {
|
|||
e
|
||||
}";
|
||||
let lexed_tokens = lex(script, &mut panic_on_error);
|
||||
println!("{}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
let expected_tokens: Vec<LexToken> =
|
||||
serde_json::from_str(r#"[
|
||||
{
|
||||
|
@ -395,7 +395,7 @@ fn integration_enum_definition() {
|
|||
assert_eq!(lexed_tokens, expected_tokens);
|
||||
|
||||
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
|
||||
println!("{}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
let expected_tree: Box<ParsedStatement> =
|
||||
serde_json::from_str(r#"{
|
||||
"Script": {
|
||||
|
|
|
@ -3,4 +3,5 @@
|
|||
////////////////////////////mod enum_definition;
|
||||
mod multiple_inheritance_class;
|
||||
mod empty_class_declaration;
|
||||
mod class_with_many_statements;
|
||||
mod add_function;
|
||||
|
|
|
@ -18,7 +18,7 @@ fn panic_on_error(msg: Message, _: Span) {
|
|||
fn integration_multiple_inheritance_class() {
|
||||
let script = "class Foo : Zom, Aar, Bar {}";
|
||||
let lexed_tokens = lex(script, &mut panic_on_error);
|
||||
println!("{}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
println!("Lexed tokens JSON: {}", serde_json::to_string(&lexed_tokens).unwrap());
|
||||
let expected_tokens: Vec<LexToken> =
|
||||
serde_json::from_str(r#"[
|
||||
{
|
||||
|
@ -152,7 +152,7 @@ fn integration_multiple_inheritance_class() {
|
|||
assert_eq!(lexed_tokens, expected_tokens);
|
||||
|
||||
let parsed_tree = parse(lexed_tokens, &mut panic_on_error);
|
||||
println!("{}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
println!("Parsed Tree JSON: {}", serde_json::to_string(&parsed_tree).unwrap());
|
||||
let expected_tree: Box<ParsedStatement> =
|
||||
serde_json::from_str(r#"{
|
||||
"Script": {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"modifiers": 0,
|
||||
"field_mod": null,
|
||||
"is_destructor": false,
|
||||
"is_constructor": false,
|
||||
"returns_reference": false,
|
||||
"return_type": {
|
||||
"Type": {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
final shared class Foobar {
|
||||
int _a;
|
||||
int _b;
|
||||
|
||||
Foobar(int a, int b) {
|
||||
_a = a;
|
||||
_b = b;
|
||||
}
|
||||
|
||||
int GetA(){
|
||||
return _a;
|
||||
}
|
||||
|
||||
int Add() {
|
||||
return _a + _b;
|
||||
}
|
||||
|
||||
class Inner {
|
||||
int a;
|
||||
}
|
||||
}
|
|
@ -736,8 +736,20 @@ fn parse_func(
|
|||
returns_reference = true;
|
||||
reader.next();
|
||||
}
|
||||
return_type.as_ref()?;
|
||||
}
|
||||
let name = parse_identifier(&mut reader, log, true);
|
||||
let mut name = parse_identifier(&mut reader, log, true);
|
||||
|
||||
let mut is_constructor = false;
|
||||
if name.is_none() && return_type.is_some() {
|
||||
if let ParsedStatement::Type { datatype, .. } = return_type.as_ref().unwrap().as_ref() {
|
||||
if let ParsedStatement::DataTypeIdentifier { identifier } = datatype.as_ref() {
|
||||
name = Some(identifier.to_string());
|
||||
is_constructor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
name.as_ref()?;
|
||||
let param_list = parse_paramlist(&mut reader, log);
|
||||
param_list.as_ref()?;
|
||||
|
@ -759,6 +771,7 @@ fn parse_func(
|
|||
modifiers,
|
||||
field_mod,
|
||||
is_destructor,
|
||||
is_constructor,
|
||||
returns_reference,
|
||||
return_type,
|
||||
name: name.unwrap(),
|
||||
|
@ -773,6 +786,7 @@ fn parse_virtprop(
|
|||
outer_reader: &mut ParseReader,
|
||||
log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
// virtprop ::= ['private' | 'protected'] type ['&'] identifier '{' {('get' | 'set') ['const'] funcattr (statblock | ';')} '}';
|
||||
let mut reader = outer_reader.create_inner();
|
||||
let mut field_mod: Option<FieldModifier> = None;
|
||||
match reader.peek().token_type {
|
||||
|
@ -794,7 +808,7 @@ fn parse_virtprop(
|
|||
reader.next();
|
||||
is_handle = true;
|
||||
}
|
||||
let identifier = parse_identifier(&mut reader, log, false);
|
||||
let identifier = parse_identifier(&mut reader, log, true);
|
||||
identifier.as_ref()?;
|
||||
let next = reader.next();
|
||||
if next.token_type != TokenType::OpenCurlyBracket {
|
||||
|
@ -1015,7 +1029,7 @@ fn parse_var(
|
|||
}
|
||||
property_type.as_ref()?;
|
||||
|
||||
let identifier = parse_identifier(&mut reader, log, false);
|
||||
let identifier = parse_identifier(&mut reader, log, true);
|
||||
identifier.as_ref()?;
|
||||
|
||||
let mut assignment: Option<Box<ParsedStatement>> = None;
|
||||
|
@ -1402,7 +1416,6 @@ fn parse_exprterm(
|
|||
})
|
||||
}
|
||||
|
||||
println!("{:?}", real_value);
|
||||
outer_reader.set_from_inner(&reader);
|
||||
Some(real_value)
|
||||
}
|
||||
|
@ -1567,7 +1580,7 @@ fn parse_exprvalue(
|
|||
|
||||
fn parse_lambda(
|
||||
reader: &mut ParseReader,
|
||||
log: &mut dyn FnMut(Message, Span),
|
||||
_log: &mut dyn FnMut(Message, Span),
|
||||
) -> Option<Box<ParsedStatement>> {
|
||||
// lambda ::= 'function' '(' [[type typemod] identifier {',' [type typemod] identifier}] ')' statblock;
|
||||
if reader.peek().token_type != TokenType::FunctionKeyword {
|
||||
|
@ -1783,7 +1796,10 @@ fn parse_assign(
|
|||
ternary.as_ref()?;
|
||||
if let Some(assign_op) = parse_assignop(reader, log) {
|
||||
let assign = parse_assign(reader, log);
|
||||
// FIXME: deal with None assign.
|
||||
if assign.is_none() {
|
||||
// FIXME: Logging
|
||||
return Some(Box::new(ParsedStatement::Invalid));
|
||||
}
|
||||
return Some(Box::new(ParsedStatement::Assignment {
|
||||
left: ternary.unwrap(),
|
||||
operator: assign_op,
|
||||
|
|
|
@ -216,6 +216,7 @@ pub enum ParsedStatement {
|
|||
modifiers: BitFlags<TypeModifier>,
|
||||
field_mod: Option<FieldModifier>,
|
||||
is_destructor: bool,
|
||||
is_constructor: bool,
|
||||
returns_reference: bool,
|
||||
return_type: Option<Box<ParsedStatement>>,
|
||||
name: String,
|
||||
|
|
Loading…
Reference in New Issue