Merge: Better autoinit conflict message
authorJean Privat <jean@pryen.org>
Tue, 14 Jul 2015 19:50:57 +0000 (15:50 -0400)
committerJean Privat <jean@pryen.org>
Tue, 14 Jul 2015 19:50:57 +0000 (15:50 -0400)
On

~~~nit
class A
    var x: Int
end

class B
    var y: Bool
end

class C
    super A
    super B
end
~~~

The error message

> a.nit:9,7: Error: conflict for inherited inits a#B#init(y=) and a#A#init(x=)

now become

> a.nit:9,7: Error: cannot generate automatic init for class C. Conflict in the order in inherited initializers a#B#init(y=) and a#A#init(x=). Use `autoinit` to order initializers. eg `autoinit x=, y=`

(fell free to simplify or propose better)

Close #1549

Pull-Request: #1568
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>

src/modelize/modelize_property.nit
tests/base_init_basic.nit
tests/sav/base_init_basic_alt3.res
tests/sav/base_init_basic_alt5.res [new file with mode: 0644]

index 1afce19..be862c6 100644 (file)
@@ -305,7 +305,12 @@ redef class ModelBuilder
                                        var i = 0
                                        for p in spd.initializers do
                                                if p != longest.initializers[i] then
-                                                       self.error(nclassdef, "Error: conflict for inherited inits {spd}({spd.initializers.join(", ")}) and {longest}({longest.initializers.join(", ")})")
+                                                       var proposal = new ArraySet[MProperty]
+                                                       for spd2 in spropdefs do
+                                                               proposal.add_all spd2.initializers
+                                                       end
+                                                       proposal.add_all initializers
+                                                       self.error(nclassdef, "Error: cannot generate automatic init for class {mclassdef.mclass}. Conflict in the order in inherited initializers {spd}({spd.initializers.join(", ")}) and {longest}({longest.initializers.join(", ")}). Use `autoinit` to order initializers. eg `autoinit {proposal.join(", ")}`")
                                                        # TODO: invalidate the initializer to avoid more errors
                                                        return
                                                end
index 6842aa3..36a1be1 100644 (file)
@@ -32,7 +32,7 @@ end
 class D
        super B
        super C
-       #alt3#var b: Int
+       #alt3,5#var b: Int
        #alt4#var b = 11
        init do 'd'.output #alt2#
 end
@@ -48,6 +48,7 @@ class F
        super D
        super E
        init do 'f'.output #alt1,2#
+       #alt5#autoinit c=, e=
 end
 
 class G
@@ -55,6 +56,7 @@ class G
        super E
        var g: Int
        init do 'g'.output #alt2#
+       #alt5#autoinit c=, e=, g=
 end
 
 class H
index a7be1ec..90f67d3 100644 (file)
@@ -1,2 +1,2 @@
-alt/base_init_basic_alt3.nit:47,7: Error: conflict for inherited inits base_init_basic_alt3#E#init(c=, e=) and base_init_basic_alt3#D#init(c=, b=)
-alt/base_init_basic_alt3.nit:53,7: Error: conflict for inherited inits base_init_basic_alt3#E#init(c=, e=) and base_init_basic_alt3#D#init(c=, b=)
+alt/base_init_basic_alt3.nit:47,7: Error: cannot generate automatic init for class F. Conflict in the order in inherited initializers base_init_basic_alt3#E#init(c=, e=) and base_init_basic_alt3#D#init(c=, b=). Use `autoinit` to order initializers. eg `autoinit c=, b=, e=`
+alt/base_init_basic_alt3.nit:54,7: Error: cannot generate automatic init for class G. Conflict in the order in inherited initializers base_init_basic_alt3#E#init(c=, e=) and base_init_basic_alt3#D#init(c=, b=). Use `autoinit` to order initializers. eg `autoinit c=, b=, e=, g=`
diff --git a/tests/sav/base_init_basic_alt5.res b/tests/sav/base_init_basic_alt5.res
new file mode 100644 (file)
index 0000000..ae87071
--- /dev/null
@@ -0,0 +1 @@
+alt/base_init_basic_alt5.nit:79,9--11: Error: expected 2 argument(s) for `init(c: Int, b: Int)`; got 1. See introduction at `standard::Object::init`.