Skip to content

Commit

Permalink
Add symbol resolve context.
Browse files Browse the repository at this point in the history
  • Loading branch information
tritao committed Aug 4, 2024
1 parent 0ec9062 commit e9356cc
Show file tree
Hide file tree
Showing 24 changed files with 1,170 additions and 32 deletions.
24 changes: 24 additions & 0 deletions sway-core/src/decl_engine/parsed_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,30 @@ decl_engine_insert!(enum_slab, EnumDeclaration);
decl_engine_insert!(enum_variant_slab, EnumVariant);
decl_engine_insert!(type_alias_slab, TypeAliasDeclaration);

macro_rules! decl_engine_replace {
($slab:ident, $decl:ty) => {
impl ParsedDeclEngineReplace<$decl> for ParsedDeclEngine {
fn replace(&self, index: ParsedDeclId<$decl>, decl: $decl) {
self.$slab.replace(index.inner(), decl);
}
}
};
}

decl_engine_replace!(variable_slab, VariableDeclaration);
decl_engine_replace!(function_slab, FunctionDeclaration);
decl_engine_replace!(trait_slab, TraitDeclaration);
decl_engine_replace!(trait_fn_slab, TraitFn);
decl_engine_replace!(trait_type_slab, TraitTypeDeclaration);
decl_engine_replace!(impl_self_or_trait_slab, ImplSelfOrTrait);
decl_engine_replace!(struct_slab, StructDeclaration);
decl_engine_replace!(storage_slab, StorageDeclaration);
decl_engine_replace!(abi_slab, AbiDeclaration);
decl_engine_replace!(configurable_slab, ConfigurableDeclaration);
decl_engine_replace!(constant_slab, ConstantDeclaration);
decl_engine_replace!(enum_slab, EnumDeclaration);
decl_engine_replace!(type_alias_slab, TypeAliasDeclaration);

