]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Move class checking to Class.check
authorJürg Billeter <j@bitron.ch>
Thu, 6 Nov 2008 20:11:45 +0000 (20:11 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Thu, 6 Nov 2008 20:11:45 +0000 (20:11 +0000)
2008-11-06  Jürg Billeter  <j@bitron.ch>

* vala/valaclass.vala:
* vala/valasemanticanalyzer.vala:

Move class checking to Class.check

svn path=/trunk/; revision=1991

ChangeLog
vala/valaclass.vala
vala/valasemanticanalyzer.vala

index 1054810c38f088b577f5c74478a563fb6be46afd..95d7fe6c759bc3f9f6f3fa2043cd62aca1524b3f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-11-06  Jürg Billeter  <j@bitron.ch>
+
+       * vala/valaclass.vala:
+       * vala/valasemanticanalyzer.vala:
+
+       Move class checking to Class.check
+
 2008-11-06  Jürg Billeter  <j@bitron.ch>
 
        * gobject/Makefile.am:
index ec1828dd221d663d906154eb9012e8b82ad0a51f..1d27d765019ecad9b6a2aab25cf0084ff61e3d28 100644 (file)
@@ -814,5 +814,189 @@ public class Vala.Class : ObjectTypeSymbol {
                        }
                }
        }
