summaryrefslogtreecommitdiff
path: root/vala/valaversionattribute.vala
diff options
context:
space:
mode:
authorFlorian Brosch <flo.brosch@gmail.com>2014-07-10 20:35:22 +0200
committerLuca Bruno <lucabru@src.gnome.org>2016-01-30 14:45:32 +0100
commitea92f8d6b5d8d627954295e14ccec7b793facdc8 (patch)
tree6fb4a3e054672fbdfc691359a02b86dea1fca4b4 /vala/valaversionattribute.vala
parentbc4fc3dcd6bd5e9b266c3158a033acfa8e64ee89 (diff)
downloadvala-ea92f8d6b5d8d627954295e14ccec7b793facdc8.tar.gz
Introduce [Version (...)]
Parameters: since: string, version number experimental: bool (was: [Experimental]) experimental_until: string, version number deprecated_since: string, version number (was: [Deprecated (since="")]) replacement: string, symbol name (was: [Deprecated (replacement="")]) deprecated: bool (was: [Deprecated]) Used symbols labeled with [Version (since = "")] are checked against the locally installed package version. Use --disable-since-check to avoid this behaviour. Fixes bug 678912.
Diffstat (limited to 'vala/valaversionattribute.vala')
-rw-r--r--vala/valaversionattribute.vala231
1 files changed, 231 insertions, 0 deletions
diff --git a/vala/valaversionattribute.vala b/vala/valaversionattribute.vala
new file mode 100644
index 000000000..9c3df391f
--- /dev/null
+++ b/vala/valaversionattribute.vala
@@ -0,0 +1,231 @@
+/* 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;
+ }
+}