macro_rules! decl_engine_clear {
($($slab:ident, $decl:ty);* $(;)?) => {
impl ParsedDeclEngine {
Expand Down
6 changes: 6 additions & 0 deletions sway-core/src/language/call_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ impl<T: OrdWithEngines> OrdWithEngines for CallPath<T> {
}
}

#[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct ResolvedCallPath<T, U = Ident> {
pub decl: T,
pub unresolved_call_path: CallPath<U>,
}

impl std::convert::From<Ident> for CallPath {
fn from(other: Ident) -> Self {
CallPath {
Expand Down
33 changes: 33 additions & 0 deletions sway-core/src/language/parsed/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ pub use r#enum::*;
pub use r#struct::*;
pub use r#trait::*;
pub use storage::*;
use sway_error::{
error::CompileError,
handler::{ErrorEmitted, Handler},
};
use sway_types::{Ident, Span, Spanned};
pub use type_alias::*;
pub use variable::*;
Expand Down Expand Up @@ -117,6 +121,35 @@ impl Declaration {
}
}

pub(crate) fn to_fn_ref(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<ParsedDeclId<FunctionDeclaration>, ErrorEmitted> {
match self {
Declaration::FunctionDeclaration(decl_id) => Ok(*decl_id),
decl => Err(handler.emit_err(CompileError::DeclIsNotAFunction {
actually: decl.friendly_type_name().to_string(),
span: decl.span(engines),
})),
}
}

pub(crate) fn to_struct_decl(
&self,
handler: &Handler,
engines: &Engines,
) -> Result<ParsedDeclId<StructDeclaration>, ErrorEmitted> {
match self {
Declaration::StructDeclaration(decl_id) => Ok(*decl_id),
decl => Err(handler.emit_err(CompileError::DeclIsNotAStruct {
actually: decl.friendly_type_name().to_string(),
span: decl.span(engines),
})),
}
}

#[allow(unused)]
pub(crate) fn visibility(&self, decl_engine: &ParsedDeclEngine) -> Visibility {
match self {
Declaration::TraitDeclaration(decl_id) => decl_engine.get_trait(decl_id).visibility,
Expand Down
1 change: 1 addition & 0 deletions sway-core/src/language/parsed/declaration/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct FunctionDeclaration {
pub type_parameters: Vec<TypeParameter>,
pub where_clause: Vec<(Ident, Vec<TraitConstraint>)>,
pub kind: FunctionDeclarationKind,
pub implementing_type: Option<Declaration>,
}

impl EqWithEngines for FunctionDeclaration {}
Expand Down
3 changes: 2 additions & 1 deletion sway-core/src/language/parsed/declaration/impl_trait.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{ConstantDeclaration, FunctionDeclaration, TraitTypeDeclaration};
use crate::{
decl_engine::parsed_id::ParsedDeclId,
decl_engine::{parsed_id::ParsedDeclId, ParsedInterfaceDeclId},
engine_threading::{
DebugWithEngines, EqWithEngines, PartialEqWithEngines, PartialEqWithEnginesContext,
},
Expand Down Expand Up @@ -69,6 +69,7 @@ pub struct ImplSelfOrTrait {
pub impl_type_parameters: Vec<TypeParameter>,
pub trait_name: CallPath,
pub trait_type_arguments: Vec<TypeArgument>,
pub trait_decl_ref: Option<ParsedInterfaceDeclId>,
pub implementing_for: TypeArgument,
pub items: Vec<ImplItem>,
// the span of the whole impl trait and block
Expand Down
7 changes: 7 additions & 0 deletions sway-core/src/language/parsed/expression/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{cmp::Ordering, fmt, hash::Hasher};

use crate::{
decl_engine::parsed_id::ParsedDeclId,
engine_threading::{
DebugWithEngines, DisplayWithEngines, EqWithEngines, HashWithEngines, OrdWithEngines,
OrdWithEnginesContext, PartialEqWithEngines, PartialEqWithEnginesContext,
Expand All @@ -22,6 +23,8 @@ pub use method_name::MethodName;
pub use scrutinee::*;
use sway_ast::intrinsics::Intrinsic;

use super::{FunctionDeclaration, StructDeclaration};

/// Represents a parsed, but not yet type checked, [Expression](https://en.wikipedia.org/wiki/Expression_(computer_science)).
#[derive(Debug, Clone)]
pub struct Expression {
Expand All @@ -32,6 +35,8 @@ pub struct Expression {
#[derive(Debug, Clone)]
pub struct FunctionApplicationExpression {
pub call_path_binding: TypeBinding<CallPath>,
pub resolved_call_path_binding:
Option<TypeBinding<ResolvedCallPath<ParsedDeclId<FunctionDeclaration>>>>,
pub arguments: Vec<Expression>,
}

Expand Down Expand Up @@ -88,6 +93,8 @@ impl PartialEqWithEngines for ArrayExpression {

#[derive(Debug, Clone)]
pub struct StructExpression {
pub resolved_call_path_binding:
Option<TypeBinding<ResolvedCallPath<ParsedDeclId<StructDeclaration>>>>,
pub call_path_binding: TypeBinding<CallPath>,
pub fields: Vec<StructExpressionField>,
}
Expand Down
8 changes: 7 additions & 1 deletion sway-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ pub use debug_generation::write_dwarf;
use indexmap::IndexMap;
use metadata::MetadataManager;
use query_engine::{ModuleCacheKey, ModulePath, ProgramsCacheEntry};
use semantic_analysis::symbol_resolve::ResolveSymbols;
use semantic_analysis::symbol_resolve_context::SymbolResolveContext;
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -537,9 +539,13 @@ pub fn parsed_to_ast(

let namespace = Namespace::init_root(initial_namespace);
// Collect the program symbols.
let _collection_ctx =
let mut symbol_collection_ctx =
ty::TyProgram::collect(handler, engines, parse_program, namespace.clone())?;

// Resolve the program symbols.
let resolve_ctx = SymbolResolveContext::new(engines, &mut symbol_collection_ctx);
parse_program.resolve_symbols(handler, resolve_ctx);

// Type check the program.
let typed_program_opt = ty::TyProgram::type_check(
handler,
Expand Down
4 changes: 3 additions & 1 deletion sway-core/src/semantic_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
pub mod ast_node;
pub(crate) mod cei_pattern_analysis;
pub(crate) mod coins_analysis;
pub mod symbol_collection_context;
mod module;
pub mod namespace;
mod node_dependencies;
mod program;
pub mod symbol_collection_context;
pub mod symbol_resolve;
pub mod symbol_resolve_context;
mod type_check_analysis;
pub(crate) mod type_check_context;
mod type_check_finalization;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ use crate::{
},
namespace::{IsExtendingExistingImpl, IsImplSelf},
semantic_analysis::{
symbol_collection_context::SymbolCollectionContext, type_check_context::EnforceTypeArguments,
ConstShadowingMode, GenericShadowingMode, TypeCheckAnalysis, TypeCheckAnalysisContext,
TypeCheckContext, TypeCheckFinalization, TypeCheckFinalizationContext,
symbol_collection_context::SymbolCollectionContext,
type_check_context::EnforceTypeArguments, ConstShadowingMode, GenericShadowingMode,
TypeCheckAnalysis, TypeCheckAnalysisContext, TypeCheckContext, TypeCheckFinalization,
TypeCheckFinalizationContext,
},
type_system::*,
Engines,
Expand Down Expand Up @@ -52,7 +53,7 @@ impl TyDecl {
}
parsed::Declaration::EnumVariantDeclaration(_decl) => {}
parsed::Declaration::FunctionDeclaration(decl_id) => {
let fn_decl = engines.pe().get_function(decl_id);
let fn_decl = engines.pe().get_function(decl_id).as_ref().clone();
let _ = ctx.insert_parsed_symbol(handler, engines, fn_decl.name.clone(), decl);
}
parsed::Declaration::TraitDeclaration(decl_id) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl TyImplSelfOrTrait {
impl_type_parameters,
trait_name,
mut trait_type_arguments,
trait_decl_ref: _,
mut implementing_for,
items,
block_span,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ impl ty::TyExpression {
ExpressionKind::FunctionApplication(function_application_expression) => {
let FunctionApplicationExpression {
call_path_binding,
resolved_call_path_binding: _,
ref arguments,
} = *function_application_expression.clone();
Self::type_check_function_application(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ pub(crate) fn type_check_method_application(
]),
span: Span::dummy(),
},
resolved_call_path_binding: None,
arguments: vec![
Expression {
kind: ExpressionKind::Literal(Literal::B256([0u8; 32])),
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/semantic_analysis/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use crate::{
};

use super::{
symbol_collection_context::SymbolCollectionContext,
declaration::auto_impl::{self, EncodingAutoImplContext},
symbol_collection_context::SymbolCollectionContext,
};

#[derive(Clone, Debug)]
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/semantic_analysis/namespace/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ impl Namespace {
}

/// Pushes a new submodule to the namespace's module hierarchy.
pub fn push_new_submodule(
pub fn push_submodule(
&mut self,
engines: &Engines,
mod_name: Ident,
Expand Down
11 changes: 10 additions & 1 deletion sway-core/src/semantic_analysis/namespace/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::{
module::Module, namespace::Namespace, trait_map::TraitMap, Ident, ResolvedTraitImplItem,
};
use crate::{
decl_engine::DeclRef,
decl_engine::{DeclEngine, DeclRef},
engine_threading::*,
language::{
parsed::*,
Expand Down Expand Up @@ -69,6 +69,15 @@ impl ResolvedDeclaration {
}
}

pub fn resolve_parsed(self, decl_engine: &DeclEngine) -> Declaration {
match self {
ResolvedDeclaration::Parsed(decl) => decl,
ResolvedDeclaration::Typed(ty_decl) => ty_decl
.get_parsed_decl(decl_engine)
.expect("expecting valid parsed declaration"),
}
}

pub fn expect_parsed(self) -> Declaration {
match self {
ResolvedDeclaration::Parsed(decl) => decl,
Expand Down
2 changes: 2 additions & 0 deletions sway-core/src/semantic_analysis/node_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ impl Dependencies {
ExpressionKind::FunctionApplication(function_application_expression) => {
let FunctionApplicationExpression {
call_path_binding,
resolved_call_path_binding: _,
arguments,
} = &**function_application_expression;
self.gather_from_call_path(&call_path_binding.inner, false, true)
Expand Down Expand Up @@ -591,6 +592,7 @@ impl Dependencies {
ExpressionKind::Struct(struct_expression) => {
let StructExpression {
call_path_binding,
resolved_call_path_binding: _,
fields,
} = &**struct_expression;
self.gather_from_call_path(&call_path_binding.inner, false, false)
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/semantic_analysis/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use super::{
};

impl TyProgram {
/// Collects the given parsed program to produce a symbol map and module evaluation order.
/// Collects the given parsed program to produce a symbol maps.
///
/// The given `initial_namespace` acts as an initial state for each module within this program.
/// It should contain a submodule for each library package dependency.
Expand Down
27 changes: 23 additions & 4 deletions sway-core/src/semantic_analysis/symbol_collection_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,33 @@ impl SymbolCollectionContext {

/// Scope the `CollectionContext` with a new lexical scope.
pub fn scoped<T>(
mut self,
&mut self,
engines: &Engines,
with_scoped_ctx: impl FnOnce(SymbolCollectionContext) -> Result<T, ErrorEmitted>,
with_scoped_ctx: impl FnOnce(&mut SymbolCollectionContext) -> Result<T, ErrorEmitted>,
) -> Result<T, ErrorEmitted> {
self.namespace
.module_mut(engines)
.write(engines, |m| m.push_new_lexical_scope());
let ret = with_scoped_ctx(self.clone());
let ret = with_scoped_ctx(self);
self.namespace
.module_mut(engines)
.write(engines, |m| m.pop_lexical_scope());
ret
}

/// Enter the lexical scope and produce a collection context ready for
/// collecting its content.
///
/// Returns the result of the given `with_ctx` function.
pub fn enter_lexical_scope<T>(
&mut self,
engines: &Engines,
with_ctx: impl FnOnce(&mut SymbolCollectionContext) -> T,
) -> T {
self.namespace
.module_mut(engines)
.write(engines, |m| m.push_new_lexical_scope());
let ret = with_ctx(self);
self.namespace
.module_mut(engines)
.write(engines, |m| m.pop_lexical_scope());
Expand All @@ -64,7 +83,7 @@ impl SymbolCollectionContext {
with_submod_ctx: impl FnOnce(&mut SymbolCollectionContext) -> T,
) -> T {
self.namespace
.push_new_submodule(engines, mod_name, visibility, module_span);
.push_submodule(engines, mod_name, visibility, module_span);
//let Self { namespace, .. } = self;
//let mut submod_ns = namespace.enter_submodule(mod_name, visibility, module_span);
let ret = with_submod_ctx(self);
Expand Down
Loading

0 comments on commit e9356cc

Please sign in to comment.