提交 e955b701 编写于 作者: T Tomas Matousek

Only use portable Reflection API in Object Formatter

上级 760a2390
......@@ -133,7 +133,7 @@
<Compile Include="Compilation.EmitStreamProvider.cs" />
<Compile Include="Compilation\SymbolFilter.cs" />
<Compile Include="CompilerPathUtilities.cs" />
<Compile Include="ReflectionUtil.cs" />
<Compile Include="InternalUtilities\ReflectionUtilities.cs" />
<Compile Include="CorLightup.cs" />
<Compile Include="Desktop\AssemblyPortabilityPolicy.cs" />
<Compile Include="Desktop\AssemblyVersion.cs" />
......
......@@ -6,7 +6,7 @@
namespace Roslyn.Utilities
{
internal static class ReflectionUtil
internal static class ReflectionUtilities
{
/// <summary>
/// Find a <see cref="Type"/> instance by first probing the contract name and then the name as it
......
......@@ -86,7 +86,7 @@ internal static class Environment
{
internal const string TypeName = "System.Environment";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_Runtime_Extensions}",
desktopName: TypeName);
......@@ -105,7 +105,7 @@ internal static class Path
{
internal const string TypeName = "System.IO.Path";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_Runtime_Extensions}",
desktopName: TypeName);
......@@ -134,7 +134,7 @@ internal static class File
{
internal const string TypeName = "System.IO.File";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_IO_FileSystem}",
desktopName: TypeName);
......@@ -173,7 +173,7 @@ internal static class Directory
{
internal const string TypeName = "System.IO.Directory";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_IO_FileSystem}",
desktopName: TypeName);
......@@ -205,7 +205,7 @@ internal static class FileMode
{
internal const string TypeName = "System.IO.FileMode";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_IO_FileSystem_Primitives}",
desktopName: TypeName);
......@@ -226,7 +226,7 @@ internal static class FileAccess
{
internal const string TypeName = "System.IO.FileAccess";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_IO_FileSystem_Primitives}",
desktopName: TypeName);
......@@ -241,7 +241,7 @@ internal static class FileShare
{
internal const string TypeName = "System.IO.FileShare";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_IO_FileSystem_Primitives}",
desktopName: TypeName);
......@@ -264,7 +264,7 @@ internal static class FileOptions
{
internal const string TypeName = "System.IO.FileOptions";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_IO_FileSystem}",
desktopName: TypeName);
......@@ -277,7 +277,7 @@ internal static class SearchOption
{
internal const string TypeName = "System.IO.SearchOption";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_IO_FileSystem}",
desktopName: TypeName);
......@@ -290,7 +290,7 @@ internal static class FileStream
{
internal const string TypeName = "System.IO.FileStream";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_IO_FileSystem}",
desktopName: TypeName);
......@@ -360,7 +360,7 @@ internal static class FileVersionInfo
internal static readonly string DesktopName = $"{TypeName}, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_Diagnostics_FileVersionInfo}",
desktopName: DesktopName);
......@@ -378,7 +378,7 @@ internal static class Thread
{
internal const string TypeName = "System.Threading.Thread";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_Threading_Thread}",
desktopName: TypeName);
......@@ -395,7 +395,7 @@ internal static class RuntimeHelpers
{
internal const string TypeName = "System.Runtime.CompilerServices.RuntimeHelpers";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_Runtime}",
desktopName: TypeName);
......@@ -430,7 +430,7 @@ internal static class Extensions
{
internal const string TypeName = "System.Xml.XPath.Extensions";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_Runtime}",
desktopName: $"{TypeName}, {DesktopNames.System_Xml_Linq}");
......@@ -471,7 +471,7 @@ internal static class Assembly
{
private const string TypeName = "System.Reflection.Assembly";
internal static readonly Type Type = ReflectionUtil.GetTypeFromEither(
internal static readonly Type Type = ReflectionUtilities.GetTypeFromEither(
contractName: $"{TypeName}, {CoreNames.System_Reflection}",
desktopName: TypeName);
......
......@@ -329,7 +329,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ObjectDisplay
Return If(options.IncludesOption(ObjectDisplayOptions.IncludeTypeSuffix), result & "D", result)
End Function
Friend Function FormatLiteral(value As DateTime) As String
Friend Function FormatLiteral(value As Date) As String
Return value.ToString("#M/d/yyyy hh:mm:ss tt#", CultureInfo.InvariantCulture)
End Function
......
......@@ -38,7 +38,6 @@
<Compile Include="DynamicFlagsCustomTypeInfo.cs" />
<Compile Include="DynamicFlagsCustomTypeInfo_Factory.cs" />
<Compile Include="Placeholders.cs" />
<Compile Include="ReflectionHelpers.cs" />
<Compile Include="ImmutableArrayExtensions.cs" />
<Compile Include="CompileResult.cs" />
<Compile Include="FrameDecoder.cs" />
......
......@@ -27,17 +27,17 @@ static ExpressionEvaluatorFatalError()
var registryType = typeof(object).GetTypeInfo().Assembly.GetType("Microsoft.Win32.Registry");
if (registryType != null)
{
var hKeyCurrentUserField = registryType.GetTypeInfo().GetField("CurrentUser");
var hKeyCurrentUserField = registryType.GetTypeInfo().GetDeclaredField("CurrentUser");
if (hKeyCurrentUserField != null && hKeyCurrentUserField.IsStatic)
{
using (var currentUserKey = (IDisposable)hKeyCurrentUserField.GetValue(null))
{
var openSubKeyMethod = currentUserKey.GetType().GetTypeInfo().GetMethod("OpenSubKey", new Type[] { typeof(string), typeof(bool) });
var openSubKeyMethod = currentUserKey.GetType().GetTypeInfo().GetDeclaredMethod("OpenSubKey", new Type[] { typeof(string), typeof(bool) });
using (var eeKey = (IDisposable)openSubKeyMethod.Invoke(currentUserKey, new object[] { RegistryKey, /*writable*/ false }))
{
if (eeKey != null)
{
var getValueMethod = eeKey.GetType().GetTypeInfo().GetMethod("GetValue", new Type[] { typeof(string) });
var getValueMethod = eeKey.GetType().GetTypeInfo().GetDeclaredMethod("GetValue", new Type[] { typeof(string) });
var value = getValueMethod.Invoke(eeKey, new object[] { RegistryValue });
if ((value != null) && (value is int))
{
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Reflection;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
using TypeInfo = System.Reflection.TypeInfo;
internal static class ReflectionHelpers
{
public static MethodInfo GetMethod(this TypeInfo typeInfo, string name, Type[] types)
{
foreach (var method in typeInfo.GetDeclaredMethods(name))
{
var parameters = method.GetParameters();
if (parameters.Length == types.Length)
{
for (int i = 0; i < types.Length; i++)
{
if (types[i] != parameters[i].ParameterType)
{
continue;
}
}
return method;
}
}
return null;
}
public static FieldInfo GetField(this TypeInfo typeInfo, string name)
{
return typeInfo.GetDeclaredField(name);
}
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@
using System;
using System.Diagnostics;
using System.Reflection;
namespace Microsoft.CodeAnalysis
{
......@@ -12,6 +13,18 @@ internal static Type GetTypeInfo(this Type type)
{
return type;
}
// Replaces a missing 4.5 method.
public static FieldInfo GetDeclaredField(this Type type, string name)
{
return type.GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
}
// Replaces a missing 4.5 method.
public static MethodInfo GetDeclaredMethod(this Type type, string name, Type[] parameterTypes)
{
return type.GetMethod(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly, null, parameterTypes, null);
}
}
/// <summary>
......
......@@ -39,6 +39,9 @@
<Compile Include="..\..\..\..\..\Compilers\Core\Portable\InternalUtilities\ExceptionUtilities.cs">
<Link>Compiler\InternalUtilities\ExceptionUtilities.cs</Link>
</Compile>
<Compile Include="..\..\..\..\..\Compilers\Core\Portable\InternalUtilities\ReflectionUtilities.cs">
<Link>Compiler\InternalUtilities\ReflectionUtilities.cs</Link>
</Compile>
<Compile Include="..\..\..\..\..\Compilers\Core\SharedCollections\ObjectPool`1.cs">
<Link>Compiler\InternalUtilities\ObjectPool`1.cs</Link>
</Compile>
......@@ -66,9 +69,6 @@
<Compile Include="..\..\ExpressionCompiler\ExpressionEvaluatorFatalError.cs">
<Link>ExpressionCompiler\ExpressionEvaluatorFatalError.cs</Link>
</Compile>
<Compile Include="..\..\ExpressionCompiler\ReflectionHelpers.cs">
<Link>ExpressionCompiler\ReflectionHelpers.cs</Link>
</Compile>
<Compile Include="Helpers\Placeholders.cs" />
</ItemGroup>
<ItemGroup Label="File References">
......
......@@ -57,6 +57,9 @@
<Compile Include="..\..\..\..\Compilers\Core\Portable\InternalUtilities\ExceptionUtilities.cs">
<Link>Compiler\InternalUtilities\ExceptionUtilities.cs</Link>
</Compile>
<Compile Include="..\..\..\..\Compilers\Core\Portable\InternalUtilities\ReflectionUtilities.cs">
<Link>Compiler\InternalUtilities\ReflectionUtilities.cs</Link>
</Compile>
<Compile Include="..\..\..\..\Compilers\Core\SharedCollections\ObjectPool`1.cs">
<Link>Compiler\InternalUtilities\ObjectPool`1.cs</Link>
</Compile>
......
......@@ -426,22 +426,15 @@ private static void ReportUnhandledException(Exception e)
#region Operations
public ObjectFormattingOptions ObjectFormattingOptions
// TODO (tomat): testing only
public void SetTestObjectFormattingOptions()
{
get
{
return _formattingOptions;
}
set
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
_formattingOptions = value;
}
_formattingOptions = new ObjectFormattingOptions(
memberFormat: MemberDisplayFormat.Inline,
quoteStrings: true,
useHexadecimalNumbers: false,
maxOutputLength: int.MaxValue,
memberIndentation: " ");
}
/// <summary>
......
......@@ -42,12 +42,7 @@ public InteractiveHostTests()
var remoteService = Host.TryGetService();
Assert.NotNull(remoteService);
remoteService.ObjectFormattingOptions = new ObjectFormattingOptions(
memberFormat: MemberDisplayFormat.Inline,
quoteStrings: true,
useHexadecimalNumbers: false,
maxOutputLength: int.MaxValue,
memberIndentation: " ");
remoteService.SetTestObjectFormattingOptions();
// assert and remove logo:
var output = ReadOutputToEnd().Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
......
......@@ -123,39 +123,38 @@ public override string FormatLiteral(decimal value)
return ObjectDisplay.FormatLiteral(value, ObjectDisplayOptions.None);
}
public override string FormatLiteral(DateTime value)
{
// DateTime is not primitive in C#
return null;
}
public override string FormatTypeName(Type type, ObjectFormattingOptions options)
{
return GetPrimitiveTypeName(type) ?? AppendComplexTypeName(new StringBuilder(), type, options).ToString();
return GetPrimitiveTypeName(GetPrimitiveSpecialType(type)) ?? AppendComplexTypeName(new StringBuilder(), type, options).ToString();
}
private static string GetPrimitiveTypeName(Type type)
private static string GetPrimitiveTypeName(SpecialType type)
{
switch (Type.GetTypeCode(type))
switch (type)
{
case TypeCode.Boolean: return "bool";
case TypeCode.Byte: return "byte";
case TypeCode.Char: return "char";
case TypeCode.Decimal: return "decimal";
case TypeCode.Double: return "double";
case TypeCode.Int16: return "short";
case TypeCode.Int32: return "int";
case TypeCode.Int64: return "long";
case TypeCode.SByte: return "sbyte";
case TypeCode.Single: return "float";
case TypeCode.String: return "string";
case TypeCode.UInt16: return "ushort";
case TypeCode.UInt32: return "uint";
case TypeCode.UInt64: return "ulong";
case TypeCode.Object:
case TypeCode.Empty:
case TypeCode.DBNull:
case TypeCode.DateTime:
case SpecialType.System_Boolean: return "bool";
case SpecialType.System_Byte: return "byte";
case SpecialType.System_Char: return "char";
case SpecialType.System_Decimal: return "decimal";
case SpecialType.System_Double: return "double";
case SpecialType.System_Int16: return "short";
case SpecialType.System_Int32: return "int";
case SpecialType.System_Int64: return "long";
case SpecialType.System_SByte: return "sbyte";
case SpecialType.System_Single: return "float";
case SpecialType.System_String: return "string";
case SpecialType.System_UInt16: return "ushort";
case SpecialType.System_UInt32: return "uint";
case SpecialType.System_UInt64: return "ulong";
case SpecialType.System_Object: return "object";
default:
if (type == typeof(object))
{
return "object";
}
return null;
}
}
......@@ -219,8 +218,7 @@ private StringBuilder AppendComplexTypeName(StringBuilder builder, Type type, Ob
return builder;
}
private StringBuilder AppendTypeInstantiation(StringBuilder builder, Type type, Type[] genericArguments, ref int genericArgIndex,
ObjectFormattingOptions options)
private StringBuilder AppendTypeInstantiation(StringBuilder builder, Type type, Type[] genericArguments, ref int genericArgIndex, ObjectFormattingOptions options)
{
// generic arguments of all the outer types and the current type;
Type[] currentGenericArgs = type.GetGenericArguments();
......
......@@ -5,21 +5,17 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Scripting.CSharp;
using ObjectFormatterFixtures;
using Roslyn.Test.Utilities;
using Xunit;
using SymbolDisplay = Microsoft.CodeAnalysis.CSharp.SymbolDisplay;
using VB = Microsoft.CodeAnalysis.VisualBasic;
using ObjectFormatterFixtures;
using Microsoft.CodeAnalysis.Scripting.CSharp;
#region Fixtures
......@@ -282,14 +278,15 @@ private int foo()
public int _38_private_get_public_set { private get { return 1; } set { } }
public int _39_public_get_private_set { get { return 1; } private set { } }
private int _40_private_get_private_set { get { return 1; } set { } }
private int _41_set_only_property { set { } }
public override string ToString()
{
return "AStr";
}
}
[DebuggerTypeProxy(typeof(ComplexProxy))]
[DebuggerTypeProxy(typeof(ComplexProxy))]
internal class TypeWithComplexProxy
{
public override string ToString()
......@@ -297,17 +294,17 @@ public override string ToString()
return "BStr";
}
}
[DebuggerTypeProxy(typeof(Proxy))]
[DebuggerDisplay("DD")]
internal class TypeWithDebuggerDisplayAndProxy
{
public override string ToString()
{
return "<ToString>";
}
[DebuggerDisplay("pxy")]
[DebuggerDisplay("pxy")]
private class Proxy
{
public Proxy(object x)
......@@ -319,7 +316,6 @@ public Proxy(object x)
}
}
internal class C
{
public readonly int A = 1;
......@@ -331,6 +327,15 @@ public override string ToString()
}
}
[DebuggerDisplay("DebuggerDisplayValue")]
internal class BaseClassWithDebuggerDisplay
{
}
internal class InheritedDebuggerDisplay : BaseClassWithDebuggerDisplay
{
}
internal class ToStringException
{
public override string ToString()
......@@ -751,6 +756,15 @@ public void DebuggerDisplay()
);
}
[Fact]
public void DebuggerDisplay_Inherited()
{
var obj = new InheritedDebuggerDisplay();
var str = CSharpObjectFormatter.Instance.FormatObject(obj, s_inline);
Assert.Equal("InheritedDebuggerDisplay(DebuggerDisplayValue)", str);
}
[Fact]
public void DebuggerProxy_DebuggerDisplayAndProxy()
{
......
......@@ -7,10 +7,12 @@
using System.Linq;
using System.Runtime.CompilerServices;
using Roslyn.Utilities;
using Ref = System.Reflection;
using System.Reflection;
namespace Microsoft.CodeAnalysis.Scripting
{
using TypeInfo = System.Reflection.TypeInfo;
public abstract partial class ObjectFormatter
{
// internal for testing
......@@ -69,7 +71,7 @@ private Builder FormatObjectRecursive(Builder result, object obj, bool quoteStri
}
object originalObj = obj;
Type originalType = originalObj.GetType();
TypeInfo originalType = originalObj.GetType().GetTypeInfo();
//
// Override KeyValuePair<,>.ToString() to get better dictionary elements formatting:
......@@ -231,7 +233,7 @@ private Builder FormatObjectRecursive(Builder result, object obj, bool quoteStri
/// }
/// </code>
/// </summary>
private void FormatObjectMembers(Builder result, object obj, Type originalType, bool includeNonPublic, bool inline)
private void FormatObjectMembers(Builder result, object obj, TypeInfo originalType, bool includeNonPublic, bool inline)
{
int lengthLimit = result.Remaining;
if (lengthLimit < 0)
......@@ -269,9 +271,9 @@ private void FormatObjectMembers(Builder result, object obj, Type originalType,
result.AppendGroupClosing(inline);
}
private static bool UseCollectionFormat(IEnumerable<FormattedMember> members, Type originalType)
private static bool UseCollectionFormat(IEnumerable<FormattedMember> members, TypeInfo originalType)
{
return typeof(IEnumerable).IsAssignableFrom(originalType) && members.All(member => member.Index >= 0);
return typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(originalType) && members.All(member => member.Index >= 0);
}
private struct FormattedMember
......@@ -344,18 +346,21 @@ private void FormatObjectMembersRecursive(List<FormattedMember> result, object o
{
Debug.Assert(obj != null);
var type = obj.GetType();
var fields = type.GetFields(Ref.BindingFlags.Instance | Ref.BindingFlags.Public | Ref.BindingFlags.NonPublic);
var properties = type.GetProperties(Ref.BindingFlags.Instance | Ref.BindingFlags.Public | Ref.BindingFlags.NonPublic);
var members = new List<Ref.MemberInfo>(fields.Length + properties.Length);
members.AddRange(fields);
members.AddRange(properties);
var members = new List<MemberInfo>();
var type = obj.GetType().GetTypeInfo();
while (type != null)
{
members.AddRange(type.DeclaredFields.Where(f => !f.IsStatic));
members.AddRange(type.DeclaredProperties.Where(f => f.GetMethod != null && !f.GetMethod.IsStatic));
type = type.BaseType?.GetTypeInfo();
}
// kirillo: need case-sensitive comparison here so that the order of members is
// always well-defined (members can differ by case only). And we don't want to
// depend on that order. TODO (tomat): sort by visibility.
members.Sort(new Comparison<Ref.MemberInfo>((x, y) =>
members.Sort((x, y) =>
{
// Need case-sensitive comparison here so that the order of members is
// always well-defined (members can differ by case only). And we don't want to
// depend on that order.
int comparisonResult = StringComparer.OrdinalIgnoreCase.Compare(x.Name, y.Name);
if (comparisonResult == 0)
{
......@@ -363,7 +368,7 @@ private void FormatObjectMembersRecursive(List<FormattedMember> result, object o
}
return comparisonResult;
}));
});
foreach (var member in members)
{
......@@ -385,7 +390,7 @@ private void FormatObjectMembersRecursive(List<FormattedMember> result, object o
rootHidden = browsable.State == DebuggerBrowsableState.RootHidden;
}
Ref.FieldInfo field = member as Ref.FieldInfo;
FieldInfo field = member as FieldInfo;
if (field != null)
{
if (!(includeNonPublic || ignoreVisibility || field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly))
......@@ -395,14 +400,20 @@ private void FormatObjectMembersRecursive(List<FormattedMember> result, object o
}
else
{
Ref.PropertyInfo property = (Ref.PropertyInfo)member;
PropertyInfo property = (PropertyInfo)member;
var getter = property.GetMethod;
if (getter == null)
{
continue;
}
var getter = property.GetGetMethod(nonPublic: true);
var setter = property.GetSetMethod(nonPublic: true);
var setter = property.SetMethod;
if (!(includeNonPublic || ignoreVisibility ||
getter != null && (getter.IsPublic || getter.IsFamily || getter.IsFamilyOrAssembly) ||
setter != null && (setter.IsPublic || setter.IsFamily || setter.IsFamilyOrAssembly)))
// If not ignoring visibility include properties that has a visible getter or setter.
if (!(includeNonPublic || ignoreVisibility ||
getter.IsPublic || getter.IsFamily || getter.IsFamilyOrAssembly ||
(setter != null && (setter.IsPublic || setter.IsFamily || setter.IsFamilyOrAssembly))))
{
continue;
}
......@@ -417,7 +428,7 @@ private void FormatObjectMembersRecursive(List<FormattedMember> result, object o
if (debuggerDisplay != null)
{
string k = FormatWithEmbeddedExpressions(lengthLimit, debuggerDisplay.Name, obj) ?? _language.FormatMemberName(member);
string v = FormatWithEmbeddedExpressions(lengthLimit, debuggerDisplay.Value, obj) ?? String.Empty; // TODO: ?
string v = FormatWithEmbeddedExpressions(lengthLimit, debuggerDisplay.Value, obj) ?? string.Empty; // TODO: ?
if (!AddMember(result, new FormattedMember(-1, k, v), ref lengthLimit))
{
return;
......@@ -454,7 +465,7 @@ private void FormatObjectMembersRecursive(List<FormattedMember> result, object o
Builder valueBuilder = MakeMemberBuilder(lengthLimit);
FormatObjectRecursive(valueBuilder, item, _options.QuoteStrings, MemberDisplayFormat.InlineValue, out name);
if (!String.IsNullOrEmpty(name))
if (!string.IsNullOrEmpty(name))
{
name = FormatWithEmbeddedExpressions(MakeMemberBuilder(lengthLimit), name, item).ToString();
}
......@@ -506,7 +517,7 @@ private bool AddMember(List<FormattedMember> members, FormattedMember member, re
// We can add more members to the result than it will eventually fit, we shouldn't add less.
// Add 2 more, even if only one or half of it fit, so that the separator is included in edge cases.
if (remainingLength == Int32.MinValue)
if (remainingLength == int.MinValue)
{
return false;
}
......@@ -514,7 +525,7 @@ private bool AddMember(List<FormattedMember> members, FormattedMember member, re
remainingLength -= member.MinimalLength;
if (remainingLength <= 0)
{
remainingLength = Int32.MinValue;
remainingLength = int.MinValue;
}
return true;
......@@ -523,7 +534,7 @@ private bool AddMember(List<FormattedMember> members, FormattedMember member, re
private void FormatException(Builder result, Exception exception)
{
result.Append("!<");
result.Append(_language.FormatTypeName(exception.GetType(), _options));
result.Append(_language.FormatTypeName(exception.GetType().GetTypeInfo(), _options));
result.Append('>');
}
......@@ -533,9 +544,9 @@ private void FormatException(Builder result, Exception exception)
private void FormatKeyValuePair(Builder result, object obj)
{
Type type = obj.GetType();
object key = type.GetProperty("Key").GetValue(obj, SpecializedCollections.EmptyObjects);
object value = type.GetProperty("Value").GetValue(obj, SpecializedCollections.EmptyObjects);
TypeInfo type = obj.GetType().GetTypeInfo();
object key = type.GetDeclaredProperty("Key").GetValue(obj, SpecializedCollections.EmptyObjects);
object value = type.GetDeclaredProperty("Value").GetValue(obj, SpecializedCollections.EmptyObjects);
string _;
result.AppendGroupOpening();
result.AppendCollectionItemSeparator(isFirst: true, inline: true);
......@@ -787,7 +798,7 @@ private Builder FormatWithEmbeddedExpressions(Builder result, string format, obj
break;
}
Ref.MemberInfo member = ResolveMember(obj, memberName, callableOnly);
MemberInfo member = ResolveMember(obj, memberName, callableOnly);
if (member == null)
{
result.AppendFormat(callableOnly ? "!<Method '{0}' not found>" : "!<Member '{0}' not found>", memberName);
......
......@@ -4,7 +4,6 @@
namespace Microsoft.CodeAnalysis.Scripting
{
[Serializable]
public sealed class ObjectFormattingOptions
{
public static readonly ObjectFormattingOptions Default = new ObjectFormattingOptions();
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Reflection
Imports System.Text
Imports Microsoft.CodeAnalysis.VisualBasic
......@@ -33,7 +31,7 @@ Namespace Microsoft.CodeAnalysis.Scripting.VisualBasic
Return ObjectDisplay.FormatLiteral(value)
End Function
Public Overloads Function FormatLiteral(value As DateTime) As String
Public Overrides Function FormatLiteral(value As Date) As String
Return ObjectDisplay.FormatLiteral(value)
End Function
......@@ -107,44 +105,44 @@ Namespace Microsoft.CodeAnalysis.Scripting.VisualBasic
End Function
Public Overrides Function FormatTypeName(type As Type, options As ObjectFormattingOptions) As String
Return If(GetPrimitiveTypeName(type), AppendComplexTypeName(New StringBuilder(), type, options).ToString())
Return If(GetPrimitiveTypeName(GetPrimitiveSpecialType(type)), AppendComplexTypeName(New StringBuilder(), type, options).ToString())
End Function
Private Shared Function GetPrimitiveTypeName(type As Type) As String
Select Case Type.GetTypeCode(type)
Case TypeCode.Boolean
Private Shared Function GetPrimitiveTypeName(type As SpecialType) As String
Select Case type
Case SpecialType.System_Boolean
Return "Boolean"
Case TypeCode.Byte
Case SpecialType.System_Byte
Return "Byte"
Case TypeCode.Char
Case SpecialType.System_Char
Return "Char"
Case TypeCode.Decimal
Case SpecialType.System_Decimal
Return "Decimal"
Case TypeCode.Double
Case SpecialType.System_Double
Return "Double"
Case TypeCode.Int16
Case SpecialType.System_Int16
Return "Short"
Case TypeCode.Int32
Case SpecialType.System_Int32
Return "Integer"
Case TypeCode.Int64
Case SpecialType.System_Int64
Return "Long"
Case TypeCode.SByte
Case SpecialType.System_SByte
Return "SByte"
Case TypeCode.Single
Case SpecialType.System_Single
Return "Single"
Case TypeCode.String
Case SpecialType.System_String
Return "String"
Case TypeCode.UInt16
Case SpecialType.System_UInt16
Return "UShort"
Case TypeCode.UInt32
Case SpecialType.System_UInt32
Return "UInteger"
Case TypeCode.UInt64
Case SpecialType.System_UInt64
Return "ULong"
Case SpecialType.System_DateTime
Return "Date"
Case SpecialType.System_Object
Return "Object"
Case Else
If type = GetType(Object) Then
Return "Object"
End If
Return Nothing
End Select
End Function
......@@ -308,11 +306,11 @@ Namespace Microsoft.CodeAnalysis.Scripting.VisualBasic
sb.Append("]"c)
End Sub
Public Overrides Function FormatMemberName(member As System.Reflection.MemberInfo) As String
Public Overrides Function FormatMemberName(member As MemberInfo) As String
Return member.Name
End Function
Public Overrides Function IsHiddenMember(member As System.Reflection.MemberInfo) As Boolean
Public Overrides Function IsHiddenMember(member As MemberInfo) As Boolean
' TODO (tomat)
Return False
End Function
......
......@@ -244,8 +244,8 @@
<Compile Include="..\..\..\Compilers\Core\Portable\MetadataFileReferenceResolver.cs">
<Link>InternalUtilities\MetadataFileReferenceResolver.cs</Link>
</Compile>
<Compile Include="..\..\..\Compilers\Core\Portable\ReflectionUtil.cs">
<Link>InternalUtilities\ReflectionUtil.cs</Link>
<Compile Include="..\..\..\Compilers\Core\Portable\InternalUtilities\ReflectionUtilities.cs">
<Link>InternalUtilities\ReflectionUtilities.cs</Link>
</Compile>
<Compile Include="..\..\..\Compilers\Core\Portable\PortableShim.cs">
<Link>InternalUtilities\PortableShim.cs</Link>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册