From: Jürg Billeter Date: Mon, 10 Nov 2008 22:01:51 +0000 (+0000) Subject: Remove unnecessary accept calls in semantic analyzer X-Git-Tag: VALA_0_5_2~101 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a86469ccc657e4e4cfe8449c2e4de83206195c24;p=thirdparty%2Fvala.git Remove unnecessary accept calls in semantic analyzer 2008-11-10 Jürg Billeter * vala/valaaddressofexpression.vala: * vala/valaarraycreationexpression.vala: * vala/valaassignment.vala: * vala/valabinaryexpression.vala: * vala/valablock.vala: * vala/valacastexpression.vala: * vala/valacatchclause.vala: * vala/valaclass.vala: * vala/valaconditionalexpression.vala: * vala/valaconstant.vala: * vala/valaconstructor.vala: * vala/valacreationmethod.vala: * vala/valadeclarationstatement.vala: * vala/valadelegate.vala: * vala/valadeletestatement.vala: * vala/valadestructor.vala: * vala/valadostatement.vala: * vala/valaelementaccess.vala: * vala/valaenum.vala: * vala/valaenumvalue.vala: * vala/valaerrorcode.vala: * vala/valaerrordomain.vala: * vala/valaexpressionstatement.vala: * vala/valafield.vala: * vala/valaforeachstatement.vala: * vala/valaformalparameter.vala: * vala/valaforstatement.vala: * vala/valaifstatement.vala: * vala/valainitializerlist.vala: * vala/valainterface.vala: * vala/valainvocationexpression.vala: * vala/valalambdaexpression.vala: * vala/valalocalvariable.vala: * vala/valalockstatement.vala: * vala/valamemberaccess.vala: * vala/valamemberinitializer.vala: * vala/valamethod.vala: * vala/valanamespace.vala: * vala/valaobjectcreationexpression.vala: * vala/valaparenthesizedexpression.vala: * vala/valapointerindirection.vala: * vala/valapostfixexpression.vala: * vala/valaproperty.vala: * vala/valapropertyaccessor.vala: * vala/valareferencetransferexpression.vala: * vala/valareturnstatement.vala: * vala/valasemanticanalyzer.vala: * vala/valasignal.vala: * vala/valasizeofexpression.vala: * vala/valasourcefile.vala: * vala/valastruct.vala: * vala/valaswitchlabel.vala: * vala/valaswitchsection.vala: * vala/valaswitchstatement.vala: * vala/valathrowstatement.vala: * vala/valatrystatement.vala: * vala/valatypecheck.vala: * vala/valatypeofexpression.vala: * vala/valaunaryexpression.vala: * vala/valawhilestatement.vala: * vala/valayieldstatement.vala: Remove unnecessary accept calls in semantic analyzer svn path=/trunk/; revision=2010 --- diff --git a/ChangeLog b/ChangeLog index b5b677a64..9d6ab0aa2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,69 @@ +2008-11-10 Jürg Billeter + + * vala/valaaddressofexpression.vala: + * vala/valaarraycreationexpression.vala: + * vala/valaassignment.vala: + * vala/valabinaryexpression.vala: + * vala/valablock.vala: + * vala/valacastexpression.vala: + * vala/valacatchclause.vala: + * vala/valaclass.vala: + * vala/valaconditionalexpression.vala: + * vala/valaconstant.vala: + * vala/valaconstructor.vala: + * vala/valacreationmethod.vala: + * vala/valadeclarationstatement.vala: + * vala/valadelegate.vala: + * vala/valadeletestatement.vala: + * vala/valadestructor.vala: + * vala/valadostatement.vala: + * vala/valaelementaccess.vala: + * vala/valaenum.vala: + * vala/valaenumvalue.vala: + * vala/valaerrorcode.vala: + * vala/valaerrordomain.vala: + * vala/valaexpressionstatement.vala: + * vala/valafield.vala: + * vala/valaforeachstatement.vala: + * vala/valaformalparameter.vala: + * vala/valaforstatement.vala: + * vala/valaifstatement.vala: + * vala/valainitializerlist.vala: + * vala/valainterface.vala: + * vala/valainvocationexpression.vala: + * vala/valalambdaexpression.vala: + * vala/valalocalvariable.vala: + * vala/valalockstatement.vala: + * vala/valamemberaccess.vala: + * vala/valamemberinitializer.vala: + * vala/valamethod.vala: + * vala/valanamespace.vala: + * vala/valaobjectcreationexpression.vala: + * vala/valaparenthesizedexpression.vala: + * vala/valapointerindirection.vala: + * vala/valapostfixexpression.vala: + * vala/valaproperty.vala: + * vala/valapropertyaccessor.vala: + * vala/valareferencetransferexpression.vala: + * vala/valareturnstatement.vala: + * vala/valasemanticanalyzer.vala: + * vala/valasignal.vala: + * vala/valasizeofexpression.vala: + * vala/valasourcefile.vala: + * vala/valastruct.vala: + * vala/valaswitchlabel.vala: + * vala/valaswitchsection.vala: + * vala/valaswitchstatement.vala: + * vala/valathrowstatement.vala: + * vala/valatrystatement.vala: + * vala/valatypecheck.vala: + * vala/valatypeofexpression.vala: + * vala/valaunaryexpression.vala: + * vala/valawhilestatement.vala: + * vala/valayieldstatement.vala: + + Remove unnecessary accept calls in semantic analyzer + 2008-11-10 Jürg Billeter * vala/valaaddressofexpression.vala: diff --git a/vala/valaaddressofexpression.vala b/vala/valaaddressofexpression.vala index 38781bb89..4874a2b0a 100644 --- a/vala/valaaddressofexpression.vala +++ b/vala/valaaddressofexpression.vala @@ -77,7 +77,8 @@ public class Vala.AddressofExpression : Expression { checked = true; - if (inner.error) { + if (!inner.check (analyzer)) { + error = true; return false; } if (!(inner.value_type is ValueType diff --git a/vala/valaarraycreationexpression.vala b/vala/valaarraycreationexpression.vala index 0c68c435d..48fbc086f 100644 --- a/vala/valaarraycreationexpression.vala +++ b/vala/valaarraycreationexpression.vala @@ -109,7 +109,7 @@ public class Vala.ArrayCreationExpression : Expression { private int create_sizes_from_initializer_list (SemanticAnalyzer analyzer, InitializerList il, int rank, Gee.List sl) { var init = new IntegerLiteral (il.size.to_string (), il.source_reference); - init.accept (analyzer); + init.check (analyzer); sl.add (init); int subsize = -1; @@ -155,18 +155,18 @@ public class Vala.ArrayCreationExpression : Expression { var initlist = initializer_list; if (element_type != null) { - element_type.accept (analyzer); + element_type.check (analyzer); } foreach (Expression e in size) { - e.accept (analyzer); + e.check (analyzer); } var calc_sizes = new ArrayList (); if (initlist != null) { initlist.target_type = new ArrayType (element_type, rank, source_reference); - initlist.accept (analyzer); + initlist.check (analyzer); var ret = create_sizes_from_initializer_list (analyzer, initlist, rank, calc_sizes); if (ret == -1) { diff --git a/vala/valaassignment.vala b/vala/valaassignment.vala index 2985ca4d9..04af2b659 100644 --- a/vala/valaassignment.vala +++ b/vala/valaassignment.vala @@ -107,9 +107,7 @@ public class Vala.Assignment : Expression { left.lvalue = true; - left.accept (analyzer); - - if (left.error) { + if (!left.check (analyzer)) { // skip on error in inner expression error = true; return false; @@ -161,9 +159,7 @@ public class Vala.Assignment : Expression { return false; } - right.accept (analyzer); - - if (right.error) { + if (!right.check (analyzer)) { // skip on error in inner expression error = true; return false; @@ -207,7 +203,7 @@ public class Vala.Assignment : Expression { } right = bin; - right.accept (analyzer); + right.check (analyzer); operator = AssignmentOperator.SIMPLE; } @@ -365,7 +361,7 @@ public class Vala.Assignment : Expression { * increment calls */ } } else { - return false; + return true; } if (left.value_type != null) { diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala index 4eafb9832..a3743c715 100644 --- a/vala/valabinaryexpression.vala +++ b/vala/valabinaryexpression.vala @@ -145,7 +145,7 @@ public class Vala.BinaryExpression : Expression { checked = true; - if (left.error || right.error) { + if (!left.check (analyzer) || !right.check (analyzer)) { /* if there were any errors in inner expressions, skip type check */ error = true; return false; diff --git a/vala/valablock.vala b/vala/valablock.vala index 7f050e314..d715b74cc 100644 --- a/vala/valablock.vala +++ b/vala/valablock.vala @@ -101,13 +101,15 @@ public class Vala.Block : Symbol, Statement { owner = analyzer.current_symbol.scope; analyzer.current_symbol = this; - accept_children (analyzer); + foreach (Statement stmt in statement_list) { + stmt.check (analyzer); + } foreach (LocalVariable local in get_local_variables ()) { local.active = false; } - foreach (Statement stmt in get_statements()) { + foreach (Statement stmt in get_statements ()) { add_error_types (stmt.get_error_types ()); } diff --git a/vala/valacastexpression.vala b/vala/valacastexpression.vala index 5703815f6..d94041ca3 100644 --- a/vala/valacastexpression.vala +++ b/vala/valacastexpression.vala @@ -105,11 +105,13 @@ public class Vala.CastExpression : Expression { checked = true; - if (inner.error) { + if (!inner.check (analyzer)) { error = true; return false; } + type_reference.check (analyzer); + // FIXME: check whether cast is allowed analyzer.current_source_file.add_type_dependency (type_reference, SourceFileDependencyType.SOURCE); diff --git a/vala/valacatchclause.vala b/vala/valacatchclause.vala index 0f1411032..0cb7d0189 100644 --- a/vala/valacatchclause.vala +++ b/vala/valacatchclause.vala @@ -113,7 +113,9 @@ public class Vala.CatchClause : CodeNode { error_type = new ErrorType (null, null, source_reference); } - accept_children (analyzer); + error_type.check (analyzer); + + body.check (analyzer); return !error; } diff --git a/vala/valaclass.vala b/vala/valaclass.vala index 9baec15df..297ec0251 100644 --- a/vala/valaclass.vala +++ b/vala/valaclass.vala @@ -884,7 +884,66 @@ public class Vala.Class : ObjectTypeSymbol { analyzer.current_source_file.add_type_dependency (base_type_reference, SourceFileDependencyType.HEADER_FULL); } - accept_children (analyzer); + foreach (DataType type in base_types) { + type.check (analyzer); + } + + foreach (TypeParameter p in type_parameters) { + p.check (analyzer); + } + + /* process enums first to avoid order problems in C code */ + foreach (Enum en in enums) { + en.check (analyzer); + } + + foreach (Field f in fields) { + f.check (analyzer); + } + + foreach (Constant c in constants) { + c.check (analyzer); + } + + foreach (Method m in methods) { + m.check (analyzer); + } + + foreach (Property prop in properties) { + prop.check (analyzer); + } + + foreach (Signal sig in signals) { + sig.check (analyzer); + } + + if (constructor != null) { + constructor.check (analyzer); + } + + if (class_constructor != null) { + class_constructor.check (analyzer); + } + + if (static_constructor != null) { + static_constructor.check (analyzer); + } + + if (destructor != null) { + destructor.check (analyzer); + } + + foreach (Class cl in classes) { + cl.check (analyzer); + } + + foreach (Struct st in structs) { + st.check (analyzer); + } + + foreach (Delegate d in delegates) { + d.check (analyzer); + } /* compact classes cannot implement interfaces */ if (is_compact) { diff --git a/vala/valaconditionalexpression.vala b/vala/valaconditionalexpression.vala index e0d665181..0ba4a859a 100644 --- a/vala/valaconditionalexpression.vala +++ b/vala/valaconditionalexpression.vala @@ -77,7 +77,7 @@ public class Vala.ConditionalExpression : Expression { checked = true; - if (condition.error || false_expression.error || true_expression.error) { + if (!condition.check (analyzer) || !false_expression.check (analyzer) || !true_expression.check (analyzer)) { return false; } diff --git a/vala/valaconstant.vala b/vala/valaconstant.vala index 4dfac387c..555531e29 100644 --- a/vala/valaconstant.vala +++ b/vala/valaconstant.vala @@ -160,7 +160,7 @@ public class Vala.Constant : Member, Lockable { process_attributes (); - type_reference.accept (analyzer); + type_reference.check (analyzer); if (!external_package) { if (initializer == null) { @@ -169,7 +169,7 @@ public class Vala.Constant : Member, Lockable { } else { initializer.target_type = type_reference; - initializer.accept (analyzer); + initializer.check (analyzer); } } diff --git a/vala/valaconstructor.vala b/vala/valaconstructor.vala index a9de8a818..a09027a75 100644 --- a/vala/valaconstructor.vala +++ b/vala/valaconstructor.vala @@ -74,7 +74,9 @@ public class Vala.Constructor : Symbol { owner = analyzer.current_symbol.scope; analyzer.current_symbol = this; - accept_children (analyzer); + if (body != null) { + body.check (analyzer); + } foreach (DataType body_error_type in body.get_error_types ()) { Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string())); diff --git a/vala/valacreationmethod.vala b/vala/valacreationmethod.vala index f7dfe265d..3f183cd0e 100644 --- a/vala/valacreationmethod.vala +++ b/vala/valacreationmethod.vala @@ -137,7 +137,17 @@ public class Vala.CreationMethod : Method { analyzer.current_symbol = this; analyzer.current_return_type = return_type; - accept_children (analyzer); + foreach (FormalParameter param in get_parameters()) { + param.check (analyzer); + } + + foreach (DataType error_type in get_error_types ()) { + error_type.check (analyzer); + } + + if (body != null) { + body.check (analyzer); + } analyzer.current_symbol = old_symbol; analyzer.current_return_type = old_return_type; diff --git a/vala/valadeclarationstatement.vala b/vala/valadeclarationstatement.vala index d29c0d6e4..a11449892 100644 --- a/vala/valadeclarationstatement.vala +++ b/vala/valadeclarationstatement.vala @@ -56,6 +56,8 @@ public class Vala.DeclarationStatement : CodeNode, Statement { checked = true; + declaration.check (analyzer); + var local = declaration as LocalVariable; if (local != null && local.initializer != null) { foreach (DataType error_type in local.initializer.get_error_types ()) { diff --git a/vala/valadelegate.vala b/vala/valadelegate.vala index 25973d6f8..89e723e28 100644 --- a/vala/valadelegate.vala +++ b/vala/valadelegate.vala @@ -343,7 +343,15 @@ public class Vala.Delegate : TypeSymbol { analyzer.current_source_file = source_reference.file; } - accept_children (analyzer); + foreach (TypeParameter p in type_parameters) { + p.check (analyzer); + } + + return_type.check (analyzer); + + foreach (FormalParameter param in parameters) { + param.check (analyzer); + } analyzer.current_source_file = old_source_file; diff --git a/vala/valadeletestatement.vala b/vala/valadeletestatement.vala index 3bbdd6283..e98408437 100644 --- a/vala/valadeletestatement.vala +++ b/vala/valadeletestatement.vala @@ -51,9 +51,7 @@ public class Vala.DeleteStatement : CodeNode, Statement { checked = true; - accept_children (analyzer); - - if (expression.error) { + if (!expression.check (analyzer)) { // if there was an error in the inner expression, skip this check return false; } diff --git a/vala/valadestructor.vala b/vala/valadestructor.vala index b2eba7d0e..fd4cf4204 100644 --- a/vala/valadestructor.vala +++ b/vala/valadestructor.vala @@ -71,7 +71,9 @@ public class Vala.Destructor : Symbol { owner = analyzer.current_symbol.scope; analyzer.current_symbol = this; - accept_children (analyzer); + if (body != null) { + body.check (analyzer); + } analyzer.current_symbol = analyzer.current_symbol.parent_symbol; diff --git a/vala/valadostatement.vala b/vala/valadostatement.vala index 73db90d41..8700c883c 100644 --- a/vala/valadostatement.vala +++ b/vala/valadostatement.vala @@ -94,9 +94,9 @@ public class Vala.DoStatement : CodeNode, Statement { checked = true; - accept_children (analyzer); + body.check (analyzer); - if (condition.error) { + if (!condition.check (analyzer)) { /* if there was an error in the condition, skip this check */ error = true; return false; diff --git a/vala/valaelementaccess.vala b/vala/valaelementaccess.vala index 0734944d4..296103b25 100644 --- a/vala/valaelementaccess.vala +++ b/vala/valaelementaccess.vala @@ -93,7 +93,7 @@ public class Vala.ElementAccess : Expression { checked = true; - container.accept (analyzer); + container.check (analyzer); if (container.value_type == null) { /* don't proceed if a child expression failed */ @@ -114,7 +114,7 @@ public class Vala.ElementAccess : Expression { } foreach (Expression index in get_indices ()) { - index.accept (analyzer); + index.check (analyzer); } bool index_int_type_check = true; diff --git a/vala/valaenum.vala b/vala/valaenum.vala index 526cd4dac..d1da55e68 100644 --- a/vala/valaenum.vala +++ b/vala/valaenum.vala @@ -313,7 +313,13 @@ public class Vala.Enum : TypeSymbol { analyzer.current_source_file = source_reference.file; } - accept_children (analyzer); + foreach (EnumValue value in values) { + value.check (analyzer); + } + + foreach (Method m in methods) { + m.check (analyzer); + } analyzer.current_source_file = old_source_file; diff --git a/vala/valaenumvalue.vala b/vala/valaenumvalue.vala index 644c17bf2..2e9abd236 100644 --- a/vala/valaenumvalue.vala +++ b/vala/valaenumvalue.vala @@ -138,7 +138,9 @@ public class Vala.EnumValue : Symbol { process_attributes (); - accept_children (analyzer); + if (value != null) { + value.check (analyzer); + } return !error; } diff --git a/vala/valaerrorcode.vala b/vala/valaerrorcode.vala index 840d4b885..e46328f16 100644 --- a/vala/valaerrorcode.vala +++ b/vala/valaerrorcode.vala @@ -80,7 +80,9 @@ public class Vala.ErrorCode : TypeSymbol { checked = true; - accept_children (analyzer); + if (value != null) { + value.check (analyzer); + } return !error; } diff --git a/vala/valaerrordomain.vala b/vala/valaerrordomain.vala index 7f061ec39..92ec0b39b 100644 --- a/vala/valaerrordomain.vala +++ b/vala/valaerrordomain.vala @@ -225,7 +225,13 @@ public class Vala.ErrorDomain : TypeSymbol { process_attributes (); - accept_children (analyzer); + foreach (ErrorCode ecode in codes) { + ecode.check (analyzer); + } + + foreach (Method m in methods) { + m.check (analyzer); + } return !error; } diff --git a/vala/valaexpressionstatement.vala b/vala/valaexpressionstatement.vala index 179b8078c..6dc66df31 100644 --- a/vala/valaexpressionstatement.vala +++ b/vala/valaexpressionstatement.vala @@ -93,7 +93,7 @@ public class Vala.ExpressionStatement : CodeNode, Statement { checked = true; - if (expression.error) { + if (!expression.check (analyzer)) { // ignore inner error error = true; return false; diff --git a/vala/valafield.vala b/vala/valafield.vala index 9feb2826a..2b9fd1fc6 100644 --- a/vala/valafield.vala +++ b/vala/valafield.vala @@ -211,7 +211,11 @@ public class Vala.Field : Member, Lockable { initializer.target_type = field_type; } - accept_children (analyzer); + field_type.check (analyzer); + + if (initializer != null) { + initializer.check (analyzer); + } if (binding == MemberBinding.INSTANCE && parent_symbol is Interface) { error = true; diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala index 2e53d5c7a..949445bfd 100644 --- a/vala/valaforeachstatement.vala +++ b/vala/valaforeachstatement.vala @@ -143,9 +143,7 @@ public class Vala.ForeachStatement : Block { checked = true; // analyze collection expression first, used for type inference - collection.accept (analyzer); - - if (collection.error) { + if (!collection.check (analyzer)) { // ignore inner error error = true; return false; @@ -230,7 +228,7 @@ public class Vala.ForeachStatement : Block { owner = analyzer.current_symbol.scope; analyzer.current_symbol = this; - body.accept (analyzer); + body.check (analyzer); foreach (LocalVariable local in get_local_variables ()) { local.active = false; diff --git a/vala/valaformalparameter.vala b/vala/valaformalparameter.vala index b5733945c..418309c9f 100644 --- a/vala/valaformalparameter.vala +++ b/vala/valaformalparameter.vala @@ -188,7 +188,13 @@ public class Vala.FormalParameter : Symbol { parameter_type.check (analyzer); } - accept_children (analyzer); + if (!ellipsis) { + parameter_type.check (analyzer); + + if (default_expression != null) { + default_expression.check (analyzer); + } + } if (analyzer.context.non_null && default_expression != null) { if (default_expression is NullLiteral diff --git a/vala/valaforstatement.vala b/vala/valaforstatement.vala index 6e309ecdc..cf02aa726 100644 --- a/vala/valaforstatement.vala +++ b/vala/valaforstatement.vala @@ -164,7 +164,19 @@ public class Vala.ForStatement : CodeNode, Statement { checked = true; - accept_children (analyzer); + foreach (Expression init_expr in initializer) { + init_expr.check (analyzer); + } + + if (condition != null) { + condition.check (analyzer); + } + + foreach (Expression it_expr in iterator) { + it_expr.check (analyzer); + } + + body.check (analyzer); if (condition != null && condition.error) { /* if there was an error in the condition, skip this check */ diff --git a/vala/valaifstatement.vala b/vala/valaifstatement.vala index 4602097c1..4a97f81c1 100644 --- a/vala/valaifstatement.vala +++ b/vala/valaifstatement.vala @@ -94,7 +94,12 @@ public class Vala.IfStatement : CodeNode, Statement { checked = true; - accept_children (analyzer); + condition.check (analyzer); + + true_statement.check (analyzer); + if (false_statement != null) { + false_statement.check (analyzer); + } if (condition.error) { /* if there was an error in the condition, skip this check */ diff --git a/vala/valainitializerlist.vala b/vala/valainitializerlist.vala index b6a58d5d7..4b10f1607 100644 --- a/vala/valainitializerlist.vala +++ b/vala/valainitializerlist.vala @@ -142,7 +142,9 @@ public class Vala.InitializerList : Expression { return false; } - accept_children (analyzer); + foreach (Expression expr in initializers) { + expr.check (analyzer); + } bool error = false; foreach (Expression e in get_initializers ()) { diff --git a/vala/valainterface.vala b/vala/valainterface.vala index 195582cb3..51ba8c0a3 100644 --- a/vala/valainterface.vala +++ b/vala/valainterface.vala @@ -590,7 +590,45 @@ public class Vala.Interface : ObjectTypeSymbol { } } - accept_children (analyzer); + foreach (DataType type in prerequisites) { + type.check (analyzer); + } + + foreach (TypeParameter p in type_parameters) { + p.check (analyzer); + } + + foreach (Enum en in enums) { + en.check (analyzer); + } + + foreach (Method m in methods) { + m.check (analyzer); + } + + foreach (Field f in fields) { + f.check (analyzer); + } + + foreach (Property prop in properties) { + prop.check (analyzer); + } + + foreach (Signal sig in signals) { + sig.check (analyzer); + } + + foreach (Class cl in classes) { + cl.check (analyzer); + } + + foreach (Struct st in structs) { + st.check (analyzer); + } + + foreach (Delegate d in delegates) { + d.check (analyzer); + } analyzer.current_source_file = old_source_file; analyzer.current_symbol = old_symbol; diff --git a/vala/valainvocationexpression.vala b/vala/valainvocationexpression.vala index 63fdab9c5..834ea46c0 100644 --- a/vala/valainvocationexpression.vala +++ b/vala/valainvocationexpression.vala @@ -128,9 +128,7 @@ public class Vala.InvocationExpression : Expression { checked = true; - call.accept (analyzer); - - if (call.error) { + if (!call.check (analyzer)) { /* if method resolving didn't succeed, skip this check */ error = true; return false; @@ -172,7 +170,7 @@ public class Vala.InvocationExpression : Expression { struct_creation_expression.target_type = target_type; analyzer.replaced_nodes.add (this); parent_node.replace_expression (this, struct_creation_expression); - struct_creation_expression.accept (analyzer); + struct_creation_expression.check (analyzer); return false; } else if (call is MemberAccess && call.symbol_reference is CreationMethod) { @@ -360,7 +358,7 @@ public class Vala.InvocationExpression : Expression { } foreach (Expression arg in get_argument_list ()) { - arg.accept (analyzer); + arg.check (analyzer); } DataType ret_type; diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala index 3cd074cfa..52415a915 100644 --- a/vala/valalambdaexpression.vala +++ b/vala/valalambdaexpression.vala @@ -189,7 +189,15 @@ public class Vala.LambdaExpression : Expression { /* lambda expressions should be usable like MemberAccess of a method */ symbol_reference = method; - accept_children (analyzer); + if (method == null) { + if (expression_body != null) { + expression_body.check (analyzer); + } else if (statement_body != null) { + statement_body.check (analyzer); + } + } else { + method.check (analyzer); + } value_type = new MethodType (method); diff --git a/vala/valalocalvariable.vala b/vala/valalocalvariable.vala index 1f1e922b9..0b05d91a2 100644 --- a/vala/valalocalvariable.vala +++ b/vala/valalocalvariable.vala @@ -110,7 +110,13 @@ public class Vala.LocalVariable : Symbol { initializer.target_type = variable_type; } - accept_children (analyzer); + if (initializer != null) { + initializer.check (analyzer); + } + + if (variable_type != null) { + variable_type.check (analyzer); + } if (variable_type == null) { /* var type */ diff --git a/vala/valalockstatement.vala b/vala/valalockstatement.vala index 49a0224c7..8f9b5a592 100644 --- a/vala/valalockstatement.vala +++ b/vala/valalockstatement.vala @@ -55,6 +55,9 @@ public class Vala.LockStatement : CodeNode, Statement { checked = true; + resource.check (analyzer); + body.check (analyzer); + /* resource must be a member access and denote a Lockable */ if (!(resource is MemberAccess && resource.symbol_reference is Lockable)) { error = true; diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala index 896236f15..7d5bacf42 100644 --- a/vala/valamemberaccess.vala +++ b/vala/valamemberaccess.vala @@ -182,6 +182,14 @@ public class Vala.MemberAccess : Expression { checked = true; + if (inner != null) { + inner.check (analyzer); + } + + foreach (DataType type_arg in type_argument_list) { + type_arg.check (analyzer); + } + Symbol base_symbol = null; FormalParameter this_parameter = null; bool may_access_instance_members = false; @@ -257,7 +265,7 @@ public class Vala.MemberAccess : Expression { if (pointer_type != null && pointer_type.base_type is ValueType) { // transform foo->bar to (*foo).bar inner = new PointerIndirection (inner, source_reference); - inner.accept (analyzer); + inner.check (analyzer); pointer_member_access = false; } } diff --git a/vala/valamemberinitializer.vala b/vala/valamemberinitializer.vala index 55ab7b598..3ca96b629 100644 --- a/vala/valamemberinitializer.vala +++ b/vala/valamemberinitializer.vala @@ -59,5 +59,9 @@ public class Vala.MemberInitializer : CodeNode { public override void accept (CodeVisitor visitor) { initializer.accept (visitor); } + + public override bool check (SemanticAnalyzer analyzer) { + return initializer.check (analyzer); + } } diff --git a/vala/valamethod.vala b/vala/valamethod.vala index c6f3e2b53..a91412ac8 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -668,7 +668,33 @@ public class Vala.Method : Member { } analyzer.current_source_file.add_type_dependency (return_type, SourceFileDependencyType.SOURCE); - accept_children (analyzer); + if (return_type != null) { + return_type.check (analyzer); + } + + foreach (FormalParameter param in parameters) { + param.check (analyzer); + } + + foreach (DataType error_type in get_error_types ()) { + error_type.check (analyzer); + } + + if (result_var != null) { + result_var.variable_type.check (analyzer); + } + + foreach (Expression precondition in preconditions) { + precondition.check (analyzer); + } + + foreach (Expression postcondition in postconditions) { + postcondition.check (analyzer); + } + + if (body != null) { + body.check (analyzer); + } analyzer.current_symbol = old_symbol; analyzer.current_return_type = old_return_type; diff --git a/vala/valanamespace.vala b/vala/valanamespace.vala index d84b9dff8..2a46ec7f7 100644 --- a/vala/valanamespace.vala +++ b/vala/valanamespace.vala @@ -525,6 +525,10 @@ public class Vala.Namespace : Symbol { process_attributes (); + foreach (Namespace ns in namespaces) { + ns.check (analyzer); + } + return !error; } } diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index c458c042a..0e42c1098 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -158,7 +158,7 @@ public class Vala.ObjectCreationExpression : Expression { checked = true; if (member_name != null) { - member_name.accept (analyzer); + member_name.check (analyzer); } TypeSymbol type = null; @@ -311,7 +311,7 @@ public class Vala.ObjectCreationExpression : Expression { } foreach (Expression arg in args) { - arg.accept (analyzer); + arg.check (analyzer); } analyzer.check_arguments (this, new MethodType (m), m.get_parameters (), args); @@ -324,7 +324,21 @@ public class Vala.ObjectCreationExpression : Expression { add_error_type (call_error_type); } } else if (type_reference is ErrorType) { - accept_children (analyzer); + if (type_reference != null) { + type_reference.check (analyzer); + } + + if (member_name != null) { + member_name.check (analyzer); + } + + foreach (Expression arg in argument_list) { + arg.check (analyzer); + } + + foreach (MemberInitializer init in object_initializer) { + init.check (analyzer); + } if (get_argument_list ().size == 0) { error = true; diff --git a/vala/valaparenthesizedexpression.vala b/vala/valaparenthesizedexpression.vala index c7e2dd5af..e6d0a2ebd 100644 --- a/vala/valaparenthesizedexpression.vala +++ b/vala/valaparenthesizedexpression.vala @@ -82,9 +82,7 @@ public class Vala.ParenthesizedExpression : Expression { inner.target_type = target_type; - accept_children (analyzer); - - if (inner.error) { + if (!inner.check (analyzer)) { // ignore inner error error = true; return false; diff --git a/vala/valapointerindirection.vala b/vala/valapointerindirection.vala index 7ea1354dd..01a27fa94 100644 --- a/vala/valapointerindirection.vala +++ b/vala/valapointerindirection.vala @@ -77,7 +77,7 @@ public class Vala.PointerIndirection : Expression { checked = true; - if (inner.error) { + if (!inner.check (analyzer)) { return false; } if (inner.value_type == null) { diff --git a/vala/valapostfixexpression.vala b/vala/valapostfixexpression.vala index c1d8eba6f..3ff4d6d69 100644 --- a/vala/valapostfixexpression.vala +++ b/vala/valapostfixexpression.vala @@ -69,6 +69,8 @@ public class Vala.PostfixExpression : Expression { checked = true; + inner.check (analyzer); + value_type = inner.value_type; return !error; diff --git a/vala/valaproperty.vala b/vala/valaproperty.vala index 3dc081174..c8fb63f47 100644 --- a/vala/valaproperty.vala +++ b/vala/valaproperty.vala @@ -424,14 +424,14 @@ public class Vala.Property : Member, Lockable { property_type.check (analyzer); if (get_accessor != null) { - get_accessor.accept (analyzer); + get_accessor.check (analyzer); } if (set_accessor != null) { - set_accessor.accept (analyzer); + set_accessor.check (analyzer); } if (default_expression != null) { - default_expression.accept (analyzer); + default_expression.check (analyzer); } // check whether property type is at least as accessible as the property diff --git a/vala/valapropertyaccessor.vala b/vala/valapropertyaccessor.vala index 22069b65d..02ad79cd8 100644 --- a/vala/valapropertyaccessor.vala +++ b/vala/valapropertyaccessor.vala @@ -176,7 +176,9 @@ public class Vala.PropertyAccessor : CodeNode { } } - accept_children (analyzer); + if (body != null) { + body.check (analyzer); + } analyzer.current_return_type = old_return_type; diff --git a/vala/valareferencetransferexpression.vala b/vala/valareferencetransferexpression.vala index 71b965ac6..e30815ae2 100644 --- a/vala/valareferencetransferexpression.vala +++ b/vala/valareferencetransferexpression.vala @@ -81,7 +81,7 @@ public class Vala.ReferenceTransferExpression : Expression { inner.lvalue = true; - accept_children (analyzer); + inner.check (analyzer); if (inner.error) { /* if there was an error in the inner expression, skip type check */ diff --git a/vala/valareturnstatement.vala b/vala/valareturnstatement.vala index 8ea4a7d6d..acea14291 100644 --- a/vala/valareturnstatement.vala +++ b/vala/valareturnstatement.vala @@ -82,9 +82,7 @@ public class Vala.ReturnStatement : CodeNode, Statement { return_expression.target_type = analyzer.current_return_type; } - accept_children (analyzer); - - if (return_expression != null && return_expression.error) { + if (return_expression != null && !return_expression.check (analyzer)) { // ignore inner error error = true; return false; diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 522dade92..8df4672c3 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -122,6 +122,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } current_symbol = root_symbol; + context.root.check (this); context.accept (this); } @@ -130,63 +131,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { next_lambda_id = 0; - file.accept_children (this); - } - - public override void visit_namespace (Namespace ns) { - ns.check (this); - } - - public override void visit_class (Class cl) { - cl.check (this); - } - - public override void visit_struct (Struct st) { - st.check (this); - } - - public override void visit_interface (Interface iface) { - iface.check (this); - } - - public override void visit_enum (Enum en) { - en.check (this); - } - - public override void visit_enum_value (EnumValue ev) { - ev.check (this); - } - - public override void visit_error_domain (ErrorDomain ed) { - ed.check (this); - } - - public override void visit_error_code (ErrorCode ec) { - ec.check (this); - } - - public override void visit_delegate (Delegate d) { - d.check (this); - } - - public override void visit_constant (Constant c) { - c.check (this); - } - - public override void visit_field (Field f) { - f.check (this); - } - - public override void visit_method (Method m) { - m.check (this); - } - - public override void visit_creation_method (CreationMethod m) { - m.check (this); - } - - public override void visit_formal_parameter (FormalParameter p) { - p.check (this); + file.check (this); } // check whether type is at least as accessible as the specified symbol @@ -203,126 +148,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return true; } - public override void visit_property (Property prop) { - prop.check (this); - } - - public override void visit_property_accessor (PropertyAccessor acc) { - acc.check (this); - } - - public override void visit_signal (Signal sig) { - sig.check (this); - } - - public override void visit_constructor (Constructor c) { - c.check (this); - } - - public override void visit_destructor (Destructor d) { - d.check (this); - } - - public override void visit_block (Block b) { - b.check (this); - } - - public override void visit_declaration_statement (DeclarationStatement stmt) { - stmt.check (this); - } - - public override void visit_local_variable (LocalVariable local) { - local.check (this); - } - - public override void visit_initializer_list (InitializerList list) { - list.check (this); - } - - public override void visit_expression_statement (ExpressionStatement stmt) { - stmt.check (this); - } - - public override void visit_if_statement (IfStatement stmt) { - stmt.check (this); - } - - public override void visit_switch_section (SwitchSection section) { - section.check (this); - } - - public override void visit_while_statement (WhileStatement stmt) { - stmt.check (this); - } - - public override void visit_do_statement (DoStatement stmt) { - stmt.check (this); - } - - public override void visit_for_statement (ForStatement stmt) { - stmt.check (this); - } - - public override void visit_foreach_statement (ForeachStatement stmt) { - stmt.check (this); - } - - public override void visit_return_statement (ReturnStatement stmt) { - stmt.check (this); - } - - public override void visit_yield_statement (YieldStatement stmt) { - stmt.check (this); - } - - public override void visit_throw_statement (ThrowStatement stmt) { - stmt.check (this); - } - - public override void visit_try_statement (TryStatement stmt) { - stmt.check (this); - } - - public override void visit_catch_clause (CatchClause clause) { - clause.check (this); - } - - public override void visit_lock_statement (LockStatement stmt) { - stmt.check (this); - } - - public override void visit_delete_statement (DeleteStatement stmt) { - stmt.check (this); - } - - public override void visit_array_creation_expression (ArrayCreationExpression expr) { - expr.check (this); - } - - public override void visit_boolean_literal (BooleanLiteral expr) { - expr.check (this); - } - - public override void visit_character_literal (CharacterLiteral expr) { - expr.check (this); - } - - public override void visit_integer_literal (IntegerLiteral expr) { - expr.check (this); - } - - public override void visit_real_literal (RealLiteral expr) { - expr.check (this); - } - - public override void visit_string_literal (StringLiteral expr) { - expr.check (this); - } - - public override void visit_null_literal (NullLiteral expr) { - expr.check (this); - } - public DataType? get_value_type_for_symbol (Symbol sym, bool lvalue) { if (sym is Field) { var f = (Field) sym; @@ -420,14 +245,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return null; } - public override void visit_parenthesized_expression (ParenthesizedExpression expr) { - expr.check (this); - } - - public override void visit_member_access (MemberAccess expr) { - expr.check (this); - } - public static DataType get_data_type_for_symbol (TypeSymbol sym) { DataType type = null; @@ -449,10 +266,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return type; } - public override void visit_invocation_expression (InvocationExpression expr) { - expr.check (this); - } - public bool check_arguments (Expression expr, DataType mtype, Gee.List params, Gee.List args) { Expression prev_arg = null; Iterator arg_it = args.iterator (); @@ -750,10 +563,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return actual_type; } - public override void visit_element_access (ElementAccess expr) { - expr.check (this); - } - public bool is_in_instance_method () { var sym = current_symbol; while (sym != null) { @@ -776,20 +585,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return false; } - public override void visit_base_access (BaseAccess expr) { - expr.check (this); - } - - public override void visit_postfix_expression (PostfixExpression expr) { - expr.check (this); - } - - public override void visit_object_creation_expression (ObjectCreationExpression expr) { - expr.check (this); - } - public void visit_member_initializer (MemberInitializer init, DataType type) { - init.accept (this); + init.check (this); init.symbol_reference = symbol_lookup_inherited (type.data_type, init.name); if (!(init.symbol_reference is Field || init.symbol_reference is Property)) { @@ -822,34 +619,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } } - public override void visit_sizeof_expression (SizeofExpression expr) { - expr.check (this); - } - - public override void visit_typeof_expression (TypeofExpression expr) { - expr.check (this); - } - - public override void visit_unary_expression (UnaryExpression expr) { - expr.check (this); - } - - public override void visit_cast_expression (CastExpression expr) { - expr.check (this); - } - - public override void visit_pointer_indirection (PointerIndirection expr) { - expr.check (this); - } - - public override void visit_addressof_expression (AddressofExpression expr) { - expr.check (this); - } - - public override void visit_reference_transfer_expression (ReferenceTransferExpression expr) { - expr.check (this); - } - public DataType? get_arithmetic_result_type (DataType left_type, DataType right_type) { if (!(left_type.data_type is Struct) || !(right_type.data_type is Struct)) { // at least one operand not struct @@ -882,18 +651,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } } - public override void visit_binary_expression (BinaryExpression expr) { - expr.check (this); - } - - public override void visit_type_check (TypeCheck expr) { - expr.check (this); - } - - public override void visit_conditional_expression (ConditionalExpression expr) { - expr.check (this); - } - public Method? find_current_method () { var sym = current_symbol; while (sym != null) { @@ -915,12 +672,4 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } return false; } - - public override void visit_lambda_expression (LambdaExpression l) { - l.check (this); - } - - public override void visit_assignment (Assignment a) { - a.check (this); - } } diff --git a/vala/valasignal.vala b/vala/valasignal.vala index fe18b0065..3eec703c1 100644 --- a/vala/valasignal.vala +++ b/vala/valasignal.vala @@ -228,7 +228,11 @@ public class Vala.Signal : Member, Lockable { process_attributes (); - accept_children (analyzer); + return_type.check (analyzer); + + foreach (FormalParameter param in parameters) { + param.check (analyzer); + } return !error; } diff --git a/vala/valasizeofexpression.vala b/vala/valasizeofexpression.vala index d558f100c..673b16e9c 100644 --- a/vala/valasizeofexpression.vala +++ b/vala/valasizeofexpression.vala @@ -76,6 +76,8 @@ public class Vala.SizeofExpression : Expression { checked = true; + type_reference.check (analyzer); + value_type = analyzer.ulong_type; return !error; diff --git a/vala/valasourcefile.vala b/vala/valasourcefile.vala index 89a08e198..085372cbe 100644 --- a/vala/valasourcefile.vala +++ b/vala/valasourcefile.vala @@ -487,6 +487,13 @@ public class Vala.SourceFile { return mapped_file.get_length (); } + + public bool check (SemanticAnalyzer analyzer) { + foreach (CodeNode node in nodes) { + node.check (analyzer); + } + return true; + } } public enum Vala.SourceFileDependencyType { diff --git a/vala/valastruct.vala b/vala/valastruct.vala index 4b2c208d6..7efc9500e 100644 --- a/vala/valastruct.vala +++ b/vala/valastruct.vala @@ -625,7 +625,25 @@ public class Vala.Struct : TypeSymbol { analyzer.current_symbol = this; analyzer.current_struct = this; - accept_children (analyzer); + foreach (DataType type in base_types) { + type.check (analyzer); + } + + foreach (TypeParameter p in type_parameters) { + p.check (analyzer); + } + + foreach (Field f in fields) { + f.check (analyzer); + } + + foreach (Constant c in constants) { + c.check (analyzer); + } + + foreach (Method m in methods) { + m.check (analyzer); + } if (!external && !external_package && get_base_types ().size == 0 && get_fields ().size == 0) { Report.error (source_reference, "structs cannot be empty"); diff --git a/vala/valaswitchlabel.vala b/vala/valaswitchlabel.vala index a8ef91036..34f2ae677 100644 --- a/vala/valaswitchlabel.vala +++ b/vala/valaswitchlabel.vala @@ -62,4 +62,12 @@ public class Vala.SwitchLabel : CodeNode { visitor.visit_switch_label (this); } + + public override bool check (SemanticAnalyzer analyzer) { + if (expression != null) { + expression.check (analyzer); + } + + return true; + } } diff --git a/vala/valaswitchsection.vala b/vala/valaswitchsection.vala index 2f38944eb..89137a09f 100644 --- a/vala/valaswitchsection.vala +++ b/vala/valaswitchsection.vala @@ -89,14 +89,14 @@ public class Vala.SwitchSection : Block { checked = true; foreach (SwitchLabel label in get_labels ()) { - label.accept (analyzer); + label.check (analyzer); } owner = analyzer.current_symbol.scope; analyzer.current_symbol = this; foreach (Statement st in get_statements ()) { - st.accept (analyzer); + st.check (analyzer); } foreach (LocalVariable local in get_local_variables ()) { diff --git a/vala/valaswitchstatement.vala b/vala/valaswitchstatement.vala index e8da2bf16..559c94259 100644 --- a/vala/valaswitchstatement.vala +++ b/vala/valaswitchstatement.vala @@ -91,4 +91,20 @@ public class Vala.SwitchStatement : CodeNode, Statement { expression = new_node; } } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + expression.check (analyzer); + + foreach (SwitchSection section in sections) { + section.check (analyzer); + } + + return !error; + } } diff --git a/vala/valathrowstatement.vala b/vala/valathrowstatement.vala index d1f8a9f0d..3f27778db 100644 --- a/vala/valathrowstatement.vala +++ b/vala/valathrowstatement.vala @@ -83,7 +83,9 @@ public class Vala.ThrowStatement : CodeNode, Statement { error_expression.target_type = new ErrorType (null, null, source_reference); error_expression.target_type.value_owned = true; - accept_children (analyzer); + if (error_expression != null) { + error_expression.check (analyzer); + } var error_type = error_expression.value_type.copy (); error_type.source_reference = source_reference; diff --git a/vala/valatrystatement.vala b/vala/valatrystatement.vala index 456724d60..fd43dde5f 100644 --- a/vala/valatrystatement.vala +++ b/vala/valatrystatement.vala @@ -94,7 +94,15 @@ public class Vala.TryStatement : CodeNode, Statement { checked = true; - accept_children (analyzer); + body.check (analyzer); + + foreach (CatchClause clause in catch_clauses) { + clause.check (analyzer); + } + + if (finally_body != null) { + finally_body.check (analyzer); + } return !error; } diff --git a/vala/valatypecheck.vala b/vala/valatypecheck.vala index 4c2436252..2dee142f1 100644 --- a/vala/valatypecheck.vala +++ b/vala/valatypecheck.vala @@ -85,6 +85,10 @@ public class Vala.TypeCheck : Expression { checked = true; + expression.check (analyzer); + + type_reference.check (analyzer); + if (type_reference.data_type == null) { /* if type resolving didn't succeed, skip this check */ error = true; diff --git a/vala/valatypeofexpression.vala b/vala/valatypeofexpression.vala index 918ae6ccd..b36559852 100644 --- a/vala/valatypeofexpression.vala +++ b/vala/valatypeofexpression.vala @@ -76,6 +76,8 @@ public class Vala.TypeofExpression : Expression { checked = true; + type_reference.check (analyzer); + value_type = analyzer.type_type; return !error; diff --git a/vala/valaunaryexpression.vala b/vala/valaunaryexpression.vala index aea2a1578..3ddd34678 100644 --- a/vala/valaunaryexpression.vala +++ b/vala/valaunaryexpression.vala @@ -148,9 +148,7 @@ public class Vala.UnaryExpression : Expression { inner.target_type = target_type; } - accept_children (analyzer); - - if (inner.error) { + if (!inner.check (analyzer)) { /* if there was an error in the inner expression, skip type check */ error = true; return false; @@ -207,7 +205,7 @@ public class Vala.UnaryExpression : Expression { parenthexp.target_type = target_type; analyzer.replaced_nodes.add (this); parent_node.replace_expression (this, parenthexp); - parenthexp.accept (analyzer); + parenthexp.check (analyzer); return true; } else if (operator == UnaryOperator.REF || operator == UnaryOperator.OUT) { if (inner.symbol_reference is Field || inner.symbol_reference is FormalParameter || inner.symbol_reference is LocalVariable) { diff --git a/vala/valawhilestatement.vala b/vala/valawhilestatement.vala index ee3a43c67..028538c0d 100644 --- a/vala/valawhilestatement.vala +++ b/vala/valawhilestatement.vala @@ -94,7 +94,9 @@ public class Vala.WhileStatement : CodeNode, Statement { checked = true; - accept_children (analyzer); + condition.check (analyzer); + + body.check (analyzer); if (condition.error) { /* if there was an error in the condition, skip this check */ diff --git a/vala/valayieldstatement.vala b/vala/valayieldstatement.vala index 2c1b06bb7..ca4d0d6fb 100644 --- a/vala/valayieldstatement.vala +++ b/vala/valayieldstatement.vala @@ -71,7 +71,7 @@ public class Vala.YieldStatement : CodeNode, Statement { public override bool check (SemanticAnalyzer analyzer) { if (yield_expression != null) { - yield_expression.accept (analyzer); + yield_expression.check (analyzer); error = yield_expression.error; }