diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | vala/valaconstant.vala | 25 | ||||
-rw-r--r-- | vala/valaconstructor.vala | 24 | ||||
-rw-r--r-- | vala/valacreationmethod.vala | 38 | ||||
-rw-r--r-- | vala/valadestructor.vala | 17 | ||||
-rw-r--r-- | vala/valafield.vala | 40 | ||||
-rw-r--r-- | vala/valaformalparameter.vala | 2 | ||||
-rw-r--r-- | vala/valaproperty.vala | 2 | ||||
-rw-r--r-- | vala/valapropertyaccessor.vala | 51 | ||||
-rw-r--r-- | vala/valasemanticanalyzer.vala | 143 | ||||
-rw-r--r-- | vala/valasignal.vala | 14 |
11 files changed, 235 insertions, 136 deletions
@@ -1,5 +1,20 @@ 2008-11-07 Jürg Billeter <j@bitron.ch> + * vala/valaconstant.vala: + * vala/valaconstructor.vala: + * vala/valacreationmethod.vala: + * vala/valadestructor.vala: + * vala/valafield.vala: + * vala/valaformalparameter.vala: + * vala/valaproperty.vala: + * vala/valapropertyaccessor.vala: + * vala/valasemanticanalyzer.vala: + * vala/valasignal.vala: + + Move member checking to code nodes + +2008-11-07 Jürg Billeter <j@bitron.ch> + * vala/valadelegate.vala: * vala/valaenum.vala: * vala/valaenumvalue.vala: diff --git a/vala/valaconstant.vala b/vala/valaconstant.vala index 6d31c5787..4dfac387c 100644 --- a/vala/valaconstant.vala +++ b/vala/valaconstant.vala @@ -150,4 +150,29 @@ public class Vala.Constant : Member, Lockable { } } } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + process_attributes (); + + type_reference.accept (analyzer); + + if (!external_package) { + if (initializer == null) { + error = true; + Report.error (source_reference, "A const field requires a initializer to be provided"); + } else { + initializer.target_type = type_reference; + + initializer.accept (analyzer); + } + } + + return !error; + } } diff --git a/vala/valaconstructor.vala b/vala/valaconstructor.vala index 6e0c476c0..a9de8a818 100644 --- a/vala/valaconstructor.vala +++ b/vala/valaconstructor.vala @@ -60,4 +60,28 @@ public class Vala.Constructor : Symbol { body.accept (visitor); } } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + this_parameter = new FormalParameter ("this", new ObjectType (analyzer.current_class)); + scope.add (this_parameter.name, this_parameter); + + owner = analyzer.current_symbol.scope; + analyzer.current_symbol = this; + + accept_children (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())); + } + + analyzer.current_symbol = analyzer.current_symbol.parent_symbol; + + return !error; + } } diff --git a/vala/valacreationmethod.vala b/vala/valacreationmethod.vala index fccca87e8..b99224cec 100644 --- a/vala/valacreationmethod.vala +++ b/vala/valacreationmethod.vala @@ -114,4 +114,42 @@ public class Vala.CreationMethod : Method { return "%s%s_%s".printf (parent.get_lower_case_cprefix (), infix, name); } } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + process_attributes (); + + if (type_name != null && type_name != analyzer.current_symbol.name) { + // type_name is null for constructors generated by GIdlParser + Report.error (source_reference, "missing return type in method `%s.%s´".printf (analyzer.current_symbol.get_full_name (), type_name)); + error = true; + return false; + } + + analyzer.current_symbol = this; + analyzer.current_return_type = return_type; + + accept_children (analyzer); + + analyzer.current_symbol = analyzer.current_symbol.parent_symbol; + analyzer.current_return_type = null; + + if (analyzer.current_symbol.parent_symbol is Method) { + /* lambda expressions produce nested methods */ + var up_method = (Method) analyzer.current_symbol.parent_symbol; + analyzer.current_return_type = up_method.return_type; + } + + if (is_abstract || is_virtual || overrides) { + Report.error (source_reference, "The creation method `%s' cannot be marked as override, virtual, or abstract".printf (get_full_name ())); + return false; + } + + return !error; + } } diff --git a/vala/valadestructor.vala b/vala/valadestructor.vala index 0d0da978e..b2eba7d0e 100644 --- a/vala/valadestructor.vala +++ b/vala/valadestructor.vala @@ -60,4 +60,21 @@ public class Vala.Destructor : Symbol { body.accept (visitor); } } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + owner = analyzer.current_symbol.scope; + analyzer.current_symbol = this; + + accept_children (analyzer); + + analyzer.current_symbol = analyzer.current_symbol.parent_symbol; + + return !error; + } } diff --git a/vala/valafield.vala b/vala/valafield.vala index f9b4a954a..251cd5b07 100644 --- a/vala/valafield.vala +++ b/vala/valafield.vala @@ -195,4 +195,44 @@ public class Vala.Field : Member, Lockable { } attr.add_argument ("type", new StringLiteral ("\"%s\"".printf (ctype))); } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + process_attributes (); + + if (initializer != null) { + initializer.target_type = field_type; + } + + accept_children (analyzer); + + if (binding == MemberBinding.INSTANCE && parent_symbol is Interface) { + error = true; + Report.error (source_reference, "Interfaces may not have instance fields"); + return false; + } + + if (!is_internal_symbol ()) { + if (field_type is ValueType) { + analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.HEADER_FULL); + } else { + analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.HEADER_SHALLOW); + } + } else { + if (parent_symbol is Namespace) { + error = true; + Report.error (source_reference, "Namespaces may not have private members"); + return false; + } + + analyzer.current_source_file.add_type_dependency (field_type, SourceFileDependencyType.SOURCE); + } + + return !error; + } } diff --git a/vala/valaformalparameter.vala b/vala/valaformalparameter.vala index a4e3adecb..36103789b 100644 --- a/vala/valaformalparameter.vala +++ b/vala/valaformalparameter.vala @@ -174,6 +174,8 @@ public class Vala.FormalParameter : Symbol { checked = true; + process_attributes (); + var old_source_file = analyzer.current_source_file; var old_symbol = analyzer.current_symbol; diff --git a/vala/valaproperty.vala b/vala/valaproperty.vala index 39247b0e4..2026a7b21 100644 --- a/vala/valaproperty.vala +++ b/vala/valaproperty.vala @@ -411,6 +411,8 @@ public class Vala.Property : Member, Lockable { checked = true; + process_attributes (); + var old_source_file = analyzer.current_source_file; var old_symbol = analyzer.current_symbol; diff --git a/vala/valapropertyaccessor.vala b/vala/valapropertyaccessor.vala index f437f4800..22069b65d 100644 --- a/vala/valapropertyaccessor.vala +++ b/vala/valapropertyaccessor.vala @@ -131,4 +131,55 @@ public class Vala.PropertyAccessor : CodeNode { } } } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + process_attributes (); + + var old_return_type = analyzer.current_return_type; + if (readable) { + analyzer.current_return_type = prop.property_type; + } else { + // void + analyzer.current_return_type = new VoidType (); + } + + if (!prop.external_package) { + if (body == null && !prop.interface_only && !prop.is_abstract) { + /* no accessor body specified, insert default body */ + + if (prop.parent_symbol is Interface) { + error = true; + Report.error (source_reference, "Automatic properties can't be used in interfaces"); + return false; + } + automatic_body = true; + body = new Block (source_reference); + var ma = new MemberAccess.simple ("_%s".printf (prop.name), source_reference); + if (readable) { + body.add_statement (new ReturnStatement (ma, source_reference)); + } else { + var assignment = new Assignment (ma, new MemberAccess.simple ("value", source_reference), AssignmentOperator.SIMPLE, source_reference); + body.add_statement (new ExpressionStatement (assignment)); + } + } + + if (body != null && (writable || construction)) { + var value_type = prop.property_type.copy (); + value_parameter = new FormalParameter ("value", value_type, source_reference); + body.scope.add (value_parameter.name, value_parameter); + } + } + + accept_children (analyzer); + + analyzer.current_return_type = old_return_type; + + return !error; + } } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index e6e199d85..826c93714 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -175,52 +175,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } public override void visit_constant (Constant c) { - c.process_attributes (); - - c.type_reference.accept (this); - - if (!c.external_package) { - if (c.initializer == null) { - c.error = true; - Report.error (c.source_reference, "A const field requires a initializer to be provided"); - } else { - c.initializer.target_type = c.type_reference; - - c.initializer.accept (this); - } - } + c.check (this); } public override void visit_field (Field f) { - f.process_attributes (); - - if (f.initializer != null) { - f.initializer.target_type = f.field_type; - } - - f.accept_children (this); - - if (f.binding == MemberBinding.INSTANCE && f.parent_symbol is Interface) { - f.error = true; - Report.error (f.source_reference, "Interfaces may not have instance fields"); - return; - } - - if (!f.is_internal_symbol ()) { - if (f.field_type is ValueType) { - current_source_file.add_type_dependency (f.field_type, SourceFileDependencyType.HEADER_FULL); - } else { - current_source_file.add_type_dependency (f.field_type, SourceFileDependencyType.HEADER_SHALLOW); - } - } else { - if (f.parent_symbol is Namespace) { - f.error = true; - Report.error (f.source_reference, "Namespaces may not have private members"); - return; - } - - current_source_file.add_type_dependency (f.field_type, SourceFileDependencyType.SOURCE); - } + f.check (this); } public override void visit_method (Method m) { @@ -228,38 +187,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } public override void visit_creation_method (CreationMethod m) { - m.process_attributes (); - - if (m.type_name != null && m.type_name != current_symbol.name) { - // type_name is null for constructors generated by GIdlParser - Report.error (m.source_reference, "missing return type in method `%s.%s´".printf (current_symbol.get_full_name (), m.type_name)); - m.error = true; - return; - } - - current_symbol = m; - current_return_type = m.return_type; - - m.accept_children (this); - - current_symbol = current_symbol.parent_symbol; - current_return_type = null; - - if (current_symbol.parent_symbol is Method) { - /* lambda expressions produce nested methods */ - var up_method = (Method) current_symbol.parent_symbol; - current_return_type = up_method.return_type; - } - - if (m.is_abstract || m.is_virtual || m.overrides) { - Report.error (m.source_reference, "The creation method `%s' cannot be marked as override, virtual, or abstract".printf (m.get_full_name ())); - return; - } + m.check (this); } public override void visit_formal_parameter (FormalParameter p) { - p.process_attributes (); - p.check (this); } @@ -278,83 +209,23 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } public override void visit_property (Property prop) { - prop.process_attributes (); - prop.check (this); } public override void visit_property_accessor (PropertyAccessor acc) { - acc.process_attributes (); - - var old_return_type = current_return_type; - if (acc.readable) { - current_return_type = acc.prop.property_type; - } else { - // void - current_return_type = new VoidType (); - } - - if (!acc.prop.external_package) { - if (acc.body == null && !acc.prop.interface_only && !acc.prop.is_abstract) { - /* no accessor body specified, insert default body */ - - if (acc.prop.parent_symbol is Interface) { - acc.error = true; - Report.error (acc.source_reference, "Automatic properties can't be used in interfaces"); - return; - } - acc.automatic_body = true; - acc.body = new Block (acc.source_reference); - var ma = new MemberAccess.simple ("_%s".printf (acc.prop.name), acc.source_reference); - if (acc.readable) { - acc.body.add_statement (new ReturnStatement (ma, acc.source_reference)); - } else { - var assignment = new Assignment (ma, new MemberAccess.simple ("value", acc.source_reference), AssignmentOperator.SIMPLE, acc.source_reference); - acc.body.add_statement (new ExpressionStatement (assignment)); - } - } - - if (acc.body != null && (acc.writable || acc.construction)) { - var value_type = acc.prop.property_type.copy (); - acc.value_parameter = new FormalParameter ("value", value_type, acc.source_reference); - acc.body.scope.add (acc.value_parameter.name, acc.value_parameter); - } - } - - acc.accept_children (this); - - current_return_type = old_return_type; + acc.check (this); } public override void visit_signal (Signal sig) { - sig.process_attributes (); - - sig.accept_children (this); + sig.check (this); } public override void visit_constructor (Constructor c) { - c.this_parameter = new FormalParameter ("this", new ObjectType (current_class)); - c.scope.add (c.this_parameter.name, c.this_parameter); - - c.owner = current_symbol.scope; - current_symbol = c; - - c.accept_children (this); - - foreach (DataType body_error_type in c.body.get_error_types ()) { - Report.warning (body_error_type.source_reference, "unhandled error `%s'".printf (body_error_type.to_string())); - } - - current_symbol = current_symbol.parent_symbol; + c.check (this); } public override void visit_destructor (Destructor d) { - d.owner = current_symbol.scope; - current_symbol = d; - - d.accept_children (this); - - current_symbol = current_symbol.parent_symbol; + d.check (this); } public override void visit_block (Block b) { diff --git a/vala/valasignal.vala b/vala/valasignal.vala index bb0a40894..fe18b0065 100644 --- a/vala/valasignal.vala +++ b/vala/valasignal.vala @@ -218,5 +218,19 @@ public class Vala.Signal : Member, Lockable { return generated_method; } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + process_attributes (); + + accept_children (analyzer); + + return !error; + } } |