2008-05-28 Jürg Billeter <j@bitron.ch>
+ * vala/valainterfacewriter.vala:
+ * vala/valamethod.vala:
+ * vala/valaproperty.vala:
+ * vala/valasemanticanalyzer.vala:
+ * gobject/valagidlwriter.vala:
+
+ Compute Method.base_method and Property.base_property when needed
+ so that we can already use them in the semantic analyzer
+
+2008-05-28 Jürg Billeter <j@bitron.ch>
+
* ccode/valaccodecastexpression.vala:
Use parentheses to ensure that the full expression is cast
}
public override void visit_property (Property prop) {
- if (!check_accessibility (prop) || prop.overrides || prop.base_interface_property != null) {
+ if (!check_accessibility (prop) || prop.overrides || (prop.base_interface_property != null && !prop.is_abstract && !prop.is_virtual)) {
return;
}
}
public override void visit_property (Property prop) {
- if (!check_accessibility (prop) || prop.overrides || prop.base_interface_property != null) {
+ if (!check_accessibility (prop) || prop.overrides || (prop.base_interface_property != null && !prop.is_abstract && !prop.is_virtual)) {
return;
}
* Reference must be weak as virtual methods set base_method to
* themselves.
*/
- public weak Method base_method { get; set; }
+ public Method base_method {
+ get {
+ find_base_methods ();
+ return _base_method;
+ }
+ }
/**
* Specifies the abstract interface method this method implements.
*/
- public Method base_interface_method { get; set; }
+ public Method base_interface_method {
+ get {
+ find_base_methods ();
+ return _base_interface_method;
+ }
+ }
/**
* Specifies the generated `this' parameter for instance methods.
private DataType _return_type;
private Block _body;
+ private weak Method _base_method;
+ private Method _base_interface_method;
+ private bool base_methods_valid;
+
/**
* Creates a new method.
*
public override CodeBinding? create_code_binding (CodeGenerator codegen) {
return codegen.create_method_binding (this);
}
+
+ private void find_base_methods () {
+ if (base_methods_valid) {
+ return;
+ }
+
+ if (parent_symbol is Class) {
+ /* VAPI classes don't specify overridden methods */
+ if (!parent_symbol.external_package) {
+ if (!(this is CreationMethod)) {
+ find_base_interface_method ((Class) parent_symbol);
+ if (is_virtual || overrides) {
+ find_base_class_method ((Class) parent_symbol);
+ }
+ }
+ } else if (is_virtual || is_abstract) {
+ _base_method = this;
+ }
+ } else if (parent_symbol is Interface) {
+ if (is_virtual || is_abstract) {
+ _base_interface_method = this;
+ }
+ }
+
+ base_methods_valid = true;
+ }
+
+ private void find_base_class_method (Class cl) {
+ var sym = cl.scope.lookup (name);
+ if (sym is Method) {
+ var base_method = (Method) sym;
+ if (base_method.is_abstract || base_method.is_virtual) {
+ string invalid_match;
+ if (!compatible (base_method, out invalid_match)) {
+ error = true;
+ Report.error (source_reference, "overriding method `%s' is incompatible with base method `%s': %s.".printf (get_full_name (), base_method.get_full_name (), invalid_match));
+ return;
+ }
+
+ _base_method = base_method;
+ return;
+ }
+ }
+
+ if (cl.base_class != null) {
+ find_base_class_method (cl.base_class);
+ }
+ }
+
+ private void find_base_interface_method (Class cl) {
+ // FIXME report error if multiple possible base methods are found
+ foreach (DataType type in cl.get_base_types ()) {
+ if (type.data_type is Interface) {
+ var sym = type.data_type.scope.lookup (name);
+ if (sym is Method) {
+ var base_method = (Method) sym;
+ if (base_method.is_abstract || base_method.is_virtual) {
+ string invalid_match;
+ if (!compatible (base_method, out invalid_match)) {
+ error = true;
+ Report.error (source_reference, "overriding method `%s' is incompatible with base method `%s': %s.".printf (get_full_name (), base_method.get_full_name (), invalid_match));
+ return;
+ }
+
+ _base_interface_method = base_method;
+ return;
+ }
+ }
+ }
+ }
+ }
}
* Reference must be weak as virtual properties set base_property to
* themselves.
*/
- public weak Property base_property { get; set; }
+ public Property base_property {
+ get {
+ find_base_properties ();
+ return _base_property;
+ }
+ }
/**
* Specifies the abstract interface property this property implements.
*/
- public Property base_interface_property { get; set; }
+ public Property base_interface_property {
+ get {
+ find_base_properties ();
+ return _base_interface_property;
+ }
+ }
/**
* Specifies the default value of this property.
private string? _nick;
private string? _blurb;
+ private weak Property _base_property;
+ private Property _base_interface_property;
+ private bool base_properties_valid;
+
/**
* Creates a new property.
*
property_type = new_type;
}
}
+
+ private void find_base_properties () {
+ if (base_properties_valid) {
+ return;
+ }
+
+ if (parent_symbol is Class) {
+ /* VAPI classes don't specify overridden properties */
+ if (!parent_symbol.external_package) {
+ find_base_interface_property ((Class) parent_symbol);
+ if (is_virtual || overrides) {
+ find_base_class_property ((Class) parent_symbol);
+ }
+ } else if (is_virtual || is_abstract) {
+ _base_property = this;
+ }
+ } else if (parent_symbol is Interface) {
+ if (is_virtual || is_abstract) {
+ _base_interface_property = this;
+ }
+ }
+
+ base_properties_valid = true;
+ }
+
+ private void find_base_class_property (Class cl) {
+ var sym = cl.scope.lookup (name);
+ if (sym is Property) {
+ var base_property = (Property) sym;
+ if (base_property.is_abstract || base_property.is_virtual) {
+ if (!equals (base_property)) {
+ error = true;
+ Report.error (source_reference, "Type and/or accessors of overriding property `%s' do not match overridden property `%s'.".printf (get_full_name (), base_property.get_full_name ()));
+ return;
+ }
+
+ _base_property = base_property;
+ return;
+ }
+ }
+
+ if (cl.base_class != null) {
+ find_base_class_property (cl.base_class);
+ }
+ }
+
+ private void find_base_interface_property (Class cl) {
+ // FIXME report error if multiple possible base properties are found
+ foreach (DataType type in cl.get_base_types ()) {
+ if (type.data_type is Interface) {
+ var sym = type.data_type.scope.lookup (name);
+ if (sym is Property) {
+ var base_property = (Property) sym;
+ if (base_property.is_abstract) {
+ if (!equals (base_property)) {
+ error = true;
+ Report.error (source_reference, "Type and/or accessors of overriding property `%s' do not match overridden property `%s'.".printf (get_full_name (), base_property.get_full_name ()));
+ return;
+ }
+
+ _base_interface_property = base_property;
+ return;
+ }
+ }
+ }
+ }
+ }
}
current_return_type = up_method.return_type;
}
- if (current_symbol is Class) {
- /* VAPI classes don't specify overridden methods */
- if (!current_symbol.external_package) {
- if (!(m is CreationMethod)) {
- find_base_interface_method (m, (Class) current_symbol);
- if (m.is_virtual || m.overrides) {
- find_base_class_method (m, (Class) current_symbol);
- if (m.base_method == null) {
- Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.get_full_name ()));
- }
- }
- }
- } else if (m.is_virtual || m.is_abstract) {
- m.base_method = m;
- }
- } else if (current_symbol is Interface) {
- if (m.is_virtual || m.is_abstract) {
- m.base_interface_method = m;
- }
- } else if (current_symbol is Struct) {
+ if (current_symbol is Struct) {
if (m.is_abstract || m.is_virtual || m.overrides) {
Report.error (m.source_reference, "A struct member `%s' cannot be marked as override, virtual, or abstract".printf (m.get_full_name ()));
return;
}
+ } else if (m.overrides && m.base_method == null) {
+ Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.get_full_name ()));
}
// check whether return type is at least as accessible as the method
}
}
- private void find_base_class_method (Method m, Class cl) {
- var sym = cl.scope.lookup (m.name);
- if (sym is Method) {
- var base_method = (Method) sym;
- if (base_method.is_abstract || base_method.is_virtual) {
- string invalid_match;
- if (!m.compatible (base_method, out invalid_match)) {
- m.error = true;
- Report.error (m.source_reference, "overriding method `%s' is incompatible with base method `%s': %s.".printf (m.get_full_name (), base_method.get_full_name (), invalid_match));
- return;
- }
-
- m.base_method = base_method;
- return;
- }
- }
-
- if (cl.base_class != null) {
- find_base_class_method (m, cl.base_class);
- }
- }
-
- private void find_base_interface_method (Method m, Class cl) {
- // FIXME report error if multiple possible base methods are found
- foreach (DataType type in cl.get_base_types ()) {
- if (type.data_type is Interface) {
- var sym = type.data_type.scope.lookup (m.name);
- if (sym is Method) {
- var base_method = (Method) sym;
- if (base_method.is_abstract || base_method.is_virtual) {
- string invalid_match;
- if (!m.compatible (base_method, out invalid_match)) {
- m.error = true;
- Report.error (m.source_reference, "overriding method `%s' is incompatible with base method `%s': %s.".printf (m.get_full_name (), base_method.get_full_name (), invalid_match));
- return;
- }
-
- m.base_interface_method = base_method;
- return;
- }
- }
- }
- }
- }
-
public override void visit_creation_method (CreationMethod m) {
if (m.type_name != null && m.type_name != current_symbol.name) {
// type_name is null for constructors generated by GIdlParser
return true;
}
- private void find_base_class_property (Property prop, Class cl) {
- var sym = cl.scope.lookup (prop.name);
- if (sym is Property) {
- var base_property = (Property) sym;
- if (base_property.is_abstract || base_property.is_virtual) {
- if (!prop.equals (base_property)) {
- prop.error = true;
- Report.error (prop.source_reference, "Type and/or accessors of overriding property `%s' do not match overridden property `%s'.".printf (prop.get_full_name (), base_property.get_full_name ()));
- return;
- }
-
- prop.base_property = base_property;
- return;
- }
- }
-
- if (cl.base_class != null) {
- find_base_class_property (prop, cl.base_class);
- }
- }
-
- private void find_base_interface_property (Property prop, Class cl) {
- // FIXME report error if multiple possible base properties are found
- foreach (DataType type in cl.get_base_types ()) {
- if (type.data_type is Interface) {
- var sym = type.data_type.scope.lookup (prop.name);
- if (sym is Property) {
- var base_property = (Property) sym;
- if (base_property.is_abstract) {
- if (!prop.equals (base_property)) {
- prop.error = true;
- Report.error (prop.source_reference, "Type and/or accessors of overriding property `%s' do not match overridden property `%s'.".printf (prop.get_full_name (), base_property.get_full_name ()));
- return;
- }
-
- prop.base_interface_property = base_property;
- return;
- }
- }
- }
- }
- }
-
public override void visit_property (Property prop) {
current_symbol = prop;
}
current_source_file.add_type_dependency (prop.property_type, SourceFileDependencyType.SOURCE);
- if (prop.parent_symbol is Class) {
- var cl = (Class) prop.parent_symbol;
-
- /* VAPI classes don't specify overridden properties */
- if (!cl.external_package) {
- find_base_interface_property (prop, cl);
- if (prop.is_virtual || prop.overrides) {
- find_base_class_property (prop, cl);
- if (prop.base_property == null) {
- prop.error = true;
- Report.error (prop.source_reference, "%s: no suitable property found to override".printf (prop.get_full_name ()));
- }
- }
- }
+ 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 */