Skip to content

Commit

Permalink
Detect infinite dependencies (#279)
Browse files Browse the repository at this point in the history
* Inifinite dependencies test.

* Detect infinite dependencies.

* Merge file_path with build_config.

* Use HashSet instead of Vec.

* Use dependency config instead of build config.

* Build config need not be mutable.

Co-authored-by: Toby Hutton <[email protected]>
  • Loading branch information
emilyaherbert and otrho authored Oct 4, 2021
1 parent f83dd8c commit e0c043b
Show file tree
Hide file tree
Showing 16 changed files with 218 additions and 36 deletions.
3 changes: 3 additions & 0 deletions core_lang/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,8 @@ pub enum CompileError<'sc> {
call_chain: String, // Pretty list of symbols, e.g., "a, b and c".
span: Span<'sc>,
},
#[error("File {file_path} generates an infinite dependency cycle.")]
InfiniteDependencies { file_path: String, span: Span<'sc> },
}

impl<'sc> std::convert::From<TypeError<'sc>> for CompileError<'sc> {
Expand Down Expand Up @@ -857,6 +859,7 @@ impl<'sc> CompileError<'sc> {
ArgumentParameterTypeMismatch { span, .. } => span,
RecursiveCall { span, .. } => span,
RecursiveCallChain { span, .. } => span,
InfiniteDependencies { span, .. } => span,
}
}

Expand Down
10 changes: 8 additions & 2 deletions core_lang/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use semantic_analysis::{TreeType, TypedParseTree};
pub mod types;
pub(crate) mod utils;
pub use crate::parse_tree::{Declaration, Expression, UseStatement, WhileLoop};
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};

pub use crate::span::Span;
pub use error::{CompileError, CompileResult, CompileWarning};
Expand Down Expand Up @@ -196,6 +196,7 @@ pub(crate) fn compile_inner_dependency<'sc>(
initial_namespace: &Namespace<'sc>,
build_config: BuildConfig,
dead_code_graph: &mut ControlFlowGraph<'sc>,
dependency_graph: &mut HashMap<String, HashSet<String>>,
) -> CompileResult<'sc, InnerDependencyCompileResult<'sc>> {
let mut warnings = Vec::new();
let mut errors = Vec::new();
Expand Down Expand Up @@ -232,6 +233,7 @@ pub(crate) fn compile_inner_dependency<'sc>(
TreeType::Library,
&build_config.clone(),
dead_code_graph,
dependency_graph,
)
.ok(&mut warnings, &mut errors)
.map(|value| (name, value))
Expand Down Expand Up @@ -277,6 +279,7 @@ pub fn compile_to_asm<'sc>(
input: &'sc str,
initial_namespace: &Namespace<'sc>,
build_config: BuildConfig,
dependency_graph: &mut HashMap<String, HashSet<String>>,
) -> CompilationResult<'sc> {
let mut warnings = Vec::new();
let mut errors = Vec::new();
Expand All @@ -300,6 +303,7 @@ pub fn compile_to_asm<'sc>(
tree_type,
&build_config.clone(),
&mut dead_code_graph,
dependency_graph,
)
.ok(&mut warnings, &mut errors)
})
Expand All @@ -321,6 +325,7 @@ pub fn compile_to_asm<'sc>(
TreeType::Library,
&build_config.clone(),
&mut dead_code_graph,
dependency_graph,
)
.ok(&mut warnings, &mut errors)
.map(|value| (name, value))
Expand Down Expand Up @@ -450,8 +455,9 @@ pub fn compile_to_bytecode<'sc>(
input: &'sc str,
initial_namespace: &Namespace<'sc>,
build_config: BuildConfig,
dependency_graph: &mut HashMap<String, HashSet<String>>,
) -> BytecodeCompilationResult<'sc> {
match compile_to_asm(input, initial_namespace, build_config) {
match compile_to_asm(input, initial_namespace, build_config, dependency_graph) {
CompilationResult::Success {
mut asm,
mut warnings,
Expand Down
3 changes: 3 additions & 0 deletions core_lang/src/semantic_analysis/ast_node/code_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::build_config::BuildConfig;
use crate::control_flow_analysis::ControlFlowGraph;
use crate::types::MaybeResolvedType;
use crate::CodeBlock;
use std::collections::{HashMap, HashSet};

#[derive(Clone, Debug)]
pub(crate) struct TypedCodeBlock<'sc> {
Expand All @@ -24,6 +25,7 @@ impl<'sc> TypedCodeBlock<'sc> {
self_type: &MaybeResolvedType<'sc>,
build_config: &BuildConfig,
dead_code_graph: &mut ControlFlowGraph<'sc>,
dependency_graph: &mut HashMap<String, HashSet<String>>,
) -> CompileResult<'sc, (Self, Option<MaybeResolvedType<'sc>>)> {
let mut warnings = Vec::new();
let mut errors = Vec::new();
Expand All @@ -43,6 +45,7 @@ impl<'sc> TypedCodeBlock<'sc> {
self_type,
build_config,
dead_code_graph,
dependency_graph,
)
.ok(&mut warnings, &mut errors)
})
Expand Down
5 changes: 4 additions & 1 deletion core_lang/src/semantic_analysis/ast_node/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
};
use crate::{control_flow_analysis::ControlFlowGraph, types::TypeInfo};
use sha2::{Digest, Sha256};
use std::collections::{HashMap, HashSet};

#[derive(Clone, Debug)]
pub enum TypedDeclaration<'sc> {
Expand Down Expand Up @@ -508,6 +509,7 @@ impl<'sc> TypedFunctionDeclaration<'sc> {
build_config: &BuildConfig,
dead_code_graph: &mut ControlFlowGraph<'sc>,
mode: Mode,
dependency_graph: &mut HashMap<String, HashSet<String>>,
) -> CompileResult<'sc, TypedFunctionDeclaration<'sc>> {
let mut warnings = Vec::new();
let mut errors = Vec::new();
Expand Down Expand Up @@ -555,7 +557,8 @@ impl<'sc> TypedFunctionDeclaration<'sc> {
"Function body's return type does not match up with its return type annotation.",
self_type,
build_config,
dead_code_graph
dead_code_graph,
dependency_graph
),
(
TypedCodeBlock {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub(crate) fn instantiate_enum<'sc>(
self_type: &MaybeResolvedType<'sc>,
build_config: &BuildConfig,
dead_code_graph: &mut ControlFlowGraph<'sc>,
dependency_graph: &mut HashMap<String, HashSet<String>>,
) -> CompileResult<'sc, TypedExpression<'sc>> {
let mut warnings = vec![];
let mut errors = vec![];
Expand Down Expand Up @@ -69,6 +70,7 @@ pub(crate) fn instantiate_enum<'sc>(
self_type,
build_config,
dead_code_graph,
dependency_graph
),
return err(warnings, errors),
warnings,
Expand Down
Loading

0 comments on commit e0c043b

Please sign in to comment.