]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Properly check GLib.Object naming convention for properties
authorRico Tzschichholz <ricotz@ubuntu.com>
Sun, 18 Apr 2021 19:02:21 +0000 (21:02 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Mon, 19 Apr 2021 06:56:10 +0000 (08:56 +0200)
tests/Makefile.am
tests/objects/property-class-invalid-name.test [new file with mode: 0644]
tests/objects/property-interface-invalid-name.test [new file with mode: 0644]
vala/valaproperty.vala
vala/valasemanticanalyzer.vala

index 5b2610dd6c1ff4ab9ca13bde158717936dab8c92..fb1133555bf6535f3d5420028ce70ee28efa1f1b 100644 (file)
@@ -480,6 +480,7 @@ TESTS = \
        objects/property-read-only-auto.vala \
        objects/property-read-only-member-write.test \
        objects/property-read-only-write.test \
+       objects/property-class-invalid-name.test \
        objects/property-construct-only.vala \
        objects/property-construct-only-write.test \
        objects/property-construct-only-write-after.test \
@@ -487,6 +488,7 @@ TESTS = \
        objects/property-delegate.vala \
        objects/property-delegate-owned.vala \
        objects/property-gboxed-nullable.vala \
+       objects/property-interface-invalid-name.test \
        objects/property-real-struct-assignment.vala \
        objects/property-real-struct-no-accessor.test \
        objects/property-simple-type-struct-nullable.vala \
diff --git a/tests/objects/property-class-invalid-name.test b/tests/objects/property-class-invalid-name.test
new file mode 100644 (file)
index 0000000..b1fa279
--- /dev/null
@@ -0,0 +1,8 @@
+Invalid Code
+
+class Foo : Object {
+       public string 1foo { get; set; }
+}
+
+void main () {
+}
diff --git a/tests/objects/property-interface-invalid-name.test b/tests/objects/property-interface-invalid-name.test
new file mode 100644 (file)
index 0000000..e23273d
--- /dev/null
@@ -0,0 +1,8 @@
+Invalid Code
+
+interface IFoo : Object {
+       public abstract string _foo { get; set; }
+}
+
+void main () {
+}
index f07f137e0a078c94f7bd7e4ce196fc6061b4e11e..3d2cbf78a37bab0b330ebea1070e4cc9c14cd092 100644 (file)
@@ -413,6 +413,14 @@ public class Vala.Property : Symbol, Lockable {
 
                checked = true;
 
+               if (context.profile == Profile.GOBJECT && parent_symbol is ObjectTypeSymbol
+                   && ((ObjectTypeSymbol) parent_symbol).is_subtype_of (context.analyzer.object_type)) {
+                       if (!is_valid_name (name)) {
+                               error = true;
+                               Report.error (source_reference, "Name `%s' is not valid for a GLib.Object property", name);
+                       }
+               }
+
                if (this_parameter != null) {
                        this_parameter.check (context);
                }
@@ -543,4 +551,24 @@ public class Vala.Property : Symbol, Lockable {
 
                return !error;
        }
+
+       // Ported from glib's "g_param_spec_is_valid_name"
+       static bool is_valid_name (string name) {
+               char* p;
+
+               if ((name[0] < 'A' || name[0] > 'Z')
+                   && (name[0] < 'a' || name[0] > 'z')) {
+                       return false;
+               }
+
+               for (p = name; *p != '\0'; p++) {
+                       char c = *p;
+                       if (c != '-' && c != '_' && (c < '0' || c > '9')
+                           && (c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) {
+                               return false;
+                       }
+               }
+
+               return true;
+       }
 }
index 9d2d7ea07e8a860c928ada8c8305a836723bbb9b..378c301bd332016db745221dd9f3a874aef29965 100644 (file)
@@ -465,11 +465,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        return false;
                }
 
-               if (!prop.name[0].isalpha ()) {
-                       // GObject requires properties to start with a letter
-                       return false;
-               }
-
                if (type_sym is Interface && !prop.is_abstract && !prop.external && !prop.external_package) {
                        // GObject does not support non-abstract interface properties,
                        // however we assume external properties always are GObject properties