Skip to content

Commit ba8cc31

Browse files
committed
Added __Regenerate.tt to generate all implementations from T4 templates.
* Converted UnitClasses.tt and UnitConverter.tt to .ttinclude files and moved into Includes folder. * Converted UnitsNet.net35.csproj to not using wildcard include anymore, it was very inconvenient when developing. The other 3 projects should still use wildcards as they are not developed on. * Modified MultipleOutputHelper.ttinclude to add output as file in same folder as template file instead of include as nested item under template file, to better match solution structure in other 3 projects. Issues: * <#@ include once="true" #> does not seem to work and I get duplicate definition build errors. Commented out includes in .ttinclude files and losing intellisense in those files.
1 parent 77595ac commit ba8cc31

10 files changed

+1176
-99
lines changed

Src/UnitsNet/Generated Code/Includes/MultipleOutputHelper.ttinclude

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class Manager {
154154
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
155155
}
156156

157-
private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
157+
private void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
158158
var keepFileNameSet = new HashSet<String>(keepFileNames);
159159
var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
160160
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";
@@ -169,7 +169,18 @@ class Manager {
169169
// Add missing files to the project
170170
foreach(String fileName in keepFileNameSet)
171171
if (!projectFiles.ContainsKey(fileName))
172-
templateProjectItem.ProjectItems.AddFromFile(fileName);
172+
{
173+
// Remove any "..\" in path when outputting to parent folder by getting full path.
174+
// Source: http://stackoverflow.com/a/4796339/134761
175+
string fileNameFullPath = Path.GetFullPath(new Uri(fileName).LocalPath);
176+
177+
// Output as item in same folder as template file.
178+
templateProjectItem.Collection.AddFromFile(fileNameFullPath);
179+
180+
// Output as nested item under template file
181+
//templateProjectItem.ProjectItems.AddFromFile(fileNameFullPath);
182+
}
183+
173184
}
174185