+
+       private void get_all_prerequisites (Interface iface, Gee.List<TypeSymbol> list) {
+               foreach (DataType prereq in iface.get_prerequisites ()) {
+                       TypeSymbol type = prereq.data_type;
+                       /* skip on previous errors */
+                       if (type == null) {
+                               continue;
+                       }
+
+                       list.add (type);
+                       if (type is Interface) {
+                               get_all_prerequisites ((Interface) type, list);
+
+                       }
+               }
+       }
+
+       private bool class_is_a (Class cl, TypeSymbol t) {
+               if (cl == t) {
+                       return true;
+               }
+
+               foreach (DataType base_type in cl.get_base_types ()) {
+                       if (base_type.data_type is Class) {
+                               if (class_is_a ((Class) base_type.data_type, t)) {
+                                       return true;
+                               }
+                       } else if (base_type.data_type == t) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+
+       public override bool check (SemanticAnalyzer analyzer) {
+               if (checked) {
+                       return !error;
+               }
+
+               checked = true;
+
+               process_attributes ();
+
+               analyzer.current_symbol = this;
+               analyzer.current_class = this;
+
+               foreach (DataType base_type_reference in get_base_types ()) {
+                       // check whether base type is at least as accessible as the class
+                       if (!analyzer.is_type_accessible (this, base_type_reference)) {
+                               error = true;
+                               Report.error (source_reference, "base type `%s` is less accessible than class `%s`".printf (base_type_reference.to_string (), get_full_name ()));
+                               return false;
+                       }
+
+                       analyzer.current_source_file.add_type_dependency (base_type_reference, SourceFileDependencyType.HEADER_FULL);
+               }
+
+               accept_children (analyzer);
+
+               /* compact classes cannot implement interfaces */
+               if (is_compact) {
+                       foreach (DataType base_type in get_base_types ()) {
+                               if (base_type.data_type is Interface) {
+                                       error = true;
+                                       Report.error (source_reference, "compact classes `%s` may not implement interfaces".printf (get_full_name ()));
+                               }
+                       }
+               }
+
+               /* gather all prerequisites */
+               Gee.List<TypeSymbol> prerequisites = new ArrayList<TypeSymbol> ();
+               foreach (DataType base_type in get_base_types ()) {
+                       if (base_type.data_type is Interface) {
+                               get_all_prerequisites ((Interface) base_type.data_type, prerequisites);
+                       }
+               }
+               /* check whether all prerequisites are met */
+               Gee.List<string> missing_prereqs = new ArrayList<string> ();
+               foreach (TypeSymbol prereq in prerequisites) {
+                       if (!class_is_a (this, prereq)) {
+                               missing_prereqs.insert (0, prereq.get_full_name ());
+                       }
+               }
+               /* report any missing prerequisites */
+               if (missing_prereqs.size > 0) {
+                       error = true;
+
+                       string error_string = "%s: some prerequisites (".printf (get_full_name ());
+                       bool first = true;
+                       foreach (string s in missing_prereqs) {
+                               if (first) {
+                                       error_string = "%s`%s'".printf (error_string, s);
+                                       first = false;
+                               } else {
+                                       error_string = "%s, `%s'".printf (error_string, s);
+                               }
+                       }
+                       error_string += ") are not met";
+                       Report.error (source_reference, error_string);
+               }
+
+               /* VAPI classes don't have to specify overridden methods */
+               if (!external_package) {
+                       /* all abstract symbols defined in base types have to be at least defined (or implemented) also in this type */
+                       foreach (DataType base_type in get_base_types ()) {
+                               if (base_type.data_type is Interface) {
+                                       Interface iface = (Interface) base_type.data_type;
+
+                                       if (base_class != null && base_class.is_subtype_of (iface)) {
+                                               // reimplementation of interface, class is not required to reimplement all methods
+                                               break;
+                                       }
+
+                                       /* We do not need to do expensive equality checking here since this is done
+                                        * already. We only need to guarantee the symbols are present.
+                                        */
+
+                                       /* check methods */
+                                       foreach (Method m in iface.get_methods ()) {
+                                               if (m.is_abstract) {
+                                                       Symbol sym = null;
+                                                       var base_class = this;
+                                                       while (base_class != null && !(sym is Method)) {
+                                                               sym = base_class.scope.lookup (m.name);
+                                                               base_class = base_class.base_class;
+                                                       }
+                                                       if (!(sym is Method)) {
+                                                               error = true;
+                                                               Report.error (source_reference, "`%s' does not implement interface method `%s'".printf (get_full_name (), m.get_full_name ()));
+                                                       }
+                                               }
+                                       }
+
+                                       /* check properties */
+                                       foreach (Property prop in iface.get_properties ()) {
+                                               if (prop.is_abstract) {
+                                                       Symbol sym = null;
+                                                       var base_class = this;
+                                                       while (base_class != null && !(sym is Property)) {
+                                                               sym = base_class.scope.lookup (prop.name);
+                                                               base_class = base_class.base_class;
+                                                       }
+                                                       if (!(sym is Property)) {
+                                                               error = true;
+                                                               Report.error (source_reference, "`%s' does not implement interface property `%s'".printf (get_full_name (), prop.get_full_name ()));
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       /* all abstract symbols defined in base classes have to be implemented in non-abstract classes */
+                       if (!is_abstract) {
+                               var base_class = base_class;
+                               while (base_class != null && base_class.is_abstract) {
+                                       foreach (Method base_method in base_class.get_methods ()) {
+                                               if (base_method.is_abstract) {
+                                                       var override_method = analyzer.symbol_lookup_inherited (this, base_method.name) as Method;
+                                                       if (override_method == null || !override_method.overrides) {
+                                                               error = true;
+                                                               Report.error (source_reference, "`%s' does not implement abstract method `%s'".printf (get_full_name (), base_method.get_full_name ()));
+                                                       }
+                                               }
+                                       }
+                                       foreach (Property base_property in base_class.get_properties ()) {
+                                               if (base_property.is_abstract) {
+                                                       var override_property = analyzer.symbol_lookup_inherited (this, base_property.name) as Property;
+                                                       if (override_property == null || !override_property.overrides) {
+                                                               error = true;
+                                                               Report.error (source_reference, "`%s' does not implement abstract property `%s'".printf (get_full_name (), base_property.get_full_name ()));
+                                                       }
+                                               }
+                                       }
+                                       base_class = base_class.base_class;
+                               }
+                       }
+               }
+
+               analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
+               analyzer.current_class = null;
+
+               return !error;
+       }
 }
 
index 2fb5d635858eafe724332ea0d53027524cb1b180..d7bc863c08a5bd871d35cf20b8d1939a5279d943 100644 (file)
@@ -33,9 +33,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        public Symbol root_symbol;
        public Symbol current_symbol { get; set; }
        public SourceFile current_source_file { get; set; }
-       DataType current_return_type;
-       Class current_class;
-       Struct current_struct;
+       public DataType current_return_type;
+       public Class current_class;
+       public Struct current_struct;
 
        public Gee.List<UsingDirective> current_using_directives;
 
@@ -143,179 +143,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        public override void visit_class (Class cl) {
-               cl.process_attributes ();
-
-               current_symbol = cl;
-               current_class = cl;
-
-               foreach (DataType base_type_reference in cl.get_base_types ()) {
-                       // check whether base type is at least as accessible as the class
-                       if (!is_type_accessible (cl, base_type_reference)) {
-                               cl.error = true;
-                               Report.error (cl.source_reference, "base type `%s` is less accessible than class `%s`".printf (base_type_reference.to_string (), cl.get_full_name ()));
-                               return;
-                       }
-
-                       current_source_file.add_type_dependency (base_type_reference, SourceFileDependencyType.HEADER_FULL);
-               }
-
-               cl.accept_children (this);
-
-               /* compact classes cannot implement interfaces */
-               if (cl.is_compact) {
-                       foreach (DataType base_type in cl.get_base_types ()) {
-                               if (base_type.data_type is Interface) {
-                                       cl.error = true;
-                                       Report.error (cl.source_reference, "compact classes `%s` may not implement interfaces".printf (cl.get_full_name ()));
-                               }
-                       }
-               }
-
-               /* gather all prerequisites */
-               Gee.List<TypeSymbol> prerequisites = new ArrayList<TypeSymbol> ();
-               foreach (DataType base_type in cl.get_base_types ()) {
-                       if (base_type.data_type is Interface) {
-                               get_all_prerequisites ((Interface) base_type.data_type, prerequisites);
-                       }
-               }
-               /* check whether all prerequisites are met */
-               Gee.List<string> missing_prereqs = new ArrayList<string> ();
-               foreach (TypeSymbol prereq in prerequisites) {
-                       if (!class_is_a (cl, prereq)) {
-                               missing_prereqs.insert (0, prereq.get_full_name ());
-                       }
-               }
-               /* report any missing prerequisites */
-               if (missing_prereqs.size > 0) {
-                       cl.error = true;
-
-                       string error_string = "%s: some prerequisites (".printf (cl.get_full_name ());
-                       bool first = true;
-                       foreach (string s in missing_prereqs) {
-                               if (first) {
-                                       error_string = "%s`%s'".printf (error_string, s);
-                                       first = false;
-                               } else {
-                                       error_string = "%s, `%s'".printf (error_string, s);
-                               }
-                       }
-                       error_string += ") are not met";
-                       Report.error (cl.source_reference, error_string);
-               }
-
-               /* VAPI classes don't have to specify overridden methods */
-               if (!cl.external_package) {
-                       /* all abstract symbols defined in base types have to be at least defined (or implemented) also in this type */
-                       foreach (DataType base_type in cl.get_base_types ()) {
-                               if (base_type.data_type is Interface) {
-                                       Interface iface = (Interface) base_type.data_type;
-
-                                       if (cl.base_class != null && cl.base_class.is_subtype_of (iface)) {
-                                               // reimplementation of interface, class is not required to reimplement all methods
-                                               break;
-                                       }
-
-                                       /* We do not need to do expensive equality checking here since this is done
-                                        * already. We only need to guarantee the symbols are present.
-                                        */
-
-                                       /* check methods */
-                                       foreach (Method m in iface.get_methods ()) {
-                                               if (m.is_abstract) {
-                                                       Symbol sym = null;
-                                                       var base_class = cl;
-                                                       while (base_class != null && !(sym is Method)) {
-                                                               sym = base_class.scope.lookup (m.name);
-                                                               base_class = base_class.base_class;
-                                                       }
-                                                       if (!(sym is Method)) {
-                                                               cl.error = true;
-                                                               Report.error (cl.source_reference, "`%s' does not implement interface method `%s'".printf (cl.get_full_name (), m.get_full_name ()));
-                                                       }
-                                               }
-                                       }
-
-                                       /* check properties */
-                                       foreach (Property prop in iface.get_properties ()) {
-                                               if (prop.is_abstract) {
-                                                       Symbol sym = null;
-                                                       var base_class = cl;
-                                                       while (base_class != null && !(sym is Property)) {
-                                                               sym = base_class.scope.lookup (prop.name);
-                                                               base_class = base_class.base_class;
-                                                       }
-                                                       if (!(sym is Property)) {
-                                                               cl.error = true;
-                                                               Report.error (cl.source_reference, "`%s' does not implement interface property `%s'".printf (cl.get_full_name (), prop.get_full_name ()));
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-
-                       /* all abstract symbols defined in base classes have to be implemented in non-abstract classes */
-                       if (!cl.is_abstract) {
-                               var base_class = cl.base_class;
-                               while (base_class != null && base_class.is_abstract) {
-                                       foreach (Method base_method in base_class.get_methods ()) {
-                                               if (base_method.is_abstract) {
-                                                       var override_method = symbol_lookup_inherited (cl, base_method.name) as Method;
-                                                       if (override_method == null || !override_method.overrides) {
-                                                               cl.error = true;
-                                                               Report.error (cl.source_reference, "`%s' does not implement abstract method `%s'".printf (cl.get_full_name (), base_method.get_full_name ()));
-                                                       }
-                                               }
-                                       }
-                                       foreach (Property base_property in base_class.get_properties ()) {
-                                               if (base_property.is_abstract) {
-                                                       var override_property = symbol_lookup_inherited (cl, base_property.name) as Property;
-                                                       if (override_property == null || !override_property.overrides) {
-                                                               cl.error = true;
-                                                               Report.error (cl.source_reference, "`%s' does not implement abstract property `%s'".printf (cl.get_full_name (), base_property.get_full_name ()));
-                                                       }
-                                               }
-                                       }
-                                       base_class = base_class.base_class;
-                               }
-                       }
-               }
-
-               current_symbol = current_symbol.parent_symbol;
-               current_class = null;
-       }
-
-       private void get_all_prerequisites (Interface iface, Gee.List<TypeSymbol> list) {
-               foreach (DataType prereq in iface.get_prerequisites ()) {
-                       TypeSymbol type = prereq.data_type;
-                       /* skip on previous errors */
-                       if (type == null) {
-                               continue;
-                       }
-
-                       list.add (type);
-                       if (type is Interface) {
-                               get_all_prerequisites ((Interface) type, list);
-
-                       }
-               }
-       }
-
-       private bool class_is_a (Class cl, TypeSymbol t) {
-               if (cl == t) {
-                       return true;
-               }
-
-               foreach (DataType base_type in cl.get_base_types ()) {
-                       if (base_type.data_type is Class) {
-                               if (class_is_a ((Class) base_type.data_type, t)) {
-                                       return true;
-                               }
-                       } else if (base_type.data_type == t) {
-                               return true;
-                       }
-               }
-
-               return false;
+               cl.check (this);
        }
 
        public override void visit_struct (Struct st) {