[vala/x-version: 1/22] Introduce [Version (...)]
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/x-version: 1/22] Introduce [Version (...)]
- Date: Sat, 19 Jul 2014 11:17:27 +0000 (UTC)
commit d9fcdde7fe5d55ec86ced9820dcd35cf3a60ccf3
Author: Florian Brosch <flo brosch gmail com>
Date: Thu Jul 10 20:35:22 2014 +0200
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.
codegen/valaccodebasemodule.vala | 6 +-
codegen/valaccodedelegatemodule.vala | 2 +-
codegen/valaccodemethodmodule.vala | 2 +-
codegen/valaccodestructmodule.vala | 4 +-
codegen/valagirwriter.vala | 11 +-
compiler/valacompiler.vala | 3 +
vala/Makefile.am | 1 +
vala/valaclass.vala | 6 +-
vala/valacodecontext.vala | 5 +
vala/valacodewriter.vala | 20 +++
vala/valagirparser.vala | 17 ++-
vala/valalambdaexpression.vala | 3 +-
vala/valamemberaccess.vala | 3 +-
vala/valaobjectcreationexpression.vala | 2 +-
vala/valasourcefile.vala | 64 +++++++++
vala/valasymbol.vala | 104 +++------------
vala/valaversionattribute.vala | 231 ++++++++++++++++++++++++++++++++
vapigen/valagidlparser.vala | 116 ++++++++--------
18 files changed, 430 insertions(+), 170 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index dae3334..b828e11 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -785,7 +785,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 ()) {
@@ -800,7 +800,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);
}
@@ -1000,7 +1000,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 744f63a..346f0a2 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 0a933ac..1104254 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 fe2a7c2..3f226d5 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 9ef70a6..8d9a28e 100644
--- a/codegen/valagirwriter.vala
+++ b/codegen/valagirwriter.vala
@@ -277,12 +277,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 6ac1e1c..706466d 100644
--- a/compiler/valacompiler.vala
+++ b/compiler/valacompiler.vala
@@ -67,6 +67,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)]
@@ -128,6 +129,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" },
@@ -180,6 +182,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 ee8d410..b697970 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -156,6 +156,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 12a82af..61a02ac 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 965e812..a8ec03d 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 0cfa469..5ce9cf0 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -1518,6 +1518,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;
@@ -1552,6 +1565,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 6af2891..1165a8a 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,
@@ -1120,7 +1121,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) {
@@ -1160,13 +1168,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)) {
@@ -1811,6 +1819,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 61482f4..314b2a8 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 26a413c..2bab0b0 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 e64b852..deb082c 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 e925a6b..f02d844 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 cc92116..6d0c963 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.
@@ -228,8 +188,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;
@@ -413,36 +371,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 0000000..9c3df39
--- /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 48c18a3..a435c21 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);
}
}
}
@@ -1013,19 +1013,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);
}
}
}
@@ -1158,12 +1158,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);
@@ -1178,7 +1178,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);
}
}
}
@@ -1237,12 +1237,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") {
@@ -1259,7 +1259,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);
}
}
}
@@ -1399,14 +1399,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") {
@@ -1423,7 +1423,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);
}
}
}
@@ -1443,12 +1443,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]));
}
}
}
@@ -1510,12 +1510,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") {
@@ -1524,7 +1524,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") {
@@ -2305,12 +2305,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") {
@@ -2338,7 +2338,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") {
@@ -2721,12 +2721,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);
@@ -2739,7 +2739,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)) {
@@ -2779,19 +2779,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);
}
}
}
@@ -2905,19 +2905,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) {
@@ -3047,12 +3047,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;
@@ -3065,7 +3065,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);
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]