Skip to content

Commit

Permalink
Merge pull request #341 from JakeGinnivan/PortableLibSupport
Browse files Browse the repository at this point in the history
Add support for coreclr/portable libraries
  • Loading branch information
JakeGinnivan committed Dec 30, 2015
2 parents cac4d16 + 212dd69 commit 89f4843
Show file tree
Hide file tree
Showing 406 changed files with 3,640 additions and 1,175 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ ShouldlyConvention.Tests/obj/
ShouldlyConvention.Tests/bin/
docs/_build/
*.received.cs
src/.vs
3 changes: 1 addition & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ build_script:
- cmd: nuget restore src\
- cmd: gitversion /l console /output buildserver /updateAssemblyInfo

- cmd: msbuild src\Shouldly.sln "/p:Configuration=%CONFIGURATION%;Platform=%PLATFORM%;TargetFrameworkVersion=v3.5"
- cmd: msbuild src\Shouldly.sln "/p:Configuration=%CONFIGURATION%;Platform=%PLATFORM%;TargetFrameworkVersion=v4.0"
- cmd: msbuild src\Shouldly.sln "/p:Configuration=%CONFIGURATION%;Platform=%PLATFORM%"

- cmd: ECHO nuget pack Shouldly.nuspec -version "%GitVersion_NuGetVersion%" -prop "target=%CONFIGURATION%"
- cmd: nuget pack Shouldly.nuspec -version "%GitVersion_NuGetVersion%" -prop "target=%CONFIGURATION%"
Expand Down
4 changes: 4 additions & 0 deletions shouldly.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
</metadata>
<files>
<file src="output\$target$\net40\Shouldly.dll" target="lib\net40\Shouldly.dll" />
<file src="output\$target$\net40\Shouldly.pdb" target="lib\net40\Shouldly.pdb" />
<file src="output\$target$\net35\Shouldly.dll" target="lib\net35\Shouldly.dll" />
<file src="output\$target$\net35\Shouldly.pdb" target="lib\net35\Shouldly.pdb" />
<file src="output\$target$\portable-net45+netcore45+wp8+wpa81\Shouldly.dll" target="lib\portable-net45+netcore45+wp8+wpa81\Shouldly.dll" />
<file src="output\$target$\portable-net45+netcore45+wp8+wpa81\Shouldly.pdb" target="lib\portable-net45+netcore45+wp8+wpa81\Shouldly.pdb" />
</files>
</package>
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;

