Skip to content

Commit

Permalink
Port FunctionDeclaration to use ParsedDeclId.
Browse files Browse the repository at this point in the history
  • Loading branch information
tritao committed Jan 9, 2024
1 parent f08a4f8 commit 6180a71
Show file tree
Hide file tree
Showing 20 changed files with 228 additions and 151 deletions.
7 changes: 5 additions & 2 deletions sway-core/src/language/parsed/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ pub use storage::*;
pub use type_alias::*;
pub use variable::*;

use crate::{decl_engine::parsed_id::ParsedDeclId, Engines};

#[derive(Debug, Clone)]
pub enum Declaration {
VariableDeclaration(VariableDeclaration),
FunctionDeclaration(FunctionDeclaration),
FunctionDeclaration(ParsedDeclId<FunctionDeclaration>),
TraitDeclaration(TraitDeclaration),
StructDeclaration(StructDeclaration),
EnumDeclaration(EnumDeclaration),
Expand All @@ -38,8 +40,9 @@ pub enum Declaration {

impl Declaration {
/// Checks if this `Declaration` is a test.
pub(crate) fn is_test(&self) -> bool {
pub(crate) fn is_test(&self, engines: &Engines) -> bool {
if let Declaration::FunctionDeclaration(fn_decl) = self {
let fn_decl = engines.pe().get_function(fn_decl);
fn_decl.is_test()
} else {
false
Expand Down
4 changes: 2 additions & 2 deletions sway-core/src/language/parsed/declaration/abi.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::transform;
use crate::{decl_engine::parsed_id::ParsedDeclId, transform};

use super::{FunctionDeclaration, Supertrait, TraitItem};

Expand All @@ -14,7 +14,7 @@ pub struct AbiDeclaration {
pub interface_surface: Vec<TraitItem>,
pub supertraits: Vec<Supertrait>,
/// The methods provided to a contract "for free" upon opting in to this interface
pub methods: Vec<FunctionDeclaration>,
pub methods: Vec<ParsedDeclId<FunctionDeclaration>>,
pub(crate) span: Span,
pub attributes: transform::AttributesMap,
}
7 changes: 5 additions & 2 deletions sway-core/src/language/parsed/declaration/impl_trait.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use super::{ConstantDeclaration, FunctionDeclaration, TraitTypeDeclaration};
use crate::{language::CallPath, type_system::TypeArgument, TypeParameter};
use crate::{
decl_engine::parsed_id::ParsedDeclId, language::CallPath, type_system::TypeArgument,
TypeParameter,
};

use sway_types::span::Span;

#[derive(Debug, Clone)]
pub enum ImplItem {
Fn(FunctionDeclaration),
Fn(ParsedDeclId<FunctionDeclaration>),
Constant(ConstantDeclaration),
Type(TraitTypeDeclaration),
}
Expand Down
8 changes: 6 additions & 2 deletions sway-core/src/language/parsed/declaration/trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use std::hash::{Hash, Hasher};
use super::{ConstantDeclaration, FunctionDeclaration, FunctionParameter};

use crate::{
decl_engine::DeclRefTrait, engine_threading::*, language::*, transform, type_system::*,
decl_engine::{parsed_id::ParsedDeclId, DeclRefTrait},
engine_threading::*,
language::*,
transform,
type_system::*,
};
use sway_error::handler::ErrorEmitted;
use sway_types::{ident::Ident, span::Span, Spanned};
Expand All @@ -23,7 +27,7 @@ pub struct TraitDeclaration {
pub(crate) type_parameters: Vec<TypeParameter>,
pub attributes: transform::AttributesMap,
pub interface_surface: Vec<TraitItem>,
pub methods: Vec<FunctionDeclaration>,
pub methods: Vec<ParsedDeclId<FunctionDeclaration>>,
pub supertraits: Vec<Supertrait>,
pub visibility: Visibility,
pub span: Span,
Expand Down
10 changes: 6 additions & 4 deletions sway-core/src/language/parsed/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub use use_statement::{ImportType, UseStatement};

use sway_types::span::Span;

use crate::Engines;

/// Represents some exportable information that results from compiling some
/// Sway source code.
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -70,16 +72,16 @@ pub enum AstNodeContent {

impl ParseTree {
/// Excludes all test functions from the parse tree.
pub(crate) fn exclude_tests(&mut self) {
self.root_nodes.retain(|node| !node.is_test());
pub(crate) fn exclude_tests(&mut self, engines: &Engines) {
self.root_nodes.retain(|node| !node.is_test(engines));
}
}

impl AstNode {
/// Checks if this `AstNode` is a test.
pub(crate) fn is_test(&self) -> bool {
pub(crate) fn is_test(&self, engines: &Engines) -> bool {
if let AstNodeContent::Declaration(decl) = &self.content {
decl.is_test()
decl.is_test(engines)
} else {
false
}
Expand Down
6 changes: 4 additions & 2 deletions sway-core/src/language/parsed/program.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use strum::EnumString;

use crate::Engines;

use super::ParseModule;

/// A parsed, but not yet type-checked, Sway program.
Expand Down Expand Up @@ -43,7 +45,7 @@ impl std::fmt::Display for TreeType {

impl ParseProgram {
/// Excludes all test functions from the parse tree.
pub(crate) fn exclude_tests(&mut self) {
self.root.tree.exclude_tests()
pub(crate) fn exclude_tests(&mut self, engines: &Engines) {
self.root.tree.exclude_tests(engines)
}
}
14 changes: 7 additions & 7 deletions sway-core/src/language/ty/declaration/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ impl TyFunctionDecl {

/// Used to create a stubbed out function when the function fails to
/// compile, preventing cascading namespace errors.
pub(crate) fn error(decl: parsed::FunctionDeclaration) -> TyFunctionDecl {
pub(crate) fn error(decl: &parsed::FunctionDeclaration) -> TyFunctionDecl {
let parsed::FunctionDeclaration {
name,
return_type,
Expand All @@ -260,19 +260,19 @@ impl TyFunctionDecl {
..
} = decl;
TyFunctionDecl {
purity,
name,
purity: *purity,
name: name.clone(),
body: TyCodeBlock::default(),
implementing_type: None,
span,
span: span.clone(),
call_path: CallPath::from(Ident::dummy()),
attributes: Default::default(),
is_contract_call: false,
parameters: Default::default(),
visibility,
return_type,
visibility: *visibility,
return_type: return_type.clone(),
type_parameters: Default::default(),
where_clause,
where_clause: where_clause.clone(),
is_trait_method_dummy: false,
}
}
Expand Down
9 changes: 4 additions & 5 deletions sway-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ pub fn compile_to_ast(
.map(|config| !config.include_tests)
.unwrap_or(true)
{
parsed_program.exclude_tests();
parsed_program.exclude_tests(engines);
}

// Type check (+ other static analysis) the CST to a typed AST.
Expand Down Expand Up @@ -1076,12 +1076,11 @@ fn test_unary_ordering() {
// expression should be `&&`
if let parsed::AstNode {
content:
parsed::AstNodeContent::Declaration(parsed::Declaration::FunctionDeclaration(
parsed::FunctionDeclaration { body, .. },
)),
parsed::AstNodeContent::Declaration(parsed::Declaration::FunctionDeclaration(decl_id)),
..
} = &prog.root.tree.root_nodes[0]
{
let fn_decl = engines.pe().get_function(decl_id);
if let parsed::AstNode {
content:
parsed::AstNodeContent::Expression(parsed::Expression {
Expand All @@ -1092,7 +1091,7 @@ fn test_unary_ordering() {
..
}),
..
} = &body.contents[2]
} = &fn_decl.body.contents[2]
{
assert_eq!(op, &language::LazyOp::And)
} else {
Expand Down
8 changes: 5 additions & 3 deletions sway-core/src/semantic_analysis/ast_node/declaration/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ impl ty::TyAbiDecl {
ctx: TypeCheckContext,
abi_decl: AbiDeclaration,
) -> Result<Self, ErrorEmitted> {
let engines = ctx.engines();
let AbiDeclaration {
name,
interface_surface,
Expand Down Expand Up @@ -167,10 +168,11 @@ impl ty::TyAbiDecl {

// Type check the items.
let mut new_items = vec![];
for method in methods.into_iter() {
for method_id in methods.into_iter() {
let method = engines.pe().get_function(&method_id);
let method =
ty::TyFunctionDecl::type_check(handler, ctx.by_ref(), method.clone(), false, false)
.unwrap_or_else(|_| ty::TyFunctionDecl::error(method.clone()));
ty::TyFunctionDecl::type_check(handler, ctx.by_ref(), &method, false, false)
.unwrap_or_else(|_| ty::TyFunctionDecl::error(&method));
error_on_shadowing_superabi_method(&method.name, &mut ctx);
for param in &method.parameters {
if param.is_reference || param.is_mutable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,15 @@ impl TyDecl {
ctx.insert_symbol(handler, call_path.suffix, decl.clone())?;
decl
}
parsed::Declaration::FunctionDeclaration(fn_decl) => {
parsed::Declaration::FunctionDeclaration(decl_id) => {
let fn_decl = engines.pe().get_function(&decl_id);
let span = fn_decl.span.clone();
let mut ctx =
ctx.with_type_annotation(type_engine.insert(engines, TypeInfo::Unknown, None));
let fn_decl = match ty::TyFunctionDecl::type_check(
handler,
ctx.by_ref(),
fn_decl,
&fn_decl,
false,
false,
) {
Expand Down
61 changes: 33 additions & 28 deletions sway-core/src/semantic_analysis/ast_node/declaration/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,19 @@ impl ty::TyFunctionDecl {
pub fn type_check(
handler: &Handler,
mut ctx: TypeCheckContext,
fn_decl: FunctionDeclaration,
fn_decl: &FunctionDeclaration,
is_method: bool,
is_in_impl_self: bool,
) -> Result<Self, ErrorEmitted> {
let mut ty_fn_decl = Self::type_check_signature(
handler,
ctx.by_ref(),
fn_decl.clone(),
is_method,
is_in_impl_self,
)?;
Self::type_check_body(handler, ctx, &fn_decl, &mut ty_fn_decl)
let mut ty_fn_decl =
Self::type_check_signature(handler, ctx.by_ref(), fn_decl, is_method, is_in_impl_self)?;
Self::type_check_body(handler, ctx, fn_decl, &mut ty_fn_decl)
}

pub fn type_check_signature(
handler: &Handler,
mut ctx: TypeCheckContext,
fn_decl: FunctionDeclaration,
fn_decl: &FunctionDeclaration,
is_method: bool,
is_in_impl_self: bool,
) -> Result<Self, ErrorEmitted> {
Expand All @@ -49,12 +44,13 @@ impl ty::TyFunctionDecl {
parameters,
span,
attributes,
mut return_type,
type_parameters,
visibility,
purity,
where_clause,
..
} = fn_decl;
let mut return_type = fn_decl.return_type.clone();

let type_engine = ctx.engines.te();
let engines = ctx.engines();
Expand All @@ -63,7 +59,7 @@ impl ty::TyFunctionDecl {
if ctx.functions_disallowed() {
return Err(handler.emit_err(CompileError::Unimplemented(
"Nested function definitions are not allowed at this time.",
span,
span.clone(),
)));
}

Expand All @@ -80,25 +76,31 @@ impl ty::TyFunctionDecl {
let mut ctx = ctx
.by_ref()
.scoped(&mut fn_namespace)
.with_purity(purity)
.with_purity(*purity)
.with_const_shadowing_mode(ConstShadowingMode::Sequential)
.disallow_functions();

// Type check the type parameters.
let new_type_parameters =
TypeParameter::type_check_type_params(handler, ctx.by_ref(), type_parameters, None)?;
let new_type_parameters = TypeParameter::type_check_type_params(
handler,
ctx.by_ref(),
type_parameters.clone(),
None,
)?;

// type check the function parameters, which will also insert them into the namespace
let mut new_parameters = vec![];
handler.scope(|handler| {
for parameter in parameters.into_iter() {
new_parameters.push({
let param =
match ty::TyFunctionParameter::type_check(handler, ctx.by_ref(), parameter)
{
Ok(val) => val,
Err(_) => continue,
};
let param = match ty::TyFunctionParameter::type_check(
handler,
ctx.by_ref(),
parameter.clone(),
) {
Ok(val) => val,
Err(_) => continue,
};
param.insert_into_namespace(handler, ctx.by_ref());
param
});
Expand All @@ -119,30 +121,33 @@ impl ty::TyFunctionDecl {

let (visibility, is_contract_call) = if is_method {
if is_in_impl_self {
(visibility, false)
(*visibility, false)
} else {
(Visibility::Public, false)
}
} else {
(visibility, matches!(ctx.abi_mode(), AbiMode::ImplAbiFn(..)))
(
*visibility,
matches!(ctx.abi_mode(), AbiMode::ImplAbiFn(..)),
)
};

let call_path = CallPath::from(name.clone()).to_fullpath(ctx.namespace);

let function_decl = ty::TyFunctionDecl {
name,
name: name.clone(),
body: TyCodeBlock::default(),
parameters: new_parameters,
implementing_type: None,
span,
span: span.clone(),
call_path,
attributes,
attributes: attributes.clone(),
return_type,
type_parameters: new_type_parameters,
visibility,
is_contract_call,
purity,
where_clause,
purity: *purity,
where_clause: where_clause.clone(),
is_trait_method_dummy: false,
};

Expand Down
Loading

0 comments on commit 6180a71

Please sign in to comment.