jskeet / unconstrained-melody

Automatically exported from code.google.com/p/unconstrained-melody
131 stars 17 forks source link

Feature Request: Move Constraint Changer Logic to MSBuild Target #13

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I've found this project to be useful but wanted to have the build-time steps in 
MSBuild.  Adding this to your *.csproj files in which you use the constraints 
should accomplish the same thing as the Constraintchanger app.  Note the 
following:

1. I've added the two constraint types to my classes root namespace and the 
substitution looks for the types in the assembly's root namespace.

2. To make Resharper happier I've added the IEnumConstraint, DelegateConstraint 
type args into my project inside an #if UNCONSTRAINED ... #endif block like so:

public static T Parse<T>(string val) where T : struct
#if UNCONSTRAINED
, IEnumConstraint
#endif
{

}

This is purely optional but keeps resharper from complaining about the 
constraint not matching when using the project's code from another project in a 
common solution.

  <PropertyGroup>
    <BuildDependsOn>
      $(BuildDependsOn);
      SwapConstraints
    </BuildDependsOn>
  </PropertyGroup>
  <ItemGroup>
    <PreprocessorDefines Include="UNCONSTRAINED" />
  </ItemGroup>
  <UsingTask TaskName="FileReplace" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <ParameterGroup>
      <FileName ParameterType="System.String" Required="true" />
      <Source ParameterType="System.String" Required="true" />
      <Replacement ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Code Type="Fragment" Language="cs"><![CDATA[
string content = File.ReadAllText(FileName);
content = content.Replace(Source, Replacement);
File.WriteAllText(FileName, content);

]]></Code>
    </Task>
  </UsingTask>
  <Target Name="SwapConstraints">
    <GetFrameworkPath>
      <Output TaskParameter="Path" PropertyName="FW" />
    </GetFrameworkPath>
    <GetFrameworkSdkPath>
      <Output TaskParameter="Path" PropertyName="SDK" />
    </GetFrameworkSdkPath>
    <PropertyGroup>
      <ILDASM>"$(SDK)bin\NETFX 4.0 Tools\ildasm.exe"</ILDASM>
      <ILASM>"$(FW)\ilasm.exe"</ILASM>
      <IlFile>$(OutputPath)$(AssemblyName).il</IlFile>
      <DllFile>$(OutputPath)$(AssemblyName).dll</DllFile>
    </PropertyGroup>
    <Exec Command="$(ILDASM) /OUT=$(IlFile) $(DllFile)" WorkingDirectory="$(ProjectDir)" />
    <FileReplace FileName="$(IlFile)" Source="($(RootNamespace).DelegateConstraint)" Replacement="([mscorlib]System.Delegate)" />
    <FileReplace FileName="$(IlFile)" Source="([mscorlib]System.ValueType, $(RootNamespace).IEnumConstraint)" Replacement="([mscorlib]System.Enum)" />
    <FileReplace FileName="$(IlFile)" Source="($(RootNamespace).IEnumConstraint), [mscorlib]System.ValueType" Replacement="([mscorlib]System.Enum)" />
    <FileReplace FileName="$(IlFile)" Source="($(RootNamespace).IEnumConstraint)" Replacement="([mscorlib]System.Enum)" />
    <Exec Command="$(ILASM) /OUTPUT=$(DllFile) /DLL $(IlFile)" WorkingDirectory="$(ProjectDir)" />
  </Target>

Original issue reported on code.google.com by j...@friesen.us on 22 Nov 2013 at 7:43

GoogleCodeExporter commented 9 years ago
Sorry, didn't mean to say #if UNCONSTRAINED ... #endif should be around type 
args for DelegateConstraint.  I've not messed with delegates to this point but 
I doubt that it would be necessary for them.

Original comment by j...@friesen.us on 22 Nov 2013 at 7:54