vala r1148 - in trunk: . vala



Author: juergbi
Date: Sat Mar 22 20:17:22 2008
New Revision: 1148
URL: http://svn.gnome.org/viewvc/vala?rev=1148&view=rev

Log:
2008-03-22  Juerg Billeter  <j bitron ch>

	* vala/valascope.vala, vala/valasemanticanalyzer.vala,
	  vala/valasymbol.vala: check accessiblity of parameter and return
	  types, fixes bug 433290


Modified:
   trunk/ChangeLog
   trunk/vala/valascope.vala
   trunk/vala/valasemanticanalyzer.vala
   trunk/vala/valasymbol.vala

Modified: trunk/vala/valascope.vala
==============================================================================
--- trunk/vala/valascope.vala	(original)
+++ trunk/vala/valascope.vala	Sat Mar 22 20:17:22 2008
@@ -1,6 +1,6 @@
 /* valascope.vala
  *
- * Copyright (C) 2006-2007  JÃrg Billeter
+ * Copyright (C) 2006-2008  JÃrg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -86,5 +86,29 @@
 		}
 		return sym;
 	}
+
+	/**
+	 * Returns whether the specified scope is an ancestor of this scope.
+	 *
+	 * @param scope a scope or null for the root scope
+	 * @return      true if this scope is a subscope of the specified
+	 *              scope, false otherwise
+	 */
+	public bool is_subscope_of (Scope? scope) {
+		if (scope == this) {
+			return true;
+		}
+
+		// null scope is the root scope
+		if (scope == null) {
+			return true;
+		}
+
+		if (parent_scope != null) {
+			return parent_scope.is_subscope_of (scope);
+		}
+
+		return false;
+	}
 }
 

Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala	(original)
+++ trunk/vala/valasemanticanalyzer.vala	Sat Mar 22 20:17:22 2008
@@ -411,6 +411,13 @@
 			}
 		}
 
+		// check whether return type is at least as accessible as the method
+		if (!is_type_accessible (m, m.return_type)) {
+			m.error = true;
+			Report.error (m.source_reference, "return type `%s` is less accessible than method `%s`".printf (m.return_type.to_string (), m.get_full_name ()));
+			return;
+		}
+
 		foreach (Expression precondition in m.get_preconditions ()) {
 			if (precondition.error) {
 				// if there was an error in the precondition, skip this check
@@ -519,6 +526,13 @@
 				current_source_file.add_type_dependency (p.type_reference, SourceFileDependencyType.HEADER_SHALLOW);
 			}
 			current_source_file.add_type_dependency (p.type_reference, SourceFileDependencyType.SOURCE);
+
+			// check whether parameter type is at least as accessible as the method
+			if (!is_type_accessible (p, p.type_reference)) {
+				p.error = true;
+				Report.error (p.source_reference, "parameter type `%s` is less accessible than method `%s`".printf (p.type_reference.to_string (), p.parent_symbol.get_full_name ()));
+				return;
+			}
 		}
 
 		/* special treatment for construct formal parameters used in creation methods */
@@ -537,6 +551,20 @@
 		}
 	}
 
+	// check whether type is at least as accessible as the specified symbol
+	private bool is_type_accessible (Symbol sym, DataType type) {
+		foreach (Symbol type_symbol in type.get_symbols ()) {
+			Scope method_scope = sym.get_top_accessible_scope ();
+			Scope type_scope = type_symbol.get_top_accessible_scope ();
+			if ((method_scope == null && type_scope != null)
+			    || (method_scope != null && !method_scope.is_subscope_of (type_scope))) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
 	private void find_base_class_property (Property! prop, Class! cl) {
 		var sym = cl.scope.lookup (prop.name);
 		if (sym is Property) {

Modified: trunk/vala/valasymbol.vala
==============================================================================
--- trunk/vala/valasymbol.vala	(original)
+++ trunk/vala/valasymbol.vala	Sat Mar 22 20:17:22 2008
@@ -218,6 +218,28 @@
 		
 		return result.str;
 	}
+
+	// get the top scope from where this symbol is still accessible
+	public Scope? get_top_accessible_scope () {
+		if (access != SymbolAccessibility.PUBLIC) {
+			// private symbols are accessible within the scope where the symbol has been declared
+			Scope scope = owner;
+
+			// skip scopes of normal namespaces, they don't influence accessibility
+			while (scope != null && scope.owner is Namespace && scope.owner.name != null) {
+				scope = scope.parent_scope;
+			}
+
+			return scope;
+		}
+
+		if (parent_symbol == null) {
+			return null;
+		}
+
+		// if this is a public symbol, it's equally accessible as the parent symbol
+		return parent_symbol.get_top_accessible_scope ();
+	}
 }
 
 public enum Vala.SymbolAccessibility {



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