Skip to content

Commit 211a557

Browse files
authored
convert gentracesources to tt (#598)
* moving gentracesources and gentracestrings to tt files these will now be generated using .tt files that are contained in the Microsoft.DotNet.Arcade.Wpf.sdk * minor fixes * remove GenerateAvTraceMessages.targets * Simplifying these targets so they should be manually included * add comment as to why we manually import Sdk.targets * Fixing targets and .tt so that they can be executed Files are finally being generated now * updating targets and tt files so that we gen the same file and filenames as before * making generated code prettier * adding formatting strings * adding note about the file being generated * removing extra line at top of files * making the .tt a bit cleaner * don't run certain targets that aren't supported when building using "dotnet" * adding codegen guidance * adding dependency via "darc add-dependency" * adding more info to codegen.md * removing use of dynamic * converting to xml instead of json * updating documentation to xml * removing newtonsoft dependency * cr feedback
1 parent 40a71a1 commit 211a557

15 files changed

+470
-456
lines changed

Documentation/codegen.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# CodeGen in the dotnet/wpf repo
2+
3+
The following document describes how code generation in this repo works. The goal is to have all our code generation done through the use of T4 text generation. See the offical [Visual Studio T4 documentation](https://docs.microsoft.com/en-us/visualstudio/modeling/design-time-code-generation-by-using-t4-text-templates?view=vs-2019) for more information.
4+
5+
## Design-Time vs Run-Time T4 templates
6+
Currently, we are evaluating the use of design-time text templates. This gives us the ability to simply add the templates and associated targets to the build, without the need of maintaining a separate tool to do run-time generation. When using the SDK-style project format, including the `Microsoft.TextTemplating.targets` requires us to manually import `Sdk.Targets` because the `BuildDependsOn` variable, which is modified by the T4 targets, would otherwise be overwritten by the automatic inclusion of `Sdk.targets`. This causes the `TransformAll` target to not run before the `Build` target. The boilerplait for including design-time templates has been encapsulated in the `$(WpfCodeGenDir)DesignTimeTextTemplating.targets` file, so the pattern for enabling these in a project looks like this:
7+
8+
```
9+
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
10+
<Import Project="$(WpfCodeGenDir)AvTrace\GenTraceSources.targets" />
11+
<Import Project="$(WpfCodeGenDir)AvTrace\GenAvMessages.targets" />
12+
<Import Project="$(WpfCodeGenDir)DesignTimeTextTemplating.targets" />
13+
```
14+
15+
## Basic T4 code generation philosophy and guidelines
16+
T4 templates can be a powerful tool, however without a conscious effort, they can quickly become unmaintainable and difficult to understand. When authoring/modifying a T4 template, extra care should be taken to ensure that the templates are as readable as possible. While the "readability" of a template may be a bit subjective, there are a few common guidelines that really help. Note that these are guidelines, and are not mandatory. The readability of the template is paramount to all things.
17+
18+
* When multiple lines of code need to be written inside of "<# #>" blocks, the "<#" and "#>" tags should be on seperate lines. This makes it easier to tell where the code starts and stops. If we follow this policy, we can know that a line that only contains a "<#" tag is the start of a multi-line code block.
19+
20+
**Correct**
21+
```
22+
<#
23+
string helloWorld = " Hello World ";
24+
hellowWorld = helloWorld.Trim();
25+
#>
26+
<#= hellowWorld #>
27+
```
28+
**Incorrect**
29+
```
30+
<# string helloWorld = " Hello World ";
31+
helloWorld = helloWorld.Trim(); #>
32+
<#= hellowWorld #>
33+
```
34+
35+
* In similar fashion, single-line code statements should contain the "<#" and "#>" tags on the same line as the code. This way we can know that any line that starts with a "<#" that has code next to it is only a one-line statement.
36+
37+
* if/else/elseif statements, and the closing bracket, should all be contained on a single line
38+
39+
**Correct**
40+
```
41+
<# if (WriteAsFunction()){ #>
42+
bool GetFoo()
43+
{
44+
...
45+
}
46+
<# } else { #>
47+
bool Foo
48+
{
49+
get {...}
50+
}
51+
<# } #>
52+
```
53+
**Incorrect**
54+
```
55+
<#
56+
if (WriteAsFunction())
57+
{
58+
#>
59+
bool GetFoo()
60+
{
61+
...
62+
}
63+
<#
64+
}
65+
else
66+
{
67+
#>
68+
bool Foo
69+
{
70+
get {...}
71+
}
72+
<#
73+
}
74+
#>
75+
```
76+
* T4 generation allows you to write functions that you can invoke in the template inside of "<#+ #>" blocks. If the function is intended to be re-used to output some common text, the name of the function should start with "Output" so that is clear to the reader the intent of the function. Also, these functions should not impose any extra indentation (or it should be minimal), as this makes it more complicated to re-use and plug
77+
in the function anywhere throughout the template.
78+
79+
**Correct**
80+
```
81+
<#+ void OutputFooFunction() { #>
82+
bool GetFoo()
83+
{
84+
...
85+
}
86+
<#+ } #>
87+
```
88+
**Incorrect**
89+
```
90+
<#+ void FooFunction() { #>
91+
bool GetFoo()
92+
{
93+
...
94+
}
95+
<#+ } #>
96+
```
97+
98+
## Location of CodeGen targets
99+
Unless there is a good reason (that should be documented), all codegen related targets should go into the $(WpfArcadeSdk)tools\CodeGen folder. This way we have a clean and clear location where we are able to keep track of all code generation in the codebase.
100+
101+
## GenTraceSources and GenAvMessages
102+
These two projects codegen the files the WPF codebase uses for tracing, and both use the AvTraceMessages.xml files located in the project location that includes it, located via the MSBuild property $(MSBuildProjectFileDirectory).
103+
104+
**Note**: GenTraceSources should currently only be used by WindowsBase. It generates the [PresentationTraceSources](https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.presentationtracesources?view=netcore3.0) class, which is a public class. Changing this file can impact the public API surface of WindowsBase or other WPF assemblies.

Documentation/developer-guide.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,4 @@ Follow the steps defined [here](https://github.com/dotnet/arcade/blob/master/Doc
158158
* [Coding guidelines](https://github.com/dotnet/corefx/tree/master/Documentation#coding-guidelines)
159159
* [up-for-grabs WPF issues](https://github.com/dotnet/wpf/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs)
160160
* [easy WPF issues](https://github.com/dotnet/wpf/issues?utf8=%E2%9C%93&q=is%3Aopen+is%3Aissue+label%3Aeasy)
161+
* [Code generation in dotnet/wpf](codegen.md)

eng/WpfArcadeSdk/Sdk/Sdk.props

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
<Import Project="$(WpfArcadeSdkToolsDir)ShippingProjects.props" />
1414

1515
<PropertyGroup>
16-
<GenTraceSources>$(WpfArcadeSdkToolsDir)AvTrace\GenTraceSources.pl</GenTraceSources>
1716
<GenXmlStringTable>$(WpfArcadeSdkToolsDir)GenXmlStringTable.pl</GenXmlStringTable>
1817

1918
<PublishWindowsPdb Condition="'$(IsShipping)'=='' And '$(IsPackagingProject)'!='true'">true</PublishWindowsPdb>
@@ -35,7 +34,7 @@
3534
<Import Project="$(WpfArcadeSdkToolsDir)Redist.props" />
3635
<Import Project="$(WpfArcadeSdkToolsDir)Pbt.props" />
3736
<Import Project="$(WpfArcadeSdkToolsDir)Signing.props" />
38-
37+
<Import Project="$(WpfArcadeSdkToolsDir)CodeGen.props" />
3938

4039
<PropertyGroup>
4140
<DebugType>full</DebugType>

eng/WpfArcadeSdk/Sdk/Sdk.targets

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
<Import Project="$(WpfArcadeSdkToolsDir)InlineTasks.targets" />
88
<Import Project="$(WpfArcadeSdkToolsDir)ShippingProjects.targets" />
99
<Import Project="$(WpfArcadeSdkToolsDir)GenerateProgramFileForTests.targets" />
10-
<Import Project="$(WpfArcadeSdkToolsDir)GenerateAvTraceMessages.targets"/>
1110
<Import Project="$(WpfArcadeSdkToolsDir)Packaging.targets" />
1211
<Import Project="$(WpfArcadeSdkToolsDir)Publishing.targets" />
1312
<Import Project="$(WpfArcadeSdkToolsDir)ReferenceAssembly.targets"/>

eng/WpfArcadeSdk/tools/AvTrace/GenTraceSources.pl

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

0 commit comments

Comments
 (0)