175186
private void CheckoutFileIfRequired(String fileName) {

Src/UnitsNet/Generated Code/Includes/UnitClass.ttinclude

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
<# // Load types in current assembly. #>
2-
<#@ assembly name="$(TargetPath)" #>
1+
<#@ assembly name="$(TargetDir)UnitsNet.net35.dll" #>
32
<#@ assembly name="System.Core" #>
43
<#@ import namespace="System.Linq" #>
54
<#@ import namespace="System.Text" #>
65
<#@ import namespace="System.Collections.Generic" #>
76
<#@ import namespace="UnitsNet" #>
87
<#@ import namespace="UnitsNet.Attributes" #>
98
<#@ import namespace="UnitsNet.Extensions" #>
10-
<#@ include file="MultipleOutputHelper.ttinclude" once="true"#>
11-
<#@ include file="Shared.ttinclude" once="true" #>
12-
<#+
9+
10+
<#/* Uncomment below for intellisense/ReSharper support,
11+
but this will give an error when trying to run __Regenerate.tt template
12+
since they are included multiple times and once="true" does not
13+
seem to work as it should. */#>
14+
15+
<#//@ include file="MultipleOutputHelper.ttinclude" once="true"#>
16+
<#//@ include file="Shared.ttinclude" once="true"#><#+
1317

1418
private void GenerateUnitClass(Type unitAttributeType, Manager manager, string className, Unit baseUnit, string xmlDocSummary)
1519
{
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<# // Load types in current assembly. #>
2+
<#@ assembly name="$(TargetPath)" #>
3+
<#@ include file="UnitClass.ttinclude" once="true"#>
4+
5+
<#/* Uncomment below for intellisense/ReSharper support,
6+
but this will give an error when trying to run __Regenerate.tt template
7+
since they are included multiple times from .ttinclude files and once="true" does not
8+
seem to work as it should. */#>
9+
10+
<#//@ include file="MultipleOutputHelper.ttinclude" once="true"#>
11+
<#//@ include file="Shared.ttinclude" once="true"#><#+
12+
13+
private void GenerateUnitClasses(Manager m)
14+
{
15+
List<UnitAttribute> unitAttributes = GetUnitAttributeImplementations();
16+
17+
foreach (UnitAttribute attr in unitAttributes)
18+
{
19+
Type unitAttributeType = attr.GetType();
20+
string unitClassName = unitAttributeType.Name.Replace("Attribute", string.Empty);
21+
GenerateUnitClass(unitAttributeType, m, unitClassName, attr.BaseUnit, attr.XmlDocSummary);
22+
}
23+
24+
}
25+
26+
#>
27+
<#+
28+
#>

Src/UnitsNet/Generated Code/UnitConverter.tt renamed to Src/UnitsNet/Generated Code/Includes/UnitConverter.ttinclude

Lines changed: 54 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
<#@ template debug="True" language="C#" hostspecific="True" #>
2-
<# // Load types in current assembly. #>
1+
<# // Load types in current assembly. #>
32
<#@ assembly name="$(TargetPath)" #>
43
<#@ assembly name="System.Core" #>
54
<#@ import namespace="System.Linq" #>
@@ -8,18 +7,23 @@
87
<#@ import namespace="UnitsNet" #>
98
<#@ import namespace="UnitsNet.Attributes" #>
109
<#@ import namespace="UnitsNet.Extensions" #>
11-
<#@ include file="Includes\MultipleOutputHelper.ttinclude" once="true"#>
12-
<#@ include file="Includes\Shared.ttinclude" once="true"#>
13-
<# // Disable output of this file, note this causes a build warning #>
14-
<#@ output extension="/" #>
15-
<#//@ output extension=".cs" #>
16-
<#
17-
List<Type> unitAttributeTypes = GetUnitAttributeTypes();
18-
List<string> unitClassNames = GetUnitClassNamesFromUnitAttributeImplementations();
10+
11+
<#/* Uncomment below for intellisense/ReSharper support,
12+
but this will give an error when trying to run __Regenerate.tt template
13+
since they are included multiple times and once="true" does not
14+
seem to work as it should. */#>
15+
16+
<#//@ include file="MultipleOutputHelper.ttinclude" once="true"#>
17+
<#//@ include file="Shared.ttinclude" once="true"#><#+
18+
19+
private void GenerateUnitConverter(Manager m)
20+
{
21+
22+
List<Type> unitAttributeTypes = GetUnitAttributeTypes();
23+
List<string> unitClassNames = GetUnitClassNamesFromUnitAttributeImplementations();
1924
Dictionary<Unit, UnitAttribute> unitToAttribute = GetUnitToAttributeDictionary<UnitAttribute>();
2025

21-
var m = Manager.Create(Host, GenerationEnvironment);
22-
using (m.StartNewFile("UnitConverter.g.cs"))
26+
using (m.StartNewFile(@"UnitConverter.g.cs"))
2327
{
2428
#>
2529
// Copyright © 2007 by Initial Force AS. All rights reserved.
@@ -66,10 +70,10 @@ namespace UnitsNet
6670
return value;
6771

6872
double newValue;
69-
<# foreach (string unitName in unitClassNames) #>
70-
<# { #>
71-
if (TryConvertFrom<#=unitName#>(value, fromUnit, toUnit, out newValue)) return newValue;
72-
<# }#>
73+
<#+ foreach (string unitName in unitClassNames) #>
74+
<#+ { #>
75+
if (TryConvertFrom<#=unitName #>(value, fromUnit, toUnit, out newValue)) return newValue;
76+
<#+ } #>
7377

7478
throw new Exception(
7579
string.Format("Conversion from unit [{0}] to [{1}] is either not valid or not yet implemented.",
@@ -92,75 +96,77 @@ namespace UnitsNet
9296
return true;
9397
}
9498

95-
<# foreach (string unitName in unitClassNames) #>
96-
<# { #>
97-
if (TryConvertFrom<#=unitName#>(value, fromUnit, toUnit, out newValue)) return true;
98-
<# }#>
99+
<#+ foreach (string unitName in unitClassNames) #>
100+
<#+ { #>
101+
if (TryConvertFrom<#=unitName #>(value, fromUnit, toUnit, out newValue)) return true;
102+
<#+ } #>
99103

100104
return false;
101105
}
102106

103107
#region Private
104108

105-
<# foreach (string unitClassName in unitClassNames) #>
106-
<# { #>
107-
<# List<Unit> unitsOfUnitClass = GetUnitsOfUnitClass(unitClassName, unitAttributeTypes, unitToAttribute); #>
108-
<##>
109+
<#+ foreach (string unitClassName in unitClassNames) #>
110+
<#+ { #>
111+
<#+ List<Unit> unitsOfUnitClass = GetUnitsOfUnitClass(unitClassName, unitAttributeTypes,
112+
unitToAttribute); #>
113+
109114
/// <summary>
110-
/// Try to dynamically convert from <#=unitClassName#> to <paramref name="toUnit"/>.
115+
/// Try to dynamically convert from <#=unitClassName #> to <paramref name="toUnit"/>.
111116
/// </summary>
112117
/// <param name="value">Value to convert from.</param>
113118
/// <param name="fromUnit">Unit to convert from.</param>
114119
/// <param name="toUnit">Compatible unit to convert to.</param>
115120
/// <param name="newValue">Value in new unit if successful, zero otherwise.</param>
116121
/// <returns>True if the two units were compatible and the conversion was successful.</returns>
117-
private static bool TryConvertFrom<#=unitClassName#>(double value, Unit fromUnit, Unit toUnit, out double newValue)
122+
private static bool TryConvertFrom<#=unitClassName #>(double value, Unit fromUnit, Unit toUnit, out double newValue)
118123
{
119124
switch (fromUnit)
120125
{
121-
<#foreach (Unit unit in unitsOfUnitClass)#>
122-
<#{#>
123-
<# string pluralUnitName = GetUnitPluralName(unitToAttribute, unit);#>
124-
case Unit.<#=unit.ToString()#>:
125-
return TryConvert(<#=unitClassName #>.From<#=pluralUnitName#>(value), toUnit, out newValue);
126-
<# } #>
126+
<#+ foreach (Unit unit in unitsOfUnitClass) #>
127+
<#+ { #>
128+
<#+ string pluralUnitName = GetUnitPluralName(unitToAttribute, unit); #>
129+
case Unit.<#=unit.ToString() #>:
130+
return TryConvert(<#=unitClassName #>.From<#=pluralUnitName #>(value), toUnit, out newValue);
131+
<#+ } #>
127132

128133
default:
129134
newValue = 0;
130135
return false;
131136
}
132137
}
133-
<# }#>
138+
<#+ } #>
139+
140+
<#+ foreach (string unitClassName in unitClassNames) #>
141+
<#+ { #>
142+
<#+ List<Unit> unitsOfUnitClass = GetUnitsOfUnitClass(unitClassName, unitAttributeTypes,
143+
unitToAttribute); #>
134144

135-
<# foreach (string unitClassName in unitClassNames) #>
136-
<# { #>
137-
<# List<Unit> unitsOfUnitClass = GetUnitsOfUnitClass(unitClassName, unitAttributeTypes, unitToAttribute); #>
138-
<##>
139145
/// <summary>
140-
/// Try to dynamically convert from <#=unitClassName#> to <paramref name="toUnit"/>.
146+
/// Try to dynamically convert from <#=unitClassName #> to <paramref name="toUnit"/>.
141147
/// </summary>
142148
/// <param name="value">Value to convert from.</param>
143149
/// <param name="toUnit">Compatible unit to convert to.</param>
144150
/// <param name="newValue">Value in new unit if successful, zero otherwise.</param>
145151
/// <returns>True if the two units were compatible and the conversion was successful.</returns>
146-
private static bool TryConvert(<#=unitClassName#> value, Unit toUnit, out double newValue)
152+
private static bool TryConvert(<#=unitClassName #> value, Unit toUnit, out double newValue)
147153
{
148154
switch (toUnit)
149155
{
150-
<#foreach (Unit unit in unitsOfUnitClass)#>
151-
<#{#>
152-
case Unit.<#=unit.ToString()#>:
153-
newValue = value.<#=GetUnitPluralName(unitToAttribute, unit)#>;
156+
<#+ foreach (Unit unit in unitsOfUnitClass) #>
157+
<#+ { #>
158+
case Unit.<#=unit.ToString() #>:
159+
newValue = value.<#=GetUnitPluralName(unitToAttribute, unit) #>;
154160
return true;
155-
<# } #>
161+
<#+ } #>
156162

157163
default:
158164
newValue = 0;
159165
return false;
160166
}
161167
}
162168

163-
<# }#>
169+
<#+ } #>
164170
#endregion
165171

166172
#region Not implemented as unit class yet, no UnitAttribute for these
@@ -240,11 +246,9 @@ namespace UnitsNet
240246
#endregion
241247
}
242248
}
243-
<#
244-
}
245-
246-
m.Process(split: true);
247-
#> <#+
248249

250+
<#+
251+
} // using (m.StartNewFile(@"..\UnitConverter.g.cs"))
252+
} // private void GenerateUnitConverter(Manager m)
249253

250254
#>

Src/UnitsNet/Generated Code/UnitClasses.tt

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)