vala r1991 - in trunk: . vala



Author: juergbi
Date: Thu Nov  6 20:11:45 2008
New Revision: 1991
URL: http://svn.gnome.org/viewvc/vala?rev=1991&view=rev

Log:
2008-11-06  JÃrg Billeter  <j bitron ch>

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

	Move class checking to Class.check


Modified:
   trunk/ChangeLog
   trunk/vala/valaclass.vala
   trunk/vala/valasemanticanalyzer.vala

Modified: trunk/vala/valaclass.vala
==============================================================================
--- trunk/vala/valaclass.vala	(original)
+++ trunk/vala/valaclass.vala	Thu Nov  6 20:11:45 2008
@@ -814,5 +814,189 @@
 			}
 		}
 	}
+
+	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;
+	}
 }
 

Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala	(original)
+++ trunk/vala/valasemanticanalyzer.vala	Thu Nov  6 20:11:45 2008
@@ -33,9 +33,9 @@
 	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 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) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]