Compare commits
4 Commits
c8ff1d0fa2
...
d38b30b755
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d38b30b755 | ||
![]() |
22deb90c3e | ||
![]() |
cbf7921c95 | ||
![]() |
20dcb4f6ce |
1117
src/ast/build.rs
1117
src/ast/build.rs
File diff suppressed because it is too large
Load Diff
1057
src/ast/children.rs
Normal file
1057
src/ast/children.rs
Normal file
File diff suppressed because it is too large
Load Diff
760
src/ast/mod.rs
760
src/ast/mod.rs
@ -1,760 +1,6 @@
|
||||
use crate::ast::named::Named;
|
||||
use crate::name_analysis::symbol::Symbol;
|
||||
use pest::Parser;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::range::Range;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub mod build;
|
||||
pub mod named;
|
||||
pub mod children;
|
||||
pub mod node;
|
||||
pub mod pretty_print;
|
||||
pub mod unparse;
|
||||
|
||||
/* Operators */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Operator {
|
||||
Binary(BinaryOperator),
|
||||
PrefixUnary(PrefixUnaryOperator),
|
||||
SuffixUnary(SuffixUnaryOperator),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BinaryOperator {
|
||||
Or,
|
||||
And,
|
||||
EqualTo,
|
||||
NotEqualTo,
|
||||
Greater,
|
||||
Less,
|
||||
GreaterEqual,
|
||||
LessEqual,
|
||||
Add,
|
||||
Subtract,
|
||||
Multiply,
|
||||
Divide,
|
||||
Modulo,
|
||||
LeftShift,
|
||||
RightShift,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PrefixUnaryOperator {
|
||||
Spread,
|
||||
BorrowMut,
|
||||
Borrow,
|
||||
Mut,
|
||||
Not,
|
||||
Negative,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SuffixUnaryOperator {
|
||||
PlusPlus,
|
||||
MinusMinus,
|
||||
}
|
||||
|
||||
/* Names */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Identifier {
|
||||
name: String,
|
||||
file_id: usize,
|
||||
range: Range<usize>,
|
||||
scope_id: Option<usize>,
|
||||
saved_symbol: Option<Symbol>,
|
||||
}
|
||||
|
||||
impl Identifier {
|
||||
pub fn new(name: &str, file_id: usize, range: Range<usize>) -> Self {
|
||||
Identifier {
|
||||
name: name.to_string(),
|
||||
file_id,
|
||||
range,
|
||||
scope_id: None,
|
||||
saved_symbol: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FullyQualifiedName {
|
||||
identifiers: Vec<Identifier>,
|
||||
file_id: usize,
|
||||
range: Range<usize>,
|
||||
scope_id: Option<usize>,
|
||||
saved_symbol: Option<Symbol>,
|
||||
}
|
||||
|
||||
impl FullyQualifiedName {
|
||||
pub fn new(identifiers: Vec<Identifier>, file_id: usize, range: Range<usize>) -> Self {
|
||||
FullyQualifiedName {
|
||||
identifiers,
|
||||
range,
|
||||
file_id,
|
||||
scope_id: None,
|
||||
saved_symbol: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn last(&self) -> &Identifier {
|
||||
&self.identifiers[self.identifiers.len() - 1]
|
||||
}
|
||||
|
||||
pub fn last_mut(&mut self) -> &mut Identifier {
|
||||
let last_index = self.identifiers.len() - 1;
|
||||
&mut self.identifiers[last_index]
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.identifiers.len()
|
||||
}
|
||||
|
||||
pub fn is_single_identifier(&self) -> bool {
|
||||
self.identifiers.len() == 1
|
||||
}
|
||||
}
|
||||
|
||||
/* Type Use */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TypeUse {
|
||||
Primitive(PrimitiveTypeUse),
|
||||
InterfaceOrClass(InterfaceOrClassTypeUse),
|
||||
Tuple(TupleTypeUse),
|
||||
Function(FunctionTypeUse),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PrimitiveTypeUse {
|
||||
Byte,
|
||||
Short,
|
||||
Char,
|
||||
Int,
|
||||
Long,
|
||||
Double,
|
||||
Bool,
|
||||
String,
|
||||
Array(Option<Box<GenericArguments>>),
|
||||
Any,
|
||||
Void,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceOrClassTypeUse {
|
||||
pub borrow_count: usize,
|
||||
pub is_mutable: bool,
|
||||
pub fqn: FullyQualifiedName,
|
||||
pub generics: GenericArguments,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TupleTypeUse {
|
||||
pub borrow_count: usize,
|
||||
pub is_mutable: bool,
|
||||
pub arguments: TupleArguments,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionTypeUse {
|
||||
pub borrow_count: usize,
|
||||
pub function_modifier: Option<FunctionTypeModifier>,
|
||||
pub generics: GenericParameters,
|
||||
pub parameters: Parameters,
|
||||
pub return_type: ReturnType,
|
||||
}
|
||||
|
||||
/* Generic arguments */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GenericArguments(pub Vec<TypeUse>);
|
||||
|
||||
impl GenericArguments {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GenericArguments {
|
||||
fn default() -> Self {
|
||||
GenericArguments(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
/* Generic parameters */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GenericParameters(pub Vec<Identifier>);
|
||||
|
||||
impl GenericParameters {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GenericParameters {
|
||||
fn default() -> Self {
|
||||
GenericParameters(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
/* Tuple Arguments */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TupleArguments(pub Vec<TypeUse>);
|
||||
|
||||
/* Implements List */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ImplementsList(pub Vec<TypeUse>);
|
||||
|
||||
impl ImplementsList {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ImplementsList {
|
||||
fn default() -> Self {
|
||||
ImplementsList(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
/* Function Type Modifier */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FunctionTypeModifier {
|
||||
Cons,
|
||||
MutRef,
|
||||
Mut,
|
||||
Ref,
|
||||
}
|
||||
|
||||
/* Function Parameters */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Parameters(pub Vec<Parameter>);
|
||||
|
||||
impl Parameters {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Parameters {
|
||||
fn default() -> Self {
|
||||
Parameters(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Parameter {
|
||||
pub identifier: Identifier,
|
||||
pub type_use: TypeUse,
|
||||
}
|
||||
|
||||
/* Return Type */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReturnType {
|
||||
pub declared_type: Box<TypeUse>,
|
||||
pub references: References,
|
||||
}
|
||||
|
||||
impl ReturnType {
|
||||
pub fn void() -> Self {
|
||||
ReturnType {
|
||||
declared_type: Box::new(TypeUse::Primitive(PrimitiveTypeUse::Void)),
|
||||
references: References::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* References */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct References(pub Vec<Identifier>);
|
||||
|
||||
impl References {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for References {
|
||||
fn default() -> Self {
|
||||
References(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
/* Top-level construct */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CompilationUnit {
|
||||
pub file_name: String,
|
||||
pub file_id: usize,
|
||||
pub namespace: Option<FullyQualifiedName>,
|
||||
pub use_statements: Vec<UseStatement>,
|
||||
pub declarations: Vec<ModuleLevelDeclaration>,
|
||||
}
|
||||
|
||||
/* Use Statement */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UseStatement {
|
||||
pub identifiers: Vec<Identifier>,
|
||||
pub last: UseStatementLast,
|
||||
pub file_id: usize,
|
||||
pub range: Range<usize>,
|
||||
}
|
||||
|
||||
impl UseStatement {
|
||||
pub fn new(
|
||||
identifiers: Vec<Identifier>,
|
||||
last: UseStatementLast,
|
||||
file_id: usize,
|
||||
range: Range<usize>,
|
||||
) -> Self {
|
||||
UseStatement {
|
||||
identifiers,
|
||||
last,
|
||||
file_id,
|
||||
range,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn base_name(&self) -> Cow<'_, str> {
|
||||
use UseStatementLast::*;
|
||||
if self.identifiers.is_empty() {
|
||||
match &self.last {
|
||||
Identifier(_) => Cow::from(""),
|
||||
Star | Identifiers(_) => panic!(), // should never get here because of grammar
|
||||
}
|
||||
} else if self.identifiers.len() == 1 {
|
||||
self.identifiers[0].name()
|
||||
} else {
|
||||
let mut acc = String::new();
|
||||
for (i, identifier) in self.identifiers.iter().enumerate() {
|
||||
acc.push_str(&identifier.name());
|
||||
if i != self.identifiers.len() - 1 {
|
||||
acc.push_str("::");
|
||||
}
|
||||
}
|
||||
Cow::from(acc)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_star(&self) -> bool {
|
||||
match &self.last {
|
||||
UseStatementLast::Star => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum UseStatementLast {
|
||||
Identifier(Rc<RefCell<Identifier>>),
|
||||
Identifiers(Vec<Rc<RefCell<Identifier>>>),
|
||||
Star,
|
||||
}
|
||||
|
||||
/* Declarations allowed in each level */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ModuleLevelDeclaration {
|
||||
Module(ModuleDeclaration),
|
||||
Interface(InterfaceDeclaration),
|
||||
Class(ClassDeclaration),
|
||||
Function(FunctionDefinition),
|
||||
PlatformFunction(PlatformFunctionDeclaration),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InterfaceLevelDeclaration {
|
||||
Module(ModuleDeclaration),
|
||||
Interface(InterfaceDeclaration),
|
||||
Class(ClassDeclaration),
|
||||
Function(InterfaceFunctionDeclaration),
|
||||
OperatorFunction(InterfaceOperatorFunctionDeclaration),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClassLevelDeclaration {
|
||||
Module(ModuleDeclaration),
|
||||
Interface(InterfaceDeclaration),
|
||||
Class(ClassDeclaration),
|
||||
Function(FunctionDefinition),
|
||||
OperatorFunction(OperatorFunctionDefinition),
|
||||
PlatformFunction(PlatformFunctionDeclaration),
|
||||
Property(PropertyDeclaration),
|
||||
Field(FieldDeclaration),
|
||||
}
|
||||
|
||||
/* Main Declarations */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ModuleDeclaration {
|
||||
pub is_public: bool,
|
||||
pub identifier: Identifier,
|
||||
pub declarations: Vec<ModuleLevelDeclaration>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceDeclaration {
|
||||
pub is_public: bool,
|
||||
pub identifier: Identifier,
|
||||
pub generics: GenericParameters,
|
||||
pub implements: ImplementsList,
|
||||
pub declarations: Vec<InterfaceLevelDeclaration>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClassDeclaration {
|
||||
pub is_public: bool,
|
||||
pub identifier: Identifier,
|
||||
pub generics: GenericParameters,
|
||||
pub class_constructor: Option<ClassConstructor>,
|
||||
pub implements: ImplementsList,
|
||||
pub declarations: Vec<ClassLevelDeclaration>,
|
||||
}
|
||||
|
||||
/* Function declarations and components */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionDefinition {
|
||||
pub is_public: bool,
|
||||
pub modifier: Option<FunctionModifier>,
|
||||
pub generics: GenericParameters,
|
||||
pub identifier: Identifier,
|
||||
pub parameters: Parameters,
|
||||
pub return_type: ReturnType,
|
||||
pub body: FunctionBody,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OperatorFunctionDefinition {
|
||||
pub is_public: bool,
|
||||
pub modifier: Option<FunctionModifier>,
|
||||
pub generics: GenericParameters,
|
||||
pub operator: Operator,
|
||||
pub parameters: Parameters,
|
||||
pub return_type: ReturnType,
|
||||
pub body: FunctionBody,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PlatformFunctionDeclaration {
|
||||
pub is_public: bool,
|
||||
pub modifier: Option<FunctionModifier>,
|
||||
pub generics: GenericParameters,
|
||||
pub identifier: Identifier,
|
||||
pub parameters: Parameters,
|
||||
pub return_type: ReturnType,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceFunctionDeclaration {
|
||||
pub modifier: Option<FunctionModifier>,
|
||||
pub generics: GenericParameters,
|
||||
pub identifier: Identifier,
|
||||
pub parameters: Parameters,
|
||||
pub return_type: ReturnType,
|
||||
pub body: Option<FunctionBody>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceOperatorFunctionDeclaration {
|
||||
pub modifier: Option<FunctionModifier>,
|
||||
pub generics: GenericParameters,
|
||||
pub operator: Operator,
|
||||
pub parameters: Parameters,
|
||||
pub return_type: ReturnType,
|
||||
pub body: Option<FunctionBody>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FunctionModifier {
|
||||
Static,
|
||||
Cons,
|
||||
Mut,
|
||||
Ref,
|
||||
MutRef,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FunctionBody {
|
||||
Equals(Expression),
|
||||
Block(BlockStatement),
|
||||
Alias(Identifier),
|
||||
}
|
||||
|
||||
/* Class components */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClassConstructor(pub Vec<ClassConstructorParameter>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClassConstructorParameter {
|
||||
Property(PropertyDeclaration),
|
||||
Field(FieldDeclaration),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PropertyDeclaration {
|
||||
pub is_mutable: bool,
|
||||
pub identifier: Identifier,
|
||||
pub declared_type: TypeUse,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FieldDeclaration {
|
||||
pub is_mutable: bool,
|
||||
pub identifier: Identifier,
|
||||
pub declared_type: TypeUse,
|
||||
}
|
||||
|
||||
/* Statements */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BlockStatement {
|
||||
pub statements: Vec<Statement>,
|
||||
pub expression: Option<Expression>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Statement {
|
||||
BlockStatement(BlockStatement),
|
||||
VariableDeclarationStatement(VariableDeclarationStatement),
|
||||
AssignStatement(AssignStatement),
|
||||
CallStatement(CallStatement),
|
||||
ReturnStatement(ReturnStatement),
|
||||
IfStatement(IfStatement),
|
||||
IfElseStatement(IfElseStatement),
|
||||
WhileStatement(WhileStatement),
|
||||
ForStatement(ForStatement),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VariableDeclarationStatement {
|
||||
pub is_mutable: bool,
|
||||
pub identifier: Identifier,
|
||||
pub declared_type: Option<TypeUse>,
|
||||
pub initializer: Option<Expression>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssignStatement {
|
||||
pub lhs: Expression,
|
||||
pub rhs: Expression,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallStatement(pub Expression);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReturnStatement(pub Option<Expression>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IfStatement {
|
||||
pub condition: Expression,
|
||||
pub then_block: BlockStatement,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IfElseStatement {
|
||||
pub if_statement: IfStatement,
|
||||
pub else_ifs: ElseIfs,
|
||||
pub else_block: Option<ElseBlock>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ElseIfs(pub Vec<IfStatement>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ElseBlock(pub BlockStatement);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WhileStatement {
|
||||
pub condition: Expression,
|
||||
pub body: BlockStatement,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ForStatement {
|
||||
pub variable: Identifier,
|
||||
pub iterator: Expression,
|
||||
pub body: BlockStatement,
|
||||
}
|
||||
|
||||
/* Expressions */
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Expression {
|
||||
Ternary(TernaryExpression),
|
||||
Binary(BinaryExpression),
|
||||
UnaryPrefix(PrefixExpression),
|
||||
UnarySuffix(SuffixExpression),
|
||||
Call(CallExpression),
|
||||
ObjectAccess(ObjectAccess),
|
||||
Literal(Literal),
|
||||
FullyQualifiedName(FullyQualifiedName),
|
||||
Closure(Closure),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TernaryExpression {
|
||||
pub condition: Box<Expression>,
|
||||
pub true_expression: Box<Expression>,
|
||||
pub false_expression: Box<Expression>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BinaryExpression {
|
||||
pub left: Box<Expression>,
|
||||
pub operator: BinaryOperator,
|
||||
pub right: Box<Expression>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrefixExpression {
|
||||
pub operator: PrefixUnaryOperator,
|
||||
pub expression: Box<Expression>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SuffixExpression {
|
||||
pub expression: Box<Expression>,
|
||||
pub operator: SuffixUnaryOperator,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallExpression {
|
||||
pub callee: Box<Expression>,
|
||||
pub turbo_fish: Option<TurboFish>,
|
||||
pub arguments: CallArguments,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TurboFish(pub GenericArguments);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallArguments(pub Vec<CallArgument>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallArgument(pub Box<Expression>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Closure {
|
||||
pub modifier: Option<ClosureModifier>,
|
||||
pub is_move: bool,
|
||||
pub captures: ClosureCaptures,
|
||||
pub parameters: ClosureParameters,
|
||||
pub statements: Vec<Statement>,
|
||||
pub expression: Option<Box<Expression>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClosureModifier {
|
||||
Cons,
|
||||
Mut,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ClosureCaptures(pub Vec<ClosureCapture>);
|
||||
|
||||
impl ClosureCaptures {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClosureCapture {
|
||||
pub borrow_count: usize,
|
||||
pub is_mutable: bool,
|
||||
pub identifier: Box<Identifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ClosureParameters(pub Vec<ClosureParameter>);
|
||||
|
||||
impl ClosureParameters {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClosureParameter {
|
||||
pub identifier: Identifier,
|
||||
pub type_use: Option<TypeUse>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectAccess {
|
||||
pub receiver: Box<Expression>,
|
||||
pub navigations: ObjectNavigations,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectNavigations(pub Vec<ObjectNavigation>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ObjectNavigation {
|
||||
Index(Box<Expression>),
|
||||
Identifier(Box<Identifier>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Literal {
|
||||
Integer(i32),
|
||||
Long(i64),
|
||||
Double(f64),
|
||||
USize(usize),
|
||||
String(String),
|
||||
DString(DString),
|
||||
BacktickString(DString),
|
||||
Boolean(bool),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DString(pub Vec<DStringPart>);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DStringPart {
|
||||
String(String),
|
||||
Expression(Box<Expression>),
|
||||
}
|
||||
|
||||
impl DStringPart {
|
||||
pub fn from_string(s: &str) -> DStringPart {
|
||||
DStringPart::String(String::from(s))
|
||||
}
|
||||
|
||||
pub fn from_expression(e: Expression) -> DStringPart {
|
||||
DStringPart::Expression(Box::new(e))
|
||||
}
|
||||
|
||||
pub fn is_string(&self) -> bool {
|
||||
match self {
|
||||
DStringPart::String(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_string(self) -> String {
|
||||
match self {
|
||||
DStringPart::String(s) => s,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_expression(&self) -> bool {
|
||||
match self {
|
||||
DStringPart::Expression(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
mod walk;
|
||||
|
@ -1,88 +0,0 @@
|
||||
use crate::ast::{FullyQualifiedName, Identifier};
|
||||
use crate::name_analysis::symbol::Symbol;
|
||||
use std::borrow::Cow;
|
||||
use std::range::Range;
|
||||
|
||||
pub trait Named {
|
||||
fn name(&self) -> Cow<'_, str>;
|
||||
|
||||
fn file_id(&self) -> usize;
|
||||
fn range(&self) -> Range<usize>;
|
||||
|
||||
fn set_scope_id(&mut self, scope_id: usize);
|
||||
fn scope_id(&self) -> Option<usize>;
|
||||
|
||||
fn set_saved_symbol(&mut self, symbol: Symbol);
|
||||
fn saved_symbol(&self) -> Option<Symbol>;
|
||||
}
|
||||
|
||||
impl Named for Identifier {
|
||||
fn name(&self) -> Cow<'_, str> {
|
||||
Cow::Borrowed(&self.name)
|
||||
}
|
||||
|
||||
fn file_id(&self) -> usize {
|
||||
self.file_id
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.range
|
||||
}
|
||||
|
||||
fn set_scope_id(&mut self, id: usize) {
|
||||
self.scope_id = Some(id);
|
||||
}
|
||||
|
||||
fn scope_id(&self) -> Option<usize> {
|
||||
self.scope_id
|
||||
}
|
||||
|
||||
fn set_saved_symbol(&mut self, saved_symbol: Symbol) {
|
||||
self.saved_symbol = Some(saved_symbol);
|
||||
}
|
||||
|
||||
fn saved_symbol(&self) -> Option<Symbol> {
|
||||
self.saved_symbol.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for FullyQualifiedName {
|
||||
fn name(&self) -> Cow<'_, str> {
|
||||
if self.identifiers.len() == 1 {
|
||||
self.identifiers[0].name()
|
||||
} else {
|
||||
let mut acc = String::new();
|
||||
for (i, identifier) in self.identifiers.iter().enumerate() {
|
||||
acc += &identifier.name();
|
||||
if i < self.identifiers.len() - 1 {
|
||||
acc += "::";
|
||||
}
|
||||
}
|
||||
Cow::Owned(acc)
|
||||
}
|
||||
}
|
||||
|
||||
fn file_id(&self) -> usize {
|
||||
self.file_id
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.range
|
||||
}
|
||||
|
||||
fn set_scope_id(&mut self, id: usize) {
|
||||
self.scope_id = Some(id);
|
||||
}
|
||||
|
||||
fn scope_id(&self) -> Option<usize> {
|
||||
self.scope_id
|
||||
}
|
||||
|
||||
fn set_saved_symbol(&mut self, symbol: Symbol) {
|
||||
self.saved_symbol = Some(symbol);
|
||||
}
|
||||
|
||||
fn saved_symbol(&self) -> Option<Symbol> {
|
||||
self.saved_symbol.clone()
|
||||
}
|
||||
}
|
106
src/ast/node/call_expression.rs
Normal file
106
src/ast/node/call_expression.rs
Normal file
@ -0,0 +1,106 @@
|
||||
use crate::ast::node::expression::Expression;
|
||||
use crate::ast::node::generics::GenericArguments;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallExpression {
|
||||
callee: Box<Expression>,
|
||||
turbo_fish: Option<Box<TurboFish>>,
|
||||
arguments: Box<CallArguments>,
|
||||
}
|
||||
|
||||
impl CallExpression {
|
||||
pub fn new(
|
||||
callee: Box<Expression>,
|
||||
turbo_fish: Option<Box<TurboFish>>,
|
||||
arguments: Box<CallArguments>,
|
||||
) -> Self {
|
||||
Self {
|
||||
callee,
|
||||
turbo_fish,
|
||||
arguments,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn callee(&self) -> &Expression {
|
||||
&self.callee
|
||||
}
|
||||
|
||||
pub fn callee_mut(&mut self) -> &mut Expression {
|
||||
&mut self.callee
|
||||
}
|
||||
|
||||
pub fn turbo_fish(&self) -> Option<&TurboFish> {
|
||||
if let Some(turbo_fish) = &self.turbo_fish {
|
||||
Some(turbo_fish.as_ref())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn turbo_fish_mut(&mut self) -> Option<&mut TurboFish> {
|
||||
if let Some(turbo_fish) = &mut self.turbo_fish {
|
||||
Some(turbo_fish.as_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arguments(&self) -> &CallArguments {
|
||||
&self.arguments
|
||||
}
|
||||
|
||||
pub fn arguments_mut(&mut self) -> &mut CallArguments {
|
||||
&mut self.arguments
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TurboFish(Box<GenericArguments>);
|
||||
|
||||
impl TurboFish {
|
||||
pub fn new(generics: Box<GenericArguments>) -> Self {
|
||||
Self(generics)
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericArguments {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericArguments {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallArguments(Vec<Box<CallArgument>>);
|
||||
|
||||
impl CallArguments {
|
||||
pub fn new(arguments: Vec<Box<CallArgument>>) -> Self {
|
||||
Self(arguments)
|
||||
}
|
||||
|
||||
pub fn arguments(&self) -> Vec<&CallArgument> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn arguments_mut(&mut self) -> Vec<&mut CallArgument> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallArgument(Box<Expression>);
|
||||
|
||||
impl CallArgument {
|
||||
pub fn new(expression: Box<Expression>) -> Self {
|
||||
Self(expression)
|
||||
}
|
||||
|
||||
pub fn expression(&self) -> &Expression {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn expression_mut(&mut self) -> &mut Expression {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
184
src/ast/node/class.rs
Normal file
184
src/ast/node/class.rs
Normal file
@ -0,0 +1,184 @@
|
||||
use crate::ast::node::generics::GenericParameters;
|
||||
use crate::ast::node::implements_list::ImplementsList;
|
||||
use crate::ast::node::level::ClassLevelDeclaration;
|
||||
use crate::ast::node::names::Identifier;
|
||||
use crate::ast::node::type_use::TypeUse;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClassDeclaration {
|
||||
is_public: bool,
|
||||
identifier: Box<Identifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
class_constructor: Option<Box<ClassConstructor>>,
|
||||
implements: Box<ImplementsList>,
|
||||
declarations: Vec<Box<ClassLevelDeclaration>>,
|
||||
}
|
||||
|
||||
impl ClassDeclaration {
|
||||
pub fn new(
|
||||
is_public: bool,
|
||||
identifier: Box<Identifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
class_constructor: Option<Box<ClassConstructor>>,
|
||||
implements: Box<ImplementsList>,
|
||||
declarations: Vec<Box<ClassLevelDeclaration>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
is_public,
|
||||
identifier,
|
||||
generics,
|
||||
class_constructor,
|
||||
implements,
|
||||
declarations,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_public(&self) -> bool {
|
||||
self.is_public
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericParameters {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericParameters {
|
||||
&mut self.generics
|
||||
}
|
||||
|
||||
pub fn class_constructor(&self) -> Option<&ClassConstructor> {
|
||||
if let Some(class_constructor) = &self.class_constructor {
|
||||
Some(class_constructor.as_ref())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn class_constructor_mut(&mut self) -> Option<&mut ClassConstructor> {
|
||||
if let Some(class_constructor) = &mut self.class_constructor {
|
||||
Some(class_constructor.as_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn implements(&self) -> &ImplementsList {
|
||||
&self.implements
|
||||
}
|
||||
|
||||
pub fn implements_mut(&mut self) -> &mut ImplementsList {
|
||||
&mut self.implements
|
||||
}
|
||||
|
||||
pub fn declarations(&self) -> Vec<&ClassLevelDeclaration> {
|
||||
self.declarations.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn declarations_mut(&mut self) -> Vec<&mut ClassLevelDeclaration> {
|
||||
self.declarations.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClassConstructor(Vec<Box<ClassConstructorParameter>>);
|
||||
|
||||
impl ClassConstructor {
|
||||
pub fn new(parameters: Vec<Box<ClassConstructorParameter>>) -> Self {
|
||||
Self(parameters)
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> Vec<&ClassConstructorParameter> {
|
||||
self.0.iter().map(|p| p.as_ref()).collect()
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> Vec<&mut ClassConstructorParameter> {
|
||||
self.0.iter_mut().map(|p| p.as_mut()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClassConstructorParameter {
|
||||
Property(Box<PropertyDeclaration>),
|
||||
Field(Box<FieldDeclaration>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PropertyDeclaration {
|
||||
is_mutable: bool,
|
||||
identifier: Box<Identifier>,
|
||||
declared_type: Box<TypeUse>,
|
||||
}
|
||||
|
||||
impl PropertyDeclaration {
|
||||
pub fn new(is_mutable: bool, identifier: Box<Identifier>, declared_type: Box<TypeUse>) -> Self {
|
||||
Self {
|
||||
is_mutable,
|
||||
identifier,
|
||||
declared_type,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_mutable(&self) -> bool {
|
||||
self.is_mutable
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn declared_type(&self) -> &TypeUse {
|
||||
&self.declared_type
|
||||
}
|
||||
|
||||
pub fn declared_type_mut(&mut self) -> &mut TypeUse {
|
||||
&mut self.declared_type
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FieldDeclaration {
|
||||
is_mutable: bool,
|
||||
identifier: Box<Identifier>,
|
||||
declared_type: Box<TypeUse>,
|
||||
}
|
||||
|
||||
impl FieldDeclaration {
|
||||
pub fn new(is_mutable: bool, identifier: Box<Identifier>, declared_type: Box<TypeUse>) -> Self {
|
||||
Self {
|
||||
is_mutable,
|
||||
identifier,
|
||||
declared_type,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_mutable(&self) -> bool {
|
||||
self.is_mutable
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn declared_type(&self) -> &TypeUse {
|
||||
&self.declared_type
|
||||
}
|
||||
|
||||
pub fn declared_type_mut(&mut self) -> &mut TypeUse {
|
||||
&mut self.declared_type
|
||||
}
|
||||
}
|
204
src/ast/node/closure.rs
Normal file
204
src/ast/node/closure.rs
Normal file
@ -0,0 +1,204 @@
|
||||
use crate::ast::node::expression::Expression;
|
||||
use crate::ast::node::names::Identifier;
|
||||
use crate::ast::node::statement::Statement;
|
||||
use crate::ast::node::type_use::TypeUse;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Closure {
|
||||
modifier: Option<ClosureModifier>,
|
||||
is_move: bool,
|
||||
captures: Box<ClosureCaptures>,
|
||||
parameters: Box<ClosureParameters>,
|
||||
statements: Vec<Box<Statement>>,
|
||||
expression: Option<Box<Expression>>,
|
||||
}
|
||||
|
||||
impl Closure {
|
||||
pub fn new(
|
||||
modifier: Option<ClosureModifier>,
|
||||
is_move: bool,
|
||||
captures: Box<ClosureCaptures>,
|
||||
parameters: Box<ClosureParameters>,
|
||||
statements: Vec<Box<Statement>>,
|
||||
expression: Option<Box<Expression>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
modifier,
|
||||
is_move,
|
||||
captures,
|
||||
parameters,
|
||||
statements,
|
||||
expression,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modifier(&self) -> Option<&ClosureModifier> {
|
||||
self.modifier.as_ref()
|
||||
}
|
||||
|
||||
pub fn is_move(&self) -> bool {
|
||||
self.is_move
|
||||
}
|
||||
|
||||
pub fn captures(&self) -> &ClosureCaptures {
|
||||
&self.captures
|
||||
}
|
||||
|
||||
pub fn captures_mut(&mut self) -> &mut ClosureCaptures {
|
||||
&mut self.captures
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> &ClosureParameters {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> &mut ClosureParameters {
|
||||
&mut self.parameters
|
||||
}
|
||||
|
||||
pub fn statements(&self) -> Vec<&Statement> {
|
||||
self.statements.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn statements_mut(&mut self) -> Vec<&mut Statement> {
|
||||
self.statements.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
|
||||
pub fn expression(&self) -> Option<&Expression> {
|
||||
if let Some(expression) = &self.expression {
|
||||
Some(expression)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expression_mut(&mut self) -> Option<&mut Expression> {
|
||||
if let Some(expression) = &mut self.expression {
|
||||
Some(expression)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClosureModifier {
|
||||
Cons,
|
||||
Mut,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ClosureCaptures(Vec<Box<ClosureCapture>>);
|
||||
|
||||
impl ClosureCaptures {
|
||||
pub fn new(captures: Vec<Box<ClosureCapture>>) -> Self {
|
||||
Self(captures)
|
||||
}
|
||||
|
||||
pub fn captures(&self) -> Vec<&ClosureCapture> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn captures_mut(&mut self) -> Vec<&mut ClosureCapture> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl ClosureCaptures {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClosureCapture {
|
||||
borrow_count: usize,
|
||||
is_mutable: bool,
|
||||
identifier: Box<Identifier>,
|
||||
}
|
||||
|
||||
impl ClosureCapture {
|
||||
pub fn new(borrow_count: usize, is_mutable: bool, identifier: Box<Identifier>) -> Self {
|
||||
Self {
|
||||
borrow_count,
|
||||
is_mutable,
|
||||
identifier,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow_count(&self) -> usize {
|
||||
self.borrow_count
|
||||
}
|
||||
|
||||
pub fn is_mutable(&self) -> bool {
|
||||
self.is_mutable
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ClosureParameters(Vec<Box<ClosureParameter>>);
|
||||
|
||||
impl ClosureParameters {
|
||||
pub fn new(parameters: Vec<Box<ClosureParameter>>) -> Self {
|
||||
Self(parameters)
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> Vec<&ClosureParameter> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> Vec<&mut ClosureParameter> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClosureParameter {
|
||||
identifier: Box<Identifier>,
|
||||
type_use: Option<Box<TypeUse>>,
|
||||
}
|
||||
|
||||
impl ClosureParameter {
|
||||
pub fn new(identifier: Box<Identifier>, type_use: Option<Box<TypeUse>>) -> Self {
|
||||
Self {
|
||||
identifier,
|
||||
type_use,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn type_use(&self) -> Option<&TypeUse> {
|
||||
if let Some(type_use) = &self.type_use {
|
||||
Some(type_use)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_use_mut(&mut self) -> Option<&mut TypeUse> {
|
||||
if let Some(type_use) = &mut self.type_use {
|
||||
Some(type_use.as_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
63
src/ast/node/compilation_unit.rs
Normal file
63
src/ast/node/compilation_unit.rs
Normal file
@ -0,0 +1,63 @@
|
||||
use crate::ast::node::level::ModuleLevelDeclaration;
|
||||
use crate::ast::node::names::FullyQualifiedName;
|
||||
use crate::ast::node::use_statement::UseStatement;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CompilationUnit {
|
||||
file_name: String,
|
||||
file_id: usize,
|
||||
namespace: Option<Box<FullyQualifiedName>>,
|
||||
use_statements: Vec<Box<UseStatement>>,
|
||||
declarations: Vec<Box<ModuleLevelDeclaration>>,
|
||||
}
|
||||
|
||||
impl CompilationUnit {
|
||||
pub fn new(
|
||||
file_name: String,
|
||||
file_id: usize,
|
||||
namespace: Option<Box<FullyQualifiedName>>,
|
||||
use_statements: Vec<Box<UseStatement>>,
|
||||
declarations: Vec<Box<ModuleLevelDeclaration>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
file_name,
|
||||
file_id,
|
||||
namespace,
|
||||
use_statements,
|
||||
declarations,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn file_name(&self) -> &str {
|
||||
&self.file_name
|
||||
}
|
||||
|
||||
pub fn file_id(&self) -> usize {
|
||||
self.file_id
|
||||
}
|
||||
|
||||
pub fn namespace(&self) -> Option<&FullyQualifiedName> {
|
||||
// We have to use this non-map syntax because we need a reference like `&self.namespace`
|
||||
if let Some(namespace) = &self.namespace {
|
||||
Some(namespace.as_ref())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn use_statements(&self) -> Vec<&UseStatement> {
|
||||
self.use_statements.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn use_statements_mut(&mut self) -> Vec<&mut UseStatement> {
|
||||
self.use_statements.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
|
||||
pub fn declarations(&self) -> Vec<&ModuleLevelDeclaration> {
|
||||
self.declarations.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn declarations_mut(&mut self) -> Vec<&mut ModuleLevelDeclaration> {
|
||||
self.declarations.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
55
src/ast/node/d_string.rs
Normal file
55
src/ast/node/d_string.rs
Normal file
@ -0,0 +1,55 @@
|
||||
use crate::ast::node::expression::Expression;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DString(Vec<Box<DStringPart>>);
|
||||
|
||||
impl DString {
|
||||
pub fn new(parts: Vec<Box<DStringPart>>) -> Self {
|
||||
Self(parts)
|
||||
}
|
||||
|
||||
pub fn parts(&self) -> Vec<&DStringPart> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn parts_mut(&mut self) -> Vec<&mut DStringPart> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DStringPart {
|
||||
String(String),
|
||||
Expression(Box<Expression>),
|
||||
}
|
||||
|
||||
impl DStringPart {
|
||||
pub fn from_string(s: &str) -> DStringPart {
|
||||
DStringPart::String(String::from(s))
|
||||
}
|
||||
|
||||
pub fn from_expression(e: Expression) -> DStringPart {
|
||||
DStringPart::Expression(Box::new(e))
|
||||
}
|
||||
|
||||
pub fn is_string(&self) -> bool {
|
||||
match self {
|
||||
DStringPart::String(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_string(self) -> String {
|
||||
match self {
|
||||
DStringPart::String(s) => s,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_expression(&self) -> bool {
|
||||
match self {
|
||||
DStringPart::Expression(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
155
src/ast/node/expression.rs
Normal file
155
src/ast/node/expression.rs
Normal file
@ -0,0 +1,155 @@
|
||||
use crate::ast::node::call_expression::CallExpression;
|
||||
use crate::ast::node::closure::Closure;
|
||||
use crate::ast::node::literal::Literal;
|
||||
use crate::ast::node::names::FullyQualifiedName;
|
||||
use crate::ast::node::object_access::ObjectAccess;
|
||||
use crate::ast::node::operators::{BinaryOperator, PrefixUnaryOperator, SuffixUnaryOperator};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Expression {
|
||||
Ternary(Box<TernaryExpression>),
|
||||
Binary(Box<BinaryExpression>),
|
||||
UnaryPrefix(Box<PrefixExpression>),
|
||||
UnarySuffix(Box<SuffixExpression>),
|
||||
Call(Box<CallExpression>),
|
||||
ObjectAccess(Box<ObjectAccess>),
|
||||
Literal(Box<Literal>),
|
||||
FullyQualifiedName(Box<FullyQualifiedName>),
|
||||
Closure(Box<Closure>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TernaryExpression {
|
||||
condition: Box<Expression>,
|
||||
true_expression: Box<Expression>,
|
||||
false_expression: Box<Expression>,
|
||||
}
|
||||
|
||||
impl TernaryExpression {
|
||||
pub fn new(
|
||||
condition: Box<Expression>,
|
||||
true_expression: Box<Expression>,
|
||||
false_expression: Box<Expression>,
|
||||
) -> Self {
|
||||
Self {
|
||||
condition,
|
||||
true_expression,
|
||||
false_expression,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn condition(&self) -> &Expression {
|
||||
&self.condition
|
||||
}
|
||||
|
||||
pub fn condition_mut(&mut self) -> &mut Expression {
|
||||
&mut self.condition
|
||||
}
|
||||
|
||||
pub fn true_expression(&self) -> &Expression {
|
||||
&self.true_expression
|
||||
}
|
||||
|
||||
pub fn true_expression_mut(&mut self) -> &mut Expression {
|
||||
&mut self.true_expression
|
||||
}
|
||||
|
||||
pub fn false_expression(&self) -> &Expression {
|
||||
&self.false_expression
|
||||
}
|
||||
|
||||
pub fn false_expression_mut(&mut self) -> &mut Expression {
|
||||
&mut self.false_expression
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BinaryExpression {
|
||||
left: Box<Expression>,
|
||||
operator: BinaryOperator,
|
||||
right: Box<Expression>,
|
||||
}
|
||||
|
||||
impl BinaryExpression {
|
||||
pub fn new(left: Box<Expression>, operator: BinaryOperator, right: Box<Expression>) -> Self {
|
||||
Self {
|
||||
left,
|
||||
operator,
|
||||
right,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn left(&self) -> &Expression {
|
||||
&self.left
|
||||
}
|
||||
|
||||
pub fn left_mut(&mut self) -> &mut Expression {
|
||||
&mut self.left
|
||||
}
|
||||
|
||||
pub fn operator(&self) -> &BinaryOperator {
|
||||
&self.operator
|
||||
}
|
||||
|
||||
pub fn right(&self) -> &Expression {
|
||||
&self.right
|
||||
}
|
||||
|
||||
pub fn right_mut(&mut self) -> &mut Expression {
|
||||
&mut self.right
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PrefixExpression {
|
||||
operator: PrefixUnaryOperator,
|
||||
expression: Box<Expression>,
|
||||
}
|
||||
|
||||
impl PrefixExpression {
|
||||
pub fn new(operator: PrefixUnaryOperator, expression: Box<Expression>) -> Self {
|
||||
Self {
|
||||
operator,
|
||||
expression,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn operator(&self) -> &PrefixUnaryOperator {
|
||||
&self.operator
|
||||
}
|
||||
|
||||
pub fn expression(&self) -> &Expression {
|
||||
&self.expression
|
||||
}
|
||||
|
||||
pub fn expression_mut(&mut self) -> &mut Expression {
|
||||
&mut self.expression
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SuffixExpression {
|
||||
expression: Box<Expression>,
|
||||
operator: SuffixUnaryOperator,
|
||||
}
|
||||
|
||||
impl SuffixExpression {
|
||||
pub fn new(expression: Box<Expression>, operator: SuffixUnaryOperator) -> Self {
|
||||
Self {
|
||||
expression,
|
||||
operator,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expression(&self) -> &Expression {
|
||||
&self.expression
|
||||
}
|
||||
|
||||
pub fn expression_mut(&mut self) -> &mut Expression {
|
||||
&mut self.expression
|
||||
}
|
||||
|
||||
pub fn operator(&self) -> &SuffixUnaryOperator {
|
||||
&self.operator
|
||||
}
|
||||
}
|
543
src/ast/node/function.rs
Normal file
543
src/ast/node/function.rs
Normal file
@ -0,0 +1,543 @@
|
||||
use crate::ast::node::expression::Expression;
|
||||
use crate::ast::node::generics::GenericParameters;
|
||||
use crate::ast::node::names::Identifier;
|
||||
use crate::ast::node::operators::Operator;
|
||||
use crate::ast::node::statement::BlockStatement;
|
||||
use crate::ast::node::type_use::{PrimitiveTypeUse, TypeUse};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FunctionTypeModifier {
|
||||
Cons,
|
||||
MutRef,
|
||||
Mut,
|
||||
Ref,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Parameters(Vec<Box<Parameter>>);
|
||||
|
||||
impl Parameters {
|
||||
pub fn new(parameters: Vec<Box<Parameter>>) -> Self {
|
||||
Self(parameters)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> Vec<&Parameter> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> Vec<&mut Parameter> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Parameters {
|
||||
fn default() -> Self {
|
||||
Parameters(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Parameter {
|
||||
identifier: Box<Identifier>,
|
||||
type_use: Box<TypeUse>,
|
||||
}
|
||||
|
||||
impl Parameter {
|
||||
pub fn new(identifier: Box<Identifier>, type_use: Box<TypeUse>) -> Self {
|
||||
Self {
|
||||
identifier,
|
||||
type_use,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn type_use(&self) -> &TypeUse {
|
||||
&self.type_use
|
||||
}
|
||||
|
||||
pub fn type_use_mut(&mut self) -> &mut TypeUse {
|
||||
&mut self.type_use
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReturnType {
|
||||
declared_type: Box<TypeUse>,
|
||||
references: Box<References>,
|
||||
}
|
||||
|
||||
impl ReturnType {
|
||||
pub fn new(declared_type: Box<TypeUse>, references: Box<References>) -> Self {
|
||||
Self {
|
||||
declared_type,
|
||||
references,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn void() -> Self {
|
||||
ReturnType {
|
||||
declared_type: Box::new(TypeUse::Primitive(Box::new(PrimitiveTypeUse::Void))),
|
||||
references: Box::new(References::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_type(&self) -> &TypeUse {
|
||||
&self.declared_type
|
||||
}
|
||||
|
||||
pub fn declared_type_mut(&mut self) -> &mut TypeUse {
|
||||
&mut self.declared_type
|
||||
}
|
||||
|
||||
pub fn references(&self) -> &References {
|
||||
&self.references
|
||||
}
|
||||
|
||||
pub fn references_mut(&mut self) -> &mut References {
|
||||
&mut self.references
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct References(Vec<Box<Identifier>>);
|
||||
|
||||
impl References {
|
||||
pub fn new(identifiers: Vec<Box<Identifier>>) -> Self {
|
||||
Self(identifiers)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn identifiers(&self) -> Vec<&Identifier> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for References {
|
||||
fn default() -> Self {
|
||||
References(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionDefinition {
|
||||
is_public: bool,
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
identifier: Box<Identifier>,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
body: Box<FunctionBody>,
|
||||
}
|
||||
|
||||
impl FunctionDefinition {
|
||||
pub fn new(
|
||||
is_public: bool,
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
identifier: Box<Identifier>,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
body: Box<FunctionBody>,
|
||||
) -> Self {
|
||||
Self {
|
||||
is_public,
|
||||
modifier,
|
||||
generics,
|
||||
identifier,
|
||||
parameters,
|
||||
return_type,
|
||||
body,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_public(&self) -> bool {
|
||||
self.is_public
|
||||
}
|
||||
|
||||
pub fn modifier(&self) -> Option<&FunctionModifier> {
|
||||
self.modifier.as_ref()
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericParameters {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericParameters {
|
||||
&mut self.generics
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> &Parameters {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> &mut Parameters {
|
||||
&mut self.parameters
|
||||
}
|
||||
|
||||
pub fn return_type(&self) -> &ReturnType {
|
||||
&self.return_type
|
||||
}
|
||||
|
||||
pub fn return_type_mut(&mut self) -> &mut ReturnType {
|
||||
&mut self.return_type
|
||||
}
|
||||
|
||||
pub fn body(&self) -> &FunctionBody {
|
||||
&self.body
|
||||
}
|
||||
|
||||
pub fn body_mut(&mut self) -> &mut FunctionBody {
|
||||
&mut self.body
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OperatorFunctionDefinition {
|
||||
is_public: bool,
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
operator: Operator,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
body: Box<FunctionBody>,
|
||||
}
|
||||
|
||||
impl OperatorFunctionDefinition {
|
||||
pub fn new(
|
||||
is_public: bool,
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
operator: Operator,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
body: Box<FunctionBody>,
|
||||
) -> Self {
|
||||
Self {
|
||||
is_public,
|
||||
modifier,
|
||||
generics,
|
||||
operator,
|
||||
parameters,
|
||||
return_type,
|
||||
body,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_public(&self) -> bool {
|
||||
self.is_public
|
||||
}
|
||||
|
||||
pub fn modifier(&self) -> Option<&FunctionModifier> {
|
||||
self.modifier.as_ref()
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericParameters {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericParameters {
|
||||
&mut self.generics
|
||||
}
|
||||
|
||||
pub fn operator(&self) -> &Operator {
|
||||
&self.operator
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> &Parameters {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> &mut Parameters {
|
||||
&mut self.parameters
|
||||
}
|
||||
|
||||
pub fn return_type(&self) -> &ReturnType {
|
||||
&self.return_type
|
||||
}
|
||||
|
||||
pub fn return_type_mut(&mut self) -> &mut ReturnType {
|
||||
&mut self.return_type
|
||||
}
|
||||
|
||||
pub fn body(&self) -> &FunctionBody {
|
||||
&self.body
|
||||
}
|
||||
|
||||
pub fn body_mut(&mut self) -> &mut FunctionBody {
|
||||
&mut self.body
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PlatformFunctionDeclaration {
|
||||
is_public: bool,
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
identifier: Box<Identifier>,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
}
|
||||
|
||||
impl PlatformFunctionDeclaration {
|
||||
pub fn new(
|
||||
is_public: bool,
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
identifier: Box<Identifier>,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
) -> Self {
|
||||
Self {
|
||||
is_public,
|
||||
modifier,
|
||||
generics,
|
||||
identifier,
|
||||
parameters,
|
||||
return_type,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_public(&self) -> bool {
|
||||
self.is_public
|
||||
}
|
||||
|
||||
pub fn modifier(&self) -> Option<&FunctionModifier> {
|
||||
self.modifier.as_ref()
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericParameters {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericParameters {
|
||||
&mut self.generics
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> &Parameters {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> &mut Parameters {
|
||||
&mut self.parameters
|
||||
}
|
||||
|
||||
pub fn return_type(&self) -> &ReturnType {
|
||||
&self.return_type
|
||||
}
|
||||
|
||||
pub fn return_type_mut(&mut self) -> &mut ReturnType {
|
||||
&mut self.return_type
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceFunctionDeclaration {
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
identifier: Box<Identifier>,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
body: Option<Box<FunctionBody>>,
|
||||
}
|
||||
|
||||
impl InterfaceFunctionDeclaration {
|
||||
pub fn new(
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
identifier: Box<Identifier>,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
body: Option<Box<FunctionBody>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
modifier,
|
||||
generics,
|
||||
identifier,
|
||||
parameters,
|
||||
return_type,
|
||||
body,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modifier(&self) -> Option<&FunctionModifier> {
|
||||
self.modifier.as_ref()
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericParameters {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericParameters {
|
||||
&mut self.generics
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> &Parameters {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> &mut Parameters {
|
||||
&mut self.parameters
|
||||
}
|
||||
|
||||
pub fn return_type(&self) -> &ReturnType {
|
||||
&self.return_type
|
||||
}
|
||||
|
||||
pub fn return_type_mut(&mut self) -> &mut ReturnType {
|
||||
&mut self.return_type
|
||||
}
|
||||
|
||||
pub fn body(&self) -> Option<&FunctionBody> {
|
||||
FunctionBody::unwrap_option(&self.body)
|
||||
}
|
||||
|
||||
pub fn body_mut(&mut self) -> Option<&mut FunctionBody> {
|
||||
FunctionBody::unwrap_option_mut(&mut self.body)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceOperatorFunctionDeclaration {
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
operator: Operator,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
body: Option<Box<FunctionBody>>,
|
||||
}
|
||||
|
||||
impl InterfaceOperatorFunctionDeclaration {
|
||||
pub fn new(
|
||||
modifier: Option<FunctionModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
operator: Operator,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
body: Option<Box<FunctionBody>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
modifier,
|
||||
generics,
|
||||
operator,
|
||||
parameters,
|
||||
return_type,
|
||||
body,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modifier(&self) -> Option<&FunctionModifier> {
|
||||
self.modifier.as_ref()
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericParameters {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericParameters {
|
||||
&mut self.generics
|
||||
}
|
||||
|
||||
pub fn operator(&self) -> &Operator {
|
||||
&self.operator
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> &Box<Parameters> {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> &mut Box<Parameters> {
|
||||
&mut self.parameters
|
||||
}
|
||||
|
||||
pub fn return_type(&self) -> &ReturnType {
|
||||
&self.return_type
|
||||
}
|
||||
|
||||
pub fn return_type_mut(&mut self) -> &mut ReturnType {
|
||||
&mut self.return_type
|
||||
}
|
||||
|
||||
pub fn body(&self) -> Option<&FunctionBody> {
|
||||
FunctionBody::unwrap_option(&self.body)
|
||||
}
|
||||
|
||||
pub fn body_mut(&mut self) -> Option<&mut FunctionBody> {
|
||||
FunctionBody::unwrap_option_mut(&mut self.body)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FunctionModifier {
|
||||
Static,
|
||||
Cons,
|
||||
Mut,
|
||||
Ref,
|
||||
MutRef,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FunctionBody {
|
||||
Equals(Box<Expression>),
|
||||
Block(Box<BlockStatement>),
|
||||
Alias(Box<Identifier>),
|
||||
}
|
||||
|
||||
impl FunctionBody {
|
||||
fn unwrap_option(opt: &Option<Box<FunctionBody>>) -> Option<&FunctionBody> {
|
||||
if let Some(body) = opt {
|
||||
Some(body.as_ref())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn unwrap_option_mut(opt: &mut Option<Box<FunctionBody>>) -> Option<&mut FunctionBody> {
|
||||
if let Some(body) = opt {
|
||||
Some(body.as_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
56
src/ast/node/generics.rs
Normal file
56
src/ast/node/generics.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use crate::ast::node::names::Identifier;
|
||||
use crate::ast::node::type_use::TypeUse;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GenericArguments(Vec<Box<TypeUse>>);
|
||||
|
||||
impl GenericArguments {
|
||||
pub fn new(arguments: Vec<Box<TypeUse>>) -> Self {
|
||||
Self(arguments)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn arguments(&self) -> Vec<&TypeUse> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn arguments_mut(&mut self) -> Vec<&mut TypeUse> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GenericArguments {
|
||||
fn default() -> Self {
|
||||
GenericArguments(Vec::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GenericParameters(Vec<Box<Identifier>>);
|
||||
|
||||
impl GenericParameters {
|
||||
pub fn new(identifiers: Vec<Box<Identifier>>) -> Self {
|
||||
Self(identifiers)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn identifiers(&self) -> Vec<&Identifier> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GenericParameters {
|
||||
fn default() -> Self {
|
||||
GenericParameters(Vec::new())
|
||||
}
|
||||
}
|
28
src/ast/node/implements_list.rs
Normal file
28
src/ast/node/implements_list.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use crate::ast::node::type_use::TypeUse;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ImplementsList(Vec<Box<TypeUse>>);
|
||||
|
||||
impl ImplementsList {
|
||||
pub fn new(type_uses: Vec<Box<TypeUse>>) -> Self {
|
||||
Self(type_uses)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn type_uses(&self) -> Vec<&TypeUse> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn type_uses_mut(&mut self) -> Vec<&mut TypeUse> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ImplementsList {
|
||||
fn default() -> Self {
|
||||
ImplementsList(Vec::new())
|
||||
}
|
||||
}
|
67
src/ast/node/interface.rs
Normal file
67
src/ast/node/interface.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use crate::ast::node::generics::GenericParameters;
|
||||
use crate::ast::node::implements_list::ImplementsList;
|
||||
use crate::ast::node::level::InterfaceLevelDeclaration;
|
||||
use crate::ast::node::names::Identifier;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceDeclaration {
|
||||
is_public: bool,
|
||||
identifier: Box<Identifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
implements: Box<ImplementsList>,
|
||||
declarations: Vec<Box<InterfaceLevelDeclaration>>,
|
||||
}
|
||||
|
||||
impl InterfaceDeclaration {
|
||||
pub fn new(
|
||||
is_public: bool,
|
||||
identifier: Box<Identifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
implements: Box<ImplementsList>,
|
||||
declarations: Vec<Box<InterfaceLevelDeclaration>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
is_public,
|
||||
identifier,
|
||||
generics,
|
||||
implements,
|
||||
declarations,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_public(&self) -> bool {
|
||||
self.is_public
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericParameters {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericParameters {
|
||||
&mut self.generics
|
||||
}
|
||||
|
||||
pub fn implements(&self) -> &ImplementsList {
|
||||
&self.implements
|
||||
}
|
||||
|
||||
pub fn implements_mut(&mut self) -> &mut ImplementsList {
|
||||
&mut self.implements
|
||||
}
|
||||
|
||||
pub fn declarations(&self) -> Vec<&InterfaceLevelDeclaration> {
|
||||
self.declarations.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn declarations_mut(&mut self) -> Vec<&mut InterfaceLevelDeclaration> {
|
||||
self.declarations.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
37
src/ast/node/level.rs
Normal file
37
src/ast/node/level.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use crate::ast::node::class::{ClassDeclaration, FieldDeclaration, PropertyDeclaration};
|
||||
use crate::ast::node::function::{
|
||||
FunctionDefinition, InterfaceFunctionDeclaration, InterfaceOperatorFunctionDeclaration,
|
||||
OperatorFunctionDefinition, PlatformFunctionDeclaration,
|
||||
};
|
||||
use crate::ast::node::interface::InterfaceDeclaration;
|
||||
use crate::ast::node::module::ModuleDeclaration;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ModuleLevelDeclaration {
|
||||
Module(Box<ModuleDeclaration>),
|
||||
Interface(Box<InterfaceDeclaration>),
|
||||
Class(Box<ClassDeclaration>),
|
||||
Function(Box<FunctionDefinition>),
|
||||
PlatformFunction(Box<PlatformFunctionDeclaration>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum InterfaceLevelDeclaration {
|
||||
Module(Box<ModuleDeclaration>),
|
||||
Interface(Box<InterfaceDeclaration>),
|
||||
Class(Box<ClassDeclaration>),
|
||||
Function(Box<InterfaceFunctionDeclaration>),
|
||||
OperatorFunction(Box<InterfaceOperatorFunctionDeclaration>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ClassLevelDeclaration {
|
||||
Module(Box<ModuleDeclaration>),
|
||||
Interface(Box<InterfaceDeclaration>),
|
||||
Class(Box<ClassDeclaration>),
|
||||
Function(Box<FunctionDefinition>),
|
||||
OperatorFunction(Box<OperatorFunctionDefinition>),
|
||||
PlatformFunction(Box<PlatformFunctionDeclaration>),
|
||||
Property(Box<PropertyDeclaration>),
|
||||
Field(Box<FieldDeclaration>),
|
||||
}
|
13
src/ast/node/literal.rs
Normal file
13
src/ast/node/literal.rs
Normal file
@ -0,0 +1,13 @@
|
||||
use crate::ast::node::d_string::DString;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Literal {
|
||||
Integer(i32),
|
||||
Long(i64),
|
||||
Double(f64),
|
||||
USize(usize),
|
||||
String(String),
|
||||
DString(Box<DString>),
|
||||
BacktickString(Box<DString>),
|
||||
Boolean(bool),
|
||||
}
|
21
src/ast/node/mod.rs
Normal file
21
src/ast/node/mod.rs
Normal file
@ -0,0 +1,21 @@
|
||||
pub mod call_expression;
|
||||
pub mod class;
|
||||
pub mod closure;
|
||||
pub mod compilation_unit;
|
||||
pub mod d_string;
|
||||
pub mod expression;
|
||||
pub mod function;
|
||||
pub mod generics;
|
||||
pub mod implements_list;
|
||||
pub mod interface;
|
||||
pub mod level;
|
||||
pub mod literal;
|
||||
pub mod module;
|
||||
pub mod named;
|
||||
pub mod names;
|
||||
pub mod object_access;
|
||||
pub mod operators;
|
||||
pub mod statement;
|
||||
pub mod tuple_arguments;
|
||||
pub mod type_use;
|
||||
pub mod use_statement;
|
43
src/ast/node/module.rs
Normal file
43
src/ast/node/module.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::ast::node::level::ModuleLevelDeclaration;
|
||||
use crate::ast::node::names::Identifier;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ModuleDeclaration {
|
||||
is_public: bool,
|
||||
identifier: Box<Identifier>,
|
||||
declarations: Vec<Box<ModuleLevelDeclaration>>,
|
||||
}
|
||||
|
||||
impl ModuleDeclaration {
|
||||
pub fn new(
|
||||
is_public: bool,
|
||||
identifier: Box<Identifier>,
|
||||
declarations: Vec<Box<ModuleLevelDeclaration>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
is_public,
|
||||
identifier,
|
||||
declarations,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_public(&self) -> bool {
|
||||
self.is_public
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn declarations(&self) -> Vec<&ModuleLevelDeclaration> {
|
||||
self.declarations.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn declarations_mut(&mut self) -> Vec<&mut ModuleLevelDeclaration> {
|
||||
self.declarations.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
16
src/ast/node/named.rs
Normal file
16
src/ast/node/named.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use crate::name_analysis::symbol::Symbol;
|
||||
use std::borrow::Cow;
|
||||
use std::range::Range;
|
||||
|
||||
pub trait Named {
|
||||
fn name(&self) -> Cow<'_, str>;
|
||||
|
||||
fn file_id(&self) -> usize;
|
||||
fn range(&self) -> Range<usize>;
|
||||
|
||||
fn set_scope_id(&mut self, scope_id: usize);
|
||||
fn scope_id(&self) -> Option<usize>;
|
||||
|
||||
fn set_saved_symbol(&mut self, symbol: Symbol);
|
||||
fn saved_symbol(&self) -> Option<Symbol>;
|
||||
}
|
146
src/ast/node/names.rs
Normal file
146
src/ast/node/names.rs
Normal file
@ -0,0 +1,146 @@
|
||||
use std::borrow::Cow;
|
||||
use crate::name_analysis::symbol::Symbol;
|
||||
use std::range::Range;
|
||||
use crate::ast::node::named::Named;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Identifier {
|
||||
name: String,
|
||||
file_id: usize,
|
||||
range: Range<usize>,
|
||||
scope_id: Option<usize>,
|
||||
saved_symbol: Option<Symbol>,
|
||||
}
|
||||
|
||||
impl Identifier {
|
||||
pub fn new(name: &str, file_id: usize, range: Range<usize>) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
file_id,
|
||||
range,
|
||||
scope_id: None,
|
||||
saved_symbol: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for Identifier {
|
||||
fn name(&self) -> Cow<'_, str> {
|
||||
Cow::Borrowed(&self.name)
|
||||
}
|
||||
|
||||
fn file_id(&self) -> usize {
|
||||
self.file_id
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.range
|
||||
}
|
||||
|
||||
fn set_scope_id(&mut self, id: usize) {
|
||||
self.scope_id = Some(id);
|
||||
}
|
||||
|
||||
fn scope_id(&self) -> Option<usize> {
|
||||
self.scope_id
|
||||
}
|
||||
|
||||
fn set_saved_symbol(&mut self, saved_symbol: Symbol) {
|
||||
self.saved_symbol = Some(saved_symbol);
|
||||
}
|
||||
|
||||
fn saved_symbol(&self) -> Option<Symbol> {
|
||||
self.saved_symbol.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FullyQualifiedName {
|
||||
identifiers: Vec<Box<Identifier>>,
|
||||
file_id: usize,
|
||||
range: Range<usize>,
|
||||
scope_id: Option<usize>,
|
||||
saved_symbol: Option<Symbol>,
|
||||
}
|
||||
|
||||
impl FullyQualifiedName {
|
||||
pub fn new(identifiers: Vec<Box<Identifier>>, file_id: usize, range: Range<usize>) -> Self {
|
||||
Self {
|
||||
identifiers,
|
||||
range,
|
||||
file_id,
|
||||
scope_id: None,
|
||||
saved_symbol: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identifiers(&self) -> Vec<&Identifier> {
|
||||
self.identifiers.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
|
||||
self.identifiers.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
|
||||
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
|
||||
pub fn last(&self) -> &Identifier {
|
||||
&self.identifiers[self.identifiers.len() - 1]
|
||||
}
|
||||
|
||||
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
|
||||
pub fn last_mut(&mut self) -> &mut Identifier {
|
||||
let last_index = self.identifiers.len() - 1;
|
||||
&mut self.identifiers[last_index]
|
||||
}
|
||||
|
||||
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
|
||||
pub fn len(&self) -> usize {
|
||||
self.identifiers.len()
|
||||
}
|
||||
|
||||
#[deprecated(note = "Grammar will instead distinguish between fqns and identifiers")]
|
||||
pub fn is_single_identifier(&self) -> bool {
|
||||
self.identifiers.len() == 1
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for FullyQualifiedName {
|
||||
fn name(&self) -> Cow<'_, str> {
|
||||
if self.identifiers.len() == 1 {
|
||||
self.identifiers[0].name()
|
||||
} else {
|
||||
let mut acc = String::new();
|
||||
for (i, identifier) in self.identifiers.iter().enumerate() {
|
||||
acc += &identifier.name();
|
||||
if i < self.identifiers.len() - 1 {
|
||||
acc += "::";
|
||||
}
|
||||
}
|
||||
Cow::Owned(acc)
|
||||
}
|
||||
}
|
||||
|
||||
fn file_id(&self) -> usize {
|
||||
self.file_id
|
||||
}
|
||||
|
||||
fn range(&self) -> Range<usize> {
|
||||
self.range
|
||||
}
|
||||
|
||||
fn set_scope_id(&mut self, id: usize) {
|
||||
self.scope_id = Some(id);
|
||||
}
|
||||
|
||||
fn scope_id(&self) -> Option<usize> {
|
||||
self.scope_id
|
||||
}
|
||||
|
||||
fn set_saved_symbol(&mut self, symbol: Symbol) {
|
||||
self.saved_symbol = Some(symbol);
|
||||
}
|
||||
|
||||
fn saved_symbol(&self) -> Option<Symbol> {
|
||||
self.saved_symbol.clone()
|
||||
}
|
||||
}
|
56
src/ast/node/object_access.rs
Normal file
56
src/ast/node/object_access.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use crate::ast::node::expression::Expression;
|
||||
use crate::ast::node::names::Identifier;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectAccess {
|
||||
receiver: Box<Expression>,
|
||||
navigations: Box<ObjectNavigations>,
|
||||
}
|
||||
|
||||
impl ObjectAccess {
|
||||
pub fn new(receiver: Box<Expression>, navigations: Box<ObjectNavigations>) -> Self {
|
||||
Self {
|
||||
receiver,
|
||||
navigations,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn receiver(&self) -> &Expression {
|
||||
&self.receiver
|
||||
}
|
||||
|
||||
pub fn receiver_mut(&mut self) -> &mut Expression {
|
||||
&mut self.receiver
|
||||
}
|
||||
|
||||
pub fn navigations(&self) -> &ObjectNavigations {
|
||||
&self.navigations
|
||||
}
|
||||
|
||||
pub fn navigations_mut(&mut self) -> &mut ObjectNavigations {
|
||||
&mut self.navigations
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectNavigations(Vec<Box<ObjectNavigation>>);
|
||||
|
||||
impl ObjectNavigations {
|
||||
pub fn new(navigations: Vec<Box<ObjectNavigation>>) -> Self {
|
||||
Self(navigations)
|
||||
}
|
||||
|
||||
pub fn navigations(&self) -> Vec<&ObjectNavigation> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn navigations_mut(&mut self) -> Vec<&mut ObjectNavigation> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ObjectNavigation {
|
||||
Index(Box<Expression>),
|
||||
Identifier(Box<Identifier>),
|
||||
}
|
44
src/ast/node/operators.rs
Normal file
44
src/ast/node/operators.rs
Normal file
@ -0,0 +1,44 @@
|
||||
#[derive(Debug)]
|
||||
pub enum Operator {
|
||||
Binary(BinaryOperator),
|
||||
PrefixUnary(PrefixUnaryOperator),
|
||||
SuffixUnary(SuffixUnaryOperator),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BinaryOperator {
|
||||
Or,
|
||||
And,
|
||||
EqualTo,
|
||||
NotEqualTo,
|
||||
Greater,
|
||||
Less,
|
||||
GreaterEqual,
|
||||
LessEqual,
|
||||
Add,
|
||||
Subtract,
|
||||
Multiply,
|
||||
Divide,
|
||||
Modulo,
|
||||
LeftShift,
|
||||
RightShift,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PrefixUnaryOperator {
|
||||
Spread,
|
||||
BorrowMut,
|
||||
Borrow,
|
||||
Star,
|
||||
Mut,
|
||||
Not,
|
||||
Negative,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SuffixUnaryOperator {
|
||||
PlusPlus,
|
||||
MinusMinus,
|
||||
Call,
|
||||
Index,
|
||||
}
|
384
src/ast/node/statement.rs
Normal file
384
src/ast/node/statement.rs
Normal file
@ -0,0 +1,384 @@
|
||||
use crate::ast::node::expression::Expression;
|
||||
use crate::ast::node::names::Identifier;
|
||||
use crate::ast::node::type_use::TypeUse;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BlockStatement {
|
||||
statements: Vec<Box<Statement>>,
|
||||
expression: Option<Box<Expression>>,
|
||||
}
|
||||
|
||||
impl BlockStatement {
|
||||
pub fn new(statements: Vec<Box<Statement>>, expression: Option<Box<Expression>>) -> Self {
|
||||
Self {
|
||||
statements,
|
||||
expression,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn statements(&self) -> Vec<&Statement> {
|
||||
self.statements.iter().map(AsRef::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn statements_mut(&mut self) -> Vec<&mut Statement> {
|
||||
self.statements.iter_mut().map(AsMut::as_mut).collect()
|
||||
}
|
||||
|
||||
pub fn expression(&self) -> Option<&Expression> {
|
||||
if let Some(ref expression) = self.expression {
|
||||
Some(expression.as_ref())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expression_mut(&mut self) -> Option<&mut Expression> {
|
||||
if let Some(ref mut expression) = self.expression {
|
||||
Some(expression.as_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Statement {
|
||||
BlockStatement(Box<BlockStatement>),
|
||||
VariableDeclarationStatement(Box<VariableDeclarationStatement>),
|
||||
AssignStatement(Box<AssignStatement>),
|
||||
CallStatement(Box<CallStatement>),
|
||||
ReturnStatement(Box<ReturnStatement>),
|
||||
IfStatement(Box<IfStatement>),
|
||||
IfElseStatement(Box<IfElseStatement>),
|
||||
WhileStatement(Box<WhileStatement>),
|
||||
ForStatement(Box<ForStatement>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VariableDeclarationStatement {
|
||||
is_mutable: bool,
|
||||
identifier: Box<Identifier>,
|
||||
declared_type: Option<Box<TypeUse>>,
|
||||
initializer: Option<Box<Expression>>,
|
||||
}
|
||||
|
||||
impl VariableDeclarationStatement {
|
||||
pub fn new(
|
||||
is_mutable: bool,
|
||||
identifier: Box<Identifier>,
|
||||
declared_type: Option<Box<TypeUse>>,
|
||||
initializer: Option<Box<Expression>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
is_mutable,
|
||||
identifier,
|
||||
declared_type,
|
||||
initializer,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_mutable(&self) -> bool {
|
||||
self.is_mutable
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> &Identifier {
|
||||
&self.identifier
|
||||
}
|
||||
|
||||
pub fn identifier_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.identifier
|
||||
}
|
||||
|
||||
pub fn declared_type(&self) -> Option<&TypeUse> {
|
||||
if let Some(type_use) = &self.declared_type {
|
||||
Some(type_use.as_ref())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_type_mut(&mut self) -> Option<&mut TypeUse> {
|
||||
if let Some(type_use) = &mut self.declared_type {
|
||||
Some(type_use.as_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initializer(&self) -> Option<&Expression> {
|
||||
if let Some(initializer) = &self.initializer {
|
||||
Some(initializer.as_ref())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initializer_mut(&mut self) -> Option<&mut Expression> {
|
||||
if let Some(initializer) = &mut self.initializer {
|
||||
Some(initializer.as_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AssignStatement {
|
||||
lhs: Box<Expression>,
|
||||
rhs: Box<Expression>,
|
||||
}
|
||||
|
||||
impl AssignStatement {
|
||||
pub fn new(lhs: Box<Expression>, rhs: Box<Expression>) -> Self {
|
||||
Self { lhs, rhs }
|
||||
}
|
||||
|
||||
pub fn lhs(&self) -> &Expression {
|
||||
&self.lhs
|
||||
}
|
||||
|
||||
pub fn lhs_mut(&mut self) -> &mut Expression {
|
||||
&mut self.lhs
|
||||
}
|
||||
|
||||
pub fn rhs(&self) -> &Expression {
|
||||
&self.rhs
|
||||
}
|
||||
|
||||
pub fn rhs_mut(&mut self) -> &mut Expression {
|
||||
&mut self.rhs
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CallStatement(Box<Expression>);
|
||||
|
||||
impl CallStatement {
|
||||
pub fn new(call_expression: Box<Expression>) -> Self {
|
||||
Self(call_expression)
|
||||
}
|
||||
|
||||
pub fn expression(&self) -> &Expression {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn expression_mut(&mut self) -> &mut Expression {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ReturnStatement(Option<Box<Expression>>);
|
||||
|
||||
impl ReturnStatement {
|
||||
pub fn new(expression: Option<Box<Expression>>) -> Self {
|
||||
Self(expression)
|
||||
}
|
||||
|
||||
pub fn expression(&self) -> Option<&Expression> {
|
||||
if let Some(expression) = &self.0 {
|
||||
Some(expression.as_ref())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expression_mut(&mut self) -> Option<&mut Expression> {
|
||||
if let Some(expression) = &mut self.0 {
|
||||
Some(expression.as_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IfStatement {
|
||||
condition: Box<Expression>,
|
||||
then_block: Box<BlockStatement>,
|
||||
}
|
||||
|
||||
impl IfStatement {
|
||||
pub fn new(condition: Box<Expression>, then_block: Box<BlockStatement>) -> Self {
|
||||
Self {
|
||||
condition,
|
||||
then_block,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn condition(&self) -> &Expression {
|
||||
&self.condition
|
||||
}
|
||||
|
||||
pub fn condition_mut(&mut self) -> &mut Expression {
|
||||
&mut self.condition
|
||||
}
|
||||
|
||||
pub fn then_block(&self) -> &BlockStatement {
|
||||
&self.then_block
|
||||
}
|
||||
|
||||
pub fn then_block_mut(&mut self) -> &mut BlockStatement {
|
||||
&mut self.then_block
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IfElseStatement {
|
||||
if_statement: Box<IfStatement>,
|
||||
else_ifs: Box<ElseIfs>,
|
||||
else_block: Option<Box<ElseBlock>>,
|
||||
}
|
||||
|
||||
impl IfElseStatement {
|
||||
pub fn new(
|
||||
if_statement: Box<IfStatement>,
|
||||
else_ifs: Box<ElseIfs>,
|
||||
else_block: Option<Box<ElseBlock>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
if_statement,
|
||||
else_ifs,
|
||||
else_block,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn if_statement(&self) -> &IfStatement {
|
||||
&self.if_statement
|
||||
}
|
||||
|
||||
pub fn if_statement_mut(&mut self) -> &mut IfStatement {
|
||||
&mut self.if_statement
|
||||
}
|
||||
|
||||
pub fn else_ifs(&self) -> &ElseIfs {
|
||||
&self.else_ifs
|
||||
}
|
||||
|
||||
pub fn else_ifs_mut(&mut self) -> &mut ElseIfs {
|
||||
&mut self.else_ifs
|
||||
}
|
||||
|
||||
pub fn else_block(&self) -> Option<&ElseBlock> {
|
||||
if let Some(else_block) = &self.else_block {
|
||||
Some(else_block.as_ref())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn else_block_mut(&mut self) -> Option<&mut ElseBlock> {
|
||||
if let Some(else_block) = &mut self.else_block {
|
||||
Some(else_block.as_mut())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ElseIfs(Vec<Box<IfStatement>>);
|
||||
|
||||
impl ElseIfs {
|
||||
pub fn new(if_statements: Vec<Box<IfStatement>>) -> Self {
|
||||
Self(if_statements)
|
||||
}
|
||||
|
||||
pub fn if_statements(&self) -> Vec<&IfStatement> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn if_statements_mut(&mut self) -> Vec<&mut IfStatement> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ElseBlock(Box<BlockStatement>);
|
||||
|
||||
impl ElseBlock {
|
||||
pub fn new(block: Box<BlockStatement>) -> Self {
|
||||
Self(block)
|
||||
}
|
||||
|
||||
pub fn block_statement(&self) -> &BlockStatement {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn block_statement_mut(&mut self) -> &mut BlockStatement {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WhileStatement {
|
||||
condition: Box<Expression>,
|
||||
body: Box<BlockStatement>,
|
||||
}
|
||||
|
||||
impl WhileStatement {
|
||||
pub fn new(condition: Box<Expression>, body: Box<BlockStatement>) -> Self {
|
||||
Self { condition, body }
|
||||
}
|
||||
|
||||
pub fn condition(&self) -> &Expression {
|
||||
&self.condition
|
||||
}
|
||||
|
||||
pub fn condition_mut(&mut self) -> &mut Expression {
|
||||
&mut self.condition
|
||||
}
|
||||
|
||||
pub fn body(&self) -> &BlockStatement {
|
||||
&self.body
|
||||
}
|
||||
|
||||
pub fn body_mut(&mut self) -> &mut BlockStatement {
|
||||
&mut self.body
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ForStatement {
|
||||
variable: Box<Identifier>,
|
||||
iterator: Box<Expression>,
|
||||
body: Box<BlockStatement>,
|
||||
}
|
||||
|
||||
impl ForStatement {
|
||||
pub fn new(
|
||||
variable: Box<Identifier>,
|
||||
iterator: Box<Expression>,
|
||||
body: Box<BlockStatement>,
|
||||
) -> Self {
|
||||
Self {
|
||||
variable,
|
||||
iterator,
|
||||
body,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn variable(&self) -> &Identifier {
|
||||
&self.variable
|
||||
}
|
||||
|
||||
pub fn variable_mut(&mut self) -> &mut Identifier {
|
||||
&mut self.variable
|
||||
}
|
||||
|
||||
pub fn iterator(&self) -> &Expression {
|
||||
&self.iterator
|
||||
}
|
||||
|
||||
pub fn iterator_mut(&mut self) -> &mut Expression {
|
||||
&mut self.iterator
|
||||
}
|
||||
|
||||
pub fn body(&self) -> &BlockStatement {
|
||||
&self.body
|
||||
}
|
||||
|
||||
pub fn body_mut(&mut self) -> &mut BlockStatement {
|
||||
&mut self.body
|
||||
}
|
||||
}
|
22
src/ast/node/tuple_arguments.rs
Normal file
22
src/ast/node/tuple_arguments.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::ast::node::type_use::TypeUse;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TupleArguments(Vec<Box<TypeUse>>);
|
||||
|
||||
impl TupleArguments {
|
||||
pub fn new(arguments: Vec<Box<TypeUse>>) -> Self {
|
||||
Self(arguments)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.0.is_empty()
|
||||
}
|
||||
|
||||
pub fn type_uses(&self) -> Vec<&TypeUse> {
|
||||
self.0.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn type_uses_mut(&mut self) -> Vec<&mut TypeUse> {
|
||||
self.0.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
}
|
167
src/ast/node/type_use.rs
Normal file
167
src/ast/node/type_use.rs
Normal file
@ -0,0 +1,167 @@
|
||||
use crate::ast::node::function::{FunctionTypeModifier, Parameters, ReturnType};
|
||||
use crate::ast::node::generics::{GenericArguments, GenericParameters};
|
||||
use crate::ast::node::names::FullyQualifiedName;
|
||||
use crate::ast::node::tuple_arguments::TupleArguments;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TypeUse {
|
||||
Primitive(Box<PrimitiveTypeUse>),
|
||||
InterfaceOrClass(Box<InterfaceOrClassTypeUse>),
|
||||
Tuple(Box<TupleTypeUse>),
|
||||
Function(Box<FunctionTypeUse>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PrimitiveTypeUse {
|
||||
Byte,
|
||||
Short,
|
||||
Char,
|
||||
Int,
|
||||
Long,
|
||||
Double,
|
||||
Bool,
|
||||
String,
|
||||
Array(Option<Box<GenericArguments>>),
|
||||
Any,
|
||||
Void,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceOrClassTypeUse {
|
||||
borrow_count: usize,
|
||||
is_mutable: bool,
|
||||
fqn: Box<FullyQualifiedName>,
|
||||
generics: Box<GenericArguments>,
|
||||
}
|
||||
|
||||
impl InterfaceOrClassTypeUse {
|
||||
pub fn new(
|
||||
borrow_count: usize,
|
||||
is_mutable: bool,
|
||||
fqn: Box<FullyQualifiedName>,
|
||||
generics: Box<GenericArguments>,
|
||||
) -> Self {
|
||||
Self {
|
||||
borrow_count,
|
||||
is_mutable,
|
||||
fqn,
|
||||
generics,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow_count(&self) -> usize {
|
||||
self.borrow_count
|
||||
}
|
||||
|
||||
pub fn is_mutable(&self) -> bool {
|
||||
self.is_mutable
|
||||
}
|
||||
|
||||
pub fn fqn(&self) -> &FullyQualifiedName {
|
||||
&self.fqn
|
||||
}
|
||||
|
||||
pub fn fqn_mut(&mut self) -> &mut FullyQualifiedName {
|
||||
&mut self.fqn
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericArguments {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericArguments {
|
||||
&mut self.generics
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TupleTypeUse {
|
||||
borrow_count: usize,
|
||||
is_mutable: bool,
|
||||
arguments: Box<TupleArguments>,
|
||||
}
|
||||
|
||||
impl TupleTypeUse {
|
||||
pub fn new(borrow_count: usize, is_mutable: bool, arguments: Box<TupleArguments>) -> Self {
|
||||
Self {
|
||||
borrow_count,
|
||||
is_mutable,
|
||||
arguments,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow_count(&self) -> usize {
|
||||
self.borrow_count
|
||||
}
|
||||
|
||||
pub fn is_mutable(&self) -> bool {
|
||||
self.is_mutable
|
||||
}
|
||||
|
||||
pub fn arguments(&self) -> &TupleArguments {
|
||||
&self.arguments
|
||||
}
|
||||
|
||||
pub fn arguments_mut(&mut self) -> &mut TupleArguments {
|
||||
&mut self.arguments
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionTypeUse {
|
||||
borrow_count: usize,
|
||||
function_modifier: Option<FunctionTypeModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
}
|
||||
|
||||
impl FunctionTypeUse {
|
||||
pub fn new(
|
||||
borrow_count: usize,
|
||||
function_modifier: Option<FunctionTypeModifier>,
|
||||
generics: Box<GenericParameters>,
|
||||
parameters: Box<Parameters>,
|
||||
return_type: Box<ReturnType>,
|
||||
) -> Self {
|
||||
Self {
|
||||
borrow_count,
|
||||
function_modifier,
|
||||
generics,
|
||||
parameters,
|
||||
return_type,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow_count(&self) -> usize {
|
||||
self.borrow_count
|
||||
}
|
||||
|
||||
pub fn function_modifier(&self) -> Option<&FunctionTypeModifier> {
|
||||
self.function_modifier.as_ref()
|
||||
}
|
||||
|
||||
pub fn generics(&self) -> &GenericParameters {
|
||||
&self.generics
|
||||
}
|
||||
|
||||
pub fn generics_mut(&mut self) -> &mut GenericParameters {
|
||||
&mut self.generics
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> &Box<Parameters> {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn parameters_mut(&mut self) -> &mut Box<Parameters> {
|
||||
&mut self.parameters
|
||||
}
|
||||
|
||||
pub fn return_type(&self) -> &ReturnType {
|
||||
&self.return_type
|
||||
}
|
||||
|
||||
pub fn return_type_mut(&mut self) -> &mut ReturnType {
|
||||
&mut self.return_type
|
||||
}
|
||||
}
|
87
src/ast/node/use_statement.rs
Normal file
87
src/ast/node/use_statement.rs
Normal file
@ -0,0 +1,87 @@
|
||||
use crate::ast::node::named::Named;
|
||||
use crate::ast::node::names::Identifier;
|
||||
use std::borrow::Cow;
|
||||
use std::range::Range;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UseStatement {
|
||||
identifiers: Vec<Box<Identifier>>,
|
||||
last: Box<UseStatementLast>,
|
||||
file_id: usize,
|
||||
range: Range<usize>,
|
||||
}
|
||||
|
||||
impl UseStatement {
|
||||
pub fn new(
|
||||
identifiers: Vec<Box<Identifier>>,
|
||||
last: Box<UseStatementLast>,
|
||||
file_id: usize,
|
||||
range: Range<usize>,
|
||||
) -> Self {
|
||||
UseStatement {
|
||||
identifiers,
|
||||
last,
|
||||
file_id,
|
||||
range,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn base_name(&self) -> Cow<'_, str> {
|
||||
use UseStatementLast::*;
|
||||
if self.identifiers.is_empty() {
|
||||
match self.last.as_ref() {
|
||||
Identifier(_) => Cow::from(""),
|
||||
Star | Identifiers(_) => panic!(), // should never get here because of grammar
|
||||
}
|
||||
} else if self.identifiers.len() == 1 {
|
||||
self.identifiers[0].name()
|
||||
} else {
|
||||
let mut acc = String::new();
|
||||
for (i, identifier) in self.identifiers.iter().enumerate() {
|
||||
acc.push_str(&identifier.name());
|
||||
if i != self.identifiers.len() - 1 {
|
||||
acc.push_str("::");
|
||||
}
|
||||
}
|
||||
Cow::from(acc)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_star(&self) -> bool {
|
||||
match self.last.as_ref() {
|
||||
UseStatementLast::Star => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identifiers(&self) -> Vec<&Identifier> {
|
||||
self.identifiers.iter().map(Box::as_ref).collect()
|
||||
}
|
||||
|
||||
pub fn identifiers_mut(&mut self) -> Vec<&mut Identifier> {
|
||||
self.identifiers.iter_mut().map(Box::as_mut).collect()
|
||||
}
|
||||
|
||||
pub fn last(&self) -> &UseStatementLast {
|
||||
&self.last
|
||||
}
|
||||
|
||||
pub fn last_mut(&mut self) -> &mut UseStatementLast {
|
||||
&mut self.last
|
||||
}
|
||||
|
||||
pub fn file_id(&self) -> usize {
|
||||
self.file_id
|
||||
}
|
||||
|
||||
pub fn range(&self) -> Range<usize> {
|
||||
self.range
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum UseStatementLast {
|
||||
Identifier(Box<Identifier>),
|
||||
Identifiers(Vec<Box<Identifier>>),
|
||||
Star,
|
||||
}
|
@ -1,4 +1,25 @@
|
||||
use crate::ast::*;
|
||||
use crate::ast::node::call_expression::*;
|
||||
use crate::ast::node::class::*;
|
||||
use crate::ast::node::closure::*;
|
||||
use crate::ast::node::compilation_unit::*;
|
||||
use crate::ast::node::d_string::*;
|
||||
use crate::ast::node::expression::*;
|
||||
use crate::ast::node::function::*;
|
||||
use crate::ast::node::generics::*;
|
||||
use crate::ast::node::implements_list::*;
|
||||
use crate::ast::node::interface::*;
|
||||
use crate::ast::node::level::*;
|
||||
use crate::ast::node::literal::*;
|
||||
use crate::ast::node::module::*;
|
||||
use crate::ast::node::named::Named;
|
||||
use crate::ast::node::names::*;
|
||||
use crate::ast::node::object_access::*;
|
||||
use crate::ast::node::operators::*;
|
||||
use crate::ast::node::statement::*;
|
||||
use crate::ast::node::tuple_arguments::*;
|
||||
use crate::ast::node::type_use::*;
|
||||
use crate::ast::node::use_statement::*;
|
||||
use crate::ast::unparse::Unparse;
|
||||
use crate::util::indent_writer::IndentWriter;
|
||||
use std::fmt::Debug;
|
||||
|
||||
@ -8,7 +29,7 @@ pub trait PrettyPrint {
|
||||
|
||||
impl PrettyPrint for Operator {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use Operator::*;
|
||||
use crate::ast::node::operators::Operator::*;
|
||||
match self {
|
||||
Binary(o) => o.pretty_print(writer),
|
||||
PrefixUnary(o) => o.pretty_print(writer),
|
||||
@ -20,24 +41,7 @@ impl PrettyPrint for Operator {
|
||||
impl PrettyPrint for BinaryOperator {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.write_indented("BinaryOperator(")?;
|
||||
use BinaryOperator::*;
|
||||
match self {
|
||||
Or => writer.write("||"),
|
||||
And => writer.write("&&"),
|
||||
EqualTo => writer.write("=="),
|
||||
NotEqualTo => writer.write("!="),
|
||||
Greater => writer.write(">"),
|
||||
Less => writer.write("<"),
|
||||
GreaterEqual => writer.write(">="),
|
||||
LessEqual => writer.write("<="),
|
||||
Add => writer.write("+"),
|
||||
Subtract => writer.write("-"),
|
||||
Multiply => writer.write("*"),
|
||||
Divide => writer.write("/"),
|
||||
Modulo => writer.write("%"),
|
||||
LeftShift => writer.write("<<"),
|
||||
RightShift => writer.write(">>"),
|
||||
}?;
|
||||
self.unparse(writer)?;
|
||||
writer.writeln(")")?;
|
||||
Ok(())
|
||||
}
|
||||
@ -46,15 +50,7 @@ impl PrettyPrint for BinaryOperator {
|
||||
impl PrettyPrint for PrefixUnaryOperator {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.write_indented("PrefixUnaryOperator(")?;
|
||||
use PrefixUnaryOperator::*;
|
||||
match self {
|
||||
Spread => writer.write("..."),
|
||||
BorrowMut => writer.write("&mut"),
|
||||
Borrow => writer.write("&"),
|
||||
Mut => writer.write("mut"),
|
||||
Not => writer.write("!"),
|
||||
Negative => writer.write("-"),
|
||||
}?;
|
||||
self.unparse(writer)?;
|
||||
writer.writeln(")")?;
|
||||
Ok(())
|
||||
}
|
||||
@ -63,11 +59,7 @@ impl PrettyPrint for PrefixUnaryOperator {
|
||||
impl PrettyPrint for SuffixUnaryOperator {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.write_indented("SuffixUnaryOperator(")?;
|
||||
use SuffixUnaryOperator::*;
|
||||
match self {
|
||||
PlusPlus => writer.write("++"),
|
||||
MinusMinus => writer.write("--"),
|
||||
}?;
|
||||
self.unparse(writer)?;
|
||||
writer.write(")")?;
|
||||
Ok(())
|
||||
}
|
||||
@ -75,7 +67,7 @@ impl PrettyPrint for SuffixUnaryOperator {
|
||||
|
||||
impl PrettyPrint for Identifier {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!("Identifier({})", self.name))
|
||||
writer.writeln_indented(&format!("Identifier({})", self.name()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +75,7 @@ impl PrettyPrint for FullyQualifiedName {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("FullyQualifiedName")?;
|
||||
writer.increase_indent();
|
||||
for identifier in &self.identifiers {
|
||||
for identifier in self.identifiers() {
|
||||
identifier.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -93,22 +85,28 @@ impl PrettyPrint for FullyQualifiedName {
|
||||
|
||||
impl PrettyPrint for TypeUse {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use TypeUse::*;
|
||||
use crate::ast::node::type_use::TypeUse::*;
|
||||
match self {
|
||||
Void => {
|
||||
writer.writeln_indented("TypeUse(Void)")?;
|
||||
Primitive(primitive_type_use) => {
|
||||
writer.writeln_indented("PrimitiveTypeUse")?;
|
||||
writer.increase_indent();
|
||||
primitive_type_use.pretty_print(writer)?;
|
||||
writer.decrease_indent()
|
||||
}
|
||||
InterfaceOrClass(t) => {
|
||||
writer.writeln_indented("InterfaceOrClassTypeUse")?;
|
||||
writer.increase_indent();
|
||||
t.pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
}
|
||||
Tuple(t) => {
|
||||
writer.writeln_indented("TupleTypeUse")?;
|
||||
writer.increase_indent();
|
||||
t.pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
}
|
||||
Function(t) => {
|
||||
writer.writeln_indented("FunctionTypeUse")?;
|
||||
writer.increase_indent();
|
||||
t.pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
@ -118,15 +116,43 @@ impl PrettyPrint for TypeUse {
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyPrint for PrimitiveTypeUse {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use crate::ast::node::type_use::PrimitiveTypeUse::*;
|
||||
match self {
|
||||
Byte => writer.writeln_indented("Byte"),
|
||||
Short => writer.writeln_indented("Short"),
|
||||
Char => writer.writeln_indented("Char"),
|
||||
Int => writer.writeln_indented("Int"),
|
||||
Long => writer.writeln_indented("Long"),
|
||||
Double => writer.writeln_indented("Double"),
|
||||
Bool => writer.writeln_indented("Bool"),
|
||||
String => writer.writeln_indented("String"),
|
||||
Array(generics) => {
|
||||
writer.writeln_indented("Array")?;
|
||||
if let Some(generics) = generics {
|
||||
writer.increase_indent();
|
||||
generics.pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Any => writer.writeln_indented("Any"),
|
||||
Void => writer.writeln_indented("Void"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PrettyPrint for InterfaceOrClassTypeUse {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"InterfaceOrClassTypeUse(borrow_count = {}, is_mutable = {})",
|
||||
self.borrow_count, self.is_mutable
|
||||
self.borrow_count(),
|
||||
self.is_mutable()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
self.fqn.pretty_print(writer)?;
|
||||
self.generics.pretty_print(writer)?;
|
||||
self.fqn().pretty_print(writer)?;
|
||||
self.generics().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -136,10 +162,11 @@ impl PrettyPrint for TupleTypeUse {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"TupleTypeUse(borrow_count = {}, is_mutable = {})",
|
||||
self.borrow_count, self.is_mutable
|
||||
self.borrow_count(),
|
||||
self.is_mutable()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
self.arguments.pretty_print(writer)?;
|
||||
self.arguments().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -149,15 +176,15 @@ impl PrettyPrint for FunctionTypeUse {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"FunctionTypeUse(borrow_count = {})",
|
||||
self.borrow_count
|
||||
self.borrow_count()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
if let Some(function_type_modifier) = &self.function_modifier {
|
||||
if let Some(function_type_modifier) = self.function_modifier() {
|
||||
function_type_modifier.pretty_print(writer)?;
|
||||
}
|
||||
self.generics.pretty_print(writer)?;
|
||||
self.parameters.pretty_print(writer)?;
|
||||
self.return_type.pretty_print(writer)?;
|
||||
self.generics().pretty_print(writer)?;
|
||||
self.parameters().pretty_print(writer)?;
|
||||
self.return_type().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -167,7 +194,7 @@ impl PrettyPrint for GenericArguments {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("GenericArguments")?;
|
||||
writer.increase_indent();
|
||||
for type_use in &self.0 {
|
||||
for type_use in self.arguments() {
|
||||
type_use.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -179,7 +206,7 @@ impl PrettyPrint for GenericParameters {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("GenericParameters")?;
|
||||
writer.increase_indent();
|
||||
for identifier in &self.0 {
|
||||
for identifier in self.identifiers() {
|
||||
identifier.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -191,7 +218,7 @@ impl PrettyPrint for TupleArguments {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("TupleArguments")?;
|
||||
writer.increase_indent();
|
||||
for type_use in &self.0 {
|
||||
for type_use in self.type_uses() {
|
||||
type_use.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -203,7 +230,7 @@ impl PrettyPrint for ImplementsList {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ImplementsList")?;
|
||||
writer.increase_indent();
|
||||
for type_use in &self.0 {
|
||||
for type_use in self.type_uses() {
|
||||
type_use.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -213,7 +240,7 @@ impl PrettyPrint for ImplementsList {
|
||||
|
||||
impl PrettyPrint for FunctionTypeModifier {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use FunctionTypeModifier::*;
|
||||
use crate::ast::node::function::FunctionTypeModifier::*;
|
||||
writer.writeln_indented(&format!(
|
||||
"FunctionTypeModifier({})",
|
||||
match self {
|
||||
@ -230,7 +257,7 @@ impl PrettyPrint for Parameters {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("Parameters")?;
|
||||
writer.increase_indent();
|
||||
for parameter in &self.0 {
|
||||
for parameter in self.parameters() {
|
||||
parameter.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -242,8 +269,8 @@ impl PrettyPrint for Parameter {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("Parameter")?;
|
||||
writer.increase_indent();
|
||||
self.identifier.pretty_print(writer)?;
|
||||
self.type_use.pretty_print(writer)?;
|
||||
self.identifier().pretty_print(writer)?;
|
||||
self.type_use().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -253,8 +280,8 @@ impl PrettyPrint for ReturnType {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ReturnType")?;
|
||||
writer.increase_indent();
|
||||
self.declared_type.pretty_print(writer)?;
|
||||
self.references.pretty_print(writer)?;
|
||||
self.declared_type().pretty_print(writer)?;
|
||||
self.references().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -264,7 +291,7 @@ impl PrettyPrint for References {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("References")?;
|
||||
writer.increase_indent();
|
||||
for identifier in &self.0 {
|
||||
for identifier in self.identifiers() {
|
||||
identifier.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -276,16 +303,16 @@ impl PrettyPrint for CompilationUnit {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("CompilationUnit")?;
|
||||
writer.increase_indent();
|
||||
if let Some(namespace) = &self.namespace {
|
||||
if let Some(namespace) = self.namespace() {
|
||||
writer.writeln_indented("Namespace")?;
|
||||
writer.increase_indent();
|
||||
namespace.pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
}
|
||||
for use_statement in &self.use_statements {
|
||||
for use_statement in self.use_statements() {
|
||||
use_statement.pretty_print(writer)?;
|
||||
}
|
||||
for declaration in &self.declarations {
|
||||
for declaration in self.declarations() {
|
||||
declaration.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -295,7 +322,7 @@ impl PrettyPrint for CompilationUnit {
|
||||
|
||||
impl PrettyPrint for ModuleLevelDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use ModuleLevelDeclaration::*;
|
||||
use crate::ast::node::level::ModuleLevelDeclaration::*;
|
||||
match self {
|
||||
Module(module) => module.pretty_print(writer),
|
||||
Interface(interface) => interface.pretty_print(writer),
|
||||
@ -308,7 +335,7 @@ impl PrettyPrint for ModuleLevelDeclaration {
|
||||
|
||||
impl PrettyPrint for InterfaceLevelDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use InterfaceLevelDeclaration::*;
|
||||
use crate::ast::node::level::InterfaceLevelDeclaration::*;
|
||||
match self {
|
||||
Module(module) => module.pretty_print(writer),
|
||||
Interface(interface) => interface.pretty_print(writer),
|
||||
@ -321,7 +348,7 @@ impl PrettyPrint for InterfaceLevelDeclaration {
|
||||
|
||||
impl PrettyPrint for ClassLevelDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use ClassLevelDeclaration::*;
|
||||
use crate::ast::node::level::ClassLevelDeclaration::*;
|
||||
match self {
|
||||
Module(module) => module.pretty_print(writer),
|
||||
Interface(interface) => interface.pretty_print(writer),
|
||||
@ -339,11 +366,11 @@ impl PrettyPrint for ModuleDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"ModuleDeclaration(is_public = {})",
|
||||
self.is_public
|
||||
self.is_public()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
self.identifier.pretty_print(writer)?;
|
||||
for declaration in &self.declarations {
|
||||
self.identifier().pretty_print(writer)?;
|
||||
for declaration in self.declarations() {
|
||||
declaration.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -355,13 +382,13 @@ impl PrettyPrint for InterfaceDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"InterfaceDeclaration(is_public = {})",
|
||||
self.is_public
|
||||
self.is_public()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
self.identifier.pretty_print(writer)?;
|
||||
self.generics.pretty_print(writer)?;
|
||||
self.implements.pretty_print(writer)?;
|
||||
for declaration in &self.declarations {
|
||||
self.identifier().pretty_print(writer)?;
|
||||
self.generics().pretty_print(writer)?;
|
||||
self.implements().pretty_print(writer)?;
|
||||
for declaration in self.declarations() {
|
||||
declaration.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -371,15 +398,18 @@ impl PrettyPrint for InterfaceDeclaration {
|
||||
|
||||
impl PrettyPrint for ClassDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!("ClassDeclaration(is_public = {})", self.is_public))?;
|
||||
writer.writeln_indented(&format!(
|
||||
"ClassDeclaration(is_public = {})",
|
||||
self.is_public()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
self.identifier.pretty_print(writer)?;
|
||||
self.generics.pretty_print(writer)?;
|
||||
if let Some(class_constructor) = &self.class_constructor {
|
||||
self.identifier().pretty_print(writer)?;
|
||||
self.generics().pretty_print(writer)?;
|
||||
if let Some(class_constructor) = self.class_constructor() {
|
||||
class_constructor.pretty_print(writer)?;
|
||||
}
|
||||
self.implements.pretty_print(writer)?;
|
||||
for declaration in &self.declarations {
|
||||
self.implements().pretty_print(writer)?;
|
||||
for declaration in self.declarations() {
|
||||
declaration.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -391,17 +421,17 @@ impl PrettyPrint for FunctionDefinition {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"FunctionDefinition(is_public = {})",
|
||||
self.is_public
|
||||
self.is_public()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
if let Some(modifier) = &self.modifier {
|
||||
if let Some(modifier) = self.modifier() {
|
||||
modifier.pretty_print(writer)?;
|
||||
}
|
||||
self.generics.pretty_print(writer)?;
|
||||
self.identifier.pretty_print(writer)?;
|
||||
self.parameters.pretty_print(writer)?;
|
||||
self.return_type.pretty_print(writer)?;
|
||||
self.body.pretty_print(writer)?;
|
||||
self.generics().pretty_print(writer)?;
|
||||
self.identifier().pretty_print(writer)?;
|
||||
self.parameters().pretty_print(writer)?;
|
||||
self.return_type().pretty_print(writer)?;
|
||||
self.body().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -411,17 +441,17 @@ impl PrettyPrint for OperatorFunctionDefinition {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"OperatorFunctionDefinition(is_public = {})",
|
||||
self.is_public
|
||||
self.is_public()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
if let Some(modifier) = &self.modifier {
|
||||
if let Some(modifier) = self.modifier() {
|
||||
modifier.pretty_print(writer)?;
|
||||
}
|
||||
self.generics.pretty_print(writer)?;
|
||||
self.operator.pretty_print(writer)?;
|
||||
self.parameters.pretty_print(writer)?;
|
||||
self.return_type.pretty_print(writer)?;
|
||||
self.body.pretty_print(writer)?;
|
||||
self.generics().pretty_print(writer)?;
|
||||
self.operator().pretty_print(writer)?;
|
||||
self.parameters().pretty_print(writer)?;
|
||||
self.return_type().pretty_print(writer)?;
|
||||
self.body().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -431,16 +461,16 @@ impl PrettyPrint for PlatformFunctionDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"PlatformFunctionDeclaration(is_public = {})",
|
||||
self.is_public
|
||||
self.is_public()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
if let Some(modifier) = &self.modifier {
|
||||
if let Some(modifier) = self.modifier() {
|
||||
modifier.pretty_print(writer)?;
|
||||
}
|
||||
self.generics.pretty_print(writer)?;
|
||||
self.identifier.pretty_print(writer)?;
|
||||
self.parameters.pretty_print(writer)?;
|
||||
self.return_type.pretty_print(writer)?;
|
||||
self.generics().pretty_print(writer)?;
|
||||
self.identifier().pretty_print(writer)?;
|
||||
self.parameters().pretty_print(writer)?;
|
||||
self.return_type().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -450,14 +480,14 @@ impl PrettyPrint for InterfaceFunctionDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("InterfaceFunctionDeclaration")?;
|
||||
writer.increase_indent();
|
||||
if let Some(modifier) = &self.modifier {
|
||||
if let Some(modifier) = self.modifier() {
|
||||
modifier.pretty_print(writer)?;
|
||||
}
|
||||
self.generics.pretty_print(writer)?;
|
||||
self.identifier.pretty_print(writer)?;
|
||||
self.parameters.pretty_print(writer)?;
|
||||
self.return_type.pretty_print(writer)?;
|
||||
if let Some(body) = &self.body {
|
||||
self.generics().pretty_print(writer)?;
|
||||
self.identifier().pretty_print(writer)?;
|
||||
self.parameters().pretty_print(writer)?;
|
||||
self.return_type().pretty_print(writer)?;
|
||||
if let Some(body) = self.body() {
|
||||
body.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -469,14 +499,14 @@ impl PrettyPrint for InterfaceOperatorFunctionDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("InterfaceOperatorFunctionDeclaration")?;
|
||||
writer.increase_indent();
|
||||
if let Some(modifier) = &self.modifier {
|
||||
if let Some(modifier) = self.modifier() {
|
||||
modifier.pretty_print(writer)?;
|
||||
}
|
||||
self.generics.pretty_print(writer)?;
|
||||
self.operator.pretty_print(writer)?;
|
||||
self.parameters.pretty_print(writer)?;
|
||||
self.return_type.pretty_print(writer)?;
|
||||
if let Some(body) = &self.body {
|
||||
self.generics().pretty_print(writer)?;
|
||||
self.operator().pretty_print(writer)?;
|
||||
self.parameters().pretty_print(writer)?;
|
||||
self.return_type().pretty_print(writer)?;
|
||||
if let Some(body) = self.body() {
|
||||
body.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -486,7 +516,7 @@ impl PrettyPrint for InterfaceOperatorFunctionDeclaration {
|
||||
|
||||
impl PrettyPrint for FunctionModifier {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use FunctionModifier::*;
|
||||
use crate::ast::node::function::FunctionModifier::*;
|
||||
writer.writeln_indented(&format!(
|
||||
"FunctionModifier({})",
|
||||
match self {
|
||||
@ -502,7 +532,7 @@ impl PrettyPrint for FunctionModifier {
|
||||
|
||||
impl PrettyPrint for FunctionBody {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use FunctionBody::*;
|
||||
use crate::ast::node::function::FunctionBody::*;
|
||||
match self {
|
||||
Equals(expression) => {
|
||||
writer.writeln_indented("EqualsFunctionBody")?;
|
||||
@ -531,7 +561,7 @@ impl PrettyPrint for ClassConstructor {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ClassConstructor")?;
|
||||
writer.increase_indent();
|
||||
for constructor_parameter in &self.0 {
|
||||
for constructor_parameter in self.parameters() {
|
||||
constructor_parameter.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -541,7 +571,7 @@ impl PrettyPrint for ClassConstructor {
|
||||
|
||||
impl PrettyPrint for ClassConstructorParameter {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use ClassConstructorParameter::*;
|
||||
use crate::ast::node::class::ClassConstructorParameter::*;
|
||||
match self {
|
||||
Property(property) => {
|
||||
writer.writeln_indented("PropertyConstructorParameter")?;
|
||||
@ -564,11 +594,11 @@ impl PrettyPrint for PropertyDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"PropertyDeclaration(is_mutable = {})",
|
||||
self.is_mutable
|
||||
self.is_mutable()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
self.identifier.pretty_print(writer)?;
|
||||
self.declared_type.pretty_print(writer)?;
|
||||
self.identifier().pretty_print(writer)?;
|
||||
self.declared_type().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -578,11 +608,11 @@ impl PrettyPrint for FieldDeclaration {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"FieldDeclaration(is_mutable = {})",
|
||||
self.is_mutable
|
||||
self.is_mutable()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
self.identifier.pretty_print(writer)?;
|
||||
self.declared_type.pretty_print(writer)?;
|
||||
self.identifier().pretty_print(writer)?;
|
||||
self.declared_type().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -592,10 +622,10 @@ impl PrettyPrint for UseStatement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("UseStatement")?;
|
||||
writer.increase_indent();
|
||||
for identifier in &self.identifiers {
|
||||
for identifier in self.identifiers() {
|
||||
identifier.pretty_print(writer)?;
|
||||
}
|
||||
self.last.pretty_print(writer)?;
|
||||
self.last().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -606,12 +636,12 @@ impl PrettyPrint for UseStatementLast {
|
||||
writer.writeln_indented("UseStatementLast")?;
|
||||
writer.increase_indent();
|
||||
match self {
|
||||
UseStatementLast::Identifier(i) => i.borrow().pretty_print(writer)?,
|
||||
UseStatementLast::Identifier(i) => i.pretty_print(writer)?,
|
||||
UseStatementLast::Identifiers(is) => {
|
||||
for i in is {
|
||||
i.borrow().pretty_print(writer)?;
|
||||
i.pretty_print(writer)?;
|
||||
}
|
||||
},
|
||||
}
|
||||
UseStatementLast::Star => {
|
||||
writer.writeln_indented("Star")?;
|
||||
}
|
||||
@ -625,10 +655,10 @@ impl PrettyPrint for BlockStatement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("BlockStatement")?;
|
||||
writer.increase_indent();
|
||||
for statement in &self.statements {
|
||||
for statement in self.statements() {
|
||||
statement.pretty_print(writer)?;
|
||||
}
|
||||
if let Some(expression) = &self.expression {
|
||||
if let Some(expression) = self.expression() {
|
||||
expression.pretty_print(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
@ -637,7 +667,7 @@ impl PrettyPrint for BlockStatement {
|
||||
|
||||
impl PrettyPrint for Statement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use Statement::*;
|
||||
use crate::ast::node::statement::Statement::*;
|
||||
match self {
|
||||
BlockStatement(block_statement) => block_statement.pretty_print(writer),
|
||||
VariableDeclarationStatement(s) => s.pretty_print(writer),
|
||||
@ -656,14 +686,14 @@ impl PrettyPrint for VariableDeclarationStatement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"VariableDeclarationStatement(is_mutable = {})",
|
||||
self.is_mutable
|
||||
self.is_mutable()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
self.identifier.pretty_print(writer)?;
|
||||
if let Some(declared_type) = &self.declared_type {
|
||||
self.identifier().pretty_print(writer)?;
|
||||
if let Some(declared_type) = self.declared_type() {
|
||||
declared_type.pretty_print(writer)?;
|
||||
}
|
||||
if let Some(initializer) = &self.initializer {
|
||||
if let Some(initializer) = self.initializer() {
|
||||
initializer.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -675,8 +705,8 @@ impl PrettyPrint for AssignStatement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("AssignStatement")?;
|
||||
writer.increase_indent();
|
||||
self.lhs.pretty_print(writer)?;
|
||||
self.rhs.pretty_print(writer)?;
|
||||
self.lhs().pretty_print(writer)?;
|
||||
self.rhs().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -686,7 +716,7 @@ impl PrettyPrint for CallStatement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("CallStatement")?;
|
||||
writer.increase_indent();
|
||||
self.0.pretty_print(writer)?;
|
||||
self.expression().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -695,7 +725,7 @@ impl PrettyPrint for CallStatement {
|
||||
impl PrettyPrint for ReturnStatement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ReturnStatement")?;
|
||||
if let Some(expression) = &self.0 {
|
||||
if let Some(expression) = self.expression() {
|
||||
writer.increase_indent();
|
||||
expression.pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
@ -709,8 +739,8 @@ impl PrettyPrint for IfStatement {
|
||||
writer.writeln_indented("IfStatement")?;
|
||||
writer.increase_indent();
|
||||
writer.increase_indent();
|
||||
self.condition.pretty_print(writer)?;
|
||||
self.then_block.pretty_print(writer)?;
|
||||
self.condition().pretty_print(writer)?;
|
||||
self.then_block().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -720,9 +750,9 @@ impl PrettyPrint for IfElseStatement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("IfElseStatement")?;
|
||||
writer.increase_indent();
|
||||
self.if_statement.pretty_print(writer)?;
|
||||
self.else_ifs.pretty_print(writer)?;
|
||||
if let Some(else_block) = &self.else_block {
|
||||
self.if_statement().pretty_print(writer)?;
|
||||
self.else_ifs().pretty_print(writer)?;
|
||||
if let Some(else_block) = self.else_block() {
|
||||
else_block.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -734,7 +764,7 @@ impl PrettyPrint for ElseIfs {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ElseIfs")?;
|
||||
writer.increase_indent();
|
||||
for if_statement in &self.0 {
|
||||
for if_statement in self.if_statements() {
|
||||
if_statement.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -746,7 +776,7 @@ impl PrettyPrint for ElseBlock {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ElseBlock")?;
|
||||
writer.increase_indent();
|
||||
self.0.pretty_print(writer)?;
|
||||
self.block_statement().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -756,8 +786,8 @@ impl PrettyPrint for WhileStatement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("WhileStatement")?;
|
||||
writer.increase_indent();
|
||||
self.condition.pretty_print(writer)?;
|
||||
self.body.pretty_print(writer)?;
|
||||
self.condition().pretty_print(writer)?;
|
||||
self.body().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -767,9 +797,9 @@ impl PrettyPrint for ForStatement {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ForStatement")?;
|
||||
writer.increase_indent();
|
||||
self.variable.pretty_print(writer)?;
|
||||
self.iterator.pretty_print(writer)?;
|
||||
self.body.pretty_print(writer)?;
|
||||
self.variable().pretty_print(writer)?;
|
||||
self.iterator().pretty_print(writer)?;
|
||||
self.body().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -777,7 +807,7 @@ impl PrettyPrint for ForStatement {
|
||||
|
||||
impl PrettyPrint for Expression {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use Expression::*;
|
||||
use crate::ast::node::expression::Expression::*;
|
||||
match self {
|
||||
Ternary(e) => e.pretty_print(writer),
|
||||
Binary(e) => e.pretty_print(writer),
|
||||
@ -785,7 +815,7 @@ impl PrettyPrint for Expression {
|
||||
UnarySuffix(e) => e.pretty_print(writer),
|
||||
Call(e) => e.pretty_print(writer),
|
||||
ObjectAccess(o) => o.pretty_print(writer),
|
||||
Literal(literial) => literial.pretty_print(writer),
|
||||
Literal(literal) => literal.pretty_print(writer),
|
||||
FullyQualifiedName(fqn) => fqn.pretty_print(writer),
|
||||
Closure(closure) => closure.pretty_print(writer),
|
||||
}
|
||||
@ -796,9 +826,9 @@ impl PrettyPrint for TernaryExpression {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("TernaryExpression")?;
|
||||
writer.increase_indent();
|
||||
self.condition.pretty_print(writer)?;
|
||||
self.true_expression.pretty_print(writer)?;
|
||||
self.false_expression.pretty_print(writer)?;
|
||||
self.condition().pretty_print(writer)?;
|
||||
self.true_expression().pretty_print(writer)?;
|
||||
self.false_expression().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -808,9 +838,9 @@ impl PrettyPrint for BinaryExpression {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("BinaryExpression")?;
|
||||
writer.increase_indent();
|
||||
self.left.pretty_print(writer)?;
|
||||
self.operator.pretty_print(writer)?;
|
||||
self.right.pretty_print(writer)?;
|
||||
self.left().pretty_print(writer)?;
|
||||
self.operator().pretty_print(writer)?;
|
||||
self.right().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -820,8 +850,8 @@ impl PrettyPrint for PrefixExpression {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("PrefixExpression")?;
|
||||
writer.increase_indent();
|
||||
self.operator.pretty_print(writer)?;
|
||||
self.expression.pretty_print(writer)?;
|
||||
self.operator().pretty_print(writer)?;
|
||||
self.expression().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -831,8 +861,8 @@ impl PrettyPrint for SuffixExpression {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("SuffixExpression")?;
|
||||
writer.increase_indent();
|
||||
self.expression.pretty_print(writer)?;
|
||||
self.operator.pretty_print(writer)?;
|
||||
self.expression().pretty_print(writer)?;
|
||||
self.operator().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -842,11 +872,11 @@ impl PrettyPrint for CallExpression {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("CallExpression")?;
|
||||
writer.increase_indent();
|
||||
self.callee.pretty_print(writer)?;
|
||||
if let Some(turbo_fish) = &self.turbo_fish {
|
||||
self.callee().pretty_print(writer)?;
|
||||
if let Some(turbo_fish) = self.turbo_fish() {
|
||||
turbo_fish.pretty_print(writer)?;
|
||||
}
|
||||
self.arguments.pretty_print(writer)?;
|
||||
self.arguments().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -856,7 +886,7 @@ impl PrettyPrint for TurboFish {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("TurboFish")?;
|
||||
writer.increase_indent();
|
||||
self.0.pretty_print(writer)?;
|
||||
self.generics().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -866,7 +896,7 @@ impl PrettyPrint for CallArguments {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("CallArguments")?;
|
||||
writer.increase_indent();
|
||||
for call_argument in &self.0 {
|
||||
for call_argument in self.arguments() {
|
||||
call_argument.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -878,7 +908,7 @@ impl PrettyPrint for CallArgument {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("CallArgument")?;
|
||||
writer.increase_indent();
|
||||
self.0.pretty_print(writer)?;
|
||||
self.expression().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -886,22 +916,22 @@ impl PrettyPrint for CallArgument {
|
||||
|
||||
impl PrettyPrint for Closure {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!("Closure(is_move = {})", self.is_move))?;
|
||||
writer.writeln_indented(&format!("Closure(is_move = {})", self.is_move()))?;
|
||||
writer.increase_indent();
|
||||
if let Some(modifier) = &self.modifier {
|
||||
if let Some(modifier) = self.modifier() {
|
||||
modifier.pretty_print(writer)?;
|
||||
}
|
||||
self.captures.pretty_print(writer)?;
|
||||
self.parameters.pretty_print(writer)?;
|
||||
if !self.statements.is_empty() {
|
||||
self.captures().pretty_print(writer)?;
|
||||
self.parameters().pretty_print(writer)?;
|
||||
if !self.statements().is_empty() {
|
||||
writer.writeln_indented("ClosureStatements")?;
|
||||
writer.increase_indent();
|
||||
for statement in &self.statements {
|
||||
for statement in self.statements() {
|
||||
statement.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
}
|
||||
if let Some(expression) = &self.expression {
|
||||
if let Some(expression) = self.expression() {
|
||||
expression.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -925,7 +955,7 @@ impl PrettyPrint for ClosureCaptures {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ClosureCaptures")?;
|
||||
writer.increase_indent();
|
||||
for capture in &self.0 {
|
||||
for capture in self.captures() {
|
||||
capture.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -937,10 +967,11 @@ impl PrettyPrint for ClosureCapture {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented(&format!(
|
||||
"ClosureCapture(borrow_count = {}, is_mutable = {})",
|
||||
self.borrow_count, self.is_mutable
|
||||
self.borrow_count(),
|
||||
self.is_mutable()
|
||||
))?;
|
||||
writer.increase_indent();
|
||||
self.identifier.pretty_print(writer)?;
|
||||
self.identifier().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -950,7 +981,7 @@ impl PrettyPrint for ClosureParameters {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ClosureParameters")?;
|
||||
writer.increase_indent();
|
||||
for parameter in &self.0 {
|
||||
for parameter in self.parameters() {
|
||||
parameter.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -962,8 +993,8 @@ impl PrettyPrint for ClosureParameter {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ClosureParameter")?;
|
||||
writer.increase_indent();
|
||||
self.identifier.pretty_print(writer)?;
|
||||
if let Some(type_use) = &self.type_use {
|
||||
self.identifier().pretty_print(writer)?;
|
||||
if let Some(type_use) = self.type_use() {
|
||||
type_use.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -975,8 +1006,8 @@ impl PrettyPrint for ObjectAccess {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ObjectAccess")?;
|
||||
writer.increase_indent();
|
||||
self.receiver.pretty_print(writer)?;
|
||||
self.navigations.pretty_print(writer)?;
|
||||
self.receiver().pretty_print(writer)?;
|
||||
self.navigations().pretty_print(writer)?;
|
||||
writer.decrease_indent();
|
||||
Ok(())
|
||||
}
|
||||
@ -986,7 +1017,7 @@ impl PrettyPrint for ObjectNavigations {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("ObjectNavigations")?;
|
||||
writer.increase_indent();
|
||||
for object_navigation in &self.0 {
|
||||
for object_navigation in self.navigations() {
|
||||
object_navigation.pretty_print(writer)?;
|
||||
}
|
||||
writer.decrease_indent();
|
||||
@ -996,7 +1027,7 @@ impl PrettyPrint for ObjectNavigations {
|
||||
|
||||
impl PrettyPrint for ObjectNavigation {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use ObjectNavigation::*;
|
||||
use crate::ast::node::object_access::ObjectNavigation::*;
|
||||
match self {
|
||||
Index(e) => {
|
||||
writer.writeln_indented("Index")?;
|
||||
@ -1017,7 +1048,7 @@ impl PrettyPrint for ObjectNavigation {
|
||||
|
||||
impl PrettyPrint for Literal {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
use Literal::*;
|
||||
use crate::ast::node::literal::Literal::*;
|
||||
match self {
|
||||
Integer(i) => writer.writeln_indented(&format!("Integer({})", i)),
|
||||
Long(l) => writer.writeln_indented(&format!("Long({})", l)),
|
||||
@ -1035,7 +1066,7 @@ impl PrettyPrint for DString {
|
||||
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||
writer.writeln_indented("DString")?;
|
||||
writer.increase_indent();
|
||||
for part in &self.0 {
|
||||
for part in self.parts() {
|
||||
part.pretty_print(writer)?;
|
||||
}
|
||||
Ok(())
|
||||
|
File diff suppressed because it is too large
Load Diff
145
src/ast/walk.rs
Normal file
145
src/ast/walk.rs
Normal file
@ -0,0 +1,145 @@
|
||||
use crate::ast::children::{NodeInner, NodeRef};
|
||||
|
||||
pub fn walk_depth_first<F>(node: &dyn NodeInner, f: &mut F)
|
||||
where
|
||||
F: FnMut(NodeRef),
|
||||
{
|
||||
use NodeRef::*;
|
||||
for child in node.children() {
|
||||
match child {
|
||||
Identifier(identifier) => walk_depth_first(identifier, f),
|
||||
FullyQualifiedName(fqn) => {
|
||||
walk_depth_first(fqn, f);
|
||||
}
|
||||
TypeUse(type_use) => walk_depth_first(type_use, f),
|
||||
PrimitiveTypeUse(primitive_type_use) => walk_depth_first(primitive_type_use, f),
|
||||
InterfaceOrClassTypeUse(interface_or_class_type_use) => {
|
||||
walk_depth_first(interface_or_class_type_use, f)
|
||||
}
|
||||
TupleTypeUse(tuple_type_use) => walk_depth_first(tuple_type_use, f),
|
||||
FunctionTypeUse(function_type_use) => walk_depth_first(function_type_use, f),
|
||||
GenericArguments(generic_arguments) => walk_depth_first(generic_arguments, f),
|
||||
GenericParameters(generic_parameters) => walk_depth_first(generic_parameters, f),
|
||||
TupleArguments(tuple_arguments) => walk_depth_first(tuple_arguments, f),
|
||||
ImplementsList(implements) => walk_depth_first(implements, f),
|
||||
Parameters(parameters) => walk_depth_first(parameters, f),
|
||||
Parameter(parameter) => walk_depth_first(parameter, f),
|
||||
ReturnType(return_type) => walk_depth_first(return_type, f),
|
||||
References(references) => walk_depth_first(references, f),
|
||||
UseStatement(use_statement) => walk_depth_first(use_statement, f),
|
||||
CompilationUnit(compilation_unit) => walk_depth_first(compilation_unit, f),
|
||||
ModuleLevelDeclaration(module_level_declaration) => {
|
||||
walk_depth_first(module_level_declaration, f)
|
||||
}
|
||||
InterfaceLevelDeclaration(interface_level_declaration) => {
|
||||
walk_depth_first(interface_level_declaration, f)
|
||||
}
|
||||
ClassLevelDeclaration(class_level_declaration) => {
|
||||
walk_depth_first(class_level_declaration, f)
|
||||
}
|
||||
ModuleDeclaration(module_declaration) => walk_depth_first(module_declaration, f),
|
||||
InterfaceDeclaration(interface_declaration) => {
|
||||
walk_depth_first(interface_declaration, f)
|
||||
}
|
||||
ClassDeclaration(class_declaration) => walk_depth_first(class_declaration, f),
|
||||
FunctionDefinition(function_definition) => walk_depth_first(function_definition, f),
|
||||
OperatorFunctionDefinition(operator_function_definition) => {
|
||||
walk_depth_first(operator_function_definition, f)
|
||||
}
|
||||
PlatformFunctionDeclaration(platform_function_declaration) => {
|
||||
walk_depth_first(platform_function_declaration, f)
|
||||
}
|
||||
InterfaceFunctionDeclaration(interface_function_declaration) => {
|
||||
walk_depth_first(interface_function_declaration, f)
|
||||
}
|
||||
InterfaceOperatorFunctionDeclaration(interface_operator_function_declaration) => {
|
||||
walk_depth_first(interface_operator_function_declaration, f)
|
||||
}
|
||||
FunctionBody(function_body) => walk_depth_first(function_body, f),
|
||||
ClassConstructor(class_constructor) => walk_depth_first(class_constructor, f),
|
||||
ClassConstructorParameter(class_constructor_parameter) => {
|
||||
walk_depth_first(class_constructor_parameter, f)
|
||||
}
|
||||
PropertyDeclaration(property_declaration) => walk_depth_first(property_declaration, f),
|
||||
FieldDeclaration(field_declaration) => walk_depth_first(field_declaration, f),
|
||||
BlockStatement(block) => walk_depth_first(block, f),
|
||||
Statement(statement) => walk_depth_first(statement, f),
|
||||
VariableDeclarationStatement(variable_declaration) => {
|
||||
walk_depth_first(variable_declaration, f)
|
||||
}
|
||||
AssignStatement(assign_statement) => walk_depth_first(assign_statement, f),
|
||||
CallStatement(call_statement) => walk_depth_first(call_statement, f),
|
||||
ReturnStatement(return_statement) => walk_depth_first(return_statement, f),
|
||||
IfStatement(if_statement) => walk_depth_first(if_statement, f),
|
||||
IfElseStatement(if_else_statement) => walk_depth_first(if_else_statement, f),
|
||||
ElseIfs(else_ifs) => walk_depth_first(else_ifs, f),
|
||||
ElseBlock(else_block) => walk_depth_first(else_block, f),
|
||||
WhileStatement(while_statement) => walk_depth_first(while_statement, f),
|
||||
ForStatement(for_statement) => walk_depth_first(for_statement, f),
|
||||
Expression(expression) => walk_depth_first(expression, f),
|
||||
TernaryExpression(ternary_expression) => walk_depth_first(ternary_expression, f),
|
||||
BinaryExpression(binary_expression) => walk_depth_first(binary_expression, f),
|
||||
PrefixExpression(prefix_expression) => walk_depth_first(prefix_expression, f),
|
||||
SuffixExpression(suffix_expression) => walk_depth_first(suffix_expression, f),
|
||||
CallExpression(call_expression) => walk_depth_first(call_expression, f),
|
||||
TurboFish(turbo_fish) => walk_depth_first(turbo_fish, f),
|
||||
CallArguments(call_arguments) => walk_depth_first(call_arguments, f),
|
||||
CallArgument(call_argument) => walk_depth_first(call_argument, f),
|
||||
Closure(closure) => walk_depth_first(closure, f),
|
||||
ClosureCaptures(closure_captures) => walk_depth_first(closure_captures, f),
|
||||
ClosureCapture(closure_capture) => walk_depth_first(closure_capture, f),
|
||||
ClosureParameters(closure_parameters) => walk_depth_first(closure_parameters, f),
|
||||
ClosureParameter(closure_parameter) => walk_depth_first(closure_parameter, f),
|
||||
ObjectAccess(object_access) => walk_depth_first(object_access, f),
|
||||
ObjectNavigations(object_navigations) => walk_depth_first(object_navigations, f),
|
||||
ObjectNavigation(object_navigations) => walk_depth_first(object_navigations, f),
|
||||
Literal(literal) => walk_depth_first(literal, f),
|
||||
DString(d_string) => walk_depth_first(d_string, f),
|
||||
DStringPart(d_string_part) => walk_depth_first(d_string_part, f),
|
||||
}
|
||||
}
|
||||
f(node.as_node_ref());
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ast::build::build_ast;
|
||||
use crate::ast::children::NodeRef;
|
||||
use crate::ast::walk::walk_depth_first;
|
||||
use crate::parser::{DeimosParser, Rule};
|
||||
use indoc::indoc;
|
||||
use pest::Parser;
|
||||
|
||||
#[test]
|
||||
fn collect_identifiers() {
|
||||
let parse_result = DeimosParser::parse(
|
||||
Rule::CompilationUnit,
|
||||
indoc! {"
|
||||
ns greeter;
|
||||
|
||||
class Greeter {}
|
||||
|
||||
fn main() {
|
||||
let greeter = Greeter();
|
||||
}
|
||||
"},
|
||||
);
|
||||
match parse_result {
|
||||
Ok(cu_pairs) => {
|
||||
let cu = build_ast("greeter.dm", 0, cu_pairs.into_iter().next().unwrap());
|
||||
let mut identifier_count = 0;
|
||||
walk_depth_first(&cu, &mut |node_ref| match node_ref {
|
||||
NodeRef::Identifier(identifier) => {
|
||||
dbg!(identifier);
|
||||
identifier_count += 1;
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
assert_eq!(identifier_count, 5);
|
||||
}
|
||||
Err(err) => {
|
||||
panic!("{}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#![feature(new_range_api)]
|
||||
#![allow(warnings)]
|
||||
extern crate core;
|
||||
|
||||
pub mod ast;
|
||||
pub mod diagnostic;
|
||||
pub mod module;
|
||||
|
@ -1,11 +1,27 @@
|
||||
use crate::ast::named::Named;
|
||||
use crate::ast::*;
|
||||
use crate::ast::node::call_expression::*;
|
||||
use crate::ast::node::class::*;
|
||||
use crate::ast::node::closure::*;
|
||||
use crate::ast::node::compilation_unit::*;
|
||||
use crate::ast::node::d_string::*;
|
||||
use crate::ast::node::expression::*;
|
||||
use crate::ast::node::function::*;
|
||||
use crate::ast::node::generics::*;
|
||||
use crate::ast::node::implements_list::*;
|
||||
use crate::ast::node::interface::*;
|
||||
use crate::ast::node::level::*;
|
||||
use crate::ast::node::literal::*;
|
||||
use crate::ast::node::module::*;
|
||||
use crate::ast::node::named::Named;
|
||||
use crate::ast::node::names::*;
|
||||
use crate::ast::node::object_access::*;
|
||||
use crate::ast::node::statement::*;
|
||||
use crate::ast::node::type_use::*;
|
||||
use crate::ast::node::use_statement::*;
|
||||
use crate::diagnostic::DmDiagnostic;
|
||||
use crate::name_analysis::fqn_context::FqnContext;
|
||||
use crate::name_analysis::symbol::*;
|
||||
use crate::name_analysis::symbol_table::{SymbolInsertError, SymbolTable};
|
||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||
use std::cell::RefCell;
|
||||
use std::ops::DerefMut;
|
||||
use std::range::Range;
|
||||
use std::rc::Rc;
|
||||
@ -106,9 +122,9 @@ fn gather_interface_or_class_type_use(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_fully_qualified_name(&mut interface_or_class_type_use.fqn, symbol_table);
|
||||
gather_fully_qualified_name(interface_or_class_type_use.fqn_mut(), symbol_table);
|
||||
gather_generic_arguments(
|
||||
&mut interface_or_class_type_use.generics,
|
||||
interface_or_class_type_use.generics_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -121,7 +137,7 @@ fn gather_tuple_type_use(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for generic_argument in &mut tuple_type_use.arguments.0 {
|
||||
for generic_argument in tuple_type_use.arguments_mut().type_uses_mut() {
|
||||
gather_type_use(generic_argument, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -133,15 +149,15 @@ fn gather_function_type_use(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
symbol_table.push_scope("FunctionTypeUseScope");
|
||||
gather_generic_parameters(&mut function_type_use.generics, symbol_table, diagnostics);
|
||||
gather_generic_parameters(function_type_use.generics_mut(), symbol_table, diagnostics);
|
||||
gather_parameters(
|
||||
&mut function_type_use.parameters,
|
||||
function_type_use.parameters_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_return_type(
|
||||
&mut function_type_use.return_type,
|
||||
function_type_use.return_type_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -157,7 +173,7 @@ fn gather_generic_arguments(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for argument in &mut generic_arguments.0 {
|
||||
for argument in generic_arguments.arguments_mut() {
|
||||
gather_type_use(argument, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -169,7 +185,7 @@ fn gather_generic_parameters(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for identifier in &mut generic_parameters.0 {
|
||||
for identifier in generic_parameters.identifiers_mut() {
|
||||
let insert_result =
|
||||
symbol_table.insert_type_symbol(TypeSymbol::Generic(GenericTypeSymbol::new(
|
||||
&identifier.name(),
|
||||
@ -199,7 +215,7 @@ fn gather_implements_list(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for type_use in &mut implements_list.0 {
|
||||
for type_use in implements_list.type_uses_mut() {
|
||||
gather_type_use(type_use, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -213,7 +229,7 @@ fn gather_parameters(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) -> Option<Vec<Rc<ParameterSymbol>>> {
|
||||
parameters
|
||||
.0
|
||||
.parameters_mut()
|
||||
.iter_mut()
|
||||
.map(|parameter| gather_parameter(parameter, symbol_table, fqn_context, diagnostics))
|
||||
.collect()
|
||||
@ -225,21 +241,21 @@ fn gather_parameter(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) -> Option<Rc<ParameterSymbol>> {
|
||||
let parameter_name = parameter.identifier.name();
|
||||
let parameter_name = parameter.identifier().name();
|
||||
|
||||
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
|
||||
¶meter_name,
|
||||
Some(¶meter.identifier),
|
||||
Some(¶meter.identifier()),
|
||||
));
|
||||
|
||||
match insert_result {
|
||||
Ok(parameter_symbol) => {
|
||||
parameter
|
||||
.identifier
|
||||
.identifier_mut()
|
||||
.set_scope_id(symbol_table.current_scope_id());
|
||||
|
||||
gather_type_use(
|
||||
&mut parameter.type_use,
|
||||
parameter.type_use_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -250,8 +266,8 @@ fn gather_parameter(
|
||||
handle_insert_error(
|
||||
err,
|
||||
¶meter_name,
|
||||
parameter.identifier.file_id(),
|
||||
parameter.identifier.range(),
|
||||
parameter.identifier().file_id(),
|
||||
parameter.identifier().range(),
|
||||
"function/variable",
|
||||
diagnostics,
|
||||
);
|
||||
@ -269,18 +285,18 @@ fn gather_return_type(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_type_use(
|
||||
&mut return_type.declared_type,
|
||||
return_type.declared_type_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
gather_references(&mut return_type.references, symbol_table);
|
||||
gather_references(return_type.references_mut(), symbol_table);
|
||||
}
|
||||
|
||||
/* References */
|
||||
|
||||
fn gather_references(references: &mut References, symbol_table: &mut SymbolTable) {
|
||||
for identifier in &mut references.0 {
|
||||
for identifier in references.identifiers_mut() {
|
||||
gather_identifier(identifier, symbol_table);
|
||||
}
|
||||
}
|
||||
@ -293,15 +309,15 @@ pub(super) fn gather_compilation_unit(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let mut fqn_context = FqnContext::new();
|
||||
if let Some(namespace) = &compilation_unit.namespace {
|
||||
if let Some(namespace) = compilation_unit.namespace() {
|
||||
fqn_context.push(&namespace.name());
|
||||
}
|
||||
|
||||
symbol_table.push_scope(&format!("FileScope({})", compilation_unit.file_name));
|
||||
for use_statement in &mut compilation_unit.use_statements {
|
||||
symbol_table.push_scope(&format!("FileScope({})", compilation_unit.file_name()));
|
||||
for use_statement in compilation_unit.use_statements_mut() {
|
||||
gather_use_statement(use_statement, symbol_table, &mut fqn_context, diagnostics)
|
||||
}
|
||||
for declaration in &mut compilation_unit.declarations {
|
||||
for declaration in compilation_unit.declarations_mut() {
|
||||
gather_module_level_declaration(declaration, symbol_table, &mut fqn_context, diagnostics);
|
||||
}
|
||||
symbol_table.pop_scope();
|
||||
@ -313,34 +329,28 @@ pub(super) fn gather_compilation_unit(
|
||||
fn handle_use_statement_import(
|
||||
symbol_table: &mut SymbolTable,
|
||||
base_name: &str,
|
||||
identifier: Rc<RefCell<Identifier>>,
|
||||
identifier: &mut Identifier,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let borrowed_identifier = identifier.borrow();
|
||||
let declared_name = borrowed_identifier.name().to_string();
|
||||
let declared_name = identifier.name().to_string();
|
||||
let insert_result = symbol_table.insert_use_statement_symbol(UseStatementSymbol::new(
|
||||
&format!("{}::{}", base_name, &declared_name),
|
||||
&declared_name,
|
||||
Some(identifier.clone()),
|
||||
Some(identifier),
|
||||
));
|
||||
|
||||
match insert_result {
|
||||
Ok(use_statement_symbol) => {
|
||||
drop(borrowed_identifier);
|
||||
gather_identifier(identifier, symbol_table);
|
||||
|
||||
let mut mutable_borrowed_identifier = identifier.borrow_mut();
|
||||
|
||||
gather_identifier(mutable_borrowed_identifier.deref_mut(), symbol_table);
|
||||
|
||||
mutable_borrowed_identifier
|
||||
.set_saved_symbol(Symbol::UseStatement(use_statement_symbol));
|
||||
identifier.set_saved_symbol(Symbol::UseStatement(use_statement_symbol));
|
||||
}
|
||||
Err(err) => {
|
||||
handle_insert_error(
|
||||
err,
|
||||
&declared_name,
|
||||
borrowed_identifier.file_id(),
|
||||
borrowed_identifier.range(),
|
||||
identifier.file_id(),
|
||||
identifier.range(),
|
||||
"Use statement",
|
||||
diagnostics,
|
||||
);
|
||||
@ -358,18 +368,13 @@ fn gather_use_statement(
|
||||
todo!()
|
||||
}
|
||||
let base_name = use_statement.base_name().to_string();
|
||||
match &mut use_statement.last {
|
||||
match use_statement.last_mut() {
|
||||
UseStatementLast::Identifier(identifier) => {
|
||||
handle_use_statement_import(symbol_table, &base_name, identifier.clone(), diagnostics)
|
||||
handle_use_statement_import(symbol_table, &base_name, identifier, diagnostics)
|
||||
}
|
||||
UseStatementLast::Identifiers(identifiers) => {
|
||||
for identifier in identifiers {
|
||||
handle_use_statement_import(
|
||||
symbol_table,
|
||||
&base_name,
|
||||
identifier.clone(),
|
||||
diagnostics,
|
||||
)
|
||||
handle_use_statement_import(symbol_table, &base_name, identifier, diagnostics)
|
||||
}
|
||||
}
|
||||
UseStatementLast::Star => panic!(),
|
||||
@ -384,7 +389,7 @@ fn gather_module_level_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use ModuleLevelDeclaration::*;
|
||||
use crate::ast::node::level::ModuleLevelDeclaration::*;
|
||||
match declaration {
|
||||
Module(module_declaration) => {
|
||||
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
||||
@ -420,7 +425,7 @@ fn gather_interface_level_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use InterfaceLevelDeclaration::*;
|
||||
use crate::ast::node::level::InterfaceLevelDeclaration::*;
|
||||
match declaration {
|
||||
Module(module_declaration) => {
|
||||
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
||||
@ -461,7 +466,7 @@ fn gather_class_level_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use ClassLevelDeclaration::*;
|
||||
use crate::ast::node::level::ClassLevelDeclaration::*;
|
||||
match declaration {
|
||||
Module(module_declaration) => {
|
||||
gather_module_declaration(module_declaration, symbol_table, fqn_context, diagnostics);
|
||||
@ -525,13 +530,13 @@ fn gather_module_declaration(
|
||||
// 5. Pop scope
|
||||
// 6. Pop fqn_context
|
||||
|
||||
let module_name = declaration.identifier.name();
|
||||
let module_name = declaration.identifier().name();
|
||||
|
||||
let insert_result = symbol_table.insert_module_symbol(ModuleSymbol::new(
|
||||
&fqn_context.resolve(&module_name),
|
||||
&module_name,
|
||||
declaration.is_public,
|
||||
Some(&declaration.identifier),
|
||||
declaration.is_public(),
|
||||
Some(declaration.identifier()),
|
||||
));
|
||||
|
||||
match insert_result {
|
||||
@ -539,7 +544,7 @@ fn gather_module_declaration(
|
||||
fqn_context.push(&module_name);
|
||||
symbol_table.push_scope(&format!("ModuleScope({})", module_name));
|
||||
|
||||
for inner_declaration in &mut declaration.declarations {
|
||||
for inner_declaration in declaration.declarations_mut() {
|
||||
gather_module_level_declaration(
|
||||
inner_declaration,
|
||||
symbol_table,
|
||||
@ -554,8 +559,8 @@ fn gather_module_declaration(
|
||||
Err(insert_error) => handle_insert_error(
|
||||
insert_error,
|
||||
&module_name,
|
||||
declaration.identifier.file_id(),
|
||||
declaration.identifier.range(),
|
||||
declaration.identifier().file_id(),
|
||||
declaration.identifier().range(),
|
||||
"Module",
|
||||
diagnostics,
|
||||
),
|
||||
@ -568,14 +573,14 @@ fn gather_interface_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let interface_name = declaration.identifier.name();
|
||||
let interface_name = declaration.identifier().name();
|
||||
|
||||
let insert_result =
|
||||
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
|
||||
&fqn_context.resolve(&interface_name),
|
||||
&interface_name,
|
||||
declaration.is_public,
|
||||
Some(&declaration.identifier),
|
||||
declaration.is_public(),
|
||||
Some(declaration.identifier()),
|
||||
)));
|
||||
|
||||
match insert_result {
|
||||
@ -583,7 +588,7 @@ fn gather_interface_declaration(
|
||||
fqn_context.push(&interface_name);
|
||||
symbol_table.push_scope(&format!("InterfaceScope({})", interface_name));
|
||||
|
||||
for inner_declaration in &mut declaration.declarations {
|
||||
for inner_declaration in declaration.declarations_mut() {
|
||||
gather_interface_level_declaration(
|
||||
inner_declaration,
|
||||
symbol_table,
|
||||
@ -599,8 +604,8 @@ fn gather_interface_declaration(
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
&interface_name,
|
||||
declaration.identifier.file_id(),
|
||||
declaration.identifier.range(),
|
||||
declaration.identifier().file_id(),
|
||||
declaration.identifier().range(),
|
||||
"Interface",
|
||||
diagnostics,
|
||||
);
|
||||
@ -614,21 +619,21 @@ fn gather_class_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let class_name = class_declaration.identifier.name();
|
||||
let class_name = class_declaration.identifier().name().to_string();
|
||||
|
||||
let insert_result =
|
||||
symbol_table.insert_type_symbol(TypeSymbol::Concrete(ConcreteTypeSymbol::new(
|
||||
&fqn_context.resolve(&class_name),
|
||||
&class_name,
|
||||
class_declaration.is_public,
|
||||
Some(&class_declaration.identifier),
|
||||
class_declaration.is_public(),
|
||||
Some(class_declaration.identifier()),
|
||||
)));
|
||||
|
||||
match insert_result {
|
||||
Ok(_) => {
|
||||
// Do this first so we can't implement generic parameters!
|
||||
gather_implements_list(
|
||||
&mut class_declaration.implements,
|
||||
class_declaration.implements_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -637,13 +642,13 @@ fn gather_class_declaration(
|
||||
fqn_context.push(&class_name);
|
||||
symbol_table.push_scope(&format!("ClassScope({})", class_name));
|
||||
|
||||
gather_generic_parameters(&mut class_declaration.generics, symbol_table, diagnostics);
|
||||
gather_generic_parameters(class_declaration.generics_mut(), symbol_table, diagnostics);
|
||||
|
||||
if let Some(class_constructor) = &mut class_declaration.class_constructor {
|
||||
if let Some(class_constructor) = class_declaration.class_constructor_mut() {
|
||||
gather_class_constructor(class_constructor, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
|
||||
for inner_declaration in &mut class_declaration.declarations {
|
||||
for inner_declaration in class_declaration.declarations_mut() {
|
||||
gather_class_level_declaration(
|
||||
inner_declaration,
|
||||
symbol_table,
|
||||
@ -659,8 +664,8 @@ fn gather_class_declaration(
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
&class_name,
|
||||
class_declaration.identifier.file_id(),
|
||||
class_declaration.identifier.range(),
|
||||
class_declaration.identifier().file_id(),
|
||||
class_declaration.identifier().range(),
|
||||
"interface/class",
|
||||
diagnostics,
|
||||
);
|
||||
@ -676,27 +681,27 @@ fn gather_function_definition(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let declared_name = function.identifier.name();
|
||||
let declared_name = function.identifier().name();
|
||||
let resolved_name = fqn_context.resolve(&declared_name);
|
||||
|
||||
let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new(
|
||||
&resolved_name,
|
||||
&declared_name,
|
||||
function.is_public,
|
||||
function.is_public(),
|
||||
false,
|
||||
Some(&function.identifier),
|
||||
Some(function.identifier()),
|
||||
));
|
||||
|
||||
match insert_result {
|
||||
Ok(function_symbol) => {
|
||||
function
|
||||
.identifier
|
||||
.identifier_mut()
|
||||
.set_scope_id(symbol_table.current_scope_id());
|
||||
|
||||
symbol_table.push_scope(&format!("FunctionParameterScope({})", resolved_name));
|
||||
|
||||
let parameters_result = gather_parameters(
|
||||
&mut function.parameters,
|
||||
function.parameters_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -712,7 +717,7 @@ fn gather_function_definition(
|
||||
}
|
||||
|
||||
gather_return_type(
|
||||
&mut function.return_type,
|
||||
function.return_type_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -720,7 +725,7 @@ fn gather_function_definition(
|
||||
|
||||
symbol_table.push_scope(&format!("FunctionBodyScope({})", resolved_name));
|
||||
|
||||
gather_function_body(&mut function.body, symbol_table, fqn_context, diagnostics);
|
||||
gather_function_body(function.body_mut(), symbol_table, fqn_context, diagnostics);
|
||||
|
||||
symbol_table.pop_scope(); // body
|
||||
symbol_table.pop_scope(); // parameters
|
||||
@ -729,8 +734,8 @@ fn gather_function_definition(
|
||||
handle_insert_error(
|
||||
err,
|
||||
&declared_name,
|
||||
function.identifier.file_id(),
|
||||
function.identifier.range(),
|
||||
function.identifier().file_id(),
|
||||
function.identifier().range(),
|
||||
"function/variable",
|
||||
diagnostics,
|
||||
);
|
||||
@ -753,24 +758,26 @@ fn gather_platform_function_definition(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let declared_name = platform_function_declaration.identifier.name();
|
||||
let declared_name = platform_function_declaration.identifier().name();
|
||||
let fully_qualified_name = fqn_context.resolve(&declared_name);
|
||||
|
||||
let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new(
|
||||
&fully_qualified_name,
|
||||
&declared_name,
|
||||
platform_function_declaration.is_public,
|
||||
platform_function_declaration.is_public(),
|
||||
true,
|
||||
Some(&platform_function_declaration.identifier),
|
||||
Some(platform_function_declaration.identifier()),
|
||||
));
|
||||
|
||||
match insert_result {
|
||||
Ok(function_symbol) => {
|
||||
let declared_name_as_string =
|
||||
platform_function_declaration.identifier.name().to_string();
|
||||
let declared_name_as_string = platform_function_declaration
|
||||
.identifier()
|
||||
.name()
|
||||
.to_string();
|
||||
|
||||
platform_function_declaration
|
||||
.identifier
|
||||
.identifier_mut()
|
||||
.set_scope_id(symbol_table.current_scope_id());
|
||||
|
||||
symbol_table.push_scope(&format!(
|
||||
@ -779,7 +786,7 @@ fn gather_platform_function_definition(
|
||||
));
|
||||
|
||||
let parameter_symbols_result = gather_parameters(
|
||||
&mut platform_function_declaration.parameters,
|
||||
platform_function_declaration.parameters_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -795,7 +802,7 @@ fn gather_platform_function_definition(
|
||||
}
|
||||
|
||||
gather_return_type(
|
||||
&mut platform_function_declaration.return_type,
|
||||
platform_function_declaration.return_type_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -807,8 +814,8 @@ fn gather_platform_function_definition(
|
||||
handle_insert_error(
|
||||
err,
|
||||
&declared_name,
|
||||
platform_function_declaration.identifier.file_id(),
|
||||
platform_function_declaration.identifier.range(),
|
||||
platform_function_declaration.identifier().file_id(),
|
||||
platform_function_declaration.identifier().range(),
|
||||
"(Platform-) Function",
|
||||
diagnostics,
|
||||
);
|
||||
@ -822,23 +829,23 @@ fn gather_interface_function_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let name = declaration.identifier.name();
|
||||
let name = declaration.identifier().name();
|
||||
let insert_result = symbol_table.insert_function_symbol(FunctionSymbol::new(
|
||||
&fqn_context.resolve(&name),
|
||||
&name,
|
||||
true,
|
||||
false,
|
||||
Some(&declaration.identifier),
|
||||
Some(declaration.identifier()),
|
||||
));
|
||||
|
||||
match insert_result {
|
||||
Ok(function_symbol) => {
|
||||
symbol_table.push_scope(&format!("FunctionParameterScope({})", &name));
|
||||
|
||||
gather_generic_parameters(&mut declaration.generics, symbol_table, diagnostics);
|
||||
gather_generic_parameters(declaration.generics_mut(), symbol_table, diagnostics);
|
||||
|
||||
let parameters = gather_parameters(
|
||||
&mut declaration.parameters,
|
||||
declaration.parameters_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -850,13 +857,13 @@ fn gather_interface_function_declaration(
|
||||
}
|
||||
|
||||
gather_return_type(
|
||||
&mut declaration.return_type,
|
||||
declaration.return_type_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
|
||||
if let Some(body) = &mut declaration.body {
|
||||
if let Some(body) = declaration.body_mut() {
|
||||
gather_function_body(body, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
|
||||
@ -866,8 +873,8 @@ fn gather_interface_function_declaration(
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
&name,
|
||||
declaration.identifier.file_id(),
|
||||
declaration.identifier.range(),
|
||||
declaration.identifier().file_id(),
|
||||
declaration.identifier().range(),
|
||||
"Interface Function",
|
||||
diagnostics,
|
||||
);
|
||||
@ -890,7 +897,7 @@ fn gather_function_body(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::FunctionBody::*;
|
||||
use crate::ast::node::function::FunctionBody::*;
|
||||
match function_body {
|
||||
Equals(expression) => gather_expression(expression, symbol_table, diagnostics),
|
||||
Block(block) => gather_block_statement_inner(block, symbol_table, fqn_context, diagnostics),
|
||||
@ -906,13 +913,18 @@ fn gather_class_constructor(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for parameter in &mut class_constructor.0 {
|
||||
for parameter in class_constructor.parameters_mut() {
|
||||
match parameter {
|
||||
ClassConstructorParameter::Property(property) => {
|
||||
gather_property_declaration(property, symbol_table, fqn_context, diagnostics);
|
||||
gather_property_declaration(
|
||||
property.deref_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
ClassConstructorParameter::Field(field) => {
|
||||
gather_field_declaration(field, symbol_table, fqn_context, diagnostics);
|
||||
gather_field_declaration(field.deref_mut(), symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -924,19 +936,18 @@ fn gather_property_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let insert_result = symbol_table.insert_class_member_symbol(
|
||||
ClassMemberSymbol::new(
|
||||
&property_declaration.identifier.name(),
|
||||
false,
|
||||
Some(SourceDefinition::from_identifier(&property_declaration.identifier))
|
||||
)
|
||||
);
|
||||
let identifier = property_declaration.identifier();
|
||||
let insert_result = symbol_table.insert_class_member_symbol(ClassMemberSymbol::new(
|
||||
&identifier.name(),
|
||||
false,
|
||||
Some(SourceDefinition::from_identifier(identifier)),
|
||||
));
|
||||
if let Err(insert_error) = insert_result {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
&property_declaration.identifier.name(),
|
||||
property_declaration.identifier.file_id(),
|
||||
property_declaration.identifier.range(),
|
||||
&identifier.name(),
|
||||
identifier.file_id(),
|
||||
identifier.range(),
|
||||
"Data Member",
|
||||
diagnostics,
|
||||
);
|
||||
@ -949,19 +960,18 @@ fn gather_field_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let insert_result = symbol_table.insert_class_member_symbol(
|
||||
ClassMemberSymbol::new(
|
||||
&field_declaration.identifier.name(),
|
||||
true,
|
||||
Some(SourceDefinition::from_identifier(&field_declaration.identifier))
|
||||
)
|
||||
);
|
||||
let identifier = field_declaration.identifier();
|
||||
let insert_result = symbol_table.insert_class_member_symbol(ClassMemberSymbol::new(
|
||||
&identifier.name(),
|
||||
true,
|
||||
Some(SourceDefinition::from_identifier(identifier)),
|
||||
));
|
||||
if let Err(insert_error) = insert_result {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
&field_declaration.identifier.name(),
|
||||
field_declaration.identifier.file_id(),
|
||||
field_declaration.identifier.range(),
|
||||
&identifier.name(),
|
||||
identifier.file_id(),
|
||||
identifier.range(),
|
||||
"Data Member",
|
||||
diagnostics,
|
||||
);
|
||||
@ -987,10 +997,10 @@ fn gather_block_statement_inner(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for statement in &mut block.statements {
|
||||
for statement in block.statements_mut() {
|
||||
gather_statement(statement, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
if let Some(expression) = &mut block.expression {
|
||||
if let Some(expression) = block.expression_mut() {
|
||||
gather_expression(expression, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -1001,7 +1011,7 @@ fn gather_statement(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::Statement::*;
|
||||
use crate::ast::node::statement::Statement::*;
|
||||
match statement {
|
||||
BlockStatement(block) => {
|
||||
gather_block_statement(block, symbol_table, fqn_context, diagnostics)
|
||||
@ -1024,30 +1034,31 @@ fn gather_variable_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let variable_name = variable_declaration.identifier.name();
|
||||
let identifier = variable_declaration.identifier();
|
||||
let variable_name = identifier.name();
|
||||
|
||||
let insert_result = symbol_table.insert_variable_symbol(VariableSymbol::new(
|
||||
&variable_name,
|
||||
variable_declaration.is_mutable,
|
||||
Some(&variable_declaration.identifier),
|
||||
variable_declaration.is_mutable(),
|
||||
Some(identifier),
|
||||
));
|
||||
|
||||
if let Err(err) = insert_result {
|
||||
handle_insert_error(
|
||||
err,
|
||||
&variable_name,
|
||||
variable_declaration.identifier.file_id(),
|
||||
variable_declaration.identifier.range(),
|
||||
identifier.file_id(),
|
||||
identifier.range(),
|
||||
"function/variable",
|
||||
diagnostics,
|
||||
)
|
||||
}
|
||||
|
||||
variable_declaration
|
||||
.identifier
|
||||
.identifier_mut()
|
||||
.set_scope_id(symbol_table.current_scope_id());
|
||||
|
||||
if let Some(initializer) = &mut variable_declaration.initializer {
|
||||
if let Some(initializer) = variable_declaration.initializer_mut() {
|
||||
gather_expression(initializer, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -1058,8 +1069,8 @@ fn gather_assign_statement(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut assign_statement.lhs, symbol_table, diagnostics);
|
||||
gather_expression(&mut assign_statement.rhs, symbol_table, diagnostics);
|
||||
gather_expression(assign_statement.lhs_mut(), symbol_table, diagnostics);
|
||||
gather_expression(assign_statement.rhs_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn gather_call_statement(
|
||||
@ -1067,16 +1078,15 @@ fn gather_call_statement(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut call_statement.0, symbol_table, diagnostics);
|
||||
gather_expression(call_statement.expression_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn gather_return_statement(
|
||||
return_statement: &mut ReturnStatement,
|
||||
symbol_table: &mut SymbolTable,
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
if let Some(expression) = &mut return_statement.0 {
|
||||
if let Some(expression) = return_statement.expression_mut() {
|
||||
gather_expression(expression, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -1087,9 +1097,9 @@ fn gather_if_statement(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut if_statement.condition, symbol_table, diagnostics);
|
||||
gather_expression(if_statement.condition_mut(), symbol_table, diagnostics);
|
||||
gather_block_statement(
|
||||
&mut if_statement.then_block,
|
||||
if_statement.then_block_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -1103,16 +1113,21 @@ fn gather_if_else_statement(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_if_statement(
|
||||
&mut if_else_statement.if_statement,
|
||||
if_else_statement.if_statement_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
for if_statement in &mut if_else_statement.else_ifs.0 {
|
||||
for if_statement in if_else_statement.else_ifs_mut().if_statements_mut() {
|
||||
gather_if_statement(if_statement, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
if let Some(else_block) = &mut if_else_statement.else_block {
|
||||
gather_block_statement(&mut else_block.0, symbol_table, fqn_context, diagnostics);
|
||||
if let Some(else_block) = if_else_statement.else_block_mut() {
|
||||
gather_block_statement(
|
||||
else_block.block_statement_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1122,9 +1137,9 @@ fn gather_while_statement(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut while_statement.condition, symbol_table, diagnostics);
|
||||
gather_expression(while_statement.condition_mut(), symbol_table, diagnostics);
|
||||
gather_block_statement(
|
||||
&mut while_statement.body,
|
||||
while_statement.body_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -1137,9 +1152,9 @@ fn gather_for_statement(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut for_statement.iterator, symbol_table, diagnostics);
|
||||
gather_expression(for_statement.iterator_mut(), symbol_table, diagnostics);
|
||||
symbol_table.push_scope("ForStatementScope");
|
||||
let variable_identifier = &mut for_statement.variable;
|
||||
let variable_identifier = for_statement.variable_mut();
|
||||
let insert_result = symbol_table.insert_variable_symbol(VariableSymbol::new(
|
||||
&variable_identifier.name(),
|
||||
false,
|
||||
@ -1149,7 +1164,7 @@ fn gather_for_statement(
|
||||
match insert_result {
|
||||
Ok(_) => {
|
||||
gather_block_statement_inner(
|
||||
&mut for_statement.body,
|
||||
for_statement.body_mut(),
|
||||
symbol_table,
|
||||
fqn_context,
|
||||
diagnostics,
|
||||
@ -1177,7 +1192,7 @@ fn gather_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::Expression::*;
|
||||
use crate::ast::node::expression::Expression::*;
|
||||
match expression {
|
||||
Ternary(ternary_expression) => {
|
||||
gather_ternary_expression(ternary_expression, symbol_table, diagnostics);
|
||||
@ -1214,14 +1229,18 @@ fn gather_ternary_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut ternary_expression.condition, symbol_table, diagnostics);
|
||||
gather_expression(
|
||||
&mut ternary_expression.true_expression,
|
||||
ternary_expression.condition_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
gather_expression(
|
||||
&mut ternary_expression.false_expression,
|
||||
ternary_expression.true_expression_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
gather_expression(
|
||||
ternary_expression.false_expression_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
@ -1232,8 +1251,8 @@ fn gather_binary_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut binary_expression.left, symbol_table, diagnostics);
|
||||
gather_expression(&mut binary_expression.right, symbol_table, diagnostics);
|
||||
gather_expression(binary_expression.left_mut(), symbol_table, diagnostics);
|
||||
gather_expression(binary_expression.right_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn gather_prefix_expression(
|
||||
@ -1241,7 +1260,11 @@ fn gather_prefix_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut prefix_expression.expression, symbol_table, diagnostics);
|
||||
gather_expression(
|
||||
prefix_expression.expression_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
|
||||
fn gather_suffix_expression(
|
||||
@ -1249,7 +1272,11 @@ fn gather_suffix_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut suffix_expression.expression, symbol_table, diagnostics);
|
||||
gather_expression(
|
||||
suffix_expression.expression_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
|
||||
fn gather_call_expression(
|
||||
@ -1257,12 +1284,12 @@ fn gather_call_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut call_expression.callee, symbol_table, diagnostics);
|
||||
if let Some(turbo_fish) = &mut call_expression.turbo_fish {
|
||||
gather_expression(call_expression.callee_mut(), symbol_table, diagnostics);
|
||||
if let Some(turbo_fish) = call_expression.turbo_fish_mut() {
|
||||
gather_turbo_fish(turbo_fish, symbol_table, diagnostics);
|
||||
}
|
||||
for call_argument in &mut call_expression.arguments.0 {
|
||||
gather_expression(&mut call_argument.0, symbol_table, diagnostics);
|
||||
for call_argument in call_expression.arguments_mut().arguments_mut() {
|
||||
gather_expression(call_argument.expression_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1287,8 +1314,8 @@ fn gather_object_access(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
gather_expression(&mut object_access.receiver, symbol_table, diagnostics);
|
||||
for object_navigation in &mut object_access.navigations.0 {
|
||||
gather_expression(object_access.receiver_mut(), symbol_table, diagnostics);
|
||||
for object_navigation in object_access.navigations_mut().navigations_mut() {
|
||||
match object_navigation {
|
||||
ObjectNavigation::Index(index_expression) => {
|
||||
gather_expression(index_expression, symbol_table, diagnostics);
|
||||
|
@ -5,7 +5,7 @@ There are two phases in name analysis.
|
||||
|
||||
## 1. Gather
|
||||
|
||||
The gather phases has three responsibilities:
|
||||
The gather phase has three responsibilities:
|
||||
|
||||
1. Add all declared symbols to the symbol table.
|
||||
2. Set the `scope_id` property of all identifiers and fully-qualified-names.
|
||||
@ -19,8 +19,8 @@ The resolve phase has one main responsibility: resolve all references based on t
|
||||
`scope_id` property.
|
||||
*/
|
||||
|
||||
use crate::ast::named::Named;
|
||||
use crate::ast::CompilationUnit;
|
||||
use crate::ast::node::compilation_unit::CompilationUnit;
|
||||
use crate::ast::node::named::Named;
|
||||
use crate::diagnostic::DmDiagnostic;
|
||||
use crate::name_analysis::gather::gather_compilation_unit;
|
||||
use crate::name_analysis::resolve::resolve_compilation_unit;
|
||||
@ -206,7 +206,7 @@ mod tests {
|
||||
use greeter::Greeter;
|
||||
|
||||
class Greeter {}
|
||||
"}
|
||||
"},
|
||||
),
|
||||
(
|
||||
"greeter.dm",
|
||||
@ -214,8 +214,8 @@ mod tests {
|
||||
ns greeter;
|
||||
|
||||
class Greeter {}
|
||||
"}
|
||||
)
|
||||
"},
|
||||
),
|
||||
]);
|
||||
assert_number_of_diagnostics(sources, &mut SymbolTable::new(), 1);
|
||||
}
|
||||
|
@ -1,13 +1,29 @@
|
||||
use crate::ast::named::Named;
|
||||
use crate::ast::*;
|
||||
use crate::ast::node::call_expression::*;
|
||||
use crate::ast::node::class::*;
|
||||
use crate::ast::node::closure::*;
|
||||
use crate::ast::node::compilation_unit::*;
|
||||
use crate::ast::node::d_string::*;
|
||||
use crate::ast::node::expression::*;
|
||||
use crate::ast::node::function::*;
|
||||
use crate::ast::node::generics::*;
|
||||
use crate::ast::node::implements_list::*;
|
||||
use crate::ast::node::interface::*;
|
||||
use crate::ast::node::level::*;
|
||||
use crate::ast::node::literal::*;
|
||||
use crate::ast::node::module::*;
|
||||
use crate::ast::node::names::*;
|
||||
use crate::ast::node::object_access::*;
|
||||
use crate::ast::node::statement::*;
|
||||
use crate::ast::node::tuple_arguments::*;
|
||||
use crate::ast::node::type_use::*;
|
||||
use crate::ast::node::use_statement::*;
|
||||
use crate::diagnostic::DmDiagnostic;
|
||||
use crate::name_analysis::symbol::Symbol;
|
||||
use crate::name_analysis::symbol_table::{SymbolLookupError, SymbolTable};
|
||||
use codespan_reporting::diagnostic::{Diagnostic, Label};
|
||||
use std::cell::RefCell;
|
||||
use std::ops::DerefMut;
|
||||
use std::range::Range;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::ast::node::named::Named;
|
||||
/* Type Use */
|
||||
|
||||
fn resolve_type_use(
|
||||
@ -56,7 +72,7 @@ fn resolve_interface_or_class_type_use(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
// 1. handle main name
|
||||
let fqn = &mut interface_or_class_type_use.fqn;
|
||||
let fqn = interface_or_class_type_use.fqn_mut();
|
||||
let lookup_result = if fqn.is_single_identifier() {
|
||||
let identifier = fqn.last();
|
||||
symbol_table.lookup_type_by_declared_name(
|
||||
@ -86,7 +102,7 @@ fn resolve_interface_or_class_type_use(
|
||||
|
||||
// 2. generics
|
||||
resolve_generic_arguments(
|
||||
&mut interface_or_class_type_use.generics,
|
||||
interface_or_class_type_use.generics_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
@ -97,7 +113,7 @@ fn resolve_tuple_type_use(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_tuple_arguments(&mut tuple_type_use.arguments, symbol_table, diagnostics);
|
||||
resolve_tuple_arguments(tuple_type_use.arguments_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn resolve_function_type_use(
|
||||
@ -105,9 +121,13 @@ fn resolve_function_type_use(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_parameters(&mut function_type_use.parameters, symbol_table, diagnostics);
|
||||
resolve_parameters(
|
||||
function_type_use.parameters_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
resolve_return_type(
|
||||
&mut function_type_use.return_type,
|
||||
function_type_use.return_type_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
@ -120,7 +140,7 @@ fn resolve_generic_arguments(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for generic_argument in &mut generic_arguments.0 {
|
||||
for generic_argument in generic_arguments.arguments_mut() {
|
||||
resolve_type_use(generic_argument, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -134,7 +154,7 @@ fn resolve_tuple_arguments(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for type_use in &mut tuple_type_use.0 {
|
||||
for type_use in tuple_type_use.type_uses_mut() {
|
||||
resolve_type_use(type_use, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -146,7 +166,7 @@ fn resolve_implements_list(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for type_use in &mut implements_list.0 {
|
||||
for type_use in implements_list.type_uses_mut() {
|
||||
resolve_type_use(type_use, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -158,8 +178,8 @@ fn resolve_parameters(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for parameter in &mut parameters.0 {
|
||||
resolve_type_use(&mut parameter.type_use, symbol_table, diagnostics);
|
||||
for parameter in parameters.parameters_mut() {
|
||||
resolve_type_use(parameter.type_use_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,8 +190,8 @@ fn resolve_return_type(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_type_use(&mut return_type.declared_type, symbol_table, diagnostics);
|
||||
resolve_references(&mut return_type.references, symbol_table, diagnostics);
|
||||
resolve_type_use(return_type.declared_type_mut(), symbol_table, diagnostics);
|
||||
resolve_references(return_type.references_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
/* References */
|
||||
@ -181,7 +201,7 @@ fn resolve_references(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for reference in &mut references.0 {
|
||||
for reference in references.identifiers_mut() {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -193,10 +213,10 @@ pub(super) fn resolve_compilation_unit(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for use_statement in &mut compilation_unit.use_statements {
|
||||
for use_statement in compilation_unit.use_statements_mut() {
|
||||
resolve_use_statement(use_statement, symbol_table, diagnostics);
|
||||
}
|
||||
for declaration in &mut compilation_unit.declarations {
|
||||
for declaration in compilation_unit.declarations_mut() {
|
||||
resolve_module_level_declaration(declaration, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -204,22 +224,20 @@ pub(super) fn resolve_compilation_unit(
|
||||
/* Use Statement */
|
||||
|
||||
fn handle_use_statement_identifier(
|
||||
identifier: Rc<RefCell<Identifier>>,
|
||||
identifier: &mut Identifier,
|
||||
base_name: &str,
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
file_id: usize,
|
||||
error_range: Range<usize>,
|
||||
) {
|
||||
let borrowed_identifier = identifier.borrow();
|
||||
let declared_name = borrowed_identifier.name().to_string();
|
||||
let declared_name = identifier.name().to_string();
|
||||
let fqn = format!("{}::{}", base_name, &declared_name);
|
||||
let lookup_result =
|
||||
symbol_table.lookup_usable_by_fqn(&fqn, borrowed_identifier.scope_id().unwrap());
|
||||
let lookup_result = symbol_table.lookup_usable_by_fqn(&fqn, identifier.scope_id().unwrap());
|
||||
|
||||
match lookup_result {
|
||||
Ok(referenced_symbol) => {
|
||||
let saved_symbol = borrowed_identifier
|
||||
let saved_symbol = identifier
|
||||
.saved_symbol()
|
||||
.expect("Identifier's saved_symbol is not set.");
|
||||
let use_statement_symbol = saved_symbol.unwrap_use_statement_symbol();
|
||||
@ -242,28 +260,31 @@ fn resolve_use_statement(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
let file_id = use_statement.file_id();
|
||||
let use_statement_range = use_statement.range();
|
||||
let base_name = use_statement.base_name().to_string();
|
||||
|
||||
match &use_statement.last {
|
||||
match use_statement.last_mut() {
|
||||
UseStatementLast::Identifier(identifier) => {
|
||||
handle_use_statement_identifier(
|
||||
identifier.clone(),
|
||||
identifier.deref_mut(),
|
||||
&base_name,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
use_statement.file_id,
|
||||
use_statement.range,
|
||||
file_id,
|
||||
use_statement_range,
|
||||
);
|
||||
}
|
||||
UseStatementLast::Identifiers(identifiers) => {
|
||||
for identifier in identifiers {
|
||||
let identifier_range = identifier.range();
|
||||
handle_use_statement_identifier(
|
||||
identifier.clone(),
|
||||
identifier.deref_mut(),
|
||||
&base_name,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
use_statement.file_id,
|
||||
identifier.borrow().range(),
|
||||
file_id,
|
||||
identifier_range,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -278,7 +299,7 @@ fn resolve_module_level_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::ModuleLevelDeclaration::*;
|
||||
use crate::ast::node::level::ModuleLevelDeclaration::*;
|
||||
match declaration {
|
||||
Module(module_declaration) => {
|
||||
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
|
||||
@ -305,7 +326,7 @@ fn resolve_interface_level_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::InterfaceLevelDeclaration::*;
|
||||
use crate::ast::node::level::InterfaceLevelDeclaration::*;
|
||||
match declaration {
|
||||
Module(module_declaration) => {
|
||||
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
|
||||
@ -338,7 +359,7 @@ fn resolve_class_level_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::ClassLevelDeclaration::*;
|
||||
use crate::ast::node::level::ClassLevelDeclaration::*;
|
||||
match declaration {
|
||||
Module(module_declaration) => {
|
||||
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
|
||||
@ -382,7 +403,7 @@ fn resolve_module_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for declaration in &mut module_declaration.declarations {
|
||||
for declaration in module_declaration.declarations_mut() {
|
||||
resolve_module_level_declaration(declaration, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -393,11 +414,11 @@ fn resolve_interface_declaration(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_implements_list(
|
||||
&mut interface_declaration.implements,
|
||||
interface_declaration.implements_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
for declaration in &mut interface_declaration.declarations {
|
||||
for declaration in interface_declaration.declarations_mut() {
|
||||
resolve_interface_level_declaration(declaration, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -407,11 +428,15 @@ fn resolve_class_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
if let Some(class_constructor) = &mut class_declaration.class_constructor {
|
||||
if let Some(class_constructor) = class_declaration.class_constructor_mut() {
|
||||
resolve_class_constructor(class_constructor, symbol_table, diagnostics);
|
||||
}
|
||||
resolve_implements_list(&mut class_declaration.implements, symbol_table, diagnostics);
|
||||
for declaration in &mut class_declaration.declarations {
|
||||
resolve_implements_list(
|
||||
class_declaration.implements_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
for declaration in class_declaration.declarations_mut() {
|
||||
resolve_class_level_declaration(declaration, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -424,16 +449,16 @@ fn resolve_function_definition(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_parameters(
|
||||
&mut function_definition.parameters,
|
||||
function_definition.parameters_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
resolve_return_type(
|
||||
&mut function_definition.return_type,
|
||||
function_definition.return_type_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
resolve_function_body(&mut function_definition.body, symbol_table, diagnostics);
|
||||
resolve_function_body(function_definition.body_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn resolve_operator_function_definition(
|
||||
@ -450,12 +475,12 @@ fn resolve_platform_function_declaration(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_parameters(
|
||||
&mut platform_function_declaration.parameters,
|
||||
platform_function_declaration.parameters_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
resolve_return_type(
|
||||
&mut platform_function_declaration.return_type,
|
||||
platform_function_declaration.return_type_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
@ -467,16 +492,16 @@ fn resolve_interface_function_declaration(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_parameters(
|
||||
&mut interface_function_declaration.parameters,
|
||||
interface_function_declaration.parameters_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
resolve_return_type(
|
||||
&mut interface_function_declaration.return_type,
|
||||
interface_function_declaration.return_type_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
if let Some(body) = &mut interface_function_declaration.body {
|
||||
if let Some(body) = interface_function_declaration.body_mut() {
|
||||
resolve_function_body(body, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -494,7 +519,7 @@ fn resolve_function_body(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::FunctionBody::*;
|
||||
use crate::ast::node::function::FunctionBody::*;
|
||||
match function_body {
|
||||
Equals(expression) => resolve_expression(expression, symbol_table, diagnostics),
|
||||
Block(block) => resolve_block_statement(block, symbol_table, diagnostics),
|
||||
@ -517,8 +542,8 @@ fn resolve_class_constructor(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::ClassConstructorParameter::*;
|
||||
for parameter in &mut class_constructor.0 {
|
||||
use crate::ast::node::class::ClassConstructorParameter::*;
|
||||
for parameter in class_constructor.parameters_mut() {
|
||||
match parameter {
|
||||
Property(property) => resolve_property_declaration(property, symbol_table, diagnostics),
|
||||
Field(field) => resolve_field_declaration(field, symbol_table, diagnostics),
|
||||
@ -532,7 +557,7 @@ fn resolve_property_declaration(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_type_use(
|
||||
&mut property_declaration.declared_type,
|
||||
property_declaration.declared_type_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
@ -544,7 +569,7 @@ fn resolve_field_declaration(
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_type_use(
|
||||
&mut field_declaration.declared_type,
|
||||
field_declaration.declared_type_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
@ -557,10 +582,10 @@ fn resolve_block_statement(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for statement in block_statement.statements.iter_mut() {
|
||||
for statement in block_statement.statements_mut() {
|
||||
resolve_statement(statement, symbol_table, diagnostics);
|
||||
}
|
||||
if let Some(expression) = block_statement.expression.as_mut() {
|
||||
if let Some(expression) = block_statement.expression_mut() {
|
||||
resolve_expression(expression, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -570,7 +595,7 @@ fn resolve_statement(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::Statement::*;
|
||||
use crate::ast::node::statement::Statement::*;
|
||||
match statement {
|
||||
BlockStatement(block) => resolve_block_statement(block, symbol_table, diagnostics),
|
||||
VariableDeclarationStatement(variable_declaration) => {
|
||||
@ -591,7 +616,7 @@ fn resolve_variable_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
if let Some(initializer) = &mut variable_declaration.initializer {
|
||||
if let Some(initializer) = variable_declaration.initializer_mut() {
|
||||
resolve_expression(initializer, symbol_table, diagnostics)
|
||||
}
|
||||
}
|
||||
@ -601,8 +626,8 @@ fn resolve_assign_statement(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_expression(&mut assign_statement.lhs, symbol_table, diagnostics);
|
||||
resolve_expression(&mut assign_statement.rhs, symbol_table, diagnostics);
|
||||
resolve_expression(assign_statement.lhs_mut(), symbol_table, diagnostics);
|
||||
resolve_expression(assign_statement.rhs_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn resolve_call_statement(
|
||||
@ -610,7 +635,7 @@ fn resolve_call_statement(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_expression(&mut call_statement.0, symbol_table, diagnostics)
|
||||
resolve_expression(call_statement.expression_mut(), symbol_table, diagnostics)
|
||||
}
|
||||
|
||||
fn resolve_return_statement(
|
||||
@ -618,7 +643,7 @@ fn resolve_return_statement(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
if let Some(expression) = &mut return_statement.0 {
|
||||
if let Some(expression) = return_statement.expression_mut() {
|
||||
resolve_expression(expression, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -654,7 +679,7 @@ fn resolve_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
use crate::ast::Expression::*;
|
||||
use crate::ast::node::expression::Expression::*;
|
||||
match expression {
|
||||
Ternary(ternary_expression) => {
|
||||
resolve_ternary_expression(ternary_expression, symbol_table, diagnostics);
|
||||
@ -737,14 +762,18 @@ fn resolve_ternary_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_expression(&mut ternary_expression.condition, symbol_table, diagnostics);
|
||||
resolve_expression(
|
||||
&mut ternary_expression.true_expression,
|
||||
ternary_expression.condition_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
resolve_expression(
|
||||
&mut ternary_expression.false_expression,
|
||||
ternary_expression.true_expression_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
resolve_expression(
|
||||
ternary_expression.false_expression_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
@ -755,8 +784,8 @@ fn resolve_binary_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_expression(&mut binary_expression.left, symbol_table, diagnostics);
|
||||
resolve_expression(&mut binary_expression.right, symbol_table, diagnostics);
|
||||
resolve_expression(binary_expression.left_mut(), symbol_table, diagnostics);
|
||||
resolve_expression(binary_expression.right_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn resolve_prefix_expression(
|
||||
@ -764,7 +793,11 @@ fn resolve_prefix_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_expression(&mut prefix_expression.expression, symbol_table, diagnostics);
|
||||
resolve_expression(
|
||||
prefix_expression.expression_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
|
||||
fn resolve_suffix_expression(
|
||||
@ -772,7 +805,11 @@ fn resolve_suffix_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_expression(&mut suffix_expression.expression, symbol_table, diagnostics);
|
||||
resolve_expression(
|
||||
suffix_expression.expression_mut(),
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
|
||||
fn resolve_call_expression(
|
||||
@ -780,11 +817,11 @@ fn resolve_call_expression(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_expression(&mut call_expression.callee, symbol_table, diagnostics);
|
||||
if let Some(turbo_fish) = &mut call_expression.turbo_fish {
|
||||
resolve_expression(call_expression.callee_mut(), symbol_table, diagnostics);
|
||||
if let Some(turbo_fish) = call_expression.turbo_fish_mut() {
|
||||
resolve_turbo_fish(turbo_fish, symbol_table, diagnostics);
|
||||
}
|
||||
resolve_call_arguments(&mut call_expression.arguments, symbol_table, diagnostics);
|
||||
resolve_call_arguments(call_expression.arguments_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn resolve_turbo_fish(
|
||||
@ -792,7 +829,7 @@ fn resolve_turbo_fish(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_generic_arguments(&mut turbo_fish.0, symbol_table, diagnostics);
|
||||
resolve_generic_arguments(turbo_fish.generics_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn resolve_call_arguments(
|
||||
@ -800,7 +837,7 @@ fn resolve_call_arguments(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
for argument in &mut call_arguments.0 {
|
||||
for argument in call_arguments.arguments_mut() {
|
||||
resolve_call_argument(argument, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
@ -810,7 +847,7 @@ fn resolve_call_argument(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
resolve_expression(&mut call_argument.0, symbol_table, diagnostics);
|
||||
resolve_expression(call_argument.expression_mut(), symbol_table, diagnostics);
|
||||
}
|
||||
|
||||
fn resolve_closure(
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::ast::named::Named;
|
||||
use crate::ast::{Identifier, UseStatement};
|
||||
use crate::ast::node::named::Named;
|
||||
use crate::ast::node::names::Identifier;
|
||||
use crate::ast::node::use_statement::UseStatement;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::ops::Deref;
|
||||
@ -31,8 +32,8 @@ impl SourceDefinition {
|
||||
#[deprecated(note = "Use identifier instead.")]
|
||||
pub fn from_use_statement(use_statement: &UseStatement) -> Self {
|
||||
SourceDefinition {
|
||||
file_id: use_statement.file_id,
|
||||
range: use_statement.range,
|
||||
file_id: use_statement.file_id(),
|
||||
range: use_statement.range(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,15 +98,11 @@ pub struct UseStatementSymbol {
|
||||
}
|
||||
|
||||
impl UseStatementSymbol {
|
||||
pub fn new(
|
||||
fqn: &str,
|
||||
declared_name: &str,
|
||||
identifier: Option<Rc<RefCell<Identifier>>>,
|
||||
) -> Self {
|
||||
pub fn new(fqn: &str, declared_name: &str, identifier: Option<&Identifier>) -> Self {
|
||||
UseStatementSymbol {
|
||||
fqn: fqn.to_string(),
|
||||
declared_name: declared_name.to_string(),
|
||||
definition: identifier.map(SourceDefinition::from_identifier_rc),
|
||||
definition: identifier.map(SourceDefinition::from_identifier),
|
||||
referenced_symbol: None,
|
||||
}
|
||||
}
|
||||
|
@ -120,6 +120,7 @@ Star = { "*" }
|
||||
LeftShift = { "<<" }
|
||||
RightShift = { ">>" }
|
||||
Index = { "[]" }
|
||||
BorrowMut = { Borrow ~ Mut }
|
||||
|
||||
Operator = {
|
||||
Or
|
||||
@ -135,16 +136,19 @@ Operator = {
|
||||
| Multiply
|
||||
| Divide
|
||||
| Modulo
|
||||
| LeftShift
|
||||
| RightShift
|
||||
// unary prefix
|
||||
| Spread
|
||||
| BorrowMut
|
||||
| Borrow
|
||||
| Star
|
||||
| Not
|
||||
| Negative
|
||||
// unary suffix
|
||||
| PlusPlus
|
||||
| MinusMinus
|
||||
| CallOp
|
||||
| Spread
|
||||
| Borrow
|
||||
| Star
|
||||
| LeftShift
|
||||
| RightShift
|
||||
| Index
|
||||
}
|
||||
|
||||
@ -457,10 +461,10 @@ InterfaceDefaultOperatorFunction = {
|
||||
Def
|
||||
~ FunctionModifier?
|
||||
~ Op
|
||||
~ GenericParameters?
|
||||
~ Operator
|
||||
~ Parameters
|
||||
~ ReturnType
|
||||
~ RefList?
|
||||
~ FunctionBody
|
||||
}
|
||||
|
||||
@ -698,10 +702,6 @@ PrefixExpression = {
|
||||
~ SuffixExpression
|
||||
}
|
||||
|
||||
BorrowMut = {
|
||||
Borrow ~ Mut
|
||||
}
|
||||
|
||||
SuffixExpression = {
|
||||
PrimaryExpression
|
||||
~ (
|
||||
|
Loading…
Reference in New Issue
Block a user