TeleSharp.Generator refactoring

Fix naming for models properties (Use JsonProperty instead)
Move models to separate folder
Rename models

Remove unused references in Program.cs
Use string instead of String
This commit is contained in:
CheshireCaat 2020-01-26 05:03:28 +03:00
parent 79cf25d257
commit d42a367cf4
7 changed files with 148 additions and 117 deletions

View file

@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Schema;
namespace TeleSharp.Generator
{
class Method
{
public int id { get; set; }
public string method { get; set; }
[Newtonsoft.Json.JsonProperty("params")]
public List<Param> Params { get; set; }
public string type { get; set; }
}
class Param
{
public string name { get; set; }
public string type { get; set; }
}
class Constructor
{
public int id { get; set; }
public string predicate { get; set; }
[Newtonsoft.Json.JsonProperty("params")]
public List<Param> Params { get; set; }
public string type { get; set; }
}
class Schema
{
public List<Constructor> constructors { get; set; }
public List<Method> methods { get; set; }
}
}

View file

@ -0,0 +1,20 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace TeleSharp.Generator.Models
{
internal class TlConstructor
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("predicate")]
public string Predicate { get; set; }
[JsonProperty("params")]
public List<TlParam> Params { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
}
}

View file

@ -0,0 +1,20 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace TeleSharp.Generator.Models
{
internal class TlMethod
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("method")]
public string Method { get; set; }
[JsonProperty("params")]
public List<TlParam> Params { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
}
}

View file

@ -0,0 +1,13 @@
using Newtonsoft.Json;
namespace TeleSharp.Generator.Models
{
internal class TlParam
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
}
}

View file

@ -0,0 +1,14 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace TeleSharp.Generator.Models
{
internal class TlSchema
{
[JsonProperty("constructors")]
public List<TlConstructor> Constructors { get; set; }
[JsonProperty("methods")]
public List<TlMethod> Methods { get; set; }
}
}

View file

