deimos-lang/src/name_analysis/resolve.rs
2025-05-26 08:30:15 -05:00

888 lines
26 KiB
Rust

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::ops::DerefMut;
use std::range::Range;
use crate::ast::node::named::Named;
/* Type Use */
fn resolve_type_use(
type_use: &mut TypeUse,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
match type_use {
TypeUse::Primitive(primitive_type_use) => {
resolve_primitive_type_use(primitive_type_use, symbol_table, diagnostics)
}
TypeUse::InterfaceOrClass(interface_or_class_type_use) => {
resolve_interface_or_class_type_use(
interface_or_class_type_use,
symbol_table,
diagnostics,
);
}
TypeUse::Tuple(tuple_type_use) => {
resolve_tuple_type_use(tuple_type_use, symbol_table, diagnostics);
}
TypeUse::Function(function_type_use) => {
resolve_function_type_use(function_type_use, symbol_table, diagnostics);
}
}
}
fn resolve_primitive_type_use(
primitive_type_use: &mut PrimitiveTypeUse,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
match primitive_type_use {
PrimitiveTypeUse::Array(generic_arguments_opt) => {
if let Some(generic_arguments) = generic_arguments_opt {
resolve_generic_arguments(generic_arguments, symbol_table, diagnostics);
}
}
_ => {}
}
}
fn resolve_interface_or_class_type_use(
interface_or_class_type_use: &mut InterfaceOrClassTypeUse,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
// 1. handle main name
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(
&identifier.name(),
identifier
.scope_id()
.expect("Identifier's scope id not set."),
)
} else {
todo!("Fully-qualified-name type uses sensitive to imports and so on")
};
match lookup_result {
Ok(type_symbol) => {
fqn.last_mut().set_saved_symbol(Symbol::Type(type_symbol));
}
Err(_) => {
diagnostics.push(
Diagnostic::error()
.with_message(&format!(
"No type symbol '{}' found in current scope.",
fqn.name()
))
.with_label(Label::primary(fqn.file_id(), fqn.range())),
);
}
}
// 2. generics
resolve_generic_arguments(
interface_or_class_type_use.generics_mut(),
symbol_table,
diagnostics,
);
}
fn resolve_tuple_type_use(
tuple_type_use: &mut TupleTypeUse,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_tuple_arguments(tuple_type_use.arguments_mut(), symbol_table, diagnostics);
}
fn resolve_function_type_use(
function_type_use: &mut FunctionTypeUse,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_parameters(
function_type_use.parameters_mut(),
symbol_table,
diagnostics,
);
resolve_return_type(
function_type_use.return_type_mut(),
symbol_table,
diagnostics,
);
}
/* Generic arguments */
fn resolve_generic_arguments(
generic_arguments: &mut GenericArguments,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for generic_argument in generic_arguments.arguments_mut() {
resolve_type_use(generic_argument, symbol_table, diagnostics);
}
}
/* Generic parameters: todo: no resolution needed? */
/* Tuple arguments */
fn resolve_tuple_arguments(
tuple_type_use: &mut TupleArguments,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for type_use in tuple_type_use.type_uses_mut() {
resolve_type_use(type_use, symbol_table, diagnostics);
}
}
/* Implements list */
fn resolve_implements_list(
implements_list: &mut ImplementsList,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for type_use in implements_list.type_uses_mut() {
resolve_type_use(type_use, symbol_table, diagnostics);
}
}
/* Function parameters */
fn resolve_parameters(
parameters: &mut Parameters,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for parameter in parameters.parameters_mut() {
resolve_type_use(parameter.type_use_mut(), symbol_table, diagnostics);
}
}
/* Return Type */
fn resolve_return_type(
return_type: &mut ReturnType,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_type_use(return_type.declared_type_mut(), symbol_table, diagnostics);
resolve_references(return_type.references_mut(), symbol_table, diagnostics);
}
/* References */
fn resolve_references(
references: &mut References,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for reference in references.identifiers_mut() {
todo!()
}
}
/* Compilation Unit/Top-level construct */
pub(super) fn resolve_compilation_unit(
compilation_unit: &mut CompilationUnit,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for use_statement in compilation_unit.use_statements_mut() {
resolve_use_statement(use_statement, symbol_table, diagnostics);
}
for declaration in compilation_unit.declarations_mut() {
resolve_module_level_declaration(declaration, symbol_table, diagnostics);
}
}
/* Use Statement */
fn handle_use_statement_identifier(
identifier: &mut Identifier,
base_name: &str,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
file_id: usize,
error_range: Range<usize>,
) {
let declared_name = identifier.name().to_string();
let fqn = format!("{}::{}", base_name, &declared_name);
let lookup_result = symbol_table.lookup_usable_by_fqn(&fqn, identifier.scope_id().unwrap());
match lookup_result {
Ok(referenced_symbol) => {
let saved_symbol = identifier
.saved_symbol()
.expect("Identifier's saved_symbol is not set.");
let use_statement_symbol = saved_symbol.unwrap_use_statement_symbol();
use_statement_symbol
.borrow_mut()
.set_referenced_symbol(referenced_symbol);
}
Err(_) => {
diagnostics.push(
Diagnostic::error()
.with_message(&format!("Unable to find symbol '{}'.", fqn))
.with_label(Label::primary(file_id, error_range)),
);
}
}
}
fn resolve_use_statement(
use_statement: &mut UseStatement,
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_mut() {
UseStatementLast::Identifier(identifier) => {
handle_use_statement_identifier(
identifier.deref_mut(),
&base_name,
symbol_table,
diagnostics,
file_id,
use_statement_range,
);
}
UseStatementLast::Identifiers(identifiers) => {
for identifier in identifiers {
let identifier_range = identifier.range();
handle_use_statement_identifier(
identifier.deref_mut(),
&base_name,
symbol_table,
diagnostics,
file_id,
identifier_range,
)
}
}
UseStatementLast::Star => todo!("star imports"),
}
}
/* Declarations allowed in each level */
fn resolve_module_level_declaration(
declaration: &mut ModuleLevelDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::node::level::ModuleLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
}
Interface(interface_declaration) => {
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
}
Function(function_definition) => {
resolve_function_definition(function_definition, symbol_table, diagnostics)
}
Class(class_declaration) => {
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
}
PlatformFunction(platform_function_declaration) => resolve_platform_function_declaration(
platform_function_declaration,
symbol_table,
diagnostics,
),
}
}
fn resolve_interface_level_declaration(
declaration: &mut InterfaceLevelDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::node::level::InterfaceLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
}
Interface(interface_declaration) => {
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
}
Class(class_declaration) => {
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
}
Function(interface_function_declaration) => {
resolve_interface_function_declaration(
interface_function_declaration,
symbol_table,
diagnostics,
);
}
OperatorFunction(interface_operator_function_declaration) => {
resolve_interface_operator_function_declaration(
interface_operator_function_declaration,
symbol_table,
diagnostics,
);
}
}
}
fn resolve_class_level_declaration(
declaration: &mut ClassLevelDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::node::level::ClassLevelDeclaration::*;
match declaration {
Module(module_declaration) => {
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
}
Interface(interface_declaration) => {
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
}
Class(class_declaration) => {
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
}
Function(function_definition) => {
resolve_function_definition(function_definition, symbol_table, diagnostics);
}
OperatorFunction(operator_function_definition) => {
resolve_operator_function_definition(
operator_function_definition,
symbol_table,
diagnostics,
);
}
PlatformFunction(platform_function_declaration) => {
resolve_platform_function_declaration(
platform_function_declaration,
symbol_table,
diagnostics,
);
}
Property(property_declaration) => {
resolve_property_declaration(property_declaration, symbol_table, diagnostics);
}
Field(field_declaration) => {
resolve_field_declaration(field_declaration, symbol_table, diagnostics);
}
}
}
/* Main Declarations */
fn resolve_module_declaration(
module_declaration: &mut ModuleDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for declaration in module_declaration.declarations_mut() {
resolve_module_level_declaration(declaration, symbol_table, diagnostics);
}
}
fn resolve_interface_declaration(
interface_declaration: &mut InterfaceDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_implements_list(
interface_declaration.implements_mut(),
symbol_table,
diagnostics,
);
for declaration in interface_declaration.declarations_mut() {
resolve_interface_level_declaration(declaration, symbol_table, diagnostics);
}
}
fn resolve_class_declaration(
class_declaration: &mut ClassDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
if let Some(class_constructor) = class_declaration.class_constructor_mut() {
resolve_class_constructor(class_constructor, symbol_table, diagnostics);
}
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);
}
}
/* Function declarations and components */
fn resolve_function_definition(
function_definition: &mut FunctionDefinition,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_parameters(
function_definition.parameters_mut(),
symbol_table,
diagnostics,
);
resolve_return_type(
function_definition.return_type_mut(),
symbol_table,
diagnostics,
);
resolve_function_body(function_definition.body_mut(), symbol_table, diagnostics);
}
fn resolve_operator_function_definition(
operator_function_definition: &mut OperatorFunctionDefinition,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
}
fn resolve_platform_function_declaration(
platform_function_declaration: &mut PlatformFunctionDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_parameters(
platform_function_declaration.parameters_mut(),
symbol_table,
diagnostics,
);
resolve_return_type(
platform_function_declaration.return_type_mut(),
symbol_table,
diagnostics,
);
}
fn resolve_interface_function_declaration(
interface_function_declaration: &mut InterfaceFunctionDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_parameters(
interface_function_declaration.parameters_mut(),
symbol_table,
diagnostics,
);
resolve_return_type(
interface_function_declaration.return_type_mut(),
symbol_table,
diagnostics,
);
if let Some(body) = interface_function_declaration.body_mut() {
resolve_function_body(body, symbol_table, diagnostics);
}
}
fn resolve_interface_operator_function_declaration(
interface_operator_function_declaration: &mut InterfaceOperatorFunctionDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
}
fn resolve_function_body(
function_body: &mut FunctionBody,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
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),
Alias(identifier) => resolve_function_alias(identifier, symbol_table, diagnostics),
}
}
fn resolve_function_alias(
identifier: &mut Identifier,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
}
/* Class components */
fn resolve_class_constructor(
class_constructor: &mut ClassConstructor,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
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),
}
}
}
fn resolve_property_declaration(
property_declaration: &mut PropertyDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_type_use(
property_declaration.declared_type_mut(),
symbol_table,
diagnostics,
);
}
fn resolve_field_declaration(
field_declaration: &mut FieldDeclaration,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_type_use(
field_declaration.declared_type_mut(),
symbol_table,
diagnostics,
);
}
/* Statements */
fn resolve_block_statement(
block_statement: &mut BlockStatement,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for statement in block_statement.statements_mut() {
resolve_statement(statement, symbol_table, diagnostics);
}
if let Some(expression) = block_statement.expression_mut() {
resolve_expression(expression, symbol_table, diagnostics);
}
}
fn resolve_statement(
statement: &mut Statement,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::node::statement::Statement::*;
match statement {
BlockStatement(block) => resolve_block_statement(block, symbol_table, diagnostics),
VariableDeclarationStatement(variable_declaration) => {
resolve_variable_declaration(variable_declaration, symbol_table, diagnostics)
}
AssignStatement(assign_statement) => {
resolve_assign_statement(assign_statement, symbol_table, diagnostics)
}
CallStatement(call_statement) => {
resolve_call_statement(call_statement, symbol_table, diagnostics)
}
_ => todo!(),
}
}
fn resolve_variable_declaration(
variable_declaration: &mut VariableDeclarationStatement,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
if let Some(initializer) = variable_declaration.initializer_mut() {
resolve_expression(initializer, symbol_table, diagnostics)
}
}
fn resolve_assign_statement(
assign_statement: &mut AssignStatement,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(assign_statement.lhs_mut(), symbol_table, diagnostics);
resolve_expression(assign_statement.rhs_mut(), symbol_table, diagnostics);
}
fn resolve_call_statement(
call_statement: &mut CallStatement,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(call_statement.expression_mut(), symbol_table, diagnostics)
}
fn resolve_return_statement(
return_statement: &mut ReturnStatement,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
if let Some(expression) = return_statement.expression_mut() {
resolve_expression(expression, symbol_table, diagnostics);
}
}
fn resolve_if_statement(
if_statement: &mut IfStatement,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
}
fn resolve_while_statement(
while_statement: &mut WhileStatement,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
}
fn resolve_for_statement(
for_statement: &mut ForStatement,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
}
/* Expressions */
fn resolve_expression(
expression: &mut Expression,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
use crate::ast::node::expression::Expression::*;
match expression {
Ternary(ternary_expression) => {
resolve_ternary_expression(ternary_expression, symbol_table, diagnostics);
}
Binary(binary_expression) => {
resolve_binary_expression(binary_expression, symbol_table, diagnostics);
}
UnaryPrefix(prefix_expression) => {
resolve_prefix_expression(prefix_expression, symbol_table, diagnostics);
}
UnarySuffix(suffix_expression) => {
resolve_suffix_expression(suffix_expression, symbol_table, diagnostics);
}
Call(call_expression) => {
resolve_call_expression(call_expression, symbol_table, diagnostics)
}
ObjectAccess(object_access) => {
resolve_object_access(object_access, symbol_table, diagnostics);
}
FullyQualifiedName(fqn) => {
if fqn.is_single_identifier() {
resolve_identifier_expression(fqn.last_mut(), symbol_table, diagnostics);
} else {
resolve_fqn_expression(fqn, symbol_table, diagnostics);
}
}
Literal(literal) => {
resolve_literal(literal, symbol_table, diagnostics);
}
Closure(closure) => {
resolve_closure(closure, symbol_table, diagnostics);
}
}
}
fn handle_named_lookup_result(
lookup_result: Result<Symbol, SymbolLookupError>,
named: &mut impl Named,
diagnostics: &mut Vec<DmDiagnostic>,
) {
match lookup_result {
Ok(referenced_symbol) => {
named.set_saved_symbol(referenced_symbol);
}
Err(_) => {
diagnostics.push(
DmDiagnostic::error()
.with_message(&format!(
"Unable to find expressible symbol {} in current scope.",
named.name()
))
.with_label(Label::primary(named.file_id(), named.range())),
);
}
}
}
fn resolve_identifier_expression(
identifier: &mut Identifier,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let lookup_result = symbol_table
.lookup_expressible_by_declared_name(&identifier.name(), identifier.scope_id().unwrap());
handle_named_lookup_result(lookup_result, identifier, diagnostics);
}
fn resolve_fqn_expression(
fqn: &mut FullyQualifiedName,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
let lookup_result =
symbol_table.lookup_expressible_by_fqn(&fqn.name(), fqn.last().scope_id().unwrap());
handle_named_lookup_result(lookup_result, fqn, diagnostics);
}
fn resolve_ternary_expression(
ternary_expression: &mut TernaryExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(
ternary_expression.condition_mut(),
symbol_table,
diagnostics,
);
resolve_expression(
ternary_expression.true_expression_mut(),
symbol_table,
diagnostics,
);
resolve_expression(
ternary_expression.false_expression_mut(),
symbol_table,
diagnostics,
);
}
fn resolve_binary_expression(
binary_expression: &mut BinaryExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(binary_expression.left_mut(), symbol_table, diagnostics);
resolve_expression(binary_expression.right_mut(), symbol_table, diagnostics);
}
fn resolve_prefix_expression(
prefix_expression: &mut PrefixExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(
prefix_expression.expression_mut(),
symbol_table,
diagnostics,
);
}
fn resolve_suffix_expression(
suffix_expression: &mut SuffixExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(
suffix_expression.expression_mut(),
symbol_table,
diagnostics,
);
}
fn resolve_call_expression(
call_expression: &mut CallExpression,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
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(call_expression.arguments_mut(), symbol_table, diagnostics);
}
fn resolve_turbo_fish(
turbo_fish: &mut TurboFish,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_generic_arguments(turbo_fish.generics_mut(), symbol_table, diagnostics);
}
fn resolve_call_arguments(
call_arguments: &mut CallArguments,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
for argument in call_arguments.arguments_mut() {
resolve_call_argument(argument, symbol_table, diagnostics);
}
}
fn resolve_call_argument(
call_argument: &mut CallArgument,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
resolve_expression(call_argument.expression_mut(), symbol_table, diagnostics);
}
fn resolve_closure(
closure: &mut Closure,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
}
fn resolve_object_access(
object_access: &mut ObjectAccess,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
}
fn resolve_literal(
literal: &mut Literal,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
match literal {
Literal::DString(d_string) => resolve_d_string(d_string, symbol_table, diagnostics),
Literal::BacktickString(d_string) => resolve_d_string(d_string, symbol_table, diagnostics),
_ => {}
}
}
fn resolve_d_string(
d_string: &mut DString,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
todo!()
}