]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Check properties when accessing them
authorJürg Billeter <j@bitron.ch>
Fri, 31 Oct 2008 10:56:14 +0000 (10:56 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 31 Oct 2008 10:56:14 +0000 (10:56 +0000)
2008-10-31  Jürg Billeter  <j@bitron.ch>

* vala/valaproperty.vala:
* vala/valasemanticanalyzer.vala:

Check properties when accessing them

svn path=/trunk/; revision=1946

ChangeLog
vala/valaproperty.vala
vala/valasemanticanalyzer.vala

index d6ffde62ffefaf0db1542c98f128e5be220e866d..54d8b371836cbd7e784a0f8db905b6f320f8f2be 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-10-31  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valaproperty.vala:
+       * vala/valasemanticanalyzer.vala:
+
+       Check properties when accessing them
+
 2008-10-31  Jürg Billeter  <j@bitron.ch>
 
        * vala/valaproperty.vala:
index c77c7e2e7fc034dfc88cfce918e9a91170c847a4..05c0c95d79913c59fdd47dcb1fbfc9fe105d9cba 100644 (file)
@@ -401,4 +401,70 @@ public class Vala.Property : Member, Lockable {
                        }
                }
        }
+
+       public override bool check (SemanticAnalyzer analyzer) {
+               if (checked) {
+                       return !error;
+               }
+
+               checked = true;
+
+               var old_source_file = analyzer.current_source_file;
+               var old_symbol = analyzer.current_symbol;
+
+               if (source_reference != null) {
+                       analyzer.current_source_file = source_reference.file;
+               }
+               analyzer.current_symbol = this;
+
+               property_type.accept (analyzer);
+               
+               if (get_accessor != null) {
+                       get_accessor.accept (analyzer);
+               }
+               if (set_accessor != null) {
+                       set_accessor.accept (analyzer);
+               }
+
+               if (default_expression != null) {
+                       default_expression.accept (analyzer);
+               }
+
+               // check whether property type is at least as accessible as the property
+               if (!analyzer.is_type_accessible (this, property_type)) {
+                       error = true;
+                       Report.error (source_reference, "property type `%s` is less accessible than property `%s`".printf (property_type.to_string (), get_full_name ()));
+               }
+
+               if (!is_internal_symbol ()) {
+                       if (property_type is ValueType && !property_type.is_real_struct_type ()) {
+                               analyzer.current_source_file.add_type_dependency (property_type, SourceFileDependencyType.HEADER_FULL);
+                       } else {
+                               analyzer.current_source_file.add_type_dependency (property_type, SourceFileDependencyType.HEADER_SHALLOW);
+                       }
+               }
+               analyzer.current_source_file.add_type_dependency (property_type, SourceFileDependencyType.SOURCE);
+
+               if (overrides && base_property == null) {
+                       Report.error (source_reference, "%s: no suitable property found to override".printf (get_full_name ()));
+               }
+
+               /* construct properties must be public */
+               if (set_accessor != null && set_accessor.construction) {
+                       if (access != SymbolAccessibility.PUBLIC) {
+                               error = true;
+                               Report.error (source_reference, "%s: construct properties must be public".printf (get_full_name ()));
+                       }
+               }
+
+               if (default_expression != null && !(default_expression.value_type.compatible (property_type))) {
+                       error = true;
+                       Report.error (default_expression.source_reference, "Expected initializer of type `%s' but got `%s'".printf (property_type.to_string (), default_expression.value_type.to_string ()));
+               }
+
+               analyzer.current_source_file = old_source_file;
+               analyzer.current_symbol = old_symbol;
+
+               return !error;
+       }
 }
index c29a524048dccac96a4ea781029ea9d5c5fb2b3d..fd62759a1238f704ea090faa6f32a721d6912c93 100644 (file)
@@ -612,58 +612,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        public override void visit_property (Property prop) {
-               current_symbol = prop;
-
-               prop.property_type.accept (this);
-               
-               if (prop.get_accessor != null) {
-                       prop.get_accessor.accept (this);
-               }
-               if (prop.set_accessor != null) {
-                       prop.set_accessor.accept (this);
-               }
-
-               if (prop.default_expression != null) {
-                       prop.default_expression.accept (this);
-               }
-
-               // check whether property type is at least as accessible as the property
-               if (!is_type_accessible (prop, prop.property_type)) {
-                       prop.error = true;
-                       Report.error (prop.source_reference, "property type `%s` is less accessible than property `%s`".printf (prop.property_type.to_string (), prop.get_full_name ()));
-                       return;
-               }
-
-               current_symbol = current_symbol.parent_symbol;
-
-               if (!prop.is_internal_symbol ()) {
-                       if (prop.property_type is ValueType && !prop.property_type.is_real_struct_type ()) {
-                               current_source_file.add_type_dependency (prop.property_type, SourceFileDependencyType.HEADER_FULL);
-                       } else {
-                               current_source_file.add_type_dependency (prop.property_type, SourceFileDependencyType.HEADER_SHALLOW);
-                       }
-               }
-               current_source_file.add_type_dependency (prop.property_type, SourceFileDependencyType.SOURCE);
-
-               if (prop.overrides && prop.base_property == null) {
-                       Report.error (prop.source_reference, "%s: no suitable property found to override".printf (prop.get_full_name ()));
-               }
-
-               /* construct properties must be public */
-               if (prop.set_accessor != null && prop.set_accessor.construction) {
-                       if (prop.access != SymbolAccessibility.PUBLIC) {
-                               prop.error = true;
-                               Report.error (prop.source_reference, "%s: construct properties must be public".printf (prop.get_full_name ()));
-                       }
-               }
-
-               if (prop.default_expression != null && !(prop.default_expression.value_type.compatible (prop.property_type))) {
-                       prop.error = true;
-                       Report.error (prop.default_expression.source_reference, "Expected initializer of type `%s' but got `%s'".printf (prop.property_type.to_string (), prop.default_expression.value_type.to_string ()));
-               }
+               prop.check (this);
        }
 
        public override void visit_property_accessor (PropertyAccessor acc) {
+               var old_return_type = current_return_type;
                if (acc.readable) {
                        current_return_type = acc.prop.property_type;
                } else {
@@ -700,7 +653,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
                acc.accept_children (this);
 
-               current_return_type = null;
+               current_return_type = old_return_type;
        }
 
        public override void visit_signal (Signal sig) {
@@ -1753,6 +1706,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        klass = (m.binding == MemberBinding.CLASS);
                } else if (member is Property) {
                        var prop = (Property) member;
+                       if (!prop.check (this)) {
+                               expr.error = true;
+                               return;
+                       }
                        access = prop.access;
                        if (expr.lvalue) {
                                if (prop.set_accessor == null) {