Skip to content

Commit

Permalink
VisualizerData rewrite -- handle types generally, fixes for test fail…
Browse files Browse the repository at this point in the history
…ures
  • Loading branch information
zspitz committed May 8, 2019
1 parent 688c7c7 commit 7ab6767
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 146 deletions.
6 changes: 0 additions & 6 deletions Shared/ExpressionExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,5 @@ public static class ExpressionExtension {

public static string ToString(this CatchBlock catchBlock, string formatter, out Dictionary<object, List<(int start, int length)>> visitedParts) =>
CodeWriter.Create(formatter, catchBlock, out visitedParts).ToString();

public static string ToString(this LabelTarget labelTarget, string formatter) =>
CodeWriter.Create(formatter, labelTarget).ToString();

public static string ToString(this LabelTarget labelTarget, string formatter, out Dictionary<object, List<(int start, int length)>> visitedParts) =>
CodeWriter.Create(formatter, labelTarget, out visitedParts).ToString();
}
}
9 changes: 6 additions & 3 deletions Shared/Util/Extensions/Expression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
namespace ExpressionToString.Util {
public static class ExpressionExtensions {
public static object ExtractValue(this Expression expr) {
if (!(expr is LambdaExpression lexpr)) {
lexpr = Lambda(expr);
if (!(expr is LambdaExpression lambda)) {
lambda = Lambda(expr);
}
return lexpr.Compile().DynamicInvoke();
return lambda.Compile().DynamicInvoke();
}

public static bool TryExtractValue(this Expression expr, out object value) {
Expand All @@ -26,5 +26,8 @@ public static class ExpressionExtensions {

public static bool IsEmpty(this Expression expr) =>
expr is DefaultExpression && expr.Type == typeof(void);

public static bool IsClosedVariable(this Expression expr) =>
expr is MemberExpression mexpr && (mexpr.Expression?.Type.IsClosureClass() ?? false);
}
}
6 changes: 0 additions & 6 deletions Shared/Util/Extensions/IEnumerable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,5 @@ public static class IEnumerableExtensions {
return false;
}
public static bool None(this IEnumerable src) => !src.Any();
public static object First(this IEnumerable src) {
foreach (var item in src) {
return item;
}
return null;
}
}
}
31 changes: 30 additions & 1 deletion Shared/Util/Extensions/Type.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static class TypeExtensions {
public static bool InheritsFromOrImplements<T>(this Type type) => typeof(T).IsAssignableFrom(type);

public static bool IsClosureClass(this Type type) =>
type.HasAttribute<CompilerGeneratedAttribute>() && type.Name.ContainsAny("DisplayClass", "Closure$");
type != null && type.HasAttribute<CompilerGeneratedAttribute>() && type.Name.ContainsAny("DisplayClass", "Closure$");

public static bool IsAnonymous(this Type type) =>
type.HasAttribute<CompilerGeneratedAttribute>() && type.Name.Contains("Anonymous") && type.Name.ContainsAny("<>", "VB$");
Expand Down Expand Up @@ -170,5 +170,34 @@ public static class TypeExtensions {
if (memberName == null) { return new PropertyInfo[] { }; }
return type.GetProperties().Where(x => x.Name == memberName).ToArray();
}

// https://stackoverflow.com/a/55244482
/// <summary>Returns T for T[] and types that implement IEnumerable&lt;T&gt;</summary>
public static Type ItemType(this Type type) {
if (type.IsArray) {
return type.GetElementType();
}

// type is IEnumerable<T>;
if (ImplIEnumT(type)) {
return type.GetGenericArguments().First();
}

// type implements/extends IEnumerable<T>;
var enumType = type.GetInterfaces().Where(ImplIEnumT).Select(t => t.GetGenericArguments().First()).FirstOrDefault();
if (enumType != null) {
return enumType;
}

// type is IEnumerable
if (IsIEnum(type) || type.GetInterfaces().Any(IsIEnum)) {
return typeof(object);
}

return null;

bool IsIEnum(Type t) => t == typeof(System.Collections.IEnumerable);
bool ImplIEnumT(Type t) => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>);
}
}
}
2 changes: 1 addition & 1 deletion Shared/Util/Functions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static class Functions {
/// <summary>Returns a string representation of the value, which may or may not be a valid literal in the language</summary>
public static string StringValue(object o, string language) {
var (isLiteral, repr) = TryRenderLiteral(o, language);
if (!isLiteral && o.GetType().GetMethod("ToString").DeclaringType != typeof(object)) {
if (!isLiteral && o.GetType().GetMethods().Where(x => x.Name=="ToString" && x.GetParameters().None() && x.DeclaringType != typeof(object)).Any()) {
return o.ToString();
}
return repr;
Expand Down
16 changes: 0 additions & 16 deletions Tests.Common/Constructed/MakeLabel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,5 @@ End Block
End Block
End Block"
);

[Fact]
[Trait("Category", Labels)]
public void ConstructLabelTarget() => RunTest(
Label("target"),
"target",
"target"
);

[Fact]
[Trait("Category", Labels)]
public void ConstructEmptyLabelTarget() => RunTest(
Label(""),
"",
""
);
}
}
4 changes: 0 additions & 4 deletions Tests.DotNetCore/Runner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ public static class Runner {
testCSharpCode = catchBlock.ToString(CSharp);
testVBCode = catchBlock.ToString(VisualBasic);
break;
case LabelTarget labelTarget:
testCSharpCode = labelTarget.ToString(CSharp);
testVBCode = labelTarget.ToString(VisualBasic);
break;
}


Expand Down

0 comments on commit 7ab6767

Please sign in to comment.