Re-enable tests for name analysis. Currently failing.
This commit is contained in:
parent
d653d26e14
commit
e5c5be6d95
@ -79,9 +79,9 @@ pub mod build {
|
|||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/src/ast/build.rs"));
|
include!(concat!(env!("OUT_DIR"), "/src/ast/build.rs"));
|
||||||
|
|
||||||
pub fn build_ast(file_id: usize, parsed_pairs: &mut Pairs<Rule>) -> Box<CompilationUnit> {
|
pub fn build_ast(file_id: usize, parsed_pairs: &mut Pairs<Rule>) -> CompilationUnit {
|
||||||
let compilation_unit_pair = parsed_pairs.next().unwrap();
|
let compilation_unit_pair = parsed_pairs.next().unwrap();
|
||||||
Box::new(build_compilation_unit(file_id, compilation_unit_pair))
|
build_compilation_unit(file_id, compilation_unit_pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@ -3,40 +3,69 @@ use codespan_reporting::term;
|
|||||||
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
||||||
use deimos::ast::build::build_ast;
|
use deimos::ast::build::build_ast;
|
||||||
use deimos::name_analysis::analyze_names;
|
use deimos::name_analysis::analyze_names;
|
||||||
use deimos::name_analysis::symbol_table::symbol_tree::SymbolTree;
|
|
||||||
use deimos::name_analysis::symbol_table::SymbolTable;
|
use deimos::name_analysis::symbol_table::SymbolTable;
|
||||||
use deimos::parser::{DeimosParser, Rule};
|
use deimos::parser::{DeimosParser, Rule};
|
||||||
use deimos::std_core::add_std_core_symbols;
|
use deimos::std_core::add_std_core_symbols;
|
||||||
use pest::Parser;
|
use pest::Parser;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Error>> {
|
struct ParseErrors {
|
||||||
let mut compilation_units = vec![];
|
errors: Vec<pest::error::Error<Rule>>,
|
||||||
let mut files: SimpleFiles<String, String> = SimpleFiles::new();
|
}
|
||||||
|
|
||||||
|
impl Debug for ParseErrors {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
Display::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ParseErrors {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
writeln!(f, "There were errors during parsing.")?;
|
||||||
|
for parse_error in &self.errors {
|
||||||
|
writeln!(f, "{}", parse_error)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for ParseErrors {}
|
||||||
|
|
||||||
|
pub fn name_analysis(paths: &[PathBuf]) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut paths_and_sources: HashMap<String, String> = HashMap::new();
|
||||||
for path in paths {
|
for path in paths {
|
||||||
let src = std::fs::read_to_string(path).unwrap();
|
let src = std::fs::read_to_string(path).unwrap();
|
||||||
let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src);
|
paths_and_sources.insert(path.display().to_string(), src);
|
||||||
let file_id = files.add(path.display().to_string(), src.clone()); // I don't love this clone
|
}
|
||||||
|
|
||||||
|
let mut compilation_units = vec![];
|
||||||
|
let mut files: SimpleFiles<&str, &str> = SimpleFiles::new();
|
||||||
|
let mut parse_errors = vec![];
|
||||||
|
|
||||||
|
for (path, source) in &paths_and_sources {
|
||||||
|
let parse_result = DeimosParser::parse(Rule::CompilationUnit, source);
|
||||||
match parse_result {
|
match parse_result {
|
||||||
Ok(mut pairs) => {
|
Ok(mut pairs) => {
|
||||||
|
let file_id = files.add(path, source);
|
||||||
let compilation_unit = build_ast(file_id, &mut pairs);
|
let compilation_unit = build_ast(file_id, &mut pairs);
|
||||||
compilation_units.push(compilation_unit);
|
compilation_units.push(compilation_unit);
|
||||||
Ok::<(), Box<dyn std::error::Error>>(())
|
|
||||||
}
|
}
|
||||||
Err(e) => Err(e.into()),
|
Err(error) => {
|
||||||
}?;
|
parse_errors.push(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !parse_errors.is_empty() {
|
||||||
|
return Err(Box::new(ParseErrors { errors: parse_errors }));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
|
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
|
||||||
|
|
||||||
let diagnostics = analyze_names(
|
let diagnostics = analyze_names(&mut compilation_units, &files, &mut symbol_table);
|
||||||
&mut compilation_units,
|
|
||||||
&files,
|
|
||||||
&mut symbol_table,
|
|
||||||
);
|
|
||||||
if diagnostics.is_empty() {
|
if diagnostics.is_empty() {
|
||||||
println!("Name analysis complete.");
|
println!("Name analysis complete.");
|
||||||
println!("{}", symbol_table);
|
println!("{}", symbol_table);
|
||||||
|
|||||||
@ -1,4 +1,9 @@
|
|||||||
use crate::ast::node::{CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody, GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters, PrimitiveType, ReturnType, StarUseStatement, TypeUse, TypedArray, UseStatement, UseStatementIdentifier, UseStatementPrefix};
|
use crate::ast::node::{
|
||||||
|
CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, Function, FunctionBody,
|
||||||
|
GenericParameters, Identifier, IdentifierOrFqn, Module, ModuleLevelDeclaration, Parameters,
|
||||||
|
PrimitiveType, ReturnType, StarUseStatement, TypeUse, TypedArray, UseStatement,
|
||||||
|
UseStatementIdentifier, UseStatementPrefix,
|
||||||
|
};
|
||||||
use crate::diagnostic::DmDiagnostic;
|
use crate::diagnostic::DmDiagnostic;
|
||||||
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
use crate::name_analysis::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
use crate::name_analysis::symbol::generic_type_symbol::GenericTypeSymbol;
|
||||||
@ -9,8 +14,10 @@ use crate::name_analysis::symbol::primitive_type_symbol::PrimitiveTypeSymbol;
|
|||||||
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
use crate::name_analysis::symbol::source_definition::SourceDefinition;
|
||||||
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
use crate::name_analysis::symbol::type_symbol::TypeSymbol;
|
||||||
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol};
|
||||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::name_analysis::symbol_table::SymbolTable;
|
||||||
use crate::name_analysis::util::{format_fqn, handle_insert_error, handle_lookup_error, join_fqn_parts};
|
use crate::name_analysis::util::{
|
||||||
|
format_fqn, handle_insert_error, handle_lookup_error, join_fqn_parts,
|
||||||
|
};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -140,10 +147,12 @@ fn na_p1_star_use_statement(
|
|||||||
.map(Identifier::name)
|
.map(Identifier::name)
|
||||||
.map(|name| Rc::from(name))
|
.map(|name| Rc::from(name))
|
||||||
.collect::<Vec<Rc<str>>>();
|
.collect::<Vec<Rc<str>>>();
|
||||||
|
|
||||||
let to_insert = StarUseSymbol::new(
|
let to_insert = StarUseSymbol::new(
|
||||||
&fqn_parts,
|
&fqn_parts,
|
||||||
Some(SourceDefinition::from_star_use_statement(star_use_statement))
|
Some(SourceDefinition::from_star_use_statement(
|
||||||
|
star_use_statement,
|
||||||
|
)),
|
||||||
);
|
);
|
||||||
match symbol_table.insert_star_use_symbol(to_insert) {
|
match symbol_table.insert_star_use_symbol(to_insert) {
|
||||||
Ok(star_use_symbol) => {
|
Ok(star_use_symbol) => {
|
||||||
|
|||||||
@ -36,8 +36,11 @@ pub mod symbol;
|
|||||||
pub mod symbol_table;
|
pub mod symbol_table;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
pub fn analyze_names<
|
||||||
compilation_units: &mut Vec<Box<CompilationUnit>>,
|
'a,
|
||||||
|
F: Files<'a, FileId = usize, Name = &'a str, Source = &'a str> + ?Sized,
|
||||||
|
>(
|
||||||
|
compilation_units: &mut Vec<CompilationUnit>,
|
||||||
files: &'a F,
|
files: &'a F,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
) -> Vec<DmDiagnostic> {
|
) -> Vec<DmDiagnostic> {
|
||||||
@ -46,7 +49,7 @@ pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
|||||||
// gather symbols
|
// gather symbols
|
||||||
for compilation_unit in compilation_units.iter_mut() {
|
for compilation_unit in compilation_units.iter_mut() {
|
||||||
let file_name = files.name(compilation_unit.file_id()).unwrap();
|
let file_name = files.name(compilation_unit.file_id()).unwrap();
|
||||||
na_p1_compilation_unit(&file_name, compilation_unit, symbol_table, &mut diagnostics);
|
na_p1_compilation_unit(file_name, compilation_unit, symbol_table, &mut diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve symbols
|
// resolve symbols
|
||||||
@ -57,218 +60,133 @@ pub fn analyze_names<'a, F: Files<'a, FileId = usize, Name = String>>(
|
|||||||
diagnostics.into()
|
diagnostics.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg(test)]
|
#[cfg(test)]
|
||||||
// mod tests {
|
mod tests {
|
||||||
// use super::*;
|
use super::*;
|
||||||
// use crate::ast::build::build_ast;
|
use crate::ast::build::build_ast;
|
||||||
// use crate::ast::children::NodeRef;
|
use crate::parser::{DeimosParser, Rule};
|
||||||
// use crate::ast::walk::walk_depth_first;
|
use crate::std_core::add_std_core_symbols;
|
||||||
// use crate::parser::{DeimosParser, Rule};
|
use codespan_reporting::files::SimpleFiles;
|
||||||
// use crate::std_core::add_std_core_symbols;
|
use codespan_reporting::term;
|
||||||
// use codespan_reporting::files::SimpleFiles;
|
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
||||||
// use codespan_reporting::term;
|
use pest::Parser;
|
||||||
// use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
use std::collections::HashMap;
|
||||||
// use indoc::indoc;
|
|
||||||
// use pest::Parser;
|
fn parse_compilation_units<'a>(
|
||||||
// use std::collections::HashMap;
|
files: &mut SimpleFiles<&'a str, &'a str>,
|
||||||
//
|
sources: HashMap<&'a str, &'a str>,
|
||||||
// fn assert_number_of_diagnostics(
|
) -> Vec<CompilationUnit> {
|
||||||
// sources: HashMap<&str, &str>,
|
let mut compilation_units: Vec<CompilationUnit> = vec![];
|
||||||
// symbol_table: &mut SymbolTable,
|
|
||||||
// n_diagnostics: usize,
|
for (file_name, source) in sources {
|
||||||
// ) -> Vec<CompilationUnit> {
|
let parse_result = DeimosParser::parse(Rule::CompilationUnit, source);
|
||||||
// let mut files = SimpleFiles::new();
|
if let Err(err) = &parse_result {
|
||||||
// let mut compilation_units = vec![];
|
panic!("{}", err);
|
||||||
//
|
}
|
||||||
// for (file_name, source) in sources {
|
let mut pairs = parse_result.unwrap();
|
||||||
// let file_id = files.add(file_name, source);
|
if pairs.as_str().trim() != source.trim() {
|
||||||
// let parse_result = DeimosParser::parse(Rule::CompilationUnit, source);
|
panic!("Parsing did not consume entire input.");
|
||||||
// if let Err(err) = &parse_result {
|
}
|
||||||
// panic!("{}", err);
|
let file_id = files.add(file_name, source);
|
||||||
// }
|
compilation_units.push(build_ast(file_id, &mut pairs));
|
||||||
// let mut pairs = parse_result.unwrap();
|
}
|
||||||
// if pairs.as_str().trim() != source.trim() {
|
|
||||||
// panic!("Parsing did not consume entire input.");
|
compilation_units
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// compilation_units.push(build_ast(file_name, file_id, pairs.next().unwrap()));
|
fn assert_number_of_diagnostics<'a>(
|
||||||
// }
|
sources: HashMap<&'a str, &'a str>,
|
||||||
//
|
symbol_table: &mut SymbolTable,
|
||||||
// let diagnostics = analyze_names(&mut compilation_units, symbol_table);
|
number_of_diagnostics: usize,
|
||||||
//
|
) -> Vec<CompilationUnit> {
|
||||||
// if diagnostics.len() != n_diagnostics {
|
let mut files = SimpleFiles::<&'a str, &'a str>::new();
|
||||||
// let writer = StandardStream::stderr(ColorChoice::Always);
|
let mut compilation_units = parse_compilation_units(&mut files, sources);
|
||||||
// let config = term::Config::default();
|
|
||||||
//
|
let diagnostics = analyze_names(&mut compilation_units, &files, symbol_table);
|
||||||
// for diagnostic in &diagnostics {
|
|
||||||
// term::emit(&mut writer.lock(), &config, &files, &diagnostic).unwrap();
|
if diagnostics.len() != number_of_diagnostics {
|
||||||
// }
|
let writer = StandardStream::stderr(ColorChoice::Always);
|
||||||
//
|
let config = term::Config::default();
|
||||||
// eprintln!("{}", symbol_table);
|
|
||||||
// }
|
for diagnostic in &diagnostics {
|
||||||
//
|
term::emit(&mut writer.lock(), &config, &files, &diagnostic).unwrap();
|
||||||
// assert_eq!(n_diagnostics, diagnostics.len());
|
}
|
||||||
//
|
|
||||||
// compilation_units
|
eprintln!("{}", symbol_table);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// fn assert_no_diagnostics(
|
assert_eq!(number_of_diagnostics, diagnostics.len());
|
||||||
// sources: HashMap<&str, &str>,
|
|
||||||
// symbol_table: &mut SymbolTable,
|
compilation_units
|
||||||
// ) -> Vec<CompilationUnit> {
|
}
|
||||||
// assert_number_of_diagnostics(sources, symbol_table, 0)
|
|
||||||
// }
|
fn assert_no_diagnostics(
|
||||||
//
|
sources: HashMap<&str, &str>,
|
||||||
// fn assert_saved_symbols(compilation_unit: &CompilationUnit) {
|
symbol_table: &mut SymbolTable,
|
||||||
// walk_depth_first(compilation_unit, &mut |node_ref| match node_ref {
|
) -> Vec<CompilationUnit> {
|
||||||
// NodeRef::Identifier(identifier) => {
|
assert_number_of_diagnostics(sources, symbol_table, 0)
|
||||||
// if identifier.saved_symbol().is_none() {
|
}
|
||||||
// panic!("{:?} does not have a saved symbol.", identifier)
|
|
||||||
// }
|
#[test]
|
||||||
// }
|
fn params_seen() {
|
||||||
// NodeRef::FullyQualifiedName(fqn) => {
|
let sources = HashMap::from([(
|
||||||
// if fqn.saved_symbol().is_none() {
|
"main.dm",
|
||||||
// panic!("{:?} does not have a saved symbol.", fqn)
|
"
|
||||||
// }
|
fn main(args: Array<String>)
|
||||||
// }
|
let x = args
|
||||||
// NodeRef::UseStatement(use_statement) => match use_statement {
|
end
|
||||||
// _ => todo!(),
|
",
|
||||||
// },
|
)]);
|
||||||
// _ => {}
|
|
||||||
// })
|
assert_no_diagnostics(sources, &mut SymbolTable::new());
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// fn assert_resolved_symbols(compilation_unit: &CompilationUnit) {
|
#[test]
|
||||||
// walk_depth_first(compilation_unit, &mut |node_ref| match node_ref {
|
fn two_files() {
|
||||||
// NodeRef::UseStatement(use_statement) => match use_statement {
|
let sources = HashMap::from([
|
||||||
// _ => todo!(),
|
(
|
||||||
// },
|
"main.dm",
|
||||||
// _ => {}
|
"
|
||||||
// })
|
use test::Greeter
|
||||||
// }
|
",
|
||||||
//
|
),
|
||||||
// #[test]
|
(
|
||||||
// fn params_seen() {
|
"deps.dm",
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([(
|
"
|
||||||
// "main.dm",
|
ns test
|
||||||
// indoc! {"
|
|
||||||
// fn main(args: Array<String>) {
|
pub class Greeter end
|
||||||
// let x = args;
|
",
|
||||||
// }"},
|
),
|
||||||
// )]);
|
]);
|
||||||
//
|
assert_no_diagnostics(sources, &mut SymbolTable::new());
|
||||||
// let cus = assert_no_diagnostics(sources, &mut SymbolTable::new());
|
}
|
||||||
// for ref cu in cus {
|
|
||||||
// assert_saved_symbols(cu);
|
#[test]
|
||||||
// }
|
fn sees_std_core_println() {
|
||||||
// }
|
let sources: HashMap<&str, &str> = HashMap::from([(
|
||||||
//
|
"main.dm",
|
||||||
// #[test]
|
"
|
||||||
// fn two_files() {
|
fn main(args: Array<String>)
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([
|
std::core::println args
|
||||||
// (
|
end
|
||||||
// "main.dm",
|
",
|
||||||
// indoc! {"
|
)]);
|
||||||
// use test::Greeter;
|
|
||||||
// "},
|
let mut symbol_table = SymbolTable::new();
|
||||||
// ),
|
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
|
||||||
// (
|
assert_no_diagnostics(sources, &mut symbol_table);
|
||||||
// "deps.dm",
|
}
|
||||||
// indoc! {"
|
|
||||||
// ns test;
|
#[test]
|
||||||
//
|
fn sees_duplicate_fn() {
|
||||||
// pub class Greeter {}
|
let sources: HashMap<&str, &str> = HashMap::from([(
|
||||||
// "},
|
"main.dm",
|
||||||
// ),
|
"
|
||||||
// ]);
|
fn main(args: Array<String>) end
|
||||||
//
|
fn main(args: Array<String>) end
|
||||||
// let cus = assert_no_diagnostics(sources, &mut SymbolTable::new());
|
",
|
||||||
// for ref cu in cus {
|
)]);
|
||||||
// assert_saved_symbols(cu);
|
assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
||||||
// assert_resolved_symbols(cu);
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[test]
|
|
||||||
// fn sees_std_core_println() {
|
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([(
|
|
||||||
// "main.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// fn main(args: Array<String>) {
|
|
||||||
// println(args)
|
|
||||||
// }
|
|
||||||
// "},
|
|
||||||
// )]);
|
|
||||||
//
|
|
||||||
// let mut symbol_table = SymbolTable::new();
|
|
||||||
// add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
|
|
||||||
// let cus = assert_no_diagnostics(sources, &mut symbol_table);
|
|
||||||
// for ref cu in cus {
|
|
||||||
// assert_saved_symbols(cu);
|
|
||||||
// assert_resolved_symbols(cu);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[test]
|
|
||||||
// fn sees_duplicate_fn() {
|
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([(
|
|
||||||
// "main.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// fn main(args: Array<String>) {}
|
|
||||||
// fn main(args: Array<String>) {}
|
|
||||||
// "},
|
|
||||||
// )]);
|
|
||||||
// assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[test]
|
|
||||||
// fn use_class_from_other_file() {
|
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([
|
|
||||||
// (
|
|
||||||
// "main.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// use greeter::Greeter;
|
|
||||||
//
|
|
||||||
// fn test(greeter: Greeter) {}
|
|
||||||
// "},
|
|
||||||
// ),
|
|
||||||
// (
|
|
||||||
// "greeter.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// ns greeter;
|
|
||||||
//
|
|
||||||
// class Greeter {}
|
|
||||||
// "},
|
|
||||||
// ),
|
|
||||||
// ]);
|
|
||||||
// let mut symbol_table = SymbolTable::new();
|
|
||||||
// let cus = assert_no_diagnostics(sources, &mut symbol_table);
|
|
||||||
// for ref cu in cus {
|
|
||||||
// assert_saved_symbols(cu);
|
|
||||||
// assert_resolved_symbols(cu);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[test]
|
|
||||||
// fn shadow_import() {
|
|
||||||
// let sources: HashMap<&str, &str> = HashMap::from([
|
|
||||||
// (
|
|
||||||
// "main.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// use greeter::Greeter;
|
|
||||||
//
|
|
||||||
// class Greeter {}
|
|
||||||
// "},
|
|
||||||
// ),
|
|
||||||
// (
|
|
||||||
// "greeter.dm",
|
|
||||||
// indoc! {"
|
|
||||||
// ns greeter;
|
|
||||||
//
|
|
||||||
// class Greeter {}
|
|
||||||
// "},
|
|
||||||
// ),
|
|
||||||
// ]);
|
|
||||||
// assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user