Port timedscopegen tool almost as-is from legacy code
This commit is contained in:
Vlad Ion 2019-10-14 17:37:53 +01:00 коммит произвёл GitHub
Родитель 91edc20011
Коммит d80a5b4dc4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 1269 добавлений и 0 удалений

Просмотреть файл

@ -52,6 +52,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CodeGenerators", "CodeGener
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Omex.CodeGenerators.GateGen", "src\CodeGenerators\gategen\Microsoft.Omex.CodeGenerators.GateGen.csproj", "{D3B05497-4540-4D95-A829-E6CD42EE09D3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Omex.CodeGenerators.TimedScopeGen", "src\CodeGenerators\TimedScopeGen\Microsoft.Omex.CodeGenerators.TimedScopeGen.csproj", "{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -148,6 +150,14 @@ Global
{D3B05497-4540-4D95-A829-E6CD42EE09D3}.Release|Any CPU.Build.0 = Release|Any CPU
{D3B05497-4540-4D95-A829-E6CD42EE09D3}.Release|x64.ActiveCfg = Release|Any CPU
{D3B05497-4540-4D95-A829-E6CD42EE09D3}.Release|x64.Build.0 = Release|Any CPU
{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55}.Debug|x64.ActiveCfg = Debug|Any CPU
{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55}.Debug|x64.Build.0 = Debug|Any CPU
{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55}.Release|Any CPU.Build.0 = Release|Any CPU
{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55}.Release|x64.ActiveCfg = Release|Any CPU
{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -165,6 +175,7 @@ Global
{C7A072C5-8F04-4A80-8B76-7E08CED9BC5A} = {551C93F8-6E89-4954-8905-7F5AC7173285}
{C5BA6376-60EB-43E5-A9EF-AD2792C8D2A8} = {3249ADDB-50EC-4C21-A8F0-65EF444662EE}
{D3B05497-4540-4D95-A829-E6CD42EE09D3} = {C5BA6376-60EB-43E5-A9EF-AD2792C8D2A8}
{DF4EDB71-F6A7-4D60-A61A-FE65D14C9C55} = {C5BA6376-60EB-43E5-A9EF-AD2792C8D2A8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E6FB7BCB-BF07-4F19-ACBA-457479D421BB}

Просмотреть файл

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45</TargetFrameworks>
<Description>Contains Omex TimedScope generator code</Description>
<RootNamespace>Microsoft.Omex.CodeGenerators.TimedScopeGen</RootNamespace>
<AssemblyName>Microsoft.Omex.CodeGenerators.TimedScopeGen</AssemblyName>
<ApplicationIcon />
<OutputType>Exe</OutputType>
<StartupObject></StartupObject>
<Win32Resource />
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Label="NuGet Properties">
<Title>Microsoft.Omex.CodeGenerators.TimedScopeGen</Title>
<DevelopmentDependency>True</DevelopmentDependency>
<Authors>Microsoft</Authors>
<Summary>Microsoft Omex TimedScopeGen</Summary>
<Description>Generates strongly typed timed scopes from a timedscope xml.</Description>
<ReleaseNotes>Initial release.</ReleaseNotes>
<PackageProjectUrl>https://github.com/microsoft/Omex/tree/master/src/CodeGenerators/TimedScopeGen</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/microsoft/Omex/blob/master/LICENSE</PackageLicenseUrl>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/microsoft/Omex</RepositoryUrl>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PackageTags>Microsoft;Omex;Logging;Metrics</PackageTags>
</PropertyGroup>
<ItemGroup>
<None Include="TimedScopeClassTemplate.tt" />
<None Include="TimedScopes.xsd" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\System\Microsoft.Omex.System.csproj" />
</ItemGroup>
<ItemGroup>
<Content Include="$(OutputPath)\**\Microsoft.Omex.System.*" Pack="true" PackagePath="lib" />
<Content Include="Microsoft.Omex.CodeGenerators.TimedScopeGen.targets" Pack="true" PackagePath="build" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,39 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!--
Generate strongly typed timedscopes from timedscope xmls
Usage :
<ItemGroup>
<TimedScope Include="timedscope_xml_path">
<Name>timedscope_file_prefix</Name>
</TimedScope>
</ItemGroup>
-->
<PropertyGroup>
<TimedScopeGenExecutable>$(MSBuildThisFileDirectory)..\lib\net45\Microsoft.Omex.CodeGenerators.TimedScopeGen.exe</TimedScopeGenExecutable>
</PropertyGroup>
<ItemGroup>
<CustomTargetInputs Include="@(TimedScope -> '%(Identity)')" />
<QCustomInput Include="@(CustomTargetInputs)" />
</ItemGroup>
<Target Name="TimedscopeGen" BeforeTargets="CoreCompile">
<Message Text="Running TimedScopeGen Target" />
<Error Text="No TimedScopes have been defined."
Condition="'(TimedScope)' == ''" />
<Error Text="The attribute 'Name' was not specified for %(TimedScope.Name) TimeScope."
Condition="'%(TimedScope.Name)' == ''" />
<!-- Generate TimedScopes.cs classes
To support multiple timedscopes, the cs classes will be named "<timedscope_name>TimedScopes.cs" -->
<Exec Command="$(TimedScopeGenExecutable) %(TimedScope.Identity) $(IntermediateOutputPath)%(TimedScope.Name)TimeScopes.cs true" Condition="'%(TimedScope.Name)' == 'shared'" />
<Exec Command="$(TimedScopeGenExecutable) %(TimedScope.Identity) $(IntermediateOutputPath)%(TimedScope.Name)TimeScopes.cs false" Condition="'%(TimedScope.Name)' != 'shared'" />
<!-- Include TimedScopes in the build process -->
<CreateItem Include="@(TimedScope -> '$(IntermediateOutputPath)%(Name)TimeScopes.cs')">
<Output TaskParameter="Include" ItemName="Compile"/>
</CreateItem>
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,101 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
namespace Microsoft.Omex.CodeGenerators.TimedScopeGen
{
/// <summary>
/// Main entry point
/// </summary>
internal class Program
{
/// <summary>
/// Omex product name
/// </summary>
public const string ProductOmex = "Omex";
/// <summary>
/// Main entry point from command line.
/// </summary>
/// <param name="arguments">Command line arguments</param>
/// <returns>0 if successfull; 1 otherwise</returns>>
private static int Main(string[] arguments)
{
if (arguments.Length < 2)
{
FileVersionInfo version = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
Console.WriteLine("Timed scope generator, version {0}", version.FileVersion);
Console.WriteLine("Usage: Microsoft.Omex.CodeGenerators.TimedScopeGen.exe [TimedScopes.xml] [OutputFile.cs]");
return 1;
}
try
{
FileInfo timedScopesDefinitionFile = new FileInfo(arguments[0]);
FileInfo timedScopesClassFile = new FileInfo(arguments[1]);
bool isSharedTimedScopes = string.Equals(arguments[2], "true", StringComparison.OrdinalIgnoreCase);
if (!timedScopesDefinitionFile.Exists)
{
Console.WriteLine("Error. File does not exist: {0}.", timedScopesDefinitionFile);
return 1;
}
GenerateTimedScopesClass(timedScopesDefinitionFile, timedScopesClassFile, isSharedTimedScopes);
}
catch (Exception exception)
{
Console.WriteLine("Error. Failed to generate timed scopes. Exception: {0}", exception);
return 1;
}
Console.WriteLine("Success");
return 0;
}
/// <summary>
/// Generates TimedScope.cs from TimedScopes.xml
/// </summary>
/// <param name="timedScopesDefinitionFile">Timed scopes definition file</param>
/// <param name="timedScopesFile">File to generate C# static class</param>
/// <param name="isSharedTimedScope">Is the TimedScope class to be generated a Shared one.</param>
public static void GenerateTimedScopesClass(FileInfo timedScopesDefinitionFile, FileInfo timedScopesFile, bool isSharedTimedScope = false)
{
TimedScopeCollection timedScopeCollection = ReadFromFile<TimedScopeCollection>(timedScopesDefinitionFile);
TimedScopeClassTemplate template = new TimedScopeClassTemplate(timedScopeCollection, isSharedTimedScope);
string generatedClass = template.TransformText();
using (StreamWriter writer = new StreamWriter(timedScopesFile.FullName))
{
writer.Write(generatedClass);
}
}
/// <summary>
/// Reads object from file using xml deserializer
/// </summary>
/// <typeparam name="T">Type of object to read</typeparam>
/// <param name="file">File from which the object should be read</param>
/// <returns>Deserialized object</returns>
public static T ReadFromFile<T>(FileInfo file)
{
using (FileStream stream = file.OpenRead())
{
using (XmlReader reader = XmlReader.Create(stream))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(reader);
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,16 @@
# Microsoft Omex TimedScopes C# file code generator.
(c) Microsoft Corporation.
This tool generates a C# code file for timed scopes, based on input timedscope xml file. See The [Gating.Example project](https://github.com/microsoft/Omex/tree/master/src/Gating.Example) in this repository for an example of these input files.
This package should be used from another project that uses timedscopes. After being added to the project it will automatically run an initial build step that will generate the `TimedScope.cs` file allowing the project files to reference strongly typed timedscopes in code.
The project needs to define the following content in the csproj file and include the corresponding timedscope xml file:
```xml
<ItemGroup>
<TimedScope Include="timedscope_xml_path">
<Name>timedscope_filename_prefix</Name>
</TimedScope>
</ItemGroup>
```

Просмотреть файл

@ -0,0 +1,584 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
// ------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version: 14.0.0.0
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
// ------------------------------------------------------------------------------
namespace Microsoft.Omex.CodeGenerators.TimedScopeGen
{
using global::System.Linq;
using System;
/// <summary>
/// Class to produce the template output
/// </summary>
#line 1 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "14.0.0.0")]
public partial class TimedScopeClassTemplate : TimedScopeClassTemplateBase
{
#line hidden
/// <summary>
/// Create the template output
/// </summary>
public virtual string TransformText()
{
this.Write(@"// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
//
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using Microsoft.Omex.System.TimedScopes;
namespace ");
#line 18 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(ScopeCollection.@namespace));
#line default
#line hidden
this.Write("\r\n{\r\n\t/// <summary>\r\n\t/// Timed scopes\r\n\t/// </summary>\r\n\t[GeneratedCode(\"");
#line 23 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(AssemblyName));
#line default
#line hidden
this.Write("\", \"");
#line 23 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(AssemblyVersion));
#line default
#line hidden
this.Write("\")]\r\n\tpublic static class ");
#line 24 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(TimedScopeClassName));
#line default
#line hidden
this.Write(@"
{
/// <summary>
/// Gets a Dictionary of ScopeName to ScopeDefinition for all Timed Scopes
/// </summary>
public static IReadOnlyDictionary<string, TimedScopeDefinition> AllScopeDefinitions
{
get
{
return s_scopeDefinitions.Value;
}
}
/// <summary>
/// Dictionary of ScopeName to ScopeDefinition for all Timed Scopes
/// </summary>
private static Lazy<Dictionary<string, TimedScopeDefinition>> s_scopeDefinitions = new Lazy<Dictionary<string, TimedScopeDefinition>>(
() => new Dictionary<string, TimedScopeDefinition>(StringComparer.Ordinal)
{
");
#line 44 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
foreach (TimedScopeArea area in ScopeCollection.TimedScopeArea.OrderBy(x => x.name))
{
foreach (TimedScope scope in area.TimedScope.OrderBy(x => x.name))
{
#line default
#line hidden
this.Write("\t\t\t{ ");
#line 50 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(area.StrippedName()));
#line default
#line hidden
this.Write(".");
#line 50 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(scope.name));
#line default
#line hidden
this.Write(".Name, ");
#line 50 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(area.StrippedName()));
#line default
#line hidden
this.Write(".");
#line 50 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(scope.name));
#line default
#line hidden
this.Write(" },\r\n");
#line 51 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
}
}
#line default
#line hidden
this.Write("\t\t});\r\n\r\n");
#line 57 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
foreach (TimedScopeArea area in ScopeCollection.TimedScopeArea.OrderBy(x => x.name))
{
#line default
#line hidden
this.Write("\t\t/// <summary>\r\n\t\t/// Timed scopes for ");
#line 62 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(area.StrippedName()));
#line default
#line hidden
this.Write("\r\n\t\t/// </summary>\r\n\t\tpublic static class ");
#line 64 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(area.StrippedName()));
#line default
#line hidden
this.Write("\r\n\t\t{\r\n");
#line 66 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
foreach (TimedScope scope in area.TimedScope.OrderBy(x => x.name))
{
#line default
#line hidden
this.Write("\t\t\t/// <summary>\r\n\t\t\t/// ");
#line 71 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(scope.name));
#line default
#line hidden
this.Write(" Timed Scope\r\n\t\t\t/// </summary>\r\n\t\t\tpublic static TimedScopeDefinition ");
#line 73 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(scope.name));
#line default
#line hidden
this.Write(" => new TimedScopeDefinition(\"");
#line 73 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(area.StrippedName()));
#line default
#line hidden
this.Write("_");
#line 73 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(scope.name));
#line default
#line hidden
this.Write("\",\r\n\t\t\t\t\"");
#line 74 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(scope.FormatDescription()));
#line default
#line hidden
this.Write("\"");
#line 74 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
if (scope.OCEHandBookLink != null)
{
#line default
#line hidden
this.Write(",\r\n\t\t\t\tlinkToOCEHandbook: @\"");
#line 77 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(scope.OCEHandBookLink));
#line default
#line hidden
this.Write("\"");
#line 77 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
}
#line default
#line hidden
#line 79 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
if (scope.onDemand)
{
#line default
#line hidden
this.Write(",\r\n\t\t\t\tonDemand: ");
#line 82 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(scope.onDemand.ToString().ToLower()));
#line default
#line hidden
#line 82 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
}
#line default
#line hidden
#line 84 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
if (scope.capturesUniqueUserHashes)
{
#line default
#line hidden
this.Write(",\r\n\t\t\t\tcapturesUniqueUserHashes: ");
#line 87 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
this.Write(this.ToStringHelper.ToStringWithCulture(scope.capturesUniqueUserHashes.ToString().ToLower()));
#line default
#line hidden
#line 87 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
}
#line default
#line hidden
this.Write(");\r\n\r\n");
#line 91 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
}
#line default
#line hidden
this.Write("\r\n\t\t}\r\n\r\n\r\n");
#line 98 "E:\OMEX2\private\omextools\codegenerators\timedscopegen\TimedScopeClassTemplate.tt"
}
#line default
#line hidden
this.Write("\r\n\t}\r\n}\r\n");
return this.GenerationEnvironment.ToString();
}
}
#line default
#line hidden
#region Base class
/// <summary>
/// Base class for this transformation
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "14.0.0.0")]
public class TimedScopeClassTemplateBase
{
#region Fields
private global::System.Text.StringBuilder generationEnvironmentField;
private global::System.CodeDom.Compiler.CompilerErrorCollection errorsField;
private global::System.Collections.Generic.List<int> indentLengthsField;
private string currentIndentField = "";
private bool endsWithNewline;
private global::System.Collections.Generic.IDictionary<string, object> sessionField;
#endregion
#region Properties
/// <summary>
/// The string builder that generation-time code is using to assemble generated output
/// </summary>
protected global::System.Text.StringBuilder GenerationEnvironment
{
get
{
if ((this.generationEnvironmentField == null))
{
this.generationEnvironmentField = new global::System.Text.StringBuilder();
}
return this.generationEnvironmentField;
}
set
{
this.generationEnvironmentField = value;
}
}
/// <summary>
/// The error collection for the generation process
/// </summary>
public global::System.CodeDom.Compiler.CompilerErrorCollection Errors
{
get
{
if ((this.errorsField == null))
{
this.errorsField = new global::System.CodeDom.Compiler.CompilerErrorCollection();
}
return this.errorsField;
}
}
/// <summary>
/// A list of the lengths of each indent that was added with PushIndent
/// </summary>
private global::System.Collections.Generic.List<int> indentLengths
{
get
{
if ((this.indentLengthsField == null))
{
this.indentLengthsField = new global::System.Collections.Generic.List<int>();
}
return this.indentLengthsField;
}
}
/// <summary>
/// Gets the current indent we use when adding lines to the output
/// </summary>
public string CurrentIndent
{
get
{
return this.currentIndentField;
}
}
/// <summary>
/// Current transformation session
/// </summary>
public virtual global::System.Collections.Generic.IDictionary<string, object> Session
{
get
{
return this.sessionField;
}
set
{
this.sessionField = value;
}
}
#endregion
#region Transform-time helpers
/// <summary>
/// Write text directly into the generated output
/// </summary>
public void Write(string textToAppend)
{
if (string.IsNullOrEmpty(textToAppend))
{
return;
}
// If we're starting off, or if the previous text ended with a newline,
// we have to append the current indent first.
if (((this.GenerationEnvironment.Length == 0)
|| this.endsWithNewline))
{
this.GenerationEnvironment.Append(this.currentIndentField);
this.endsWithNewline = false;
}
// Check if the current text ends with a newline
if (textToAppend.EndsWith(global::System.Environment.NewLine, global::System.StringComparison.CurrentCulture))
{
this.endsWithNewline = true;
}
// This is an optimization. If the current indent is "", then we don't have to do any
// of the more complex stuff further down.
if ((this.currentIndentField.Length == 0))
{
this.GenerationEnvironment.Append(textToAppend);
return;
}
// Everywhere there is a newline in the text, add an indent after it
textToAppend = textToAppend.Replace(global::System.Environment.NewLine, (global::System.Environment.NewLine + this.currentIndentField));
// If the text ends with a newline, then we should strip off the indent added at the very end
// because the appropriate indent will be added when the next time Write() is called
if (this.endsWithNewline)
{
this.GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - this.currentIndentField.Length));
}
else
{
this.GenerationEnvironment.Append(textToAppend);
}
}
/// <summary>
/// Write text directly into the generated output
/// </summary>
public void WriteLine(string textToAppend)
{
this.Write(textToAppend);
this.GenerationEnvironment.AppendLine();
this.endsWithNewline = true;
}
/// <summary>
/// Write formatted text directly into the generated output
/// </summary>
public void Write(string format, params object[] args)
{
this.Write(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args));
}
/// <summary>
/// Write formatted text directly into the generated output
/// </summary>
public void WriteLine(string format, params object[] args)
{
this.WriteLine(string.Format(global::System.Globalization.CultureInfo.CurrentCulture, format, args));
}
/// <summary>
/// Raise an error
/// </summary>
public void Error(string message)
{
global::System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError();
error.ErrorText = message;
this.Errors.Add(error);
}
/// <summary>
/// Raise a warning
/// </summary>
public void Warning(string message)
{
global::System.CodeDom.Compiler.CompilerError error = new global::System.CodeDom.Compiler.CompilerError();
error.ErrorText = message;
error.IsWarning = true;
this.Errors.Add(error);
}
/// <summary>
/// Increase the indent
/// </summary>
public void PushIndent(string indent)
{
if ((indent == null))
{
throw new global::System.ArgumentNullException("indent");
}
this.currentIndentField = (this.currentIndentField + indent);
this.indentLengths.Add(indent.Length);
}
/// <summary>
/// Remove the last indent that was added with PushIndent
/// </summary>
public string PopIndent()
{
string returnValue = "";
if ((this.indentLengths.Count > 0))
{
int indentLength = this.indentLengths[(this.indentLengths.Count - 1)];
this.indentLengths.RemoveAt((this.indentLengths.Count - 1));
if ((indentLength > 0))
{
returnValue = this.currentIndentField.Substring((this.currentIndentField.Length - indentLength));
this.currentIndentField = this.currentIndentField.Remove((this.currentIndentField.Length - indentLength));
}
}
return returnValue;
}
/// <summary>
/// Remove any indentation
/// </summary>
public void ClearIndent()
{
this.indentLengths.Clear();
this.currentIndentField = "";
}
#endregion
#region ToString Helpers
/// <summary>
/// Utility class to produce culture-oriented representation of an object as a string.
/// </summary>
public class ToStringInstanceHelper
{
private global::System.IFormatProvider formatProviderField = global::System.Globalization.CultureInfo.InvariantCulture;
/// <summary>
/// Gets or sets format provider to be used by ToStringWithCulture method.
/// </summary>
public global::System.IFormatProvider FormatProvider
{
get
{
return this.formatProviderField ;
}
set
{
if ((value != null))
{
this.formatProviderField = value;
}
}
}
/// <summary>
/// This is called from the compile/run appdomain to convert objects within an expression block to a string
/// </summary>
public string ToStringWithCulture(object objectToConvert)
{
if ((objectToConvert == null))
{
throw new global::System.ArgumentNullException("objectToConvert");
}
global::System.Type t = objectToConvert.GetType();
global::System.Reflection.MethodInfo method = t.GetMethod("ToString", new global::System.Type[] {
typeof(global::System.IFormatProvider)});
if ((method == null))
{
return objectToConvert.ToString();
}
else
{
return ((string)(method.Invoke(objectToConvert, new object[] {
this.formatProviderField })));
}
}
}
private ToStringInstanceHelper toStringHelperField = new ToStringInstanceHelper();
/// <summary>
/// Helper to produce culture-oriented representation of an object as a string
/// </summary>
public ToStringInstanceHelper ToStringHelper
{
get
{
return this.toStringHelperField;
}
}
#endregion
}
#endregion
}

Просмотреть файл

@ -0,0 +1,106 @@
<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using Microsoft.Omex.System.Logging;
namespace <#= ScopeCollection.@namespace #>
{
/// <summary>
/// Timed scopes
/// </summary>
[GeneratedCode("<#= AssemblyName #>", "<#= AssemblyVersion #>")]
public static class <#= TimedScopeClassName #>
{
/// <summary>
/// Gets a Dictionary of ScopeName to ScopeDefinition for all Timed Scopes
/// </summary>
public static IReadOnlyDictionary<string, TimedScopeDefinition> AllScopeDefinitions
{
get
{
return s_scopeDefinitions.Value;
}
}
/// <summary>
/// Dictionary of ScopeName to ScopeDefinition for all Timed Scopes
/// </summary>
private static Lazy<Dictionary<string, TimedScopeDefinition>> s_scopeDefinitions = new Lazy<Dictionary<string, TimedScopeDefinition>>(
() => new Dictionary<string, TimedScopeDefinition>(StringComparer.Ordinal)
{
<#
foreach (TimedScopeArea area in ScopeCollection.TimedScopeArea.OrderBy(x => x.name))
{
foreach (TimedScope scope in area.TimedScope.OrderBy(x => x.name))
{
#>
{ <#= area.StrippedName() #>.<#= scope.name #>.Name, <#= area.StrippedName() #>.<#= scope.name #> },
<#
}
}
#>
});
<#
foreach (TimedScopeArea area in ScopeCollection.TimedScopeArea.OrderBy(x => x.name))
{
#>
/// <summary>
/// Timed scopes for <#= area.StrippedName() #>
/// </summary>
public static class <#= area.StrippedName() #>
{
<#
foreach (TimedScope scope in area.TimedScope.OrderBy(x => x.name))
{
#>
/// <summary>
/// <#= scope.name #> Timed Scope
/// </summary>
public static TimedScopeDefinition <#= scope.name #> => new TimedScopeDefinition("<#= area.StrippedName() #>_<#= scope.name #>",
"<#= scope.FormatDescription() #>"<# if (scope.OCEHandBookLink != null)
{
#>,
linkToOCEHandbook: @"<#= scope.OCEHandBookLink #>"<#
}
#><# if (scope.onDemand)
{
#>,
onDemand: <#= scope.onDemand.ToString().ToLower() #><#
}
#><# if (scope.capturesUniqueUserHashes)
{
#>,
capturesUniqueUserHashes: <#= scope.capturesUniqueUserHashes.ToString().ToLower() #><#
}
#>);
<#
}
#>
}
<#
}
#>
}
}

Просмотреть файл

@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System.Diagnostics;
using System.Reflection;
namespace Microsoft.Omex.CodeGenerators.TimedScopeGen
{
/// <summary>
/// Partial definitions for TimedScopeClassTemplate genarated generator
/// </summary>
public partial class TimedScopeClassTemplate
{
/// <summary>
/// Collection of timed scopes to be generated to the C# class
/// </summary>
private TimedScopeCollection ScopeCollection { get; }
/// <summary>
/// Are we rendering shared timed scopes?
/// </summary>
private bool IsSharedTimedScopes { get; }
/// <summary>
/// Name of the generated class
/// </summary>
private string TimedScopeClassName => IsSharedTimedScopes ? "SharedTimedScopes" : "TimedScopes";
/// <summary>
/// Assembly name
/// </summary>
private string AssemblyName => Assembly.GetExecutingAssembly().GetName().Name;
/// <summary>
/// Assembly version
/// </summary>
private string AssemblyVersion
{
get
{
FileVersionInfo version = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
return string.Concat(version.FileMajorPart, ".", version.FileMinorPart, ".0000.0000");
}
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="scopeCollection">Scope collection</param>
/// <param name="isSharedTimedScopes">Are we rendering shared timed scopes?</param>
public TimedScopeClassTemplate(TimedScopeCollection scopeCollection, bool isSharedTimedScopes)
{
ScopeCollection = scopeCollection;
IsSharedTimedScopes = isSharedTimedScopes;
}
}
}

Просмотреть файл

@ -0,0 +1,198 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
//
// This source code was auto-generated by xsd, Version=4.6.1055.0.
//
#pragma warning disable 1591
namespace Microsoft.Omex.CodeGenerators.TimedScopeGen {
using global::System.Xml.Serialization;
/// <remarks/>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[global::System.SerializableAttribute()]
[global::System.Diagnostics.DebuggerStepThroughAttribute()]
[global::System.ComponentModel.DesignerCategoryAttribute("code")]
[global::System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/TimedScopes.xsd")]
[global::System.Xml.Serialization.XmlRootAttribute("TimedScopes", Namespace="http://tempuri.org/TimedScopes.xsd", IsNullable=false)]
public partial class TimedScopeCollection {
private TimedScopeArea[] timedScopeAreaField;
private string namespaceField;
/// <remarks/>
[global::System.Xml.Serialization.XmlElementAttribute("TimedScopeArea")]
public TimedScopeArea[] TimedScopeArea {
get {
return this.timedScopeAreaField;
}
set {
this.timedScopeAreaField = value;
}
}
/// <remarks/>
[global::System.Xml.Serialization.XmlAttributeAttribute()]
public string @namespace {
get {
return this.namespaceField;
}
set {
this.namespaceField = value;
}
}
}
/// <remarks/>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[global::System.SerializableAttribute()]
[global::System.Diagnostics.DebuggerStepThroughAttribute()]
[global::System.ComponentModel.DesignerCategoryAttribute("code")]
[global::System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/TimedScopes.xsd")]
public partial class TimedScopeArea {
private TimedScope[] timedScopeField;
private string nameField;
private string friendlyNameField;
/// <remarks/>
[global::System.Xml.Serialization.XmlElementAttribute("TimedScope")]
public TimedScope[] TimedScope {
get {
return this.timedScopeField;
}
set {
this.timedScopeField = value;
}
}
/// <remarks/>
[global::System.Xml.Serialization.XmlAttributeAttribute()]
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
/// <remarks/>
[global::System.Xml.Serialization.XmlAttributeAttribute()]
public string friendlyName {
get {
return this.friendlyNameField;
}
set {
this.friendlyNameField = value;
}
}
}
/// <remarks/>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[global::System.SerializableAttribute()]
[global::System.Diagnostics.DebuggerStepThroughAttribute()]
[global::System.ComponentModel.DesignerCategoryAttribute("code")]
[global::System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/TimedScopes.xsd")]
public partial class TimedScope {
private string descriptionField;
private string oCEHandBookLinkField;
private string[] textField;
private string nameField;
private bool onDemandField;
private bool capturesUniqueUserHashesField;
public TimedScope() {
this.onDemandField = false;
this.capturesUniqueUserHashesField = false;
}
/// <remarks/>
public string Description {
get {
return this.descriptionField;
}
set {
this.descriptionField = value;
}
}
/// <remarks/>
public string OCEHandBookLink {
get {
return this.oCEHandBookLinkField;
}
set {
this.oCEHandBookLinkField = value;
}
}
/// <remarks/>
[global::System.Xml.Serialization.XmlTextAttribute()]
public string[] Text {
get {
return this.textField;
}
set {
this.textField = value;
}
}
/// <remarks/>
[global::System.Xml.Serialization.XmlAttributeAttribute()]
public string name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
/// <remarks/>
[global::System.Xml.Serialization.XmlAttributeAttribute()]
[global::System.ComponentModel.DefaultValueAttribute(false)]
public bool onDemand {
get {
return this.onDemandField;
}
set {
this.onDemandField = value;
}
}
/// <remarks/>
[global::System.Xml.Serialization.XmlAttributeAttribute()]
[global::System.ComponentModel.DefaultValueAttribute(false)]
public bool capturesUniqueUserHashes {
get {
return this.capturesUniqueUserHashesField;
}
set {
this.capturesUniqueUserHashesField = value;
}
}
}
}
#pragma warning restore 1591

Просмотреть файл

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="TimedScopes" targetNamespace="http://tempuri.org/TimedScopes.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/TimedScopes.xsd" xmlns:mstns="http://tempuri.org/TimedScopes.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="TimedScopes" type="mstns:TimedScopeCollection" />
<xs:complexType name ="TimedScopeCollection">
<xs:sequence>
<xs:element name="TimedScopeArea" type="mstns:TimedScopeArea" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="namespace" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="TimedScopeArea">
<xs:sequence>
<xs:element name="TimedScope" type="mstns:TimedScope" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="friendlyName" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="TimedScope" mixed="true">
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="OCEHandBookLink" type="xs:string" minOccurs="0" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="onDemand" type="xs:boolean" use="optional" default="false" />
<xs:attribute name="capturesUniqueUserHashes" type="xs:boolean" use="optional" default="false" />
</xs:complexType>
</xs:schema>

Просмотреть файл

@ -0,0 +1,69 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Text;
namespace Microsoft.Omex.CodeGenerators.TimedScopeGen
{
/// <summary>
/// Contains extension methods for converting timed scope definitions to perf counters
/// </summary>
public static class TimedScopesDefinitionExtensions
{
/// <summary>
/// Strips TimedScopeArea name
/// </summary>
/// <param name="timedScopeArea"></param>
/// <returns>Striped name</returns>
public static string StrippedName(this TimedScopeArea timedScopeArea)
{
if (timedScopeArea.name.StartsWith(Program.ProductOmex, StringComparison.OrdinalIgnoreCase))
{
return timedScopeArea.name.Substring(Program.ProductOmex.Length);
}
return timedScopeArea.name;
}
/// <summary>
/// Formats timed scope description by dividing it into several lines.
/// </summary>
/// <param name="scope">Scope</param>
/// <param name="maxCharactersPerLine">the maximal number of characters allowed per line</param>
/// <param name="indentationLevel">the indentation level used for new lines</param>
/// <returns>Description text devided into several lines</returns>
public static string FormatDescription(this TimedScope scope, int maxCharactersPerLine = 140, int indentationLevel = 5)
{
string description = scope.GetDescription() ?? "MissingDescription";
StringBuilder result = new StringBuilder(description.Length + 50);
int startIndex = 0;
do
{
if (startIndex + maxCharactersPerLine < description.Length)
{
result.Append(description.Substring(startIndex, maxCharactersPerLine));
result.AppendLine("\" +");
for (int i = 0; i < indentationLevel; i++)
{
result.Append('\t');
}
result.Append("\"");
}
else
{
result.Append(description.Substring(startIndex, description.Length - startIndex));
break;
}
startIndex += maxCharactersPerLine;
}
while (startIndex < description.Length);
return result.ToString();
}
}
}

Просмотреть файл

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
namespace Microsoft.Omex.CodeGenerators.TimedScopeGen
{
/// <summary>
/// Partial definitions for the TimedScope class
/// </summary>
public partial class TimedScope
{
/// <summary>
/// Gets the description
/// </summary>
/// <returns>Description</returns>
public string GetDescription() => Description ?? string.Join(string.Empty, Text);
}
}