提交 6aec6bcd 编写于 作者: I ili

TypeScript files generation for T4 models

上级 c659e761
...@@ -58,7 +58,7 @@ public partial class ModelSource : ITree ...@@ -58,7 +58,7 @@ public partial class ModelSource : ITree
{ {
public int CurrentNamespace = 0; public int CurrentNamespace = 0;
public List<string> Usings = new List<String> { "System" }; public List<string> Usings = new List<String>();
public List<Namespace> Namespaces = new List<Namespace> { new Namespace() }; public List<Namespace> Namespaces = new List<Namespace> { new Namespace() };
public Namespace Namespace { get { return Namespaces[CurrentNamespace]; } } public Namespace Namespace { get { return Namespaces[CurrentNamespace]; } }
...@@ -140,6 +140,13 @@ public partial class Class : TypeBase ...@@ -140,6 +140,13 @@ public partial class Class : TypeBase
{ {
} }
private bool _isAbstract = false;
public bool IsAbstract
{
get { return _isAbstract || Members.OfType<Method>().Any(_ => _.IsAbstract); }
set { _isAbstract = value; }
}
public Class(string name, params IClassMember[] members) public Class(string name, params IClassMember[] members)
{ {
Name = name; Name = name;
...@@ -502,8 +509,12 @@ public abstract class BaseRenderer : IRenderer ...@@ -502,8 +509,12 @@ public abstract class BaseRenderer : IRenderer
protected virtual void RenderUsings(List<string> usings) protected virtual void RenderUsings(List<string> usings)
{ {
Trim();
foreach (var u in usings.Distinct()) foreach (var u in usings.Distinct())
WriteLine(u); WriteLine(u);
WriteLine("");
} }
protected virtual void RenderNamespace(Namespace ns) protected virtual void RenderNamespace(Namespace ns)
...@@ -657,7 +668,7 @@ public abstract class BaseRenderer : IRenderer ...@@ -657,7 +668,7 @@ public abstract class BaseRenderer : IRenderer
protected abstract void BeginAttributes(); protected abstract void BeginAttributes();
protected abstract void EndAttributes (); protected abstract void EndAttributes ();
protected abstract void SplitAttributes(); protected abstract void SplitAttributes();
protected abstract void RenderAttribute(Attribute attributes); protected abstract void RenderAttribute(Attribute attribute);
protected abstract void BeginClass(Class cl); protected abstract void BeginClass(Class cl);
protected abstract void EndClass (Class cl); protected abstract void EndClass (Class cl);
...@@ -695,8 +706,10 @@ public abstract class BaseRenderer : IRenderer ...@@ -695,8 +706,10 @@ public abstract class BaseRenderer : IRenderer
_tt.WriteSpaces(count); _tt.WriteSpaces(count);
} }
public virtual void WriteComment(string comment) public virtual void WriteComment(string comment, params object[] args)
{ {
if (args.Length > 0) comment = string.Format(comment, args);
WriteLine("//{0}", comment); WriteLine("//{0}", comment);
} }
...@@ -739,6 +752,27 @@ public abstract class BaseRenderer : IRenderer ...@@ -739,6 +752,27 @@ public abstract class BaseRenderer : IRenderer
_tt.Error(error); _tt.Error(error);
} }
public void WriteEndLineComment(string comment)
{
if (!string.IsNullOrEmpty(comment))
{
RemoveSpace();
Write(" ");
WriteComment(" " + comment);
}
else
WriteLine("");
}
public void WriteLines(List<string> lines)
{
foreach (var line in lines)
{
WriteLine(line);
}
}
#endregion #endregion
} }
...@@ -772,8 +806,9 @@ public class CSharpRenderer : BaseRenderer ...@@ -772,8 +806,9 @@ public class CSharpRenderer : BaseRenderer
public Action<BaseRenderer,Class> WriteBeginClass = (tt,cl) => public Action<BaseRenderer,Class> WriteBeginClass = (tt,cl) =>
{ {
tt.Write(cl.AccessModifier.ToString().ToLower() + " "); tt.Write(cl.AccessModifier.ToString().ToLower() + " ");
if (cl.IsStatic) tt.Write("static "); if (cl.IsStatic) tt.Write("static ");
if (cl.IsPartial) tt.Write("partial ", cl.Name); if (cl.IsPartial) tt.Write("partial ", cl.Name);
if (cl.IsAbstract) tt.Write("abstract ", cl.Name);
tt.Write("class {0}", cl.Name); tt.Write("class {0}", cl.Name);
if (!string.IsNullOrEmpty(cl.BaseClass) || cl.Interfaces.Count > 0) if (!string.IsNullOrEmpty(cl.BaseClass) || cl.Interfaces.Count > 0)
...@@ -1116,6 +1151,13 @@ public class CSharpRenderer : BaseRenderer ...@@ -1116,6 +1151,13 @@ public class CSharpRenderer : BaseRenderer
_generateProcedureErrors = tt.GenerateProcedureErrors; _generateProcedureErrors = tt.GenerateProcedureErrors;
} }
protected override void RenderModelSource(ModelSource model)
{
model.Usings.Insert(0, "System");
base.RenderModelSource(model);
}
protected override void RenderUsings(List<string> usings) protected override void RenderUsings(List<string> usings)
{ {
var q = var q =
......
<#
{
CreateRenderer = CreateTypeScriptRenderer;
}
#>
<#+
static IRenderer CreateTypeScriptRenderer(GeneratedTextTransformation tt)
{
return new TypeScriptRenderer(tt);
}
partial class Property
{
public List<Attribute> GetAttributes = new List<Attribute>();
public List<Attribute> SetAttributes = new List<Attribute>();
}
partial class Field
{
public bool IsOptional;
}
public class TypeScriptRenderer : BaseRenderer
{
public TypeScriptRenderer(GeneratedTextTransformation tt) : base(tt)
{
Indent = " ";
}
protected override void BeginNamespace(Namespace ns)
{
WriteLine("namespace {0} {{", ns.Name);
}
protected override void EndNamespace(Namespace ns)
{
WriteLine("}");
}
protected override void BeginConditional(string condition, bool isCompact)
{
if (!string.IsNullOrEmpty(condition))
throw new NotSupportedException("Conditional is not supported for TypeScript");
}
protected override void EndConditional(string condition, bool isCompact)
{
if (!string.IsNullOrEmpty(condition))
throw new NotSupportedException("Conditional is not supported for TypeScript");
}
protected override void BeginAttributes()
{
}
protected override void EndAttributes()
{
}
protected override void SplitAttributes()
{
}
protected override void RenderAttribute(Attribute attribute)
{
Write("@" + attribute.Name);
if (attribute.Parameters.Count > 0) Write("(");
for (var i = 0; i < attribute.Parameters.Count; i++)
{
if (i > 0) Write(", ");
Write(attribute.Parameters[i]);
}
if (attribute.Parameters.Count > 0) Write(")");
}
protected override void BeginClass(Class cl)
{
if (cl.AccessModifier == AccessModifier.Public)
Write("export ");
if (cl.IsAbstract)
Write("abstract ");
Write("class {0} ", cl.Name);
if (!string.IsNullOrEmpty(cl.BaseClass))
Write("extends {0} ", cl.BaseClass);
if (cl.Interfaces.Count > 0)
Write("implements ");
for (var i = 0; i < cl.Interfaces.Count; i++)
{
if (i > 0) Write(", ");
Write(cl.Interfaces[i]);
}
if (cl.Interfaces.Count > 0)
Write(" ");
WriteLine("{");
}
protected override void EndClass(Class cl)
{
WriteLine("}");
}
protected override void RenderEvent(Event ev)
{
throw new NotSupportedException("Events are not supported for TypeScript");
}
protected override void RenderField(Field fl)
{
var am = fl.AccessModifier.ToString().ToLower();
Write(am + " ");
if (fl.IsStatic) Write("static ");
if (fl.IsReadonly) Write("readonly ");
Write(fl.Name);
if (fl.IsOptional) Write("?");
Write(": {0}", fl.Type);
if (fl.InitValue != null) Write(" = {0}", fl.InitValue);
Write(";");
WriteEndLineComment(fl.EndLineComment);
}
protected override void RenderProperty(Property pt, bool isCompact)
{
if (pt.IsAuto || (pt.HasGetter == pt.HasSetter == false))
{
RenderField(new Field()
{
Name = pt.Name,
AccessModifier = pt.AccessModifier,
Type = pt.Type,
EndLineComment = pt.EndLineComment,
IsReadonly = pt.HasSetter == false,
InitValue = pt.InitValue
});
return;
}
if (pt.HasGetter)
{
RenderAttributes(pt.GetAttributes);
Write("get {0}(): {1} {{", pt.Name, pt.Type);
WriteEndLineComment(pt.EndLineComment);
PushIndent();
WriteLines(pt.GetBody);
PopIndent();
WriteLine("}");
}
if (pt.HasSetter)
{
RenderAttributes(pt.SetAttributes);
Write("set {0}(value: {1}) {{", pt.Name, pt.Type);
WriteEndLineComment(pt.EndLineComment);
PushIndent();
WriteLines(pt.SetBody);
PopIndent();
WriteLine("}");
}
}
protected override void RenderMethod(Method mt, bool isCompact)
{
var am = mt.AccessModifier.ToString().ToLower();
Write(am + " ");
if (mt.IsStatic) Write("static ");
if (mt.IsAbstract) Write("abstract ");
Write("{0}(", mt.Name);
for (var i = 0; i < mt.Parameters.Count; i++)
{
if (i > 0) Write(", ");
Write(mt.Parameters[i]);
}
Write(")");
if (!string.IsNullOrEmpty(mt.Type)) Write(": {0}", mt.Type);
if (mt.Body.Count > 0) Write(" {");
else Write(";");
WriteEndLineComment(mt.EndLineComment);
if (mt.Body.Count > 0)
{
PushIndent();
WriteLines(mt.Body);
PopIndent();
WriteLine("}");
}
}
protected override void RenderMemberGroup(MemberGroup mg, bool isCompact)
{
if (!string.IsNullOrEmpty(mg.Region))
{
WriteComment("Begin {0}", mg.Region);
WriteLine("");
}
foreach (var m in mg.Members)
Render(m);
if (!string.IsNullOrEmpty(mg.Region))
WriteComment("End {0}", mg.Region);
}
}
#>
...@@ -14,6 +14,11 @@ ...@@ -14,6 +14,11 @@
<None Remove="bbb.txt" /> <None Remove="bbb.txt" />
<Content Include="bbb.txt" /> <Content Include="bbb.txt" />
<None Include="TypeScript.generated.ts">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>TypeScript.tt</DependentUpon>
</None>
<None Update="EditableModelTest.tt"> <None Update="EditableModelTest.tt">
<Generator>TextTemplatingFileGenerator</Generator> <Generator>TextTemplatingFileGenerator</Generator>
...@@ -42,6 +47,11 @@ ...@@ -42,6 +47,11 @@
<LastGenOutput>MultipleFiles.generated.cs</LastGenOutput> <LastGenOutput>MultipleFiles.generated.cs</LastGenOutput>
</None> </None>
<None Update="TypeScript.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>TypeScript.generated.ts</LastGenOutput>
</None>
<Compile Update="MultipleFiles.generated.cs"> <Compile Update="MultipleFiles.generated.cs">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
......
//---------------------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by T4Model template for T4 (https://github.com/linq2db/linq2db).
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//---------------------------------------------------------------------------------------------------
import { ISomething, format, g, sealed, configurable } from "./include"
export class TestClass1 {
@format("test")
public numberValue: number = 12345;
public stringValue: string;
//Begin Test Region
// <summary>
// 123
// </summary>
public Field1?: number;
public Field221: string;
//End Test Region
//Begin Test Region 2
public Field12: boolean; // Field3 comnt
get PField23(): string { // Fieomment
return null;
}
@configurable(true)
set PField23(value: string) { // Fieomment
//some setter
}
//End Test Region 2
}
@sealed
export class TestClass2 extends TestClass1 implements ISomething {
@g()
public something(val?: number): void { // This is method comment
//line1
//line2
}
}
<#@ template language="C#" debug="True" hostSpecific="True" #>
<#@ output extension=".generated.ts" #>
<#@ include file="..\..\Source\LinqToDB.Templates\T4Model.ttinclude" #>
<#@ include file="..\..\Source\LinqToDB.Templates\TypeScript.ttinclude" #>
<#
Model.Namespaces[0].Usings.Add("import { ISomething, format, g, sealed, configurable } from \"./include\"");
Model.Namespaces[0].Types.Add(new Class
{
Name = "TestClass1",
Members =
{
new Property ("number", "numberValue") { InitValue = "12345", Attributes = { new Attribute("format", "\"test\"") }},
new Property ("string", "stringValue"),
new MemberGroup
{
Region = "Test Region",
IsCompact = true,
Members =
{
new Field
{
Type = "number",
Name = "Field1",
Comment = { " <summary>", " 123", " </summary>" },
IsOptional = true
},
new Property
{
Type = "string",
Name = "Field221",
}
}
},
new MemberGroup
{
Region = "Test Region 2",
IsCompact = true,
Members =
{
new Field ("boolean", "Field12") { EndLineComment = "Field3 comnt" },
new Property("string", "PField23", new[] { "return null;" }, new[] { "//some setter" }) { EndLineComment = "Fieomment", SetAttributes = { new Attribute("configurable", "true") } },
}
},
}
});
Model.Namespaces[0].Types.Add(new Class
{
Name = "TestClass2",
BaseClass = "TestClass1",
Interfaces = { "ISomething" },
Attributes = { new Attribute("sealed") },
Members =
{
new Method("void", "something", new [] {"val?: number"}, new []{"//line1", "//line2"}) {EndLineComment = "This is method comment", Attributes = { new Attribute("g", "") }}
}
});
GenerateModel();
#>
export function format(formatString: string) {
return function (target, propertyKey: string) {
console.log("format(): called");
}
}
export function getFormat(target: any, propertyKey: string) {
//return Reflect.getMetadata(formatMetadataKey, target, propertyKey);
}
export interface ISomething {
something(val?: number);
}
export function g() {
console.log("g(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("g(): called");
}
}
export function sealed(constructor?: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
export function configurable(value: boolean) {
return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.configurable = value;
};
}
{
"compilerOptions": {
"noImplicitAny": false,
"noEmitOnError": true,
"removeComments": false,
"sourceMap": true,
"target": "es5",
"experimentalDecorators": true
},
"exclude": [
"node_modules",
"wwwroot"
]
}
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio 15
VisualStudioVersion = 15.0.27130.2027 VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{885042E3-18EA-4927-B1CF-5E0E3DBD1C00}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{885042E3-18EA-4927-B1CF-5E0E3DBD1C00}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
...@@ -51,6 +51,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LinqToDB.Templates", "LinqT ...@@ -51,6 +51,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LinqToDB.Templates", "LinqT
Source\LinqToDB.Templates\PluralizationService.ttinclude = Source\LinqToDB.Templates\PluralizationService.ttinclude Source\LinqToDB.Templates\PluralizationService.ttinclude = Source\LinqToDB.Templates\PluralizationService.ttinclude
Source\LinqToDB.Templates\README.md = Source\LinqToDB.Templates\README.md Source\LinqToDB.Templates\README.md = Source\LinqToDB.Templates\README.md
Source\LinqToDB.Templates\T4Model.ttinclude = Source\LinqToDB.Templates\T4Model.ttinclude Source\LinqToDB.Templates\T4Model.ttinclude = Source\LinqToDB.Templates\T4Model.ttinclude
Source\LinqToDB.Templates\TypeScript.ttinclude = Source\LinqToDB.Templates\TypeScript.ttinclude
Source\LinqToDB.Templates\Validation.ttinclude = Source\LinqToDB.Templates\Validation.ttinclude Source\LinqToDB.Templates\Validation.ttinclude = Source\LinqToDB.Templates\Validation.ttinclude
EndProjectSection EndProjectSection
EndProject EndProject
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册