Commit fb3a3163 authored by Jürg Billeter's avatar Jürg Billeter

Replace SemanticAnalyzer with CodeContext in CodeNode.check parameter

parent 2cd44b16
......@@ -72,14 +72,14 @@ public class Vala.AddressofExpression : Expression {
return inner.is_pure ();
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
checked = true;
if (!inner.check (analyzer)) {
if (!inner.check (context)) {
error = true;
return false;
}
......
......@@ -128,11 +128,11 @@ public class Vala.ArrayCreationExpression : Expression {
}
}
private int create_sizes_from_initializer_list (SemanticAnalyzer analyzer, InitializerList il, int rank, List<Literal> sl) {
private int create_sizes_from_initializer_list (CodeContext context, InitializerList il, int rank, List<Literal> sl) {
if (sl.size == (this.rank - rank)) {
// only add size if this is the first initializer list of the current dimension
var init = new IntegerLiteral (il.size.to_string (), il.source_reference);
init.check (analyzer);
init.check (context);
sl.add (init);
}
......@@ -145,7 +145,7 @@ public class Vala.ArrayCreationExpression : Expression {
Report.error (e.source_reference, "Expected array element, got array initializer list");
return -1;
}
int size = create_sizes_from_initializer_list (analyzer, (InitializerList) e, rank - 1, sl);
int size = create_sizes_from_initializer_list (context, (InitializerList) e, rank - 1, sl);
if (size == -1) {
return -1;
}
......@@ -168,7 +168,7 @@ public class Vala.ArrayCreationExpression : Expression {
return il.size;
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
......@@ -179,20 +179,20 @@ public class Vala.ArrayCreationExpression : Expression {
var initlist = initializer_list;
if (element_type != null) {
element_type.check (analyzer);
element_type.check (context);
}
foreach (Expression e in sizes) {
e.check (analyzer);
e.check (context);
}
var calc_sizes = new ArrayList<Literal> ();
if (initlist != null) {
initlist.target_type = new ArrayType (element_type, rank, source_reference);
initlist.check (analyzer);
initlist.check (context);
var ret = create_sizes_from_initializer_list (analyzer, initlist, rank, calc_sizes);
var ret = create_sizes_from_initializer_list (context, initlist, rank, calc_sizes);
if (ret == -1) {
error = true;
}
......
......@@ -236,13 +236,13 @@ public class Vala.ArrayType : ReferenceType {
return element_type.is_accessible (sym);
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (invalid_syntax) {
Report.error (source_reference, "syntax error, no expression allowed between array brackets");
error = true;
return false;
}
return element_type.check (analyzer);
return element_type.check (context);
}
public override string? get_type_id () {
......
......@@ -97,7 +97,7 @@ public class Vala.Assignment : Expression {
return false;
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
......@@ -109,15 +109,15 @@ public class Vala.Assignment : Expression {
var local = new LocalVariable (null, get_temp_name (), right, right.source_reference);
var decl = new DeclarationStatement (local, source_reference);
decl.check (analyzer);
insert_statement (analyzer.insert_block, decl);
decl.check (context);
insert_statement (context.analyzer.insert_block, decl);
int i = 0;
ExpressionStatement stmt = null;
foreach (var expr in tuple.get_expressions ()) {
if (stmt != null) {
stmt.check (analyzer);
insert_statement (analyzer.insert_block, stmt);
stmt.check (context);
insert_statement (context.analyzer.insert_block, stmt);
}
var temp_access = new MemberAccess.simple (local.name, right.source_reference);
......@@ -129,14 +129,14 @@ public class Vala.Assignment : Expression {
i++;
}
analyzer.replaced_nodes.add (this);
context.analyzer.replaced_nodes.add (this);
parent_node.replace_expression (this, stmt.expression);
return stmt.expression.check (analyzer);
return stmt.expression.check (context);
}
left.lvalue = true;
if (!left.check (analyzer)) {
if (!left.check (context)) {
// skip on error in inner expression
error = true;
return false;
......@@ -146,7 +146,7 @@ public class Vala.Assignment : Expression {
var ma = (MemberAccess) left;
if ((!(ma.symbol_reference is Signal || ma.symbol_reference is DynamicProperty) && ma.value_type == null) ||
(ma.inner == null && ma.member_name == "this" && analyzer.is_in_instance_method ())) {
(ma.inner == null && ma.member_name == "this" && context.analyzer.is_in_instance_method ())) {
error = true;
Report.error (source_reference, "unsupported lvalue in assignment");
return false;
......@@ -165,11 +165,11 @@ public class Vala.Assignment : Expression {
if (ma.symbol_reference is DynamicSignal) {
// target_type not available for dynamic signals
if (!analyzer.context.deprecated) {
if (!context.deprecated) {
Report.warning (source_reference, "deprecated syntax, use `connect' method instead");
}
} else if (ma.symbol_reference is Signal) {
if (!analyzer.context.deprecated) {
if (!context.deprecated) {
Report.warning (source_reference, "deprecated syntax, use `connect' method instead");
}
var sig = (Signal) ma.symbol_reference;
......@@ -181,7 +181,7 @@ public class Vala.Assignment : Expression {
} else if (left is ElementAccess) {
var ea = (ElementAccess) left;
if (ea.container.value_type.data_type == analyzer.string_type.data_type) {
if (ea.container.value_type.data_type == context.analyzer.string_type.data_type) {
error = true;
Report.error (ea.source_reference, "strings are immutable");
return false;
......@@ -196,7 +196,7 @@ public class Vala.Assignment : Expression {
}
set_call.add_argument (right);
parent_node.replace_expression (this, set_call);
return set_call.check (analyzer);
return set_call.check (context);
} else {
right.target_type = left.value_type;
}
......@@ -208,7 +208,7 @@ public class Vala.Assignment : Expression {
return false;
}
if (!right.check (analyzer)) {
if (!right.check (context)) {
// skip on error in inner expression
error = true;
return false;
......@@ -252,7 +252,7 @@ public class Vala.Assignment : Expression {
}
right = bin;
right.check (analyzer);
right.check (context);
operator = AssignmentOperator.SIMPLE;
}
......@@ -306,14 +306,14 @@ public class Vala.Assignment : Expression {
}
if (prop.set_accessor == null
|| (!prop.set_accessor.writable && !(analyzer.find_current_method () is CreationMethod || analyzer.is_in_constructor ()))) {
|| (!prop.set_accessor.writable && !(context.analyzer.find_current_method () is CreationMethod || context.analyzer.is_in_constructor ()))) {
ma.error = true;
Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
return false;
} else if (!analyzer.context.deprecated
} else if (!context.deprecated
&& !prop.set_accessor.writable
&& analyzer.find_current_method () is CreationMethod) {
if (ma.inner.symbol_reference != analyzer.find_current_method ().this_parameter) {
&& context.analyzer.find_current_method () is CreationMethod) {
if (ma.inner.symbol_reference != context.analyzer.find_current_method ().this_parameter) {
// trying to set construct-only property in creation method for foreign instance
Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ()));
return false;
......
......@@ -49,36 +49,36 @@ public class Vala.BaseAccess : Expression {
return true;
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
checked = true;
if (!analyzer.is_in_instance_method ()) {
if (!context.analyzer.is_in_instance_method ()) {
error = true;
Report.error (source_reference, "Base access invalid outside of instance methods");
return false;
}
if (analyzer.current_class == null) {
if (analyzer.current_struct == null) {
if (context.analyzer.current_class == null) {
if (context.analyzer.current_struct == null) {
error = true;
Report.error (source_reference, "Base access invalid outside of class and struct");
return false;
} else if (analyzer.current_struct.base_type == null) {
} else if (context.analyzer.current_struct.base_type == null) {
error = true;
Report.error (source_reference, "Base access invalid without base type");
return false;
}
value_type = analyzer.current_struct.base_type;
} else if (analyzer.current_class.base_class == null) {
value_type = context.analyzer.current_struct.base_type;
} else if (context.analyzer.current_class.base_class == null) {
error = true;
Report.error (source_reference, "Base access invalid without base class");
return false;
} else {
foreach (var base_type in analyzer.current_class.get_base_types ()) {
foreach (var base_type in context.analyzer.current_class.get_base_types ()) {
if (base_type.data_type is Class) {
value_type = base_type.copy ();
value_type.value_owned = false;
......
......@@ -141,7 +141,7 @@ public class Vala.BinaryExpression : Expression {
return left.is_non_null () && right.is_non_null ();
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
......@@ -150,14 +150,14 @@ public class Vala.BinaryExpression : Expression {
// some expressions are not in a block,
// for example, expressions in method contracts
if (analyzer.current_symbol is Block
if (context.analyzer.current_symbol is Block
&& (operator == BinaryOperator.AND || operator == BinaryOperator.OR)) {
// convert conditional expression into if statement
// required for flow analysis and exception handling
var local = new LocalVariable (analyzer.bool_type.copy (), get_temp_name (), null, source_reference);
var local = new LocalVariable (context.analyzer.bool_type.copy (), get_temp_name (), null, source_reference);
var decl = new DeclarationStatement (local, source_reference);
decl.check (analyzer);
decl.check (context);
var right_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, right.source_reference), right, AssignmentOperator.SIMPLE, right.source_reference), right.source_reference);
......@@ -176,17 +176,17 @@ public class Vala.BinaryExpression : Expression {
var if_stmt = new IfStatement (left, true_block, false_block, source_reference);
insert_statement (analyzer.insert_block, decl);
insert_statement (analyzer.insert_block, if_stmt);
insert_statement (context.analyzer.insert_block, decl);
insert_statement (context.analyzer.insert_block, if_stmt);
if (!if_stmt.check (analyzer)) {
if (!if_stmt.check (context)) {
error = true;
return false;
}
var ma = new MemberAccess.simple (local.name, source_reference);
ma.target_type = target_type;
ma.check (analyzer);
ma.check (context);
parent_node.replace_expression (this, ma);
......@@ -196,7 +196,7 @@ public class Vala.BinaryExpression : Expression {
if (operator == BinaryOperator.COALESCE) {
var local = new LocalVariable (null, get_temp_name (), left, source_reference);
var decl = new DeclarationStatement (local, source_reference);
decl.check (analyzer);
decl.check (context);
var right_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, right.source_reference), right, AssignmentOperator.SIMPLE, right.source_reference), right.source_reference);
......@@ -208,24 +208,24 @@ public class Vala.BinaryExpression : Expression {
var if_stmt = new IfStatement (cond, true_block, null, source_reference);
insert_statement (analyzer.insert_block, decl);
insert_statement (analyzer.insert_block, if_stmt);
insert_statement (context.analyzer.insert_block, decl);
insert_statement (context.analyzer.insert_block, if_stmt);
if (!if_stmt.check (analyzer)) {
if (!if_stmt.check (context)) {
error = true;
return false;
}
var ma = new MemberAccess.simple (local.name, source_reference);
ma.target_type = target_type;
ma.check (analyzer);
ma.check (context);
parent_node.replace_expression (this, ma);
return true;
}
if (!left.check (analyzer) || !right.check (analyzer)) {
if (!left.check (context) || !right.check (context)) {
/* if there were any errors in inner expressions, skip type check */
error = true;
return false;
......@@ -243,31 +243,31 @@ public class Vala.BinaryExpression : Expression {
return false;
}
if (left.value_type.data_type == analyzer.string_type.data_type
if (left.value_type.data_type == context.analyzer.string_type.data_type
&& operator == BinaryOperator.PLUS) {
// string concatenation
if (analyzer.context.profile == Profile.DOVA) {
if (context.profile == Profile.DOVA) {
var concat_call = new MethodCall (new MemberAccess (left, "concat", source_reference), source_reference);
concat_call.add_argument (right);
concat_call.target_type = target_type;
parent_node.replace_expression (this, concat_call);
return concat_call.check (analyzer);
return concat_call.check (context);
}
if (right.value_type == null || right.value_type.data_type != analyzer.string_type.data_type) {
if (right.value_type == null || right.value_type.data_type != context.analyzer.string_type.data_type) {
error = true;
Report.error (source_reference, "Operands must be strings");
return false;
}
value_type = analyzer.string_type.copy ();
value_type = context.analyzer.string_type.copy ();
if (left.is_constant () && right.is_constant ()) {
value_type.value_owned = false;
} else {
value_type.value_owned = true;
}
} else if (analyzer.context.profile == Profile.DOVA && left.value_type.data_type == analyzer.list_type.data_type
} else if (context.profile == Profile.DOVA && left.value_type.data_type == context.analyzer.list_type.data_type
&& operator == BinaryOperator.PLUS) {
// list concatenation
......@@ -275,8 +275,8 @@ public class Vala.BinaryExpression : Expression {
concat_call.add_argument (right);
concat_call.target_type = target_type;
parent_node.replace_expression (this, concat_call);
return concat_call.check (analyzer);
} else if (analyzer.context.profile != Profile.DOVA && left.value_type is ArrayType && operator == BinaryOperator.PLUS) {
return concat_call.check (context);
} else if (context.profile != Profile.DOVA && left.value_type is ArrayType && operator == BinaryOperator.PLUS) {
// array concatenation
var array_type = (ArrayType) left.value_type;
......@@ -313,16 +313,16 @@ public class Vala.BinaryExpression : Expression {
}
} else if (right.value_type is PointerType) {
// pointer arithmetic: pointer - pointer
if (analyzer.context.profile == Profile.DOVA) {
value_type = analyzer.long_type;
if (context.profile == Profile.DOVA) {
value_type = context.analyzer.long_type;
} else {
value_type = analyzer.size_t_type;
value_type = context.analyzer.size_t_type;
}
}
}
if (value_type == null) {
value_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
value_type = context.analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
}
if (value_type == null) {
......@@ -334,7 +334,7 @@ public class Vala.BinaryExpression : Expression {
|| operator == BinaryOperator.SHIFT_LEFT
|| operator == BinaryOperator.SHIFT_RIGHT
|| operator == BinaryOperator.BITWISE_XOR) {
value_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
value_type = context.analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
if (value_type == null) {
error = true;
......@@ -345,8 +345,8 @@ public class Vala.BinaryExpression : Expression {
|| operator == BinaryOperator.GREATER_THAN
|| operator == BinaryOperator.LESS_THAN_OR_EQUAL
|| operator == BinaryOperator.GREATER_THAN_OR_EQUAL) {
if (left.value_type.compatible (analyzer.string_type)
&& right.value_type.compatible (analyzer.string_type)) {
if (left.value_type.compatible (context.analyzer.string_type)
&& right.value_type.compatible (context.analyzer.string_type)) {
// string comparison
} else if (left.value_type is PointerType && right.value_type is PointerType) {
// pointer arithmetic
......@@ -355,9 +355,9 @@ public class Vala.BinaryExpression : Expression {
if (chained) {
var lbe = (BinaryExpression) left;
resulting_type = analyzer.get_arithmetic_result_type (lbe.right.value_type, right.value_type);
resulting_type = context.analyzer.get_arithmetic_result_type (lbe.right.value_type, right.value_type);
} else {
resulting_type = analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
resulting_type = context.analyzer.get_arithmetic_result_type (left.value_type, right.value_type);
}
if (resulting_type == null) {
......@@ -374,7 +374,7 @@ public class Vala.BinaryExpression : Expression {
right.target_type.value_owned = false;
}
value_type = analyzer.bool_type;
value_type = context.analyzer.bool_type;
} else if (operator == BinaryOperator.EQUALITY
|| operator == BinaryOperator.INEQUALITY) {
/* relational operation */
......@@ -400,10 +400,10 @@ public class Vala.BinaryExpression : Expression {
}
}
if (left.value_type.compatible (analyzer.string_type)
&& right.value_type.compatible (analyzer.string_type)) {
if (left.value_type.compatible (context.analyzer.string_type)
&& right.value_type.compatible (context.analyzer.string_type)) {
// string comparison
if (analyzer.context.profile == Profile.DOVA) {
if (context.profile == Profile.DOVA) {
var string_ma = new MemberAccess.simple ("string", source_reference);
string_ma.qualified = true;
var equals_call = new MethodCall (new MemberAccess (string_ma, "equals", source_reference), source_reference);
......@@ -411,16 +411,16 @@ public class Vala.BinaryExpression : Expression {
equals_call.add_argument (right);
if (operator == BinaryOperator.EQUALITY) {
parent_node.replace_expression (this, equals_call);
return equals_call.check (analyzer);
return equals_call.check (context);
} else {
var not = new UnaryExpression (UnaryOperator.LOGICAL_NEGATION, equals_call, source_reference);
parent_node.replace_expression (this, not);
return not.check (analyzer);
return not.check (context);
}
}
}
value_type = analyzer.bool_type;
value_type = context.analyzer.bool_type;
} else if (operator == BinaryOperator.BITWISE_AND
|| operator == BinaryOperator.BITWISE_OR) {
// integer type or flags type
......@@ -428,15 +428,15 @@ public class Vala.BinaryExpression : Expression {
value_type = left.value_type;
} else if (operator == BinaryOperator.AND
|| operator == BinaryOperator.OR) {
if (!left.value_type.compatible (analyzer.bool_type) || !right.value_type.compatible (analyzer.bool_type)) {
if (!left.value_type.compatible (context.analyzer.bool_type) || !right.value_type.compatible (context.analyzer.bool_type)) {
error = true;
Report.error (source_reference, "Operands must be boolean");
}
value_type = analyzer.bool_type;
value_type = context.analyzer.bool_type;
} else if (operator == BinaryOperator.IN) {
if (left.value_type.compatible (analyzer.int_type)
&& right.value_type.compatible (analyzer.int_type)) {
if (left.value_type.compatible (context.analyzer.int_type)
&& right.value_type.compatible (context.analyzer.int_type)) {
// integers or enums
} else if (right.value_type is ArrayType) {
if (!left.value_type.compatible (((ArrayType) right.value_type).element_type)) {
......@@ -455,7 +455,7 @@ public class Vala.BinaryExpression : Expression {
error = true;
return false;
}
if (!contains_method.return_type.compatible (analyzer.bool_type)) {
if (!contains_method.return_type.compatible (context.analyzer.bool_type)) {
Report.error (source_reference, "`%s' must return a boolean value".printf (contains_method.get_full_name ()));
error = true;
return false;
......@@ -464,10 +464,10 @@ public class Vala.BinaryExpression : Expression {
var contains_call = new MethodCall (new MemberAccess (right, "contains"));
contains_call.add_argument (left);
parent_node.replace_expression (this, contains_call);
return contains_call.check (analyzer);
return contains_call.check (context);
}
value_type = analyzer.bool_type;
value_type = context.analyzer.bool_type;
} else {
assert_not_reached ();
......
......@@ -135,22 +135,22 @@ public class Vala.Block : Symbol, Statement {
}
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
checked = true;
owner = analyzer.current_symbol.scope;
owner = context.analyzer.current_symbol.scope;
var old_symbol = analyzer.current_symbol;
var old_insert_block = analyzer.insert_block;
analyzer.current_symbol = this;
analyzer.insert_block = this;
var old_symbol = context.analyzer.current_symbol;
var old_insert_block = context.analyzer.insert_block;
context.analyzer.current_symbol = this;
context.analyzer.insert_block = this;
for (int i = 0; i < statement_list.size; i++) {
statement_list[i].check (analyzer);
statement_list[i].check (context);
}
foreach (LocalVariable local in get_local_variables ()) {
......@@ -166,8 +166,8 @@ public class Vala.Block : Symbol, Statement {
add_error_types (stmt.get_error_types ());
}
analyzer.current_symbol = old_symbol;
analyzer.insert_block = old_insert_block;
context.analyzer.current_symbol = old_symbol;
context.analyzer.insert_block = old_insert_block;
return !error;
}
......
......@@ -61,14 +61,14 @@ public class Vala.BooleanLiteral : Literal {
return true;
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
checked = true;
value_type = analyzer.bool_type;
value_type = context.analyzer.bool_type;
return !error;
}
......
......@@ -109,14 +109,14 @@ public class Vala.CastExpression : Expression {
}
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
checked = true;
if (!inner.check (analyzer)) {
if (!inner.check (context)) {
error = true;
return false;
}
......@@ -133,7 +133,7 @@ public class Vala.CastExpression : Expression {
type_reference.nullable = false;
}
type_reference.check (analyzer);
type_reference.check (context);
// FIXME: check whether cast is allowed
......
......@@ -109,7 +109,7 @@ public class Vala.CatchClause : CodeNode {
}
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
......@@ -125,16 +125,16 @@ public class Vala.CatchClause : CodeNode {
error_variable.checked = true;
} else {
// generic catch clause
if (analyzer.context.profile == Profile.GOBJECT) {
if (context.profile == Profile.GOBJECT) {
error_type = new ErrorType (null, null, source_reference);
} else {
error_type = analyzer.error_type;
error_type = context.analyzer.error_type;
}
}
error_type.check (analyzer);
error_type.check (context);
body.check (analyzer);
body.check (context);
return !error;
}
......
......@@ -83,20 +83,20 @@ public class Vala.CharacterLiteral : Literal {
return value;
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
checked = true;
if (analyzer.context.profile == Profile.DOVA) {
value_type = new IntegerType ((Struct) analyzer.root_symbol.scope.lookup ("char"), get_char ().to_string (), "int");
if (context.profile == Profile.DOVA) {
value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("char"), get_char ().to_string (), "int");
} else {
if (get_char () < 128) {
value_type = new IntegerType ((Struct) analyzer.root_symbol.scope.lookup ("char"));
value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("char"));
} else {
value_type = new IntegerType ((Struct) analyzer.root_symbol.scope.lookup ("unichar"));
value_type = new IntegerType ((Struct) context.analyzer.root_symbol.scope.lookup ("unichar"));
}
}
......
......@@ -995,7 +995,7 @@ public class Vala.Class : ObjectTypeSymbol {
return false;
}
public override bool check (SemanticAnalyzer analyzer) {
public override bool check (CodeContext context) {
if (checked) {
return !error;
}
...