[vala] Warn about unused attributes



commit 44af0246c480b9421f391dd71376298b43a99e2a
Author: Luca Bruno <lucabru src gnome org>
Date:   Wed Dec 3 12:39:23 2014 +0100

    Warn about unused attributes
    
    This may not be the best approach, but it's a start

 compiler/valacompiler.vala |    6 ++
 vala/Makefile.am           |    1 +
 vala/valacodecontext.vala  |    6 ++
 vala/valausedattr.vala     |  186 ++++++++++++++++++++++++++++++++++++++++++++
 vapi/glib-2.0.vapi         |    1 -
 5 files changed, 199 insertions(+), 1 deletions(-)
---
diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala
index 3f88124..fe0fdb9 100644
--- a/compiler/valacompiler.vala
+++ b/compiler/valacompiler.vala
@@ -457,6 +457,12 @@ class Vala.Compiler {
                        context.write_dependencies (dependencies);
                }
 
+               context.used_attr.check_unused (context);
+
+               if (context.report.get_errors () > 0 || (fatal_warnings && context.report.get_warnings () > 
0)) {
+                       return quit ();
+               }
+               
                if (!ccode_only) {
                        var ccompiler = new CCodeCompiler ();
                        if (cc_command == null && Environment.get_variable ("CC") != null) {
diff --git a/vala/Makefile.am b/vala/Makefile.am
index c7fbc0e..a5a99d1 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -156,6 +156,7 @@ libvalacore_la_VALASOURCES = \
        valaunlockstatement.vala \
        valaunresolvedsymbol.vala \
        valaunresolvedtype.vala \
+       valausedattr.vala \
        valausingdirective.vala \
        valavaluetype.vala \
        valavariable.vala \
diff --git a/vala/valacodecontext.vala b/vala/valacodecontext.vala
index 00c242c..b9ac824 100644
--- a/vala/valacodecontext.vala
+++ b/vala/valacodecontext.vala
@@ -230,10 +230,16 @@ public class Vala.CodeContext {
         */
        public CodeGenerator codegen { get; set; }
 
+       /**
+        * Mark attributes used by the compiler and report unused at the end.
+        */
+       public UsedAttr used_attr { get; set; }
+
        public CodeContext () {
                resolver = new SymbolResolver ();
                analyzer = new SemanticAnalyzer ();
                flow_analyzer = new FlowAnalyzer ();
+               used_attr = new UsedAttr ();
        }
 
        /**
diff --git a/vala/valausedattr.vala b/vala/valausedattr.vala
new file mode 100644
index 0000000..ecd4c06
--- /dev/null
+++ b/vala/valausedattr.vala
@@ -0,0 +1,186 @@
+/* valaunusedattr.vala
+ *
+ * Copyright (C) 2014-2015  Jürg Billeter
+ * Copyright (C) 2014-2015  Luca Bruno
+ *
+ * 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:
+ *     Luca Bruno <lucabru src gnome org>
+ */
+
+using GLib;
+
+/**
+ * Code visitor to warn about unused attributes
+ */
+public class Vala.UsedAttr : CodeVisitor {
+       public Vala.Map<string,Vala.Set<string>> marked = new HashMap<string,Vala.Set<string>> (str_hash, 
str_equal);
+
+       const string valac_default_attrs[] = {
+               "CCode", "type_signature", "default_value", "set_value_function", "type_id", "cprefix", 
"cheader_filename",
+               "marshaller_type_name", "get_value_function", "cname", "cheader_filename", 
"destroy_function", "lvalue_access",
+               "has_type_id", "instance_pos", "const_cname", "take_value_function", "copy_function", 
"free_function",
+               "param_spec_function", "has_target", "type_cname", "ref_function", "ref_function_void", 
"unref_function", "type",
+               "has_construct_function", "returns_floating_reference", "gir_namespace", "gir_version", 
"construct_function",
+               "lower_case_cprefix", "simple_generics", "sentinel", "scope", "has_destroy_function",
+               "has_copy_function", "lower_case_csuffix", "ref_sink_function", "dup_function", 
"finish_function",
+               "array_length_type", "array_length", "array_length_cname", "array_length_cexpr", 
"array_null_terminated",
+               "vfunc_name", "finish_name", "free_function_address_of", "pos", "delegate_target", 
"delegate_target_cname", "",
+
+               "Immutable", "",
+               "Compact", "",
+               "Flags", "",
+               "Experimental", "",
+               "NoReturn", "",
+               "Assert", "",
+               "ErrorBase", "",
+               "Deprecated", "since", "replacement", "",
+               
+               "IntegerType", "rank", "min", "max", "",
+               "FloatingType", "rank", "",
+               "BooleanType", "",
+               "SimpleType", "",
+               "PrintfFormat", "",
+               
+               "GIR", "name", "",
+
+       };
+       
+       public UsedAttr () {
+               // mark default valac attrs
+               var curattr = "";
+               foreach (unowned string val in valac_default_attrs) {
+                       if (val == "") {
+                               curattr = "";
+                       } else {
+                               if (curattr == "") {
+                                       curattr = val;
+                                       mark (curattr, null);
+                               } else {
+                                       mark (curattr, val);
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Mark the attribute or attribute argument as used by the compiler
+        */
+       public void mark (string attribute, string? argument) {
+               var set = marked.get (attribute);
+               if (set == null) {
+                       set = new HashSet<string> (str_hash, str_equal);
+                       marked.set (attribute, set);
+               }
+
+               if (argument != null) {
+                       set.add (argument);
+               }
+       }
+       
+       /**
+        * Traverse the code tree and warn about unused attributes.
+        *
+        * @param context a code context
+        */
+       public void check_unused (CodeContext context) {
+               context.root.accept (this);
+       }
+
+       void check_unused_attr (Symbol sym) {
+               // optimize by not looking at all the symbols
+               if (sym.used) {
+                       foreach (unowned Attribute attr in sym.attributes) {
+                               var set = marked.get (attr.name);
+                               if (set == null) {
+                                       Report.warning (attr.source_reference, "attribute `%s' never 
used".printf (attr.name));
+                               } else {
+                                       foreach (var arg in attr.args.get_keys()) {
+                                               if (!set.contains (arg)) {
+                                                       Report.warning (attr.source_reference, "argument `%s' 
never used".printf (arg));
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       public override void visit_namespace (Namespace ns) {
+               check_unused_attr (ns);
+               ns.accept_children (this);
+       }
+       
+       public override void visit_class (Class cl) {
+               check_unused_attr (cl);
+               cl.accept_children (this);
+       }
+
+       public override void visit_struct (Struct st) {
+               check_unused_attr (st);
+               st.accept_children (this);
+       }
+
+       public override void visit_interface (Interface iface) {
+               check_unused_attr (iface);
+               iface.accept_children (this);
+       }
+
+       public override void visit_enum (Enum en) {
+               check_unused_attr (en);
+               en.accept_children (this);
+       }
+
+       public override void visit_error_domain (ErrorDomain ed) {
+               check_unused_attr (ed);
+               ed.accept_children (this);
+       }
+
+       public override void visit_delegate (Delegate cb) {
+               check_unused_attr (cb);
+               cb.accept_children (this);
+       }
+
+       public override void visit_constant (Constant c) {
+               check_unused_attr (c);
+       }
+
+       public override void visit_field (Field f) {
+               check_unused_attr (f);
+       }
+
+       public override void visit_method (Method m) {
+               check_unused_attr (m);
+               m.accept_children (this);
+       }
+
+       public override void visit_creation_method (CreationMethod m) {
+               check_unused_attr (m);
+               m.accept_children (this);
+       }
+
+       public override void visit_formal_parameter (Parameter p) {
+               check_unused_attr (p);
+       }
+
+       public override void visit_property (Property prop) {
+               check_unused_attr (prop);
+       }
+
+       public override void visit_signal (Signal sig) {
+               check_unused_attr (sig);
+               sig.accept_children (this);
+       }
+}
diff --git a/vapi/glib-2.0.vapi b/vapi/glib-2.0.vapi
index 8ce1433..7a7c20e 100644
--- a/vapi/glib-2.0.vapi
+++ b/vapi/glib-2.0.vapi
@@ -5016,7 +5016,6 @@ namespace GLib {
        }
 
        [Compact]
-       [CCode (copy_func = "g_variant_iter_copy", free_func = "g_variant_iter_free")]
        public class VariantIter {
                public VariantIter (Variant value);
                public size_t n_children ();


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