// ReSharper disable CheckNamespace
namespace ExpressionToString
{
class ExpressionStringBuilder : ExpressionVisitor
{
// ReSharper disable InconsistentNaming
private readonly StringBuilder builder = new StringBuilder();
private readonly bool trimLongArgumentList;
bool skipDot;

private ExpressionStringBuilder(bool trimLongArgumentList)
{
this.trimLongArgumentList = trimLongArgumentList;
}

/// <summary>
/// A nicely formatted ToString of an expression
/// </summary>
/// <param name="expression">The expression to format</param>
/// <param name="trimLongArgumentList">If true will replace large (>3) argument lists with an elipsis</param>
/// <returns></returns>
public static string ToString(Expression expression, bool trimLongArgumentList = false)
{
var visitor = new ExpressionStringBuilder(trimLongArgumentList);
visitor.Visit(expression);
var s = visitor.builder.ToString();
return s;
}


protected override Expression VisitLambda<T>(Expression<T> node)
{
if (node.Parameters.Any())
{
Out("(");
Out(String.Join(",", node.Parameters.Select(n => n.Name)));
Out(") => ");
}
Visit(node.Body);
return node;
}

protected override Expression VisitInvocation(InvocationExpression node)
{
var visitInvocation = base.VisitInvocation(node);
Out("()");
return visitInvocation;
}

protected override Expression VisitBinary(BinaryExpression node)
{
Out("(");
Visit(node.Left);
Out(" ");
Out(ToString(node.NodeType));
Out(" ");
Visit(node.Right);
Out(")");
return node;
}

protected override Expression VisitParameter(ParameterExpression node)
{
Out(node.Name);
return node;
}

protected override Expression VisitMember(MemberExpression node)
{
if (node.Expression.NodeType == ExpressionType.Constant)
{
Visit(node.Expression);
if (skipDot)
{
skipDot = false;
Out(node.Member.Name);
}
else
Out("." + node.Member.Name);
}
else
{
Visit(node.Expression);
Out("." + node.Member.Name);
}

return node;
}

protected override Expression VisitConstant(ConstantExpression node)
{
if (CheckIfAnonymousType(node.Type))
{
skipDot = true;
return node;
}
if (node.Value == null)
{
Out("null");
}
else
{
var stringValue = node.Value as string;
if (stringValue != null)
{
Out("\"" + stringValue + "\"");
}
else
{
if (node.Value is bool)
{
Out(node.Value.ToString().ToLower());
}
else
{
var valueToString = node.Value.ToString();
var type = node.Value.GetType();
if (type.FullName != valueToString)
{
Out(valueToString);
}
else
{
skipDot = true;
}
}
}
}

return node;
}

protected override Expression VisitUnary(UnaryExpression node)
{
if (node.NodeType == ExpressionType.Convert)
{
Visit(node.Operand);
return node;
}
if (node.NodeType == ExpressionType.Not)
{
Out("!");
Visit(node.Operand);
return node;
}
if (node.NodeType == ExpressionType.TypeAs)
{
Out("(");
Visit(node.Operand);
Out(" As " + node.Type.Name + ")");
return node;
}

return base.VisitUnary(node);
}

protected override Expression VisitNew(NewExpression node)
{
Out("new " + node.Type.Name + "(");
VisitArguments(node.Arguments.ToArray());
Out(")");
return node;
}

protected override Expression VisitMethodCall(MethodCallExpression node)
{
Visit(node.Object);

if (!skipDot && !node.Method.IsStatic)
{
Out(".");
skipDot = false;
}
Out(node.Method.Name + "(");
var args = node.Arguments.ToArray();
if (args.Length > 3 && trimLongArgumentList)
{
Out("...");
}
else
{
VisitArguments(args);
}

Out(")");
return node;
}

protected override Expression VisitConditional(ConditionalExpression node)
{
Out("IIF(");
Visit(node.Test);
Out(", ");
Visit(node.IfTrue);
Out(", ");
Visit(node.IfFalse);
Out(")");
return node;
}

void VisitArguments(Expression[] arguments)
{
int argindex = 0;
while (argindex < arguments.Length)
{
Visit(arguments[argindex]);
argindex++;

if (argindex < arguments.Length)
{
Out(", ");
}
}
}

static bool CheckIfAnonymousType(Type type)
{
#if PORTABLE
// hack: the only way to detect anonymous types right now
var typeInfo = type.GetTypeInfo();
var isDefined = typeInfo.IsDefined(typeof(CompilerGeneratedAttribute), false);
return isDefined
&& (typeInfo.IsGenericType && type.Name.Contains("AnonymousType") || type.Name.Contains("DisplayClass"))
&& (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"));
#else
// hack: the only way to detect anonymous types right now
var isDefined = type.IsDefined(typeof(CompilerGeneratedAttribute), false);
return isDefined
&& (type.IsGenericType && type.Name.Contains("AnonymousType") || type.Name.Contains("DisplayClass"))
&& (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"));
#endif
}

static string ToString(ExpressionType type)
{
switch (type)
{
case ExpressionType.Add:
return "+";
case ExpressionType.And:
return "&";
case ExpressionType.AndAlso:
return "&&";
case ExpressionType.Divide:
return "/";
case ExpressionType.Equal:
return "==";
case ExpressionType.GreaterThan:
return ">";
case ExpressionType.GreaterThanOrEqual:
return ">=";
case ExpressionType.LessThan:
return "<";
case ExpressionType.LessThanOrEqual:
return "<=";
case ExpressionType.Modulo:
return "%";
case ExpressionType.Multiply:
return "*";
case ExpressionType.Negate:
return "-";
case ExpressionType.Not:
return "!";
case ExpressionType.NotEqual:
return "!=";
case ExpressionType.Or:
return "|";
case ExpressionType.OrElse:
return "||";
case ExpressionType.Subtract:
return "-";
case ExpressionType.Coalesce:
return "??";
case ExpressionType.ExclusiveOr:
return "^";
default:
throw new NotImplementedException();
}
}

private void Out(string s)
{
builder.Append(s);
}
}
}
3 changes: 3 additions & 0 deletions src/Shouldly.Portable/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System.Reflection;

[assembly: AssemblyVersion("0.0.0.0")]
61 changes: 61 additions & 0 deletions src/Shouldly.Portable/Shouldly.Portable.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5AB38DF3-F95E-4B6A-B8E7-8E5270C24DFB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Shouldly</RootNamespace>
<AssemblyName>Shouldly</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\output\Debug\portable-net45+netcore45+wp8+wpa81\</OutputPath>
<DefineConstants>TRACE;DEBUG;PORTABLE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\output\Release\portable-net45+netcore45+wp8+wpa81\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>sn.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="App_Packages\ExpressionStringBuilder.0.10.0\ExpressionStringBuilder.cs" />
<Compile Include="App_Packages\JetBrainsAnnotations\JetBrainsAnnotations.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="sn.key.pub" />
<None Include="sn.snk" />
</ItemGroup>
<Import Project="..\Shouldly.Shared\Shouldly.Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
4 changes: 4 additions & 0 deletions src/Shouldly.Portable/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ExpressionToString" version="0.10.0" />
</packages>
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@
[assembly: AssemblyCompany("Shouldly")]
[assembly: AssemblyProduct("Shouldly")]
[assembly: AssemblyCopyright("Copyright (c) 2015 Shouldly")]
[assembly: AssemblyVersion("0.0.0.0")]

File renamed without changes.

0 comments on commit 89f4843

Please sign in to comment.