--- /dev/null
+/* valaversionattribute.vala
+ *
+ * Copyright (C) 2013 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+using GLib;
+
+
+/**
+ * Represents a [Version] attribute
+ */
+public class Vala.VersionAttribute {
+ private weak Symbol symbol;
+
+ private bool? _deprecated;
+ private bool? _experimental;
+
+ /**
+ * Constructs a new VersionAttribute.
+ *
+ * @param symbol the owner
+ * @return a new VersionAttribute
+ * @see Vala.Symbol
+ */
+ public VersionAttribute (Symbol symbol) {
+ this.symbol = symbol;
+ }
+
+
+
+ /**
+ * Specifies whether this symbol has been deprecated.
+ */
+ public bool deprecated {
+ get {
+ if (_deprecated == null) {
+ _deprecated = symbol.get_attribute_bool ("Version", "deprecated", false)
+ || symbol.get_attribute_string ("Version", "deprecated_since") != null
+ || symbol.get_attribute_string ("Version", "replacement") != null
+ // [Deprecated] is deprecated
+ || symbol.get_attribute ("Deprecated") != null;
+ }
+ return _deprecated;
+ }
+ set {
+ _deprecated = value;
+ symbol.set_attribute_bool ("Version", "deprecated", _deprecated);
+ }
+ }
+
+ /**
+ * Specifies what version this symbol has been deprecated since.
+ */
+ public string? deprecated_since {
+ owned get {
+ return symbol.get_attribute_string ("Version", "deprecated_since")
+ // [Deprecated] is deprecated
+ ?? symbol.get_attribute_string ("Deprecated", "since");
+ }
+ set {
+ symbol.set_attribute_string ("Version", "deprecated_since", value);
+ }
+ }
+
+ /**
+ * Specifies the replacement if this symbol has been deprecated.
+ */
+ public string? replacement {
+ owned get {
+ return symbol.get_attribute_string ("Version", "replacement")
+ // [Deprecated] is deprecated
+ ?? symbol.get_attribute_string ("Deprecated", "replacement");
+ }
+ set {
+ symbol.set_attribute_string ("Version", "replacement", value);
+ }
+ }
+
+
+
+ /**
+ * Specifies whether this symbol is experimental.
+ */
+ public bool experimental {
+ get {
+ if (_experimental == null) {
+ _experimental = symbol.get_attribute_bool ("Version", "experimental", false)
+ || symbol.get_attribute_string ("Version", "experimental_until") != null
+ || symbol.get_attribute ("Experimental") != null;
+ }
+ return _experimental;
+ }
+ set {
+ _experimental = value;
+ symbol.set_attribute_bool ("Version", "experimental", value);
+ }
+ }
+
+ /**
+ * Specifies until which version this symbol is experimental.
+ */
+ public string? experimental_until {
+ owned get {
+ return symbol.get_attribute_string ("Version", "experimental_until");
+ }
+ set {
+ symbol.set_attribute_string ("Version", "experimental_until", value);
+ }
+ }
+
+
+
+ /**
+ * The minimum version for {@link Vala.VersionAttribute.symbol}
+ */
+ public string? since {
+ owned get {
+ return symbol.get_attribute_string ("Version", "since");
+ }
+ set {
+ symbol.set_attribute_string ("Version", "since", value);
+ }
+ }
+
+
+
+ /**
+ * Check to see if the symbol is experimental, deprecated or not available
+ * and emit a warning if it is.
+ */
+ public bool check (SourceReference? source_ref = null) {
+ bool result = false;
+
+ // deprecation:
+ if (symbol.external_package && deprecated) {
+ if (!CodeContext.get ().deprecated) {
+ Report.deprecated (source_ref, "%s %s%s".printf (symbol.get_full_name (), (deprecated_since == null) ? "is deprecated" : "has been deprecated since %s".printf (deprecated_since), (replacement == null) ? "" : ". Use %s".printf (replacement)));
+ }
+ result = true;
+ }
+
+ // availability:
+ if (symbol.external_package && since != null) {
+ string? package_version = symbol.source_reference.file.installed_version;
+
+ if (CodeContext.get ().since_check && package_version != null && VersionAttribute.cmp_versions (package_version, since) < 0) {
+ unowned string filename = symbol.source_reference.file.filename;
+ string pkg = Path.get_basename (filename[0:filename.last_index_of_char ('.')]);
+ Report.error (source_ref, "%s is not available in %s %s. Use %s >= %s".printf (symbol.get_full_name (), pkg, package_version, pkg, since));
+ }
+ result = true;
+ }
+
+ // experimental:
+ if (symbol.external_package && experimental) {
+ if (!CodeContext.get ().experimental) {
+ string? package_version = symbol.source_reference.file.installed_version;
+ string? experimental_until = this.experimental_until;
+
+ if (experimental_until == null || package_version == null || VersionAttribute.cmp_versions (package_version, experimental_until) < 0) {
+ Report.experimental (source_ref, "%s is experimental%s".printf (symbol.get_full_name (), (experimental_until != null) ? " until %s".printf (experimental_until) : ""));
+ }
+ }
+ result = true;
+ }
+
+ return result;
+ }
+
+
+ /**
+ * A simple version comparison function.
+ *
+ * @param v1str a version number
+ * @param v2str a version number
+ * @return an integer less than, equal to, or greater than zero, if v1str is <, == or > than v2str
+ * @see GLib.CompareFunc
+ */
+ public static int cmp_versions (string v1str, string v2str) {
+ string[] v1arr = v1str.split (".");
+ string[] v2arr = v2str.split (".");
+ int i = 0;
+
+ while (v1arr[i] != null && v2arr[i] != null) {
+ int v1num = int.parse (v1arr[i]);
+ int v2num = int.parse (v2arr[i]);
+
+ if (v1num < 0 || v2num < 0) {
+ // invalid format
+ return 0;
+ }
+
+ if (v1num > v2num) {
+ return 1;
+ }
+
+ if (v1num < v2num) {
+ return -1;
+ }
+
+ i++;
+ }
+
+ if (v1arr[i] != null && v2arr[i] == null) {
+ return 1;
+ }
+
+ if (v1arr[i] == null && v2arr[i] != null) {
+ return -1;
+ }
+
+ return 0;
+ }
+}
ns.set_attribute_string ("CCode", "gir_version", eval (nv[1]));
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- ns.set_attribute ("Deprecated", true);
+ ns.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- ns.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ ns.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- ns.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ ns.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
}
}
}
cb.return_type = return_type = parse_type_from_string (eval (nv[1]), return_type.value_owned);
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- cb.set_attribute ("Deprecated", true);
+ cb.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- cb.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ cb.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- cb.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ cb.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "type_arguments") {
parse_type_arguments_from_string (return_type, eval (nv[1]));
} else if (nv[0] == "instance_pos") {
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- cb.set_attribute ("Experimental", true);
+ cb.set_attribute_bool ("Version", "experimental", true);
}
}
}
}
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- st.set_attribute ("Deprecated", true);
+ st.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- st.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ st.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- st.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ st.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "has_destroy_function") {
if (eval (nv[1]) == "0") {
st.set_attribute_bool ("CCode", "has_destroy_function", false);
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- st.set_attribute ("Experimental", true);
+ st.set_attribute_bool ("Version", "experimental", true);
}
}
}
}
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- cl.set_attribute ("Deprecated", true);
+ cl.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- cl.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ cl.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- cl.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ cl.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "type_parameters") {
foreach (string type_param_name in eval (nv[1]).split (",")) {
cl.add_type_parameter (new TypeParameter (type_param_name, current_source_reference));
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- cl.set_attribute ("Experimental", true);
+ cl.set_attribute_bool ("Version", "experimental", true);
}
} else if (nv[0] == "delegate_target_cname") {
cl.set_attribute_string ("CCode", "delegate_target_cname", eval (nv[1]));
st.set_attribute_string ("CCode", "cheader_filename", eval (nv[1]));
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- st.set_attribute ("Deprecated", true);
+ st.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- st.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ st.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- st.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ st.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "hidden") {
if (eval (nv[1]) == "1") {
return;
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- st.set_attribute ("Experimental", true);
+ st.set_attribute_bool ("Version", "experimental", true);
}
}
}
st.set_attribute_string ("CCode", "cheader_filename", eval (nv[1]));
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- st.set_attribute ("Deprecated", true);
+ st.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- st.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ st.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- st.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ st.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "immutable") {
if (eval (nv[1]) == "1") {
st.set_attribute ("Immutable", true);
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- st.set_attribute ("Experimental", true);
+ st.set_attribute_bool ("Version", "experimental", true);
}
}
}
}
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- cl.set_attribute ("Deprecated", true);
+ cl.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- cl.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ cl.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- cl.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ cl.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "const_cname") {
cl.set_attribute_string ("CCode", "const_cname", eval (nv[1]));
} else if (nv[0] == "free_function") {
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- cl.set_attribute ("Experimental", true);
+ cl.set_attribute_bool ("Version", "experimental", true);
}
}
}
}
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- en.set_attribute ("Deprecated", true);
+ en.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "default_value") {
en.set_attribute_string ("CCode", "default_value", eval (nv[1]));
} else if (nv[0] == "replacement") {
- en.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ en.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- en.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ en.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "rename_to") {
en.name = eval (nv[1]);
} else if (nv[0] == "errordomain") {
en.add_method (m);
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- en.set_attribute ("Experimental", true);
+ en.set_attribute_bool ("Version", "experimental", true);
}
}
}
is_hidden = true;
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- ev.set_attribute ("Deprecated", true);
+ ev.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- ev.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ ev.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- ev.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ ev.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
}
}
}
cl.set_attribute_string ("CCode", "type_check_function", eval (nv[1]));
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- cl.set_attribute ("Deprecated", true);
+ cl.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- cl.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ cl.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- cl.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ cl.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "type_id") {
cl.set_attribute_string ("CCode", "type_id", eval (nv[1]));
} else if (nv[0] == "abstract") {
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- cl.set_attribute ("Experimental", true);
+ cl.set_attribute_bool ("Version", "experimental", true);
}
} else if (nv[0] == "compact") {
if (eval (nv[1]) == "1") {
parse_type_arguments_from_string (return_type, eval (nv[1]));
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- m.set_attribute ("Deprecated", true);
+ m.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- m.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ m.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- m.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ m.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "cheader_filename") {
m.set_attribute_string ("CCode", "cheader_filename", eval (nv[1]));
} else if (nv[0] == "abstract") {
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- m.set_attribute ("Experimental", true);
+ m.set_attribute_bool ("Version", "experimental", true);
}
} else if (nv[0] == "simple_generics") {
if (eval (nv[1]) == "1") {
parse_type_arguments_from_string (prop.property_type, eval (nv[1]));
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- prop.set_attribute ("Deprecated", true);
+ prop.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- prop.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ prop.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- prop.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ prop.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "accessor_method") {
if (eval (nv[1]) == "0") {
prop.set_attribute ("NoAccessorMethod", true);
prop.property_type = parse_type_from_string (eval (nv[1]), false);
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- prop.set_attribute ("Experimental", true);
+ prop.set_attribute_bool ("Version", "experimental", true);
}
} else if (nv[0] == "nullable") {
if (eval (nv[1]) == "1" && !(prop.property_type is VoidType)) {
c.set_attribute_string ("CCode", "cheader_filename", eval (nv[1]));
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- c.set_attribute ("Deprecated", true);
+ c.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- c.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ c.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- c.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ c.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "hidden") {
if (eval (nv[1]) == "1") {
return null;
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- c.set_attribute ("Experimental", true);
+ c.set_attribute_bool ("Version", "experimental", true);
}
}
}
}
if (deprecated) {
- field.set_attribute ("Deprecated", true);
+ field.set_attribute_bool ("Version", "deprecated", true);
if (deprecated_since != null) {
- field.set_attribute_string ("Deprecated", "since", deprecated_since);
+ field.set_attribute_string ("Version", "deprecated_since", deprecated_since);
}
if (replacement != null) {
- field.set_attribute_string ("Deprecated", "replacement", replacement);
+ field.set_attribute_string ("Version", "replacement", replacement);
}
}
if (experimental) {
- field.set_attribute ("Experimental", true);
+ field.set_attribute_bool ("Version", "experimental", true);
}
if (ctype != null) {
}
} else if (nv[0] == "deprecated") {
if (eval (nv[1]) == "1") {
- sig.set_attribute ("Deprecated", true);
+ sig.set_attribute_bool ("Version", "deprecated", true);
}
} else if (nv[0] == "replacement") {
- sig.set_attribute_string ("Deprecated", "replacement", eval (nv[1]));
+ sig.set_attribute_string ("Version", "replacement", eval (nv[1]));
} else if (nv[0] == "deprecated_since") {
- sig.set_attribute_string ("Deprecated", "since", eval (nv[1]));
+ sig.set_attribute_string ("Version", "deprecated_since", eval (nv[1]));
} else if (nv[0] == "transfer_ownership") {
if (eval (nv[1]) == "1") {
sig.return_type.value_owned = true;
parse_type_arguments_from_string (sig.return_type, eval (nv[1]));
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- sig.set_attribute ("Experimental", true);
+ sig.set_attribute_bool ("Version", "experimental", true);
}
}
}