diff --git a/src/error.cs b/src/error.cs index 23a517bcbcee..d2e845b9f783 100644 --- a/src/error.cs +++ b/src/error.cs @@ -60,6 +60,7 @@ // BI1043 Repeated overload {mi.Name} and no [DelegateApiNameAttribute] provided to generate property name on host class. // BI1044 Repeated name '{apiName.Name}' provided in [DelegateApiNameAttribute]. // BI1045 Only a single [DefaultEnumValue] attribute can be used inside enum {type.Name}. +// BI1046 The [Field] constant {fa.SymbolName} cannot only be used once inside enum {type.Name}. // BI11xx warnings // BI1101 Trying to use a string as a [Target] // BI1102 Using the deprecated EventArgs for a delegate signature in {0}.{1}, please use DelegateName instead diff --git a/src/generator-enums.cs b/src/generator-enums.cs index 13bdb78c0a8f..9436d5d92470 100644 --- a/src/generator-enums.cs +++ b/src/generator-enums.cs @@ -71,10 +71,12 @@ void GenerateEnum (Type type) print ("[Native (\"{0}\")]", native.NativeName); } + var unique_constants = new HashSet (); var fields = new Dictionary (); Tuple null_field = null; Tuple default_symbol = null; - print ("public enum {0} : {1} {{", type.Name, GetCSharpTypeName (Enum.GetUnderlyingType (type))); + var underlying_type = GetCSharpTypeName (Enum.GetUnderlyingType (type)); + print ("public enum {0} : {1} {{", type.Name, underlying_type); indent++; foreach (var f in type.GetFields ()) { // skip value__ field @@ -89,8 +91,12 @@ void GenerateEnum (Type type) continue; if (fa.SymbolName == null) null_field = new Tuple (f, fa); - else + else if (unique_constants.Contains (fa.SymbolName)) + throw new BindingException (1046, true, $"The [Field] constant {fa.SymbolName} cannot only be used once inside enum {type.Name}."); + else { fields.Add (f, fa); + unique_constants.Add (fa.SymbolName); + } if (GetAttribute (f) != null) { if (default_symbol != null) throw new BindingException (1045, true, $"Only a single [DefaultEnumValue] attribute can be used inside enum {type.Name}."); @@ -99,6 +105,7 @@ void GenerateEnum (Type type) } indent--; print ("}"); + unique_constants.Clear (); var library_name = type.Namespace; var error = GetAttribute (type); @@ -164,10 +171,11 @@ void GenerateEnum (Type type) print ("public static NSString GetConstant (this {0} self)", type.Name); print ("{"); indent++; - print ("switch (self) {"); + print ("switch (({0}) self) {{", underlying_type); var default_symbol_name = default_symbol?.Item2.SymbolName; + // more than one enum member can share the same numeric value - ref: #46285 foreach (var kvp in fields) { - print ("case {0}.{1}:", type.Name, kvp.Key.Name); + print ("case {0}: // {1}.{2}", Convert.ToInt64 (kvp.Key.GetValue (null)), type.Name, kvp.Key.Name); var sn = kvp.Value.SymbolName; if (sn == default_symbol_name) print ("default:"); diff --git a/tests/generator/Makefile b/tests/generator/Makefile index 53edab2064ab..d5f69ae16328 100644 --- a/tests/generator/Makefile +++ b/tests/generator/Makefile @@ -14,7 +14,7 @@ include $(TOP)/Make.config IOS_CURRENT_DIR=$(IOS_DESTDIR)/Library/Frameworks/Xamarin.iOS.framework/Versions/Current IOS_GENERATOR = $(IOS_CURRENT_DIR)/bin/btouch /baselib:$(IOS_CURRENT_DIR)/lib/mono/2.1/monotouch.dll /unsafe /compiler:$(IOS_CURRENT_DIR)/bin/smcs IOS_TESTS = bug15283 bug15307 bug15799 bug16036 sof20696157 bug23041 bug27430 bug27428 bug34042 btouch-with-hyphen-in-name property-redefination-ios arrayfromhandlebug bug36457 bug39614 bug40282 bug17232 bug24078-ignore-methods-events strong-dict-support-templated-dicts bug43579 -IOS_CUSTOM_TESTS = forum54078 desk63279 desk79124 multiple-api-definitions1 multiple-api-definitions2 bug29493 classNameCollision bi1036 bug37527 bug27986 bug35176 +IOS_CUSTOM_TESTS = forum54078 desk63279 desk79124 multiple-api-definitions1 multiple-api-definitions2 bug29493 classNameCollision bi1036 bug37527 bug27986 bug35176 bi1046 MAC_CURRENT_DIR=$(MAC_DESTDIR)/Library/Frameworks/Xamarin.Mac.framework/Versions/Current MAC_GENERATOR = $(MAC_CURRENT_DIR)/bin/bmac @@ -135,6 +135,9 @@ forcedtype: bi1036: $(if $(V),,@echo "$@";) $(IOS_GENERATOR) $@.cs | grep BI1036 >/dev/null 2>&1 +bi1046: + $(if $(V),,@echo "$@";) $(IOS_GENERATOR) $@.cs --process-enums | grep BI1046 >/dev/null 2>&1 + clean-local:: rm -f *.dll *.source rm -Rf *.tmpdir diff --git a/tests/generator/bi1046.cs b/tests/generator/bi1046.cs new file mode 100644 index 000000000000..9482bf2dc370 --- /dev/null +++ b/tests/generator/bi1046.cs @@ -0,0 +1,13 @@ +using System; +using MonoTouch.Foundation; + +namespace BindingTests +{ + public enum HMAccessoryCategoryType { + [Field ("HMAccessoryCategoryTypeGarageDoorOpener")] + DoorOpener, + + [Field ("HMAccessoryCategoryTypeGarageDoorOpener")] + GarageDoorOpener = DoorOpener, + } +}