in Sharpmake/Target.cs [696:801]
internal void Initialize(Type targetType)
{
if (_verifiedTargetTypes.ContainsKey(targetType))
{
TargetType = targetType;
return; // Type already validated.
}
if (targetType == null)
throw new InternalError();
if (!targetType.IsSubclassOf(typeof(ITarget)))
throw new InternalError("target type {0} must be a subclass of {1}", targetType.FullName, typeof(ITarget).FullName);
TargetType = targetType;
FieldInfo[] fragments = TargetType.GetFields();
List<Type> fragmentsType = new List<Type>();
foreach (FieldInfo field in fragments)
{
if (!field.FieldType.IsEnum && !field.FieldType.IsDefined(typeof(FlagsAttribute), false))
throw new Error("fragment of Target Type must be enum with [Flags] attributes: " + field);
if (fragmentsType.Contains(field.FieldType))
throw new Error("enum type in target must be used only once: " + field.FieldType);
Type enumType = field.FieldType;
FieldInfo[] enumFields = enumType.GetFields();
for (int i = 0; i < enumFields.Length; ++i)
{
// GetFields() does not guarantee order; filter out the enum's special name field
if (enumFields[i].Attributes.HasFlag(FieldAttributes.SpecialName))
continue;
if (enumFields[i].GetCustomAttribute<ObsoleteAttribute>() != null)
continue;
// combinations of fragments are not actual fragments so skip them
if (enumFields[i].GetCustomAttribute<CompositeFragmentAttribute>() != null)
continue;
// skip duplicate fragment values that have been explicitely marked as ignored
if (enumFields[i].GetCustomAttribute<IgnoreDuplicateFragmentValueAttribute>() != null)
continue;
int enumFieldValue = (int)enumFields[i].GetRawConstantValue();
if (enumFieldValue == 0)
throw new Error("0 enum field value, fragment value must 1 bit set, {0} fragment: {1}={2}", enumType.FullName, enumFields[i].Name, enumFieldValue);
// TODO: check if only one bit flag value
if (!IsPowerOfTwo((ulong)enumFieldValue))
throw new Error("enum field value must be power of two, ie only one bit set,{0} fragment: {1}={2}", enumType.FullName, enumFields[i].Name, enumFieldValue);
// make sure same value is not there twice
if (!field.FieldType.IsDefined(typeof(TolerateDoubleAttribute), false))
{
for (int j = 0; j < enumFields.Length; ++j)
{
// GetFields() does not guarantee order; filter out the enum's special name field
if (enumFields[j].Attributes.HasFlag(FieldAttributes.SpecialName))
continue;
if (enumFields[j].GetCustomAttribute<ObsoleteAttribute>() != null)
continue;
// skip duplicate fragment values that have been explicitely marked as ignored
if (enumFields[j].GetCustomAttribute<IgnoreDuplicateFragmentValueAttribute>() != null)
continue;
if (i != j)
{
int jEnumFieldValue = (int)enumFields[j].GetRawConstantValue();
if (enumFieldValue == jEnumFieldValue)
{
throw new Error("2 enum fields with the same value found in {0} fragment: {1}={2} and {3}={4}",
enumType.FullName,
enumFields[i].Name,
enumFieldValue,
enumFields[j].Name,
jEnumFieldValue
);
}
}
}
}
}
fragmentsType.Add(field.FieldType);
}
// Validate mandatory fragments
if (!fragmentsType.Contains(typeof(DevEnv)))
throw new Error("Mandatory fragment type \"{0}\" not found in target type \"{1}\" (fields also must be public)", typeof(DevEnv).ToString(), targetType);
if (!fragmentsType.Contains(typeof(Platform)))
throw new Error("Mandatory fragment type \"{0}\" not found in target type \"{1}\" (fields also must be public)", typeof(Platform).ToString(), targetType);
// Mark this type as validated successfully.
_verifiedTargetTypes.TryAdd(targetType, true);
}