[vala/staging] Recognize multiple valid CCode.gir_namespace/_version attributes in VAPI files



commit 2b1ac18dee9a805447b0196b2de2f6050789002a
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Mon Jun 28 20:39:09 2021 +0200

    Recognize multiple valid CCode.gir_namespace/_version attributes in VAPI files
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/1189

 codegen/valagirwriter.vala                 | 29 +++++++++++++---
 tests/Makefile.am                          |  3 ++
 tests/girwriter/combined.test              | 54 ++++++++++++++++++++++++++++++
 tests/girwriter/combined.vapi              | 15 +++++++++
 tests/girwriter/tests-extra-environment.sh |  1 +
 vala/valanamespace.vala                    |  7 +++-
 vala/valasourcefile.vala                   |  2 ++
 7 files changed, 106 insertions(+), 5 deletions(-)
---
diff --git a/codegen/valagirwriter.vala b/codegen/valagirwriter.vala
index 7b339198a..4be2b370a 100644
--- a/codegen/valagirwriter.vala
+++ b/codegen/valagirwriter.vala
@@ -124,6 +124,16 @@ public class Vala.GIRWriter : CodeVisitor {
                public bool equal (GIRNamespace g) {
                        return ((ns == g.ns) && (version == g.version));
                }
+
+               public static GIRNamespace for_symbol (Symbol sym) {
+                       while (sym.parent_symbol != null && sym.parent_symbol.name != null) {
+                               sym = sym.parent_symbol;
+                       }
+                       assert (sym is Namespace);
+                       string gir_namespace = sym.get_attribute_string ("CCode", "gir_namespace");
+                       string gir_version = sym.get_attribute_string ("CCode", "gir_version");
+                       return GIRNamespace (gir_namespace, gir_version);
+               }
        }
 
        private ArrayList<GIRNamespace?> externals = new ArrayList<GIRNamespace?> ((EqualFunc<GIRNamespace>) 
GIRNamespace.equal);
@@ -300,7 +310,12 @@ public class Vala.GIRWriter : CodeVisitor {
                        if (node is Namespace && ((Namespace) node).parent_symbol == context.root) {
                                var a = node.get_attribute ("CCode");
                                if (a != null && a.has_argument ("gir_namespace")) {
-                                       source_file.gir_namespace = a.get_string ("gir_namespace");
+                                       var new_gir = a.get_string ("gir_namespace");
+                                       var old_gir = source_file.gir_namespace;
+                                       if (old_gir != null && old_gir != new_gir) {
+                                               source_file.gir_ambiguous = true;
+                                       }
+                                       source_file.gir_namespace = new_gir;
                                }
                                if (a != null && a.has_argument ("gir_version")) {
                                        source_file.gir_version = a.get_string ("gir_version");
@@ -1725,8 +1740,14 @@ public class Vala.GIRWriter : CodeVisitor {
                        Namespace ns = parent as Namespace;
                        var ns_gir_name = ns.get_attribute_string ("GIR", "name") ?? ns.name;
                        if (ns_gir_name != null) {
-                               if (type_symbol.source_reference.file.gir_namespace != null) {
-                                       GIRNamespace external = GIRNamespace 
(type_symbol.source_reference.file.gir_namespace, type_symbol.source_reference.file.gir_version);
+                               unowned SourceFile source_file = type_symbol.source_reference.file;
+                               if (source_file.gir_namespace != null) {
+                                       GIRNamespace external;
+                                       if (source_file.gir_ambiguous) {
+                                               external = GIRNamespace.for_symbol (type_symbol);
+                                       } else {
+                                               external = GIRNamespace (source_file.gir_namespace, 
source_file.gir_version);
+                                       }
                                        if (!externals.contains (external)) {
                                                externals.add (external);
                                        }
@@ -1735,7 +1756,7 @@ public class Vala.GIRWriter : CodeVisitor {
                                                return gir_fullname;
                                        }
                                        var type_name = type_symbol.get_attribute_string ("GIR", "name") ?? 
type_symbol.name;
-                                       return "%s.%s".printf 
(type_symbol.source_reference.file.gir_namespace, type_name);
+                                       return "%s.%s".printf (external.ns, type_name);
                                } else {
                                        unannotated_namespaces.add(ns);
                                }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6f3064dad..ca110d712 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -769,6 +769,7 @@ TESTS = \
        gir/symbol-type-csuffix.test \
        gir/union.test \
        gir/union-transparent.test \
+       girwriter/combined.test \
        gtktemplate/gtkcallback-incompatible.test \
        gtktemplate/gtkcallback-unknown.test \
        gtktemplate/gtkchild-field-assignment.test \
@@ -1272,6 +1273,8 @@ endif
 
 EXTRA_DIST = \
        glib/tests-extra-environment.sh \
+       girwriter/tests-extra-environment.sh \
+       girwriter/combined.vapi \
        gtktemplate/tests-extra-environment.sh \
        parser-keep-going/tests-extra-environment.sh \
        linux/tests-extra-environment.sh \
diff --git a/tests/girwriter/combined.test b/tests/girwriter/combined.test
new file mode 100644
index 000000000..a56f26ada
--- /dev/null
+++ b/tests/girwriter/combined.test
@@ -0,0 +1,54 @@
+Packages: combined
+GIRWriter
+
+Input:
+
+public Foo.Test use_combined_foo (Foo.Test param) {
+       return param;
+}
+public Bar.Test use_combined_bar (Bar.Test param) {
+       return param;
+}
+public Manam.Test use_combined_manam (Manam.Test param) {
+       return param;
+}
+
+Output:
+
+<include name="Foo" version="1.0"/>
+<include name="Bar" version="1.0"/>
+<include name="Manam" version="1.0"/>
+<package name="test"/>
+<c:include name="test.h"/>
+<namespace name="Test" version="1.2" c:prefix="Test" c:identifier-prefixes="Test" c:symbol-prefixes="test">
+  <function name="use_combined_foo" c:identifier="test_use_combined_foo">
+    <return-value transfer-ownership="full">
+      <type name="Foo.Test" c:type="FooTest*"/>
+    </return-value>
+    <parameters>
+      <parameter name="param" transfer-ownership="none">
+        <type name="Foo.Test" c:type="FooTest*"/>
+      </parameter>
+    </parameters>
+  </function>
+  <function name="use_combined_bar" c:identifier="test_use_combined_bar">
+    <return-value transfer-ownership="full">
+      <type name="Bar.Test" c:type="BarTest*"/>
+    </return-value>
+    <parameters>
+      <parameter name="param" transfer-ownership="none">
+        <type name="Bar.Test" c:type="BarTest*"/>
+      </parameter>
+    </parameters>
+  </function>
+  <function name="use_combined_manam" c:identifier="test_use_combined_manam">
+    <return-value transfer-ownership="full">
+      <type name="Manam.Test" c:type="ManamTest*"/>
+    </return-value>
+    <parameters>
+      <parameter name="param" transfer-ownership="none">
+        <type name="Manam.Test" c:type="ManamTest*"/>
+      </parameter>
+    </parameters>
+  </function>
+</namespace>
diff --git a/tests/girwriter/combined.vapi b/tests/girwriter/combined.vapi
new file mode 100644
index 000000000..9c9c8775a
--- /dev/null
+++ b/tests/girwriter/combined.vapi
@@ -0,0 +1,15 @@
+[CCode (cprefix = "Bar", gir_namespace = "Bar", gir_version = "1.0", lower_case_cprefix = "bar_")]
+namespace Bar {
+       public class Test {
+       }
+}
+[CCode (cprefix = "Foo", gir_namespace = "Foo", gir_version = "1.0", lower_case_cprefix = "foo_")]
+namespace Foo {
+       public class Test {
+       }
+}
+[CCode (cprefix = "Manam", gir_namespace = "Manam", gir_version = "1.0", lower_case_cprefix = "manam_")]
+namespace Manam {
+       public class Test {
+       }
+}
diff --git a/tests/girwriter/tests-extra-environment.sh b/tests/girwriter/tests-extra-environment.sh
new file mode 100644
index 000000000..6287225e7
--- /dev/null
+++ b/tests/girwriter/tests-extra-environment.sh
@@ -0,0 +1 @@
+VALAFLAGS="--vapidir ${abs_srcdir}/girwriter"
diff --git a/vala/valanamespace.vala b/vala/valanamespace.vala
index 121ad9f5e..d62babb63 100644
--- a/vala/valanamespace.vala
+++ b/vala/valanamespace.vala
@@ -467,7 +467,12 @@ public class Vala.Namespace : Symbol {
 
                var a = get_attribute ("CCode");
                if (a != null && a.has_argument ("gir_namespace")) {
-                       source_reference.file.gir_namespace = a.get_string ("gir_namespace");
+                       var new_gir = a.get_string ("gir_namespace");
+                       var old_gir = source_reference.file.gir_namespace;
+                       if (old_gir != null && old_gir != new_gir) {
+                               source_reference.file.gir_ambiguous = true;
+                       }
+                       source_reference.file.gir_namespace = new_gir;
                }
                if (a != null && a.has_argument ("gir_version")) {
                        source_reference.file.gir_version = a.get_string ("gir_version");
diff --git a/vala/valasourcefile.vala b/vala/valasourcefile.vala
index 709053bcc..9d8808038 100644
--- a/vala/valasourcefile.vala
+++ b/vala/valasourcefile.vala
@@ -105,6 +105,8 @@ public class Vala.SourceFile {
 
        public string gir_version { get; set; }
 
+       public bool gir_ambiguous { get; set; }
+
        /**
         * The context this source file belongs to.
         */


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