Commit a2c97938 authored by Evan Nemerson's avatar Evan Nemerson Committed by Jürg Billeter

Add support for [Deprecated] attribute

Fixes bug 614712.
parent ae840f4c
......@@ -673,6 +673,8 @@ public class Vala.Class : ObjectTypeSymbol {
is_compact = true;
} else if (a.name == "Immutable") {
is_immutable = true;
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......@@ -1115,6 +1117,7 @@ public class Vala.Class : ObjectTypeSymbol {
}
if (sym is Method) {
// method is used as interface implementation, so it is not unused
sym.check_deprecated (source_reference);
sym.used = true;
} else {
error = true;
......@@ -1134,6 +1137,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.used = true;
} else {
error = true;
......
......@@ -160,6 +160,30 @@ public class Vala.CodeWriter : CodeVisitor {
return cheaders;
}
private void emit_deprecated_attribute (Symbol symbol) {
if (symbol.deprecated) {
write_indent ();
write_string ("[Deprecated");
var since = symbol.deprecated_since;
var replacement = symbol.replacement;
if (since != null || replacement != null) {
write_string (" (");
if (since != null) {
write_string ("since = \"%s\"".printf (since));
}
if (since != null && replacement != null) {
write_string (", ");
}
if (replacement != null) {
write_string ("replacement = \"%s\"".printf (since));
}
write_string (")");
}
write_string ("]");
}
}
public override void visit_class (Class cl) {
if (cl.external_package) {
return;
......@@ -181,6 +205,8 @@ public class Vala.CodeWriter : CodeVisitor {
write_newline ();
}
emit_deprecated_attribute (cl);
write_indent ();
write_string ("[CCode (");
......@@ -330,6 +356,8 @@ public class Vala.CodeWriter : CodeVisitor {
write_newline ();
}
emit_deprecated_attribute (st);
write_indent ();
write_string ("[CCode (");
......@@ -411,6 +439,8 @@ public class Vala.CodeWriter : CodeVisitor {
return;
}
emit_deprecated_attribute (iface);
write_indent ();
write_string ("[CCode (cheader_filename = \"%s\"".printf (get_cheaders(iface)));
......@@ -485,6 +515,8 @@ public class Vala.CodeWriter : CodeVisitor {
return;
}
emit_deprecated_attribute (en);
write_indent ();
write_string ("[CCode (cprefix = \"%s\", ".printf (en.get_cprefix ()));
......@@ -554,6 +586,8 @@ public class Vala.CodeWriter : CodeVisitor {
return;
}
emit_deprecated_attribute (edomain);
write_indent ();
write_string ("[CCode (cprefix = \"%s\", cheader_filename = \"%s\")]".printf (edomain.get_cprefix (), get_cheaders(edomain)));
......@@ -588,6 +622,8 @@ public class Vala.CodeWriter : CodeVisitor {
return;
}
emit_deprecated_attribute (c);
bool custom_cname = (c.get_cname () != c.get_default_cname ());
bool custom_cheaders = (c.parent_symbol is Namespace);
if (custom_cname || custom_cheaders) {
......@@ -630,6 +666,8 @@ public class Vala.CodeWriter : CodeVisitor {
return;
}
emit_deprecated_attribute (f);
bool custom_cname = (f.get_cname () != f.get_default_cname ());
bool custom_ctype = (f.get_ctype () != null);
bool custom_cheaders = (f.parent_symbol is Namespace);
......@@ -826,6 +864,8 @@ public class Vala.CodeWriter : CodeVisitor {
return;
}
emit_deprecated_attribute (cb);
write_indent ();
write_string ("[CCode (cheader_filename = \"%s\"".printf (get_cheaders(cb)));
......@@ -897,6 +937,8 @@ public class Vala.CodeWriter : CodeVisitor {
write_string ("[ScanfFormat]");
}
emit_deprecated_attribute (m);
var ccode_params = new StringBuilder ();
var separator = "";
......@@ -1022,6 +1064,8 @@ public class Vala.CodeWriter : CodeVisitor {
return;
}
emit_deprecated_attribute (prop);
if (prop.no_accessor_method) {
write_indent ();
write_string ("[NoAccessorMethod]");
......@@ -1089,6 +1133,8 @@ public class Vala.CodeWriter : CodeVisitor {
write_indent ();
write_string ("[HasEmitter]");
}
emit_deprecated_attribute (sig);
write_indent ();
write_accessibility (sig);
......
......@@ -153,6 +153,8 @@ public class Vala.Constant : Member, Lockable {
foreach (Attribute a in attributes) {
if (a.name == "CCode") {
process_ccode_attribute (a);
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -276,6 +276,8 @@ public class Vala.Delegate : TypeSymbol {
foreach (Attribute a in attributes) {
if (a.name == "CCode") {
process_ccode_attribute (a);
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -244,6 +244,8 @@ public class Vala.Enum : TypeSymbol {
process_ccode_attribute (a);
} else if (a.name == "Flags") {
is_flags = true;
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -102,6 +102,8 @@ public class Vala.EnumValue : Symbol {
foreach (Attribute a in attributes) {
if (a.name == "CCode" && a.has_argument("cname")) {
cname = a.get_string ("cname");
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -189,6 +189,8 @@ public class Vala.ErrorDomain : TypeSymbol {
foreach (Attribute a in attributes) {
if (a.name == "CCode") {
process_ccode_attribute (a);
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -249,6 +249,8 @@ public class Vala.Field : Member, Lockable {
foreach (Attribute a in attributes) {
if (a.name == "CCode") {
process_ccode_attribute (a);
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -482,6 +482,8 @@ public class Vala.Interface : ObjectTypeSymbol {
foreach (Attribute a in attributes) {
if (a.name == "CCode") {
process_ccode_attribute (a);
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -136,6 +136,7 @@ public class Vala.LambdaExpression : Expression {
method = new Method (get_lambda_name (analyzer), cb.return_type, source_reference);
// track usage for flow analyzer
method.used = true;
method.check_deprecated (source_reference);
if (!cb.has_target || !analyzer.is_in_instance_method ()) {
method.binding = MemberBinding.STATIC;
......
......@@ -640,6 +640,7 @@ public class Vala.MemberAccess : Expression {
}
member.used = true;
member.check_deprecated (source_reference);
if (access == SymbolAccessibility.PROTECTED) {
var target_type = (TypeSymbol) member.parent_symbol;
......
......@@ -498,6 +498,8 @@ public class Vala.Method : Member {
} else if (a.name == "NoArrayLength") {
Report.warning (source_reference, "NoArrayLength attribute is deprecated, use [CCode (array_length = false)] instead.");
no_array_length = true;
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -261,6 +261,7 @@ public class Vala.ObjectCreationExpression : Expression {
// track usage for flow analyzer
symbol_reference.used = true;
symbol_reference.check_deprecated (source_reference);
}
if (symbol_reference != null && symbol_reference.access == SymbolAccessibility.PRIVATE) {
......
......@@ -294,6 +294,8 @@ public class Vala.Property : Member, Lockable {
if (a.has_argument ("blurb")) {
blurb = a.get_string ("blurb");
}
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -246,9 +246,10 @@ public class Vala.Signal : Member, Lockable {
foreach (Attribute a in attributes) {
if (a.name == "HasEmitter") {
has_emitter = true;
}
if (a.name == "Signal") {
} else if (a.name == "Signal") {
process_signal_attribute (a);
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -497,6 +497,8 @@ public class Vala.Struct : TypeSymbol {
process_floating_type_attribute (a);
} else if (a.name == "Immutable") {
is_immutable = true;
} else if (a.name == "Deprecated") {
process_deprecated_attribute (a);
}
}
}
......
......@@ -67,6 +67,21 @@ public abstract class Vala.Symbol : CodeNode {
*/
public bool active { get; set; default = true; }
/**
* Specifies whether this symbol has been deprecated.
*/
public bool deprecated { get; set; default = false; }
/**
* Specifies what version this symbol has been deprecated since.
*/
public string? deprecated_since { get; set; default = null; }
/**
* Specifies the replacement if this symbol has been deprecated.
*/
public string? replacement { get; set; default = null; }
/**
* Specifies whether this symbol has been accessed.
*/
......@@ -365,6 +380,39 @@ public abstract class Vala.Symbol : CodeNode {
return isclass;
}
/**
* Process a [Deprecated] attribute
*/
public virtual void process_deprecated_attribute (Attribute attr) {
if (attr.name != "Deprecated") {
return;
}
deprecated = true;
if (attr.has_argument ("since")) {
deprecated_since = attr.get_string ("since");
}
if (attr.has_argument ("replacement")) {
replacement = attr.get_string ("replacement");
}
}
/**
* 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 (deprecated) {
if (!CodeContext.get ().deprecated) {
Report.warning (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;
}
}
}
public enum Vala.SymbolAccessibility {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment