From 5a375584b9fca8d6d3b09ae62226950e4b01a691 Mon Sep 17 00:00:00 2001 From: Glyphack Date: Thu, 10 Oct 2024 21:00:55 +0200 Subject: [PATCH] Pass file to checker --- benchmark/benches/typecheck_benchmark.rs | 3 ++- enderpy/src/main.rs | 3 ++- lsp/src/main.rs | 3 ++- typechecker/src/build.rs | 5 +++-- typechecker/src/checker.rs | 7 +++++-- typechecker/src/type_evaluator.rs | 7 +++++-- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/benchmark/benches/typecheck_benchmark.rs b/benchmark/benches/typecheck_benchmark.rs index 3ed4adc0..43843952 100644 --- a/benchmark/benches/typecheck_benchmark.rs +++ b/benchmark/benches/typecheck_benchmark.rs @@ -33,7 +33,8 @@ pub fn benchmark_type_checker(c: &mut Criterion) { let builder = BuildManager::new(Settings::test_settings()); let file_path = PathBuf::from(path); builder.build_one(&PathBuf::from("../../"), &file_path); - builder.type_check(&file_path); + let file = builder.get_state(&file_path); + builder.type_check(&file_path, &file); 0 }); diff --git a/enderpy/src/main.rs b/enderpy/src/main.rs index acc831ad..d592bc41 100644 --- a/enderpy/src/main.rs +++ b/enderpy/src/main.rs @@ -126,7 +126,8 @@ fn check(path: &Path) -> Result<()> { let build_manager = BuildManager::new(settings); build_manager.build(root); build_manager.build_one(root, path); - build_manager.type_check(path); + let file = build_manager.get_state(path); + build_manager.type_check(path, &file); if build_manager.diagnostics.is_empty() { println!("zero errors"); diff --git a/lsp/src/main.rs b/lsp/src/main.rs index 8b6368b4..ed0dbb05 100644 --- a/lsp/src/main.rs +++ b/lsp/src/main.rs @@ -15,7 +15,8 @@ impl<'a> Backend { fn build(&self, path: PathBuf) { let root = find_project_root(&path); self.manager.build_one(root, &path); - self.manager.type_check(&path); + let file = self.manager.get_state(&path); + self.manager.type_check(&path, &file); } } diff --git a/typechecker/src/build.rs b/typechecker/src/build.rs index b75816f0..c45e0dcd 100755 --- a/typechecker/src/build.rs +++ b/typechecker/src/build.rs @@ -104,12 +104,13 @@ impl<'a> BuildManager { // Performs type checking passes over the code // This step happens after the binding phase - pub fn type_check(&self, path: &Path) -> TypeChecker { + pub fn type_check(&'a self, path: &Path, file: &'a EnderpyFile) -> TypeChecker<'a> { let mut module_to_check = self.get_state(path); let span = span!(Level::TRACE, "type check", path = %path.display()); let _guard = span.enter(); let mut checker = TypeChecker::new( + file, self.get_symbol_table(path), &self.symbol_tables, &self.module_ids, @@ -132,7 +133,7 @@ impl<'a> BuildManager { pub fn get_hover_information(&self, path: &Path, line: u32, column: u32) -> String { let module = self.get_state(path); - let checker = self.type_check(path); + let checker = self.type_check(path, &module); let symbol_table = self.get_symbol_table(path); let hovered_offset = module.line_starts[line as usize] + column; diff --git a/typechecker/src/checker.rs b/typechecker/src/checker.rs index 43e04c81..da28bab2 100644 --- a/typechecker/src/checker.rs +++ b/typechecker/src/checker.rs @@ -7,6 +7,7 @@ use enderpy_python_parser as parser; use enderpy_python_parser::ast::{self, *}; use super::{type_evaluator::TypeEvaluator, types::PythonType}; +use crate::file::EnderpyFile; use crate::symbol_table::Id; use crate::types::ModuleRef; use crate::{ast_visitor::TraversalVisitor, diagnostic::CharacterSpan, symbol_table::SymbolTable}; @@ -28,13 +29,14 @@ pub struct TypeCheckError { #[allow(unused)] impl<'a> TypeChecker<'a> { pub fn new( + file: &'a EnderpyFile, symbol_table: SymbolTable, symbol_tables: &'a DashMap, ids: &'a DashMap, ) -> Self { TypeChecker { errors: vec![], - type_evaluator: TypeEvaluator::new(symbol_table, symbol_tables, ids), + type_evaluator: TypeEvaluator::new(file, symbol_table, symbol_tables, ids), types: Lapper::new(vec![]), } } @@ -629,7 +631,8 @@ mod tests { let root = &PathBuf::from(""); manager.build(root); manager.build_one(root, &path); - let checker = manager.type_check(&path); + let module = manager.get_state(&path); + let checker = manager.type_check(&path, &module); let module = manager.get_state(&path); let result = checker.types; diff --git a/typechecker/src/type_evaluator.rs b/typechecker/src/type_evaluator.rs index e82ef552..323ec0a0 100755 --- a/typechecker/src/type_evaluator.rs +++ b/typechecker/src/type_evaluator.rs @@ -23,10 +23,10 @@ use super::{ }, }; use crate::{ + file::EnderpyFile, semantic_analyzer::get_member_access_info, symbol_table::{ self, Class, Declaration, Id, LookupSymbolRequest, SymbolTable, SymbolTableNode, - TypeParameter, }, types::CallableArgs, }; @@ -40,6 +40,7 @@ const SPECIAL_FORM: &str = "_SpecialForm"; #[derive(Clone, Debug)] pub struct TypeEvaluator<'a> { // TODO: make this a reference to the symbol table in the checker + pub file: &'a EnderpyFile, pub symbol_table: SymbolTable, pub imported_symbol_tables: &'a DashMap, pub ids: &'a DashMap, @@ -68,12 +69,14 @@ bitflags::bitflags! { /// Struct for evaluating the type of an expression impl<'a> TypeEvaluator<'a> { pub fn new( + file: &'a EnderpyFile, symbol_table: SymbolTable, imported_symbol_tables: &'a DashMap, ids: &'a DashMap, ) -> Self { TypeEvaluator { symbol_table, + file, imported_symbol_tables, ids, flags: Cell::new(GetTypeFlags::empty()), @@ -562,7 +565,7 @@ impl<'a> TypeEvaluator<'a> { // then local scope. // https://peps.python.org/pep-0563/#backwards-compatibility ast::ConstantValue::Str => { - let mut parser = Parser::new(""); + let mut parser = Parser::new(&self.file.source); // Wrap the parsing logic inside a `catch_unwind` block let parse_result = catch_unwind(AssertUnwindSafe(|| parser.parse()));