public FieldSpec CreateField(FieldInfo fi, TypeSpec declaringType)
{
Modifiers mod = 0;
var fa = fi.Attributes;
switch (fa & FieldAttributes.FieldAccessMask) {
case FieldAttributes.Public:
mod = Modifiers.PUBLIC;
break;
case FieldAttributes.Assembly:
mod = Modifiers.INTERNAL;
break;
case FieldAttributes.Family:
mod = Modifiers.PROTECTED;
break;
case FieldAttributes.FamORAssem:
mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
break;
default:
// Ignore private fields (even for error reporting) to not require extra dependencies
if (IgnorePrivateMembers || HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "CompilerGeneratedAttribute", CompilerServicesNamespace))
return null;
mod = Modifiers.PRIVATE;
break;
}
TypeSpec field_type;
try {
field_type = ImportType (fi.FieldType, new DynamicTypeReader (fi));
} catch (Exception e) {
// TODO: I should construct fake TypeSpec based on TypeRef signature
// but there is no way to do it with System.Reflection
throw new InternalErrorException (e, "Cannot import field `{0}.{1}' referenced in assembly `{2}'",
declaringType.GetSignatureForError (), fi.Name, declaringType.MemberDefinition.DeclaringAssembly);
}
var definition = new ImportedMemberDefinition (fi, field_type, this);
if ((fa & FieldAttributes.Literal) != 0) {
var c = Constant.CreateConstantFromValue (field_type, fi.GetRawConstantValue (), Location.Null);
return new ConstSpec (declaringType, definition, field_type, fi, mod, c);
}
if ((fa & FieldAttributes.InitOnly) != 0) {
if (field_type == TypeManager.decimal_type) {
var dc = ReadDecimalConstant (CustomAttributeData.GetCustomAttributes (fi));
if (dc != null)
return new ConstSpec (declaringType, definition, field_type, fi, mod, dc);
}
mod |= Modifiers.READONLY;
} else {
//var req_mod = fi.GetRequiredCustomModifiers ();
//if (req_mod.Length > 0 && HasVolatileModifier (req_mod))
// mod |= Modifiers.VOLATILE;
}
if ((fa & FieldAttributes.Static) != 0) {
mod |= Modifiers.STATIC;
} else {
// Fixed buffers cannot be static
if (declaringType.IsStruct && field_type.IsStruct && field_type.IsNested &&
HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "FixedBufferAttribute", CompilerServicesNamespace)) {
// TODO: Sanity check on field_type (only few type are allowed)
var element_field = CreateField (fi.FieldType.GetField (FixedField.FixedElementName), declaringType);
return new FixedFieldSpec (declaringType, definition, fi, element_field, mod);
}
}
return new FieldSpec (declaringType, definition, field_type, fi, mod);
}