[vala] Add support for [Deprecated] attribute



commit a2c979388250683f8dc91c18db45d3a0a5b3b3e3
Author: Evan Nemerson <evan coeus-group com>
Date:   Sat May 15 15:14:48 2010 -0700

    Add support for [Deprecated] attribute
    
    Fixes bug 614712.

 vala/valaclass.vala                    |    4 ++
 vala/valacodewriter.vala               |   46 ++++++++++++++++++++++++++++++
 vala/valaconstant.vala                 |    2 +
 vala/valadelegate.vala                 |    2 +
 vala/valaenum.vala                     |    2 +
 vala/valaenumvalue.vala                |    2 +
 vala/valaerrordomain.vala              |    2 +
 vala/valafield.vala                    |    2 +
 vala/valainterface.vala                |    2 +
 vala/valalambdaexpression.vala         |    1 +
 vala/valamemberaccess.vala             |    1 +
 vala/valamethod.vala                   |    2 +
 vala/valaobjectcreationexpression.vala |    1 +
 vala/valaproperty.vala                 |    2 +
 vala/valasignal.vala                   |    5 ++-
 vala/valastruct.vala                   |    2 +
 vala/valasymbol.vala                   |   48 ++++++++++++++++++++++++++++++++
 17 files changed, 124 insertions(+), 2 deletions(-)
---
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index eef5075..54916c5 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -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;
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index a2bb0f9..2fc5f82 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -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);
diff --git a/vala/valaconstant.vala b/vala/valaconstant.vala
index 6c0ee9e..b9d29a2 100644
--- a/vala/valaconstant.vala
+++ b/vala/valaconstant.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valadelegate.vala b/vala/valadelegate.vala
index 09538e9..6952409 100644
--- a/vala/valadelegate.vala
+++ b/vala/valadelegate.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valaenum.vala b/vala/valaenum.vala
index ef8a077..85bd3b4 100644
--- a/vala/valaenum.vala
+++ b/vala/valaenum.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valaenumvalue.vala b/vala/valaenumvalue.vala
index eaade92..47f11ee 100644
--- a/vala/valaenumvalue.vala
+++ b/vala/valaenumvalue.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valaerrordomain.vala b/vala/valaerrordomain.vala
index dbc6b45..24b8072 100644
--- a/vala/valaerrordomain.vala
+++ b/vala/valaerrordomain.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valafield.vala b/vala/valafield.vala
index b038c72..ed7e091 100644
--- a/vala/valafield.vala
+++ b/vala/valafield.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valainterface.vala b/vala/valainterface.vala
index e88d44f..02c63a8 100644
--- a/vala/valainterface.vala
+++ b/vala/valainterface.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala
index 25e54b0..4bc618f 100644
--- a/vala/valalambdaexpression.vala
+++ b/vala/valalambdaexpression.vala
@@ -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;
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index c566995..6d12220 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -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;
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 61a5aa1..60995c8 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala
index 2c8ad17..ab726e7 100644
--- a/vala/valaobjectcreationexpression.vala
+++ b/vala/valaobjectcreationexpression.vala
@@ -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) {
diff --git a/vala/valaproperty.vala b/vala/valaproperty.vala
index ac15b8e..ea9d2e1 100644
--- a/vala/valaproperty.vala
+++ b/vala/valaproperty.vala
@@ -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);
 			}			
 		}
 	}
diff --git a/vala/valasignal.vala b/vala/valasignal.vala
index f4859d5..89bca45 100644
--- a/vala/valasignal.vala
+++ b/vala/valasignal.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valastruct.vala b/vala/valastruct.vala
index b7af767..bcfa13e 100644
--- a/vala/valastruct.vala
+++ b/vala/valastruct.vala
@@ -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);
 			}
 		}
 	}
diff --git a/vala/valasymbol.vala b/vala/valasymbol.vala
index 231eace..8cb6e43 100644
--- a/vala/valasymbol.vala
+++ b/vala/valasymbol.vala
@@ -68,6 +68,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.
 	 */
 	public bool used { get; set; }
@@ -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 {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]