summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--codegen/valaccodebasemodule.vala6
-rw-r--r--codegen/valaccodedelegatemodule.vala2
-rw-r--r--codegen/valaccodemethodmodule.vala2
-rw-r--r--codegen/valaccodestructmodule.vala4
-rw-r--r--codegen/valagirwriter.vala11
-rw-r--r--compiler/valacompiler.vala3
-rw-r--r--vala/Makefile.am1
-rw-r--r--vala/valaclass.vala6
-rw-r--r--vala/valacodecontext.vala5
-rw-r--r--vala/valacodewriter.vala20
-rw-r--r--vala/valagirparser.vala17
-rw-r--r--vala/valalambdaexpression.vala3
-rw-r--r--vala/valamemberaccess.vala3
-rw-r--r--vala/valaobjectcreationexpression.vala2
-rw-r--r--vala/valasourcefile.vala64
-rw-r--r--vala/valasymbol.vala104
-rw-r--r--vala/valaversionattribute.vala231
-rw-r--r--vapigen/valagidlparser.vala116
18 files changed, 430 insertions, 170 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 6f4fc6c05..0f79235bd 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -788,7 +788,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
var cenum = new CCodeEnum (get_ccode_name (en));
- cenum.deprecated = en.deprecated;
+ cenum.deprecated = en.version.deprecated;
int flag_shift = 0;
foreach (EnumValue ev in en.get_values ()) {
@@ -803,7 +803,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
ev.value.emit (this);
c_ev = new CCodeEnumValue (get_ccode_name (ev), get_cvalue (ev.value));
}
- c_ev.deprecated = ev.deprecated;
+ c_ev.deprecated = ev.version.deprecated;
cenum.add_value (c_ev);
}
@@ -1003,7 +1003,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
} else {
cdecl.modifiers = CCodeModifiers.EXTERN;
}
- if (f.deprecated) {
+ if (f.version.deprecated) {
cdecl.modifiers |= CCodeModifiers.DEPRECATED;
}
decl_space.add_type_member_declaration (cdecl);
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index 9eb57ed34..f97420f43 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -116,7 +116,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
}
var ctypedef = new CCodeTypeDefinition (return_type_cname, cfundecl);
- ctypedef.deprecated = d.deprecated;
+ ctypedef.deprecated = d.version.deprecated;
decl_space.add_type_definition (ctypedef);
}
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 710bc1151..d147eb18b 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -169,7 +169,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
function.modifiers |= CCodeModifiers.INTERNAL;
}
- if (m.deprecated) {
+ if (m.version.deprecated) {
function.modifiers |= CCodeModifiers.DEPRECATED;
}
diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala
index fe2a7c2a7..3f226d55b 100644
--- a/codegen/valaccodestructmodule.vala
+++ b/codegen/valaccodestructmodule.vala
@@ -64,7 +64,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
}
var instance_struct = new CCodeStruct ("_%s".printf (get_ccode_name (st)));
- instance_struct.deprecated = st.deprecated;
+ instance_struct.deprecated = st.version.deprecated;
foreach (Field f in st.get_fields ()) {
string field_ctype = get_ccode_name (f.variable_type);
@@ -77,7 +77,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
var suffix = get_ccode_declarator_suffix (f.variable_type);
if (suffix != null) {
- suffix.deprecated = f.deprecated;
+ suffix.deprecated = f.version.deprecated;
}
instance_struct.add_field (field_ctype, get_ccode_name (f), suffix);
diff --git a/codegen/valagirwriter.vala b/codegen/valagirwriter.vala
index a69e12a93..01389cfab 100644
--- a/codegen/valagirwriter.vala
+++ b/codegen/valagirwriter.vala
@@ -282,12 +282,15 @@ public class Vala.GIRWriter : CodeVisitor {
}
private void write_symbol_attributes (Symbol symbol) {
- if (symbol.deprecated) {
- buffer.append_printf (" deprecated=\"%s\"", (symbol.replacement == null) ? "" : "Use %s".printf (symbol.replacement));
- if (symbol.deprecated_since != null) {
- buffer.append_printf (" deprecated-version=\"%s\"", symbol.deprecated_since);
+ if (symbol.version.deprecated) {
+ buffer.append_printf (" deprecated=\"%s\"", (symbol.version.replacement == null) ? "" : "Use %s".printf (symbol.version.replacement));
+ if (symbol.version.deprecated_since != null) {
+ buffer.append_printf (" deprecated-version=\"%s\"", symbol.version.deprecated_since);
}
}
+ if (symbol.version.since != null) {
+ buffer.append_printf (" version=\"%s\"", symbol.version.since);
+ }
}
public override void visit_class (Class cl) {
diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala
index ee5d45b7e..ebae467aa 100644
--- a/compiler/valacompiler.vala
+++ b/compiler/valacompiler.vala
@@ -71,6 +71,7 @@ class Vala.Compiler {
static bool experimental;
static bool experimental_non_null;
static bool gobject_tracing;
+ static bool disable_since_check;
static bool disable_warnings;
static string cc_command;
[CCode (array_length = false, array_null_terminated = true)]
@@ -135,6 +136,7 @@ class Vala.Compiler {
{ "enable-experimental", 0, 0, OptionArg.NONE, ref experimental, "Enable experimental features", null },
{ "disable-warnings", 0, 0, OptionArg.NONE, ref disable_warnings, "Disable warnings", null },
{ "fatal-warnings", 0, 0, OptionArg.NONE, ref fatal_warnings, "Treat warnings as fatal", null },
+ { "disable-since-check", 0, 0, OptionArg.NONE, ref disable_since_check, "Do not check whether used symbols exist in local packages", null },
{ "enable-experimental-non-null", 0, 0, OptionArg.NONE, ref experimental_non_null, "Enable experimental enhancements for non-null types", null },
{ "enable-gobject-tracing", 0, 0, OptionArg.NONE, ref gobject_tracing, "Enable GObject creation tracing", null },
{ "cc", 0, 0, OptionArg.STRING, ref cc_command, "Use COMMAND as C compiler command", "COMMAND" },
@@ -198,6 +200,7 @@ class Vala.Compiler {
context.assert = !disable_assert;
context.checking = enable_checking;
context.deprecated = deprecated;
+ context.since_check = !disable_since_check;
context.hide_internal = hide_internal;
context.experimental = experimental;
context.experimental_non_null = experimental_non_null;
diff --git a/vala/Makefile.am b/vala/Makefile.am
index a5a99d173..bd16142d7 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -160,6 +160,7 @@ libvalacore_la_VALASOURCES = \
valausingdirective.vala \
valavaluetype.vala \
valavariable.vala \
+ valaversionattribute.vala \
valavoidtype.vala \
valawhilestatement.vala \
valayieldstatement.vala \
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 085f0ddb0..5dc7c1a96 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -793,8 +793,7 @@ public class Vala.Class : ObjectTypeSymbol {
foreach (var impl in base_class.get_methods ()) {
if (impl.name == m.name && (impl.base_interface_type == null || impl.base_interface_type.data_type == iface)) {
// method is used as interface implementation, so it is not unused
- impl.check_deprecated (source_reference);
- impl.check_experimental (source_reference);
+ impl.version.check (source_reference);
impl.used = true;
implemented = true;
break;
@@ -820,8 +819,7 @@ public class Vala.Class : ObjectTypeSymbol {
}
if (sym is Property) {
// property is used as interface implementation, so it is not unused
- sym.check_deprecated (source_reference);
- sym.check_experimental (source_reference);
+ sym.version.check (source_reference);
sym.used = true;
} else {
error = true;
diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala
index b2c2b4731..55add5041 100644
--- a/vala/valacodecontext.vala
+++ b/vala/valacodecontext.vala
@@ -47,6 +47,11 @@ public class Vala.CodeContext {
public bool hide_internal { get; set; }
/**
+ * Do not check whether used symbols exist in local packages.
+ */
+ public bool since_check { get; set; }
+
+ /**
* Do not warn when using experimental features.
*/
public bool experimental { get; set; }
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index 2fce86f71..ec48ed03d 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -1615,6 +1615,19 @@ public class Vala.CodeWriter : CodeVisitor {
}
}
+ private bool skip_since_tag_check (Symbol sym, string since_val) {
+ Symbol parent_symbol = sym;
+
+ while (parent_symbol.parent_symbol != null) {
+ parent_symbol = parent_symbol.parent_symbol;
+ if (parent_symbol.version.since == since_val) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
private void write_attributes (CodeNode node) {
var sym = node as Symbol;
@@ -1649,6 +1662,13 @@ public class Vala.CodeWriter : CodeVisitor {
continue;
}
+ if (sym != null && attr.args.size == 1 && attr.name == "Version") {
+ string since_val = attr.get_string ("since");
+ if (since_val != null && skip_since_tag_check (sym, since_val)) {
+ continue;
+ }
+ }
+
if (!(node is Parameter) && !(node is PropertyAccessor)) {
write_indent ();
}
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 1ca871a66..a9c994a2d 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -52,6 +52,7 @@ public class Vala.GirParser : CodeVisitor {
DEPRECATED,
REPLACEMENT,
DEPRECATED_SINCE,
+ SINCE,
ARRAY,
ARRAY_LENGTH_IDX,
ARRAY_NULL_TERMINATED,
@@ -1161,7 +1162,14 @@ public class Vala.GirParser : CodeVisitor {
// experimental
if (metadata.has_argument (ArgumentType.EXPERIMENTAL)) {
- symbol.set_attribute ("Experimental", metadata.get_bool (ArgumentType.EXPERIMENTAL));
+ symbol.set_attribute_bool ("Version", "experimental", metadata.get_bool (ArgumentType.EXPERIMENTAL));
+ }
+
+ // since
+ if (metadata.has_argument (ArgumentType.SINCE)) {
+ symbol.version.since = metadata.get_string (ArgumentType.SINCE);
+ } else if (symbol is Namespace == false && girdata["version"] != null) {
+ symbol.version.since = girdata.get ("version");
}
if (parent.symbol is Namespace) {
@@ -1201,13 +1209,13 @@ public class Vala.GirParser : CodeVisitor {
}
}
if (node.deprecated) {
- node.symbol.set_attribute ("Deprecated", true);
+ node.symbol.version.deprecated = true;
}
if (node.deprecated_since != null) {
- node.symbol.set_attribute_string ("Deprecated", "since", node.deprecated_since);
+ node.symbol.version.deprecated_since = node.deprecated_since;
}
if (node.deprecated_replacement != null) {
- node.symbol.set_attribute_string ("Deprecated", "replacement", node.deprecated_replacement);
+ node.symbol.version.replacement = node.deprecated_replacement;
}
if (node.new_symbol && !node.merged && !metadata.get_bool (ArgumentType.HIDDEN)) {
@@ -1850,6 +1858,7 @@ public class Vala.GirParser : CodeVisitor {
parse_include ();
} else if (reader.name == "package") {
var pkg = parse_package ();
+ this.current_source_file.package_name = pkg;
if (context.has_package (pkg)) {
// package already provided elsewhere, stop parsing this GIR
return;
diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala
index 691871056..1d6f95713 100644
--- a/vala/valalambdaexpression.vala
+++ b/vala/valalambdaexpression.vala
@@ -137,8 +137,7 @@ public class Vala.LambdaExpression : Expression {
method = new Method (get_lambda_name (context), return_type, source_reference);
// track usage for flow analyzer
method.used = true;
- method.check_deprecated (source_reference);
- method.check_experimental (source_reference);
+ method.version.check (source_reference);
if (!cb.has_target || !context.analyzer.is_in_instance_method ()) {
method.binding = MemberBinding.STATIC;
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 26a413ca9..2bab0b0df 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -694,8 +694,7 @@ public class Vala.MemberAccess : Expression {
}
member.used = true;
- member.check_deprecated (source_reference);
- member.check_experimental (source_reference);
+ member.version.check (source_reference);
if (access == SymbolAccessibility.PROTECTED) {
var target_type = (TypeSymbol) member.parent_symbol;
diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala
index 6b18efddc..954f77c4c 100644
--- a/vala/valaobjectcreationexpression.vala
+++ b/vala/valaobjectcreationexpression.vala
@@ -257,7 +257,7 @@ public class Vala.ObjectCreationExpression : Expression {
// track usage for flow analyzer
symbol_reference.used = true;
- symbol_reference.check_deprecated (source_reference);
+ symbol_reference.version.check (source_reference);
}
if (symbol_reference != null && symbol_reference.access == SymbolAccessibility.PRIVATE) {
diff --git a/vala/valasourcefile.vala b/vala/valasourcefile.vala
index 0126b1671..04dfeff4c 100644
--- a/vala/valasourcefile.vala
+++ b/vala/valasourcefile.vala
@@ -37,6 +37,70 @@ public class Vala.SourceFile {
}
}
+ private string _package_name;
+
+ public string? package_name {
+ get {
+ if (file_type != SourceFileType.PACKAGE) {
+ return null;
+ }
+
+ if (_package_name == null) {
+ _package_name = Path.get_basename (filename[0:filename.last_index_of_char ('.')]);
+ }
+
+ return _package_name;
+ }
+ set {
+ _package_name = value;
+ }
+ }
+
+ private string? _installed_version = null;
+ private bool _version_requested = false;
+
+ /**
+ * The installed package version or null
+ */
+ public string? installed_version {
+ get {
+ if (_version_requested) {
+ return _installed_version;
+ }
+
+ _version_requested = true;
+
+ string pkg_config_name = package_name;
+ if (pkg_config_name == null) {
+ return null;
+ }
+
+ string? standard_output;
+ int exit_status;
+
+ try {
+ Process.spawn_command_line_sync ("pkg-config --silence-errors --modversion %s".printf (pkg_config_name), out standard_output, null, out exit_status);
+ if (exit_status != 0) {
+ return null;
+ }
+ } catch (GLib.SpawnError err) {
+ return null;
+ }
+
+ standard_output = standard_output[0:-1];
+ if (standard_output != "") {
+ _installed_version = standard_output;
+ }
+
+ return _installed_version;
+ }
+ set {
+ _version_requested = value != null;
+ _installed_version = value;
+ }
+ }
+
+
/**
* Specifies whether this file is a VAPI package file.
*/
diff --git a/vala/valasymbol.vala b/vala/valasymbol.vala
index 18df74ab4..3dcd820cc 100644
--- a/vala/valasymbol.vala
+++ b/vala/valasymbol.vala
@@ -68,62 +68,6 @@ public abstract class Vala.Symbol : CodeNode {
public bool active { get; set; default = true; }
/**
- * Specifies whether this symbol has been deprecated.
- */
- public bool deprecated {
- get {
- if (_deprecated == null) {
- _deprecated = get_attribute ("Deprecated") != null;
- }
- return _deprecated;
- }
- set {
- _deprecated = value;
- set_attribute ("Deprecated", _deprecated);
- }
- }
-
- /**
- * Specifies what version this symbol has been deprecated since.
- */
- public string? deprecated_since {
- owned get {
- return get_attribute_string ("Deprecated", "since");
- }
- set {
- set_attribute_string ("Deprecated", "since", value);
- }
- }
-
- /**
- * Specifies the replacement if this symbol has been deprecated.
- */
- public string? replacement {
- owned get {
- return get_attribute_string ("Deprecated", "replacement");
- }
- set {
- set_attribute_string ("Deprecated", "replacement", value);
- }
- }
-
- /**
- * Specifies whether this symbol is experimental.
- */
- public bool experimental {
- get {
- if (_experimental == null) {
- _experimental = get_attribute ("Experimental") != null;
- }
- return _experimental;
- }
- set {
- _experimental = value;
- set_attribute ("Experimental", value);
- }
- }
-
- /**
* Specifies whether this symbol has been accessed.
*/
public bool used { get; set; }
@@ -138,6 +82,22 @@ public abstract class Vala.Symbol : CodeNode {
public Comment? comment { get; set; }
+
+ private VersionAttribute _version;
+
+ /**
+ * The associated [Version] attribute
+ */
+ public VersionAttribute version {
+ get {
+ if (_version == null) {
+ _version = new VersionAttribute (this);
+ }
+
+ return _version;
+ }
+ }
+
/**
* Specifies whether this method explicitly hides a member of a base
* type.
@@ -231,8 +191,6 @@ public abstract class Vala.Symbol : CodeNode {
private weak Scope _owner;
private Scope _scope;
- private bool? _deprecated;
- private bool? _experimental;
public Symbol (string? name, SourceReference? source_reference, Comment? comment = null) {
this.name = name;
@@ -416,36 +374,6 @@ public abstract class Vala.Symbol : CodeNode {
return isclass;
}
- /**
- * Check to see if the symbol has been deprecated, and emit a warning
- * if it has.
- */
- public bool check_deprecated (SourceReference? source_ref = null) {
- if (external_package && deprecated) {
- if (!CodeContext.get ().deprecated) {
- Report.deprecated (source_ref, "%s %s%s".printf (get_full_name (), (deprecated_since == null) ? "is deprecated" : "has been deprecated since %s".printf (deprecated_since), (replacement == null) ? "" : ". Use %s".printf (replacement)));
- }
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Check to see if the symbol is experimental, and emit a warning
- * if it is.
- */
- public bool check_experimental (SourceReference? source_ref = null) {
- if (external_package && experimental) {
- if (!CodeContext.get ().experimental) {
- Report.experimental (source_ref, "%s is experimental".printf (get_full_name ()));
- }
- return true;
- } else {
- return false;
- }
- }
-
public Symbol? get_hidden_member () {
Symbol sym = null;
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;
+ }
+}
diff --git a/vapigen/valagidlparser.vala b/vapigen/valagidlparser.vala
index 9bced0b93..563eabee2 100644
--- a/vapigen/valagidlparser.vala
+++ b/vapigen/valagidlparser.vala
@@ -507,12 +507,12 @@ public class Vala.GIdlParser : CodeVisitor {
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]));
}
}
}
@@ -618,12 +618,12 @@ public class Vala.GIdlParser : CodeVisitor {
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") {
@@ -634,7 +634,7 @@ public class Vala.GIdlParser : CodeVisitor {
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- cb.set_attribute ("Experimental", true);
+ cb.set_attribute_bool ("Version", "experimental", true);
}
}
}
@@ -820,19 +820,19 @@ public class Vala.GIdlParser : CodeVisitor {
}
} 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);
}
}
}
@@ -914,19 +914,19 @@ public class Vala.GIdlParser : CodeVisitor {
}
} 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]));
@@ -1015,19 +1015,19 @@ public class Vala.GIdlParser : CodeVisitor {
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);
}
}
}
@@ -1160,12 +1160,12 @@ public class Vala.GIdlParser : CodeVisitor {
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);
@@ -1180,7 +1180,7 @@ public class Vala.GIdlParser : CodeVisitor {
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- st.set_attribute ("Experimental", true);
+ st.set_attribute_bool ("Version", "experimental", true);
}
}
}
@@ -1239,12 +1239,12 @@ public class Vala.GIdlParser : CodeVisitor {
}
} 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") {
@@ -1261,7 +1261,7 @@ public class Vala.GIdlParser : CodeVisitor {
}
} else if (nv[0] == "experimental") {
if (eval (nv[1]) == "1") {
- cl.set_attribute ("Experimental", true);
+ cl.set_attribute_bool ("Version", "experimental", true);
}
}
}
@@ -1401,14 +1401,14 @@ public class Vala.GIdlParser : CodeVisitor {
}
} 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") {
@@ -1425,7 +1425,7 @@ public class Vala.GIdlParser : CodeVisitor {
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);
}
}
}
@@ -1445,12 +1445,12 @@ public class Vala.GIdlParser : CodeVisitor {
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]));
}
}
}
@@ -1512,12 +1512,12 @@ public class Vala.GIdlParser : CodeVisitor {
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") {
@@ -1526,7 +1526,7 @@ public class Vala.GIdlParser : CodeVisitor {
}
} 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") {
@@ -2314,12 +2314,12 @@ public class Vala.GIdlParser : CodeVisitor {
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") {
@@ -2347,7 +2347,7 @@ public class Vala.GIdlParser : CodeVisitor {
}
} 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") {
@@ -2732,12 +2732,12 @@ public class Vala.GIdlParser : CodeVisitor {
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);
@@ -2750,7 +2750,7 @@ public class Vala.GIdlParser : CodeVisitor {
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)) {
@@ -2790,19 +2790,19 @@ public class Vala.GIdlParser : CodeVisitor {
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);
}
}
}
@@ -2916,19 +2916,19 @@ public class Vala.GIdlParser : CodeVisitor {
}
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) {
@@ -3058,12 +3058,12 @@ public class Vala.GIdlParser : CodeVisitor {
}
} 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;
@@ -3076,7 +3076,7 @@ public class Vala.GIdlParser : CodeVisitor {
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);
}
}
}