Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify MetadataBuilder.GetConstantType. #702

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 13 additions & 58 deletions Mono.Cecil/AssemblyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1625,7 +1625,7 @@ void AddField (FieldDefinition field)
AddCustomAttributes (field);

if (field.HasConstant)
AddConstant (field, field.FieldType);
AddConstant (field);

if (field.HasMarshalInfo)
AddMarshalInfo (field);
Expand Down Expand Up @@ -1757,7 +1757,7 @@ void AddParameter (ushort sequence, ParameterDefinition parameter, ParamTable ta
AddCustomAttributes (parameter);

if (parameter.HasConstant)
AddConstant (parameter, parameter.ParameterType);
AddConstant (parameter);

if (parameter.HasMarshalInfo)
AddMarshalInfo (parameter);
Expand Down Expand Up @@ -1805,7 +1805,7 @@ void AddProperty (PropertyDefinition property)
AddCustomAttributes (property);

if (property.HasConstant)
AddConstant (property, property.PropertyType);
AddConstant (property);
}

void AddOtherSemantic (IMetadataTokenProvider owner, Collection<MethodDefinition> others)
Expand Down Expand Up @@ -1862,73 +1862,27 @@ void AddSemantic (MethodSemanticsAttributes semantics, IMetadataTokenProvider pr
MakeCodedRID (provider, CodedIndex.HasSemantics)));
}

void AddConstant (IConstantProvider owner, TypeReference type)
void AddConstant (IConstantProvider owner)
{
var constant = owner.Constant;
var etype = GetConstantType (type, constant);
var etype = GetConstantType (constant);

constant_table.AddRow (new ConstantRow (
etype,
MakeCodedRID (owner.MetadataToken, CodedIndex.HasConstant),
GetBlobIndex (GetConstantSignature (etype, constant))));
}

static ElementType GetConstantType (TypeReference constant_type, object constant)
static ElementType GetConstantType (object constant)
{
// The allowed constant types are defined in the informative
// text section after §II.22.9 of the ECMA-355 specification.
if (constant == null)
return ElementType.Class;

var etype = constant_type.etype;
switch (etype) {
case ElementType.None:
var type = constant_type.CheckedResolve ();
if (type.IsEnum)
return GetConstantType (type.GetEnumUnderlyingType (), constant);

return ElementType.Class;
case ElementType.String:
return ElementType.String;
case ElementType.Object:
return GetConstantType (constant.GetType ());
case ElementType.Array:
case ElementType.SzArray:
case ElementType.MVar:
case ElementType.Var:
return ElementType.Class;
case ElementType.GenericInst:
var generic_instance = (GenericInstanceType) constant_type;
if (generic_instance.ElementType.IsTypeOf ("System", "Nullable`1"))
return GetConstantType (generic_instance.GenericArguments [0], constant);

return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
case ElementType.CModOpt:
case ElementType.CModReqD:
case ElementType.ByRef:
case ElementType.Sentinel:
return GetConstantType (((TypeSpecification) constant_type).ElementType, constant);
case ElementType.Boolean:
case ElementType.Char:
case ElementType.I:
case ElementType.I1:
case ElementType.I2:
case ElementType.I4:
case ElementType.I8:
case ElementType.U:
case ElementType.U1:
case ElementType.U2:
case ElementType.U4:
case ElementType.U8:
case ElementType.R4:
case ElementType.R8:
return GetConstantType (constant.GetType ());
default:
return etype;
}
}
var constType = constant.GetType ();

static ElementType GetConstantType (Type type)
{
switch (Type.GetTypeCode (type)) {
switch (Type.GetTypeCode (constType)) {
case TypeCode.Boolean:
return ElementType.Boolean;
case TypeCode.Byte:
Expand Down Expand Up @@ -1956,7 +1910,8 @@ static ElementType GetConstantType (Type type)
case TypeCode.String:
return ElementType.String;
default:
throw new NotSupportedException (type.FullName);
throw new NotSupportedException (
$"Only primitive types, strings and null references are permitted in constant fields; objects of type {constType.FullName} are not.");
}
}

Expand Down Expand Up @@ -2532,7 +2487,7 @@ void AddImportTarget (ImportTarget target, SignatureWriter signature)
break;
case ImportTargetKind.ImportXmlNamespaceWithAlias:
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace));
break;
case ImportTargetKind.ImportAlias:
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias));
Expand Down