hurden
(Taras Vozniuk)
June 6, 2017, 1:31am
1
How is the thing with enums going in Silver?
Enums with tuple parameters seems to be still broken. (9.1.99.2141 )
public enum UltimateEnum {
case initRealm
case initSomethingWithValue(String)
}
//...
if ultimate == UltimateEnum.initRealm {
print("First thing is working")
}
let lessUltimate = UltimateEnum.initSomethingWithValue("wow wow")
if case .initSomethingWithValue(let string) = lessUltimate {
print("Would be call if this would be working too")
}
This compiles, however instantiation of lessUltimate
fails with
[NullPointerException]: Attempt to write to field 'long lakestonecore.eunit.UltimateEnum.fValue' on a null object reference
Is there any way I can make it working somehow, so that syntactically silver enums with tuple parameters will correspond to Swift?
I am writing Redux architecture in a shared framework and it is quite critical for enums like this to work.
Any suggestion guys?
hurden
(Taras Vozniuk)
June 6, 2017, 4:15am
3
Android. (sorry, forgot to mention)
Thanks, logged as bugs://77957
hurden
(Taras Vozniuk)
June 6, 2017, 4:28am
5
@mh - Any way I can hack it somehow with something like reflection?
Or any compiler magic that I can make my custom structs that will be interpreted as enums with == .something ?
mh
(marc hoffman)
June 6, 2017, 4:33am
6
i can’t say, i’ll have to check with Cerlo.
geothings
(GeoThings Inc.)
June 6, 2017, 5:00am
8
(post withdrawn by author, will be automatically deleted in 24 hours unless flagged)
hurden
(Taras Vozniuk)
June 6, 2017, 5:04am
9
(More feedback)The decompiled java indicates the issue during the initialization:
public final class UltimateEnum {
public static final int __initRealm = 0;
public static final int __initSomethingWithValue = 1;
public static final int __initSomethingWithSomethingElse = 2;
private int fValue;
private Object fAssocValue;
public int get__Value() {
return self.fValue;
}
public static UltimateEnum initRealm() {
Object Result = null;
Result = null;
((UltimateEnum)Result).fValue = 0;
return (UltimateEnum)Result;
}
public static UltimateEnum initSomethingWithValue(String par0) {
if(par0 == null) {
throw new IllegalArgumentException("par0");
} else {
Object Result = null;
Result = null;
((UltimateEnum)Result).fValue = 1;
((UltimateEnum)Result).fAssocValue = par0;
return (UltimateEnum)Result;
}
}
public static UltimateEnum initSomethingWithSomethingElse(String par0, String par1) {
if(par0 == null) {
throw new IllegalArgumentException("par0");
} else if(par1 == null) {
throw new IllegalArgumentException("par1");
} else {
Object Result = null;
Result = null;
((UltimateEnum)Result).fValue = 2;
((UltimateEnum)Result).fAssocValue = new Tuple2(par0, par1);
return (UltimateEnum)Result;
}
}
public int hashCode() {
return self.fValue ^ (self.fAssocValue != null?self.fAssocValue.hashCode():0);
}
public static boolean op_Equality(UltimateEnum aLeft, UltimateEnum aRight) {
return aLeft.fValue != aRight.fValue?false:(aLeft.fAssocValue == null & aRight.fAssocValue == null?true:(aLeft.fAssocValue == null | aRight.fAssocValue == null?false:aLeft.fAssocValue.equals(aRight.fAssocValue)));
}
public static boolean op_Inequality(UltimateEnum aLeft, UltimateEnum aRight) {
return !op_Equality(aLeft, aRight);
}
public boolean equals(Object aOther) {
return !(aOther instanceof UltimateEnum)?false:op_Equality(self, (UltimateEnum)aOther);
}
}
hurden
(Taras Vozniuk)
June 6, 2017, 5:56am
10
@mh : Ok, with some luck It actually can work with help of Objenesis and reflection.
The enum backing class has no constructors, so Objenesis can help instantiating such objects. Glad the if case pattern works…
Reference code:
let genesis = ObjenesisStd()
let inst = genesis.getInstantiatorOf(UltimateEnum.self)
let enumEntry = inst.newInstance() as! UltimateEnum
if let valueField = (try enumEntry.Class.getDeclaredFields().filter { (field) in return field.Name == "fValue" }).first,
let associatedValueField = (try enumEntry.Class.getDeclaredFields().filter { (field) in return field.Name == "fAssocValue"}).first {
valueField.setAccessible(true)
associatedValueField.setAccessible(true)
valueField.`set`(enumEntry, 1)
associatedValueField.`set`(enumEntry, "someString")
}
if case .initSomethingWithValue(let string) = enumEntry {
print("I am here woohoo!!!")
print(string)
}
hurden
(Taras Vozniuk)
June 6, 2017, 5:57am
11
But still it would be great if the actual issue can get fixed soon
bugs://77957 got closed with status fixed.
ck
(Carlo Kok)
June 6, 2017, 7:57am
13
This was indeed because of the lack of a default constructor (java only). Fixed for vnext, thanks!
1 Like