You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,238 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="SourceInfo.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace System.Xml.Serialization {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
internal class SourceInfo {
|
||||
//a[ia]
|
||||
//((global::System.Xml.Serialization.XmlSerializerNamespaces)p[0])
|
||||
static Regex regex = new Regex("([(][(](?<t>[^)]+)[)])?(?<a>[^[]+)[[](?<ia>.+)[]][)]?");
|
||||
//((global::Microsoft.CFx.Test.Common.TypeLibrary.IXSType_9)o), @"IXSType_9", @"", true, true);
|
||||
static Regex regex2 = new Regex("[(][(](?<cast>[^)]+)[)](?<arg>[^)]+)[)]");
|
||||
|
||||
static readonly Lazy<MethodInfo> iListGetItemMethod = new Lazy<MethodInfo>(
|
||||
() =>
|
||||
{
|
||||
return typeof(IList).GetMethod(
|
||||
"get_Item",
|
||||
CodeGenerator.InstanceBindingFlags,
|
||||
null,
|
||||
new Type[] { typeof(Int32) },
|
||||
null
|
||||
);
|
||||
});
|
||||
|
||||
public string Source;
|
||||
public readonly string Arg;
|
||||
public readonly MemberInfo MemberInfo;
|
||||
public readonly Type Type;
|
||||
public readonly CodeGenerator ILG;
|
||||
|
||||
public SourceInfo(string source, string arg, MemberInfo memberInfo, Type type, CodeGenerator ilg) {
|
||||
this.Source = source;
|
||||
this.Arg = arg ?? source;
|
||||
this.MemberInfo = memberInfo;
|
||||
this.Type = type;
|
||||
this.ILG = ilg;
|
||||
}
|
||||
|
||||
public SourceInfo CastTo(TypeDesc td) {
|
||||
return new SourceInfo("((" + td.CSharpName + ")" + Source + ")", Arg, MemberInfo, td.Type, ILG);
|
||||
}
|
||||
|
||||
public void LoadAddress(Type elementType) {
|
||||
InternalLoad(elementType, asAddress: true);
|
||||
}
|
||||
|
||||
public void Load(Type elementType) {
|
||||
InternalLoad(elementType);
|
||||
}
|
||||
|
||||
private void InternalLoad(Type elementType, bool asAddress = false) {
|
||||
Match match = regex.Match(Arg);
|
||||
if (match.Success) {
|
||||
object varA = ILG.GetVariable(match.Groups["a"].Value);
|
||||
Type varType = ILG.GetVariableType(varA);
|
||||
object varIA = ILG.GetVariable(match.Groups["ia"].Value);
|
||||
if (varType.IsArray) {
|
||||
ILG.Load(varA);
|
||||
ILG.Load(varIA);
|
||||
Type eType = varType.GetElementType();
|
||||
if (CodeGenerator.IsNullableGenericType(eType)) {
|
||||
ILG.Ldelema(eType);
|
||||
ConvertNullableValue(eType, elementType);
|
||||
}
|
||||
else {
|
||||
if (eType.IsValueType) {
|
||||
ILG.Ldelema(eType);
|
||||
if (!asAddress) {
|
||||
ILG.Ldobj(eType);
|
||||
}
|
||||
}
|
||||
else
|
||||
ILG.Ldelem(eType);
|
||||
if (elementType != null)
|
||||
ILG.ConvertValue(eType, elementType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ILG.Load(varA);
|
||||
ILG.Load(varIA);
|
||||
MethodInfo get_Item = varType.GetMethod(
|
||||
"get_Item",
|
||||
CodeGenerator.InstanceBindingFlags,
|
||||
null,
|
||||
new Type[] { typeof(Int32) },
|
||||
null
|
||||
);
|
||||
|
||||
if (get_Item == null && typeof(IList).IsAssignableFrom(varType))
|
||||
{
|
||||
get_Item = iListGetItemMethod.Value;
|
||||
}
|
||||
|
||||
Debug.Assert(get_Item != null);
|
||||
ILG.Call(get_Item);
|
||||
Type eType = get_Item.ReturnType;
|
||||
if (CodeGenerator.IsNullableGenericType(eType)) {
|
||||
LocalBuilder localTmp = ILG.GetTempLocal(eType);
|
||||
ILG.Stloc(localTmp);
|
||||
ILG.Ldloca(localTmp);
|
||||
ConvertNullableValue(eType, elementType);
|
||||
}
|
||||
else if ((elementType != null) && !(eType.IsAssignableFrom(elementType) || elementType.IsAssignableFrom(eType))) {
|
||||
throw new CodeGeneratorConversionException(eType, elementType, asAddress, "IsNotAssignableFrom");
|
||||
}
|
||||
else {
|
||||
Convert(eType, elementType, asAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Source == "null") {
|
||||
ILG.Load(null);
|
||||
}
|
||||
else {
|
||||
object var;
|
||||
Type varType;
|
||||
if (Arg.StartsWith("o.@", StringComparison.Ordinal) || MemberInfo != null) {
|
||||
var = ILG.GetVariable(Arg.StartsWith("o.@", StringComparison.Ordinal) ? "o" : Arg);
|
||||
varType = ILG.GetVariableType(var);
|
||||
if (varType.IsValueType)
|
||||
ILG.LoadAddress(var);
|
||||
else
|
||||
ILG.Load(var);
|
||||
}
|
||||
else {
|
||||
var = ILG.GetVariable(Arg);
|
||||
varType = ILG.GetVariableType(var);
|
||||
|
||||
if (CodeGenerator.IsNullableGenericType(varType) &&
|
||||
varType.GetGenericArguments()[0] == elementType) {
|
||||
|
||||
ILG.LoadAddress(var);
|
||||
ConvertNullableValue(varType, elementType);
|
||||
}
|
||||
else {
|
||||
if (asAddress)
|
||||
ILG.LoadAddress(var);
|
||||
else
|
||||
ILG.Load(var);
|
||||
}
|
||||
}
|
||||
|
||||
if (MemberInfo != null) {
|
||||
Type memberType = (MemberInfo is FieldInfo) ?
|
||||
((FieldInfo)MemberInfo).FieldType : ((PropertyInfo)MemberInfo).PropertyType;
|
||||
if (CodeGenerator.IsNullableGenericType(memberType)) {
|
||||
ILG.LoadMemberAddress(MemberInfo);
|
||||
ConvertNullableValue(memberType, elementType);
|
||||
}
|
||||
else {
|
||||
ILG.LoadMember(MemberInfo);
|
||||
Convert(memberType, elementType, asAddress);
|
||||
}
|
||||
}
|
||||
else {
|
||||
match = regex2.Match(Source);
|
||||
if (match.Success) {
|
||||
Debug.Assert(match.Groups["arg"].Value == Arg);
|
||||
Debug.Assert(match.Groups["cast"].Value == CodeIdentifier.GetCSharpName(Type));
|
||||
if (asAddress)
|
||||
ILG.ConvertAddress(varType, Type);
|
||||
else
|
||||
ILG.ConvertValue(varType, Type);
|
||||
varType = Type;
|
||||
}
|
||||
Convert(varType, elementType, asAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Convert(Type sourceType, Type targetType, bool asAddress) {
|
||||
if (targetType != null) {
|
||||
if (asAddress)
|
||||
ILG.ConvertAddress(sourceType, targetType);
|
||||
else
|
||||
ILG.ConvertValue(sourceType, targetType);
|
||||
}
|
||||
}
|
||||
|
||||
private void ConvertNullableValue(Type nullableType, Type targetType) {
|
||||
System.Diagnostics.Debug.Assert(targetType == nullableType || targetType.IsAssignableFrom(nullableType.GetGenericArguments()[0]));
|
||||
if (targetType != nullableType) {
|
||||
MethodInfo Nullable_get_Value = nullableType.GetMethod(
|
||||
"get_Value",
|
||||
CodeGenerator.InstanceBindingFlags,
|
||||
null,
|
||||
CodeGenerator.EmptyTypeArray,
|
||||
null
|
||||
);
|
||||
ILG.Call(Nullable_get_Value);
|
||||
if (targetType != null) {
|
||||
ILG.ConvertValue(Nullable_get_Value.ReturnType, targetType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator string(SourceInfo source) {
|
||||
return source.Source;
|
||||
}
|
||||
|
||||
public static bool operator !=(SourceInfo a, SourceInfo b) {
|
||||
if ((object)a != null)
|
||||
return !a.Equals(b);
|
||||
return (object)b != null;
|
||||
}
|
||||
|
||||
public static bool operator ==(SourceInfo a, SourceInfo b) {
|
||||
if ((object)a != null)
|
||||
return a.Equals(b);
|
||||
return (object)b == null;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == null)
|
||||
return Source == null;
|
||||
SourceInfo info = obj as SourceInfo;
|
||||
if (info != null)
|
||||
return Source == info.Source;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return (Source == null) ? 0 : Source.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user