@ -3,19 +3,15 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.CodeDom;
using System.Reflection;
using System.Text.RegularExpressions;
using TeleSharp.Generator.Models;
namespace TeleSharp.Generator
{
class Program
{
static List<String> keywords = new List<string>(new string[] { "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while", "add", "alias", "ascending", "async", "await", "descending", "dynamic", "from", "get", "global", "group", "into", "join", "let", "orderby", "partial", "partial", "remove", "select", "set", "value", "var", "where", "where", "yield" });
static List<String> interfacesList = new List<string>();
static List<String> classesList = new List<string>();
static List<string> keywords = new List<string>(new string[] { "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", "goto", "if", "implicit", "in", "in", "int", "interface", "internal", "is", "lock", "long", "namespace", "new", "null", "object", "operator", "out", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", "volatile", "while", "add", "alias", "ascending", "async", "await", "descending", "dynamic", "from", "get", "global", "group", "into", "join", "let", "orderby", "partial", "partial", "remove", "select", "set", "value", "var", "where", "where", "yield" });
static List<string> interfacesList = new List<string>();
static List<string> classesList = new List<string>();
static void Main(string[] args)
{
@ -30,26 +26,26 @@ namespace TeleSharp.Generator
Json = File.ReadAllText(url);
FileStream file = File.OpenWrite("Result.cs");
StreamWriter sw = new StreamWriter(file);
Schema schema = JsonConvert.DeserializeObject<Schema>(Json);
foreach (var c in schema.constructors)
TlSchema schema = JsonConvert.DeserializeObject<TlSchema>(Json);
foreach (var c in schema.Constructors)
{
interfacesList.Add(c.type);
classesList.Add(c.predicate);
interfacesList.Add(c.Type);
classesList.Add(c.Predicate);
}
foreach (var c in schema.constructors)
foreach (var c in schema.Constructors)
{
var list = schema.constructors.Where(x => x.type == c.type);
var list = schema.Constructors.Where(x => x.Type == c.Type);
if (list.Count() > 1)
{
string path = (GetNameSpace(c.type).Replace("TeleSharp.TL", "TL\\").Replace(".", "") + "\\" + GetNameofClass(c.type, true) + ".cs").Replace("\\\\", "\\");
string path = (GetNameSpace(c.Type).Replace("TeleSharp.TL", "TL\\").Replace(".", "") + "\\" + GetNameofClass(c.Type, true) + ".cs").Replace("\\\\", "\\");
FileStream classFile = MakeFile(path);
using (StreamWriter writer = new StreamWriter(classFile))
{
string nspace = (GetNameSpace(c.type).Replace("TeleSharp.TL", "TL\\").Replace(".", "")).Replace("\\\\", "\\").Replace("\\", ".");
string nspace = (GetNameSpace(c.Type).Replace("TeleSharp.TL", "TL\\").Replace(".", "")).Replace("\\\\", "\\").Replace("\\", ".");
if (nspace.EndsWith("."))
nspace = nspace.Remove(nspace.Length - 1, 1);
string temp = AbsStyle.Replace("/* NAMESPACE */", "TeleSharp." + nspace);
temp = temp.Replace("/* NAME */", GetNameofClass(c.type, true));
temp = temp.Replace("/* NAME */", GetNameofClass(c.Type, true));
writer.Write(temp);
writer.Close();
classFile.Close();
@ -57,47 +53,47 @@ namespace TeleSharp.Generator
}
else
{
interfacesList.Remove(list.First().type);
list.First().type = "himself";
interfacesList.Remove(list.First().Type);
list.First().Type = "himself";
}
}
foreach (var c in schema.constructors)
foreach (var c in schema.Constructors)
{
string path = (GetNameSpace(c.predicate).Replace("TeleSharp.TL", "TL\\").Replace(".", "") + "\\" + GetNameofClass(c.predicate, false) + ".cs").Replace("\\\\", "\\");
string path = (GetNameSpace(c.Predicate).Replace("TeleSharp.TL", "TL\\").Replace(".", "") + "\\" + GetNameofClass(c.Predicate, false) + ".cs").Replace("\\\\", "\\");
FileStream classFile = MakeFile(path);
using (StreamWriter writer = new StreamWriter(classFile))
{
#region About Class
string nspace = (GetNameSpace(c.predicate).Replace("TeleSharp.TL", "TL\\").Replace(".", "")).Replace("\\\\", "\\").Replace("\\", ".");
string nspace = (GetNameSpace(c.Predicate).Replace("TeleSharp.TL", "TL\\").Replace(".", "")).Replace("\\\\", "\\").Replace("\\", ".");
if (nspace.EndsWith("."))
nspace = nspace.Remove(nspace.Length - 1, 1);
string temp = NormalStyle.Replace("/* NAMESPACE */", "TeleSharp." + nspace);
temp = (c.type == "himself") ? temp.Replace("/* PARENT */", "TLObject") : temp.Replace("/* PARENT */", GetNameofClass(c.type, true));
temp = temp.Replace("/*Constructor*/", c.id.ToString());
temp = temp.Replace("/* NAME */", GetNameofClass(c.predicate, false));
temp = (c.Type == "himself") ? temp.Replace("/* PARENT */", "TLObject") : temp.Replace("/* PARENT */", GetNameofClass(c.Type, true));
temp = temp.Replace("/*Constructor*/", c.Id.ToString());
temp = temp.Replace("/* NAME */", GetNameofClass(c.Predicate, false));
#endregion
#region Fields
string fields = "";
foreach (var tmp in c.Params)
{
fields += $" public {CheckForFlagBase(tmp.type, GetTypeName(tmp.type))} {CheckForKeywordAndPascalCase(tmp.name)} " + "{get;set;}" + Environment.NewLine;
fields += $" public {CheckForFlagBase(tmp.Type, GetTypeName(tmp.Type))} {CheckForKeywordAndPascalCase(tmp.Name)} " + "{get;set;}" + Environment.NewLine;
}
temp = temp.Replace("/* PARAMS */", fields);
#endregion
#region ComputeFlagFunc
if (!c.Params.Any(x => x.name == "Flags")) temp = temp.Replace("/* COMPUTE */", "");
if (!c.Params.Any(x => x.Name == "Flags")) temp = temp.Replace("/* COMPUTE */", "");
else
{
var compute = "Flags = 0;" + Environment.NewLine;
foreach (var param in c.Params.Where(x => IsFlagBase(x.type)))
foreach (var param in c.Params.Where(x => IsFlagBase(x.Type)))
{
if (IsTrueFlag(param.type))
if (IsTrueFlag(param.Type))
{
compute += $"Flags = {CheckForKeywordAndPascalCase(param.name)} ? (Flags | {GetBitMask(param.type)}) : (Flags & ~{GetBitMask(param.type)});" + Environment.NewLine;
compute += $"Flags = {CheckForKeywordAndPascalCase(param.Name)} ? (Flags | {GetBitMask(param.Type)}) : (Flags & ~{GetBitMask(param.Type)});" + Environment.NewLine;
}
else
{
compute += $"Flags = {CheckForKeywordAndPascalCase(param.name)} != null ? (Flags | {GetBitMask(param.type)}) : (Flags & ~{GetBitMask(param.type)});" + Environment.NewLine;
compute += $"Flags = {CheckForKeywordAndPascalCase(param.Name)} != null ? (Flags | {GetBitMask(param.Type)}) : (Flags & ~{GetBitMask(param.Type)});" + Environment.NewLine;
}
}
temp = temp.Replace("/* COMPUTE */", compute);
@ -106,8 +102,8 @@ namespace TeleSharp.Generator
#region SerializeFunc
var serialize = "";
if (c.Params.Any(x => x.name == "Flags")) serialize += "ComputeFlags();" + Environment.NewLine + "bw.Write(Flags);" + Environment.NewLine;
foreach (var p in c.Params.Where(x => x.name != "Flags"))
if (c.Params.Any(x => x.Name == "Flags")) serialize += "ComputeFlags();" + Environment.NewLine + "bw.Write(Flags);" + Environment.NewLine;
foreach (var p in c.Params.Where(x => x.Name != "Flags"))
{
serialize += WriteWriteCode(p) + Environment.NewLine;
}
@ -127,44 +123,44 @@ namespace TeleSharp.Generator
classFile.Close();
}
}
foreach (var c in schema.methods)
foreach (var c in schema.Methods)
{
string path = (GetNameSpace(c.method).Replace("TeleSharp.TL", "TL\\").Replace(".", "") + "\\" + GetNameofClass(c.method, false, true) + ".cs").Replace("\\\\", "\\");
string path = (GetNameSpace(c.Method).Replace("TeleSharp.TL", "TL\\").Replace(".", "") + "\\" + GetNameofClass(c.Method, false, true) + ".cs").Replace("\\\\", "\\");
FileStream classFile = MakeFile(path);
using (StreamWriter writer = new StreamWriter(classFile))
{
#region About Class
string nspace = (GetNameSpace(c.method).Replace("TeleSharp.TL", "TL\\").Replace(".", "")).Replace("\\\\", "\\").Replace("\\", ".");
string nspace = (GetNameSpace(c.Method).Replace("TeleSharp.TL", "TL\\").Replace(".", "")).Replace("\\\\", "\\").Replace("\\", ".");
if (nspace.EndsWith("."))
nspace = nspace.Remove(nspace.Length - 1, 1);
string temp = MethodStyle.Replace("/* NAMESPACE */", "TeleSharp." + nspace);
temp = temp.Replace("/* PARENT */", "TLMethod");
temp = temp.Replace("/*Constructor*/", c.id.ToString());
temp = temp.Replace("/* NAME */", GetNameofClass(c.method, false, true));
temp = temp.Replace("/*Constructor*/", c.Id.ToString());
temp = temp.Replace("/* NAME */", GetNameofClass(c.Method, false, true));
#endregion
#region Fields
string fields = "";
foreach (var tmp in c.Params)
{
fields += $" public {CheckForFlagBase(tmp.type, GetTypeName(tmp.type))} {CheckForKeywordAndPascalCase(tmp.name)} " + "{get;set;}" + Environment.NewLine;
fields += $" public {CheckForFlagBase(tmp.Type, GetTypeName(tmp.Type))} {CheckForKeywordAndPascalCase(tmp.Name)} " + "{get;set;}" + Environment.NewLine;
}
fields += $" public {CheckForFlagBase(c.type, GetTypeName(c.type))} Response" + "{ get; set;}" + Environment.NewLine;
fields += $" public {CheckForFlagBase(c.Type, GetTypeName(c.Type))} Response" + "{ get; set;}" + Environment.NewLine;
temp = temp.Replace("/* PARAMS */", fields);
#endregion
#region ComputeFlagFunc
if (!c.Params.Any(x => x.name == "Flags")) temp = temp.Replace("/* COMPUTE */", "");
if (!c.Params.Any(x => x.Name == "Flags")) temp = temp.Replace("/* COMPUTE */", "");
else
{
var compute = "Flags = 0;" + Environment.NewLine;
foreach (var param in c.Params.Where(x => IsFlagBase(x.type)))
foreach (var param in c.Params.Where(x => IsFlagBase(x.Type)))
{
if (IsTrueFlag(param.type))
if (IsTrueFlag(param.Type))
{
compute += $"Flags = {CheckForKeywordAndPascalCase(param.name)} ? (Flags | {GetBitMask(param.type)}) : (Flags & ~{GetBitMask(param.type)});" + Environment.NewLine;
compute += $"Flags = {CheckForKeywordAndPascalCase(param.Name)} ? (Flags | {GetBitMask(param.Type)}) : (Flags & ~{GetBitMask(param.Type)});" + Environment.NewLine;
}
else
{
compute += $"Flags = {CheckForKeywordAndPascalCase(param.name)} != null ? (Flags | {GetBitMask(param.type)}) : (Flags & ~{GetBitMask(param.type)});" + Environment.NewLine;
compute += $"Flags = {CheckForKeywordAndPascalCase(param.Name)} != null ? (Flags | {GetBitMask(param.Type)}) : (Flags & ~{GetBitMask(param.Type)});" + Environment.NewLine;
}
}
temp = temp.Replace("/* COMPUTE */", compute);
@ -173,8 +169,8 @@ namespace TeleSharp.Generator
#region SerializeFunc
var serialize = "";
if (c.Params.Any(x => x.name == "Flags")) serialize += "ComputeFlags();" + Environment.NewLine + "bw.Write(Flags);" + Environment.NewLine;
foreach (var p in c.Params.Where(x => x.name != "Flags"))
if (c.Params.Any(x => x.Name == "Flags")) serialize += "ComputeFlags();" + Environment.NewLine + "bw.Write(Flags);" + Environment.NewLine;
foreach (var p in c.Params.Where(x => x.Name != "Flags"))
{
serialize += WriteWriteCode(p) + Environment.NewLine;
}
@ -191,7 +187,7 @@ namespace TeleSharp.Generator
#endregion
#region DeSerializeRespFunc
var deserializeResp = "";
Param p2 = new Param() { name = "Response", type = c.type };
TlParam p2 = new TlParam() { Name = "Response", Type = c.Type };
deserializeResp += WriteReadCode(p2) + Environment.NewLine;
temp = temp.Replace("/* DESERIALIZEResp */", deserializeResp);
#endregion
@ -203,7 +199,7 @@ namespace TeleSharp.Generator
}
public static string FormatName(string input)
{
if (String.IsNullOrEmpty(input))
if (string.IsNullOrEmpty(input))
throw new ArgumentException("ARGH!");
if (input.IndexOf('.') != -1)
{
@ -346,79 +342,79 @@ namespace TeleSharp.Generator
else
return src;
}
public static string WriteWriteCode(Param p, bool flag = false)
public static string WriteWriteCode(TlParam p, bool flag = false)
{
switch (p.type.ToLower())
switch (p.Type.ToLower())
{
case "#":
case "int":
return flag ? $"bw.Write({CheckForKeywordAndPascalCase(p.name)}.Value);" : $"bw.Write({CheckForKeywordAndPascalCase(p.name)});";
return flag ? $"bw.Write({CheckForKeywordAndPascalCase(p.Name)}.Value);" : $"bw.Write({CheckForKeywordAndPascalCase(p.Name)});";
case "long":
return flag ? $"bw.Write({CheckForKeywordAndPascalCase(p.name)}.Value);" : $"bw.Write({CheckForKeywordAndPascalCase(p.name)});";
return flag ? $"bw.Write({CheckForKeywordAndPascalCase(p.Name)}.Value);" : $"bw.Write({CheckForKeywordAndPascalCase(p.Name)});";
case "string":
return $"StringUtil.Serialize({CheckForKeywordAndPascalCase(p.name)},bw);";
return $"StringUtil.Serialize({CheckForKeywordAndPascalCase(p.Name)},bw);";
case "bool":
return flag ? $"BoolUtil.Serialize({CheckForKeywordAndPascalCase(p.name)}.Value,bw);" : $"BoolUtil.Serialize({CheckForKeywordAndPascalCase(p.name)},bw);";
return flag ? $"BoolUtil.Serialize({CheckForKeywordAndPascalCase(p.Name)}.Value,bw);" : $"BoolUtil.Serialize({CheckForKeywordAndPascalCase(p.Name)},bw);";
case "true":
return $"BoolUtil.Serialize({CheckForKeywordAndPascalCase(p.name)},bw);";
return $"BoolUtil.Serialize({CheckForKeywordAndPascalCase(p.Name)},bw);";
case "bytes":
return $"BytesUtil.Serialize({CheckForKeywordAndPascalCase(p.name)},bw);";
return $"BytesUtil.Serialize({CheckForKeywordAndPascalCase(p.Name)},bw);";
case "double":
return flag ? $"bw.Write({CheckForKeywordAndPascalCase(p.name)}.Value);" : $"bw.Write({CheckForKeywordAndPascalCase(p.name)});";
return flag ? $"bw.Write({CheckForKeywordAndPascalCase(p.Name)}.Value);" : $"bw.Write({CheckForKeywordAndPascalCase(p.Name)});";
default:
if (!IsFlagBase(p.type))
return $"ObjectUtils.SerializeObject({CheckForKeywordAndPascalCase(p.name)},bw);";
if (!IsFlagBase(p.Type))
return $"ObjectUtils.SerializeObject({CheckForKeywordAndPascalCase(p.Name)},bw);";
else
{
if (IsTrueFlag(p.type))
if (IsTrueFlag(p.Type))
return $"";
else
{
Param p2 = new Param() { name = p.name, type = p.type.Split('?')[1] };
return $"if ((Flags & {GetBitMask(p.type).ToString()}) != 0)" + Environment.NewLine +
TlParam p2 = new TlParam() { Name = p.Name, Type = p.Type.Split('?')[1] };
return $"if ((Flags & {GetBitMask(p.Type).ToString()}) != 0)" + Environment.NewLine +
WriteWriteCode(p2, true);
}
}
}
}
public static string WriteReadCode(Param p)
public static string WriteReadCode(TlParam p)
{
switch (p.type.ToLower())
switch (p.Type.ToLower())
{
case "#":
case "int":
return $"{CheckForKeywordAndPascalCase(p.name)} = br.ReadInt32();";
return $"{CheckForKeywordAndPascalCase(p.Name)} = br.ReadInt32();";
case "long":
return $"{CheckForKeywordAndPascalCase(p.name)} = br.ReadInt64();";
return $"{CheckForKeywordAndPascalCase(p.Name)} = br.ReadInt64();";
case "string":
return $"{CheckForKeywordAndPascalCase(p.name)} = StringUtil.Deserialize(br);";
return $"{CheckForKeywordAndPascalCase(p.Name)} = StringUtil.Deserialize(br);";
case "bool":
case "true":
return $"{CheckForKeywordAndPascalCase(p.name)} = BoolUtil.Deserialize(br);";
return $"{CheckForKeywordAndPascalCase(p.Name)} = BoolUtil.Deserialize(br);";
case "bytes":
return $"{CheckForKeywordAndPascalCase(p.name)} = BytesUtil.Deserialize(br);";
return $"{CheckForKeywordAndPascalCase(p.Name)} = BytesUtil.Deserialize(br);";
case "double":
return $"{CheckForKeywordAndPascalCase(p.name)} = br.ReadDouble();";
return $"{CheckForKeywordAndPascalCase(p.Name)} = br.ReadDouble();";
default:
if (!IsFlagBase(p.type))
if (!IsFlagBase(p.Type))
{
if (p.type.ToLower().Contains("vector"))
if (p.Type.ToLower().Contains("vector"))
{
return $"{CheckForKeywordAndPascalCase(p.name)} = ({GetTypeName(p.type)})ObjectUtils.DeserializeVector<{GetTypeName(p.type).Replace("TLVector<", "").Replace(">", "")}>(br);";
return $"{CheckForKeywordAndPascalCase(p.Name)} = ({GetTypeName(p.Type)})ObjectUtils.DeserializeVector<{GetTypeName(p.Type).Replace("TLVector<", "").Replace(">", "")}>(br);";
}
else return $"{CheckForKeywordAndPascalCase(p.name)} = ({GetTypeName(p.type)})ObjectUtils.DeserializeObject(br);";
else return $"{CheckForKeywordAndPascalCase(p.Name)} = ({GetTypeName(p.Type)})ObjectUtils.DeserializeObject(br);";
}
else
{
if (IsTrueFlag(p.type))
return $"{CheckForKeywordAndPascalCase(p.name)} = (Flags & {GetBitMask(p.type).ToString()}) != 0;";
if (IsTrueFlag(p.Type))
return $"{CheckForKeywordAndPascalCase(p.Name)} = (Flags & {GetBitMask(p.Type).ToString()}) != 0;";
else
{
Param p2 = new Param() { name = p.name, type = p.type.Split('?')[1] };
return $"if ((Flags & {GetBitMask(p.type).ToString()}) != 0)" + Environment.NewLine +
TlParam p2 = new TlParam() { Name = p.Name, Type = p.Type.Split('?')[1] };
return $"if ((Flags & {GetBitMask(p.Type).ToString()}) != 0)" + Environment.NewLine +
WriteReadCode(p2) + Environment.NewLine +
"else" + Environment.NewLine +
$"{CheckForKeywordAndPascalCase(p.name)} = null;" + Environment.NewLine;
$"{CheckForKeywordAndPascalCase(p.Name)} = null;" + Environment.NewLine;
}
}
}

View file

@ -47,9 +47,12 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Models.cs" />
<Compile Include="Models\TlMethod.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Models\TlConstructor.cs" />
<Compile Include="Models\TlParam.cs" />
<Compile Include="Models\TlSchema.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
@ -69,6 +72,7 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.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.