Fixing name checking for constructor assignment destinations. WIP.
This commit is contained in:
parent
344761022b
commit
4d6aa3ffd4
@ -40,7 +40,7 @@ impl AssignStatement {
|
|||||||
) -> Vec<Diagnostic> {
|
) -> Vec<Diagnostic> {
|
||||||
[
|
[
|
||||||
self.destination
|
self.destination
|
||||||
.check_constructor_local_names(symbol_table, class_symbol),
|
.check_constructor_destination_names(symbol_table, class_symbol),
|
||||||
self.value
|
self.value
|
||||||
.check_constructor_local_names(symbol_table, class_symbol),
|
.check_constructor_local_names(symbol_table, class_symbol),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -77,6 +77,34 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check_constructor_destination_names(
|
||||||
|
&self,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
class_symbol: &ClassSymbol,
|
||||||
|
) -> Vec<Diagnostic> {
|
||||||
|
match self {
|
||||||
|
Expression::Binary(_) => {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
Expression::Negative(_) => {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
Expression::Call(_) => {
|
||||||
|
panic!()
|
||||||
|
}
|
||||||
|
Expression::Identifier(identifier) => {
|
||||||
|
if let Some(diagnostic) =
|
||||||
|
identifier.check_constructor_destination_name(symbol_table, class_symbol)
|
||||||
|
{
|
||||||
|
vec![diagnostic]
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_constructor_local_names(
|
pub fn check_constructor_local_names(
|
||||||
&self,
|
&self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
|
|||||||
@ -132,6 +132,40 @@ impl Identifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check_constructor_destination_name(
|
||||||
|
&self,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
class_symbol: &ClassSymbol,
|
||||||
|
) -> Option<Diagnostic> {
|
||||||
|
let expressible_symbol =
|
||||||
|
symbol_table.find_expressible_symbol(self.scope_id.unwrap(), &self.name);
|
||||||
|
if let Some(expressible_symbol) = expressible_symbol {
|
||||||
|
match expressible_symbol {
|
||||||
|
ExpressibleSymbol::Class(_) => {
|
||||||
|
panic!("Class is not an L value")
|
||||||
|
}
|
||||||
|
ExpressibleSymbol::Field(field_symbol) => {
|
||||||
|
// This is just a stop-gap for now. We need to decide if we are going to do
|
||||||
|
// field assignment analysis (whether it's initialized already, if it's mut,
|
||||||
|
// etc.) during name checking or during type checking.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
ExpressibleSymbol::Function(_) => {
|
||||||
|
panic!("Function is not an L value")
|
||||||
|
}
|
||||||
|
ExpressibleSymbol::Parameter(_) => {
|
||||||
|
panic!("Parameter is not an L value")
|
||||||
|
}
|
||||||
|
ExpressibleSymbol::Variable(variable_symbol) => {
|
||||||
|
// Again, a stop-gap.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Some(symbol_not_found(&self.name, &self.source_range))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_constructor_local_name(
|
pub fn check_constructor_local_name(
|
||||||
&self,
|
&self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user