├── TypescriptParser
├── packages.config
├── Generics.cs
├── Details.cs
├── Arguments.cs
├── Parameter.cs
├── TTypeClassDeclaration.cs
├── Field.cs
├── GenericDeclaration.cs
├── NamedType.cs
├── MethodOrDelegate.cs
├── Type.cs
├── Properties
│ └── AssemblyInfo.cs
├── TypescriptParser.csproj
├── Namespace.cs
├── TypeDeclaration.cs
└── MTypescriptParser.cs
├── TypescriptToCS
├── packages.config
├── App.config
├── Properties
│ └── AssemblyInfo.cs
├── TypescriptToCS.csproj
├── Program.cs
└── TypescriptToCSConverter.cs
├── README.md
├── LICENSE
├── TypescriptParser.sln
├── .gitattributes
└── .gitignore
/TypescriptParser/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/TypescriptToCS/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/TypescriptToCS/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TypescriptToCS2
2 |
3 | [](https://gitter.im/TypescriptToCS2/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4 |
5 | This will probably now be replace by Retyped.
6 |
--------------------------------------------------------------------------------
/TypescriptParser/Generics.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace TypescriptParser
8 | {
9 | public class Generics
10 | {
11 | public List Generic;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/TypescriptParser/Details.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace TypescriptParser
4 | {
5 | public class Details
6 | {
7 | public Dictionary paramDescription = new Dictionary();
8 | public string returns;
9 | public string summary;
10 | }
11 | }
--------------------------------------------------------------------------------
/TypescriptParser/Arguments.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace TypescriptParser
5 | {
6 | public class Arguments
7 | {
8 | public List Parameters;
9 |
10 | public void FindTypeReference (Action toRun)
11 | {
12 | Parameters?.ForEach(v => toRun(v.Type));
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/TypescriptParser/Parameter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace TypescriptParser
8 | {
9 | public class Parameter
10 | {
11 | public Type Type;
12 | public string Name;
13 | public bool Optional;
14 | public bool Params;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/TypescriptParser/TTypeClassDeclaration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace TypescriptParser
8 | {
9 | public class TTypeDeclaration
10 | {
11 | public string Name;
12 | public Type Type;
13 | public GenericDeclaration GenericDeclaration;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/TypescriptParser/Field.cs:
--------------------------------------------------------------------------------
1 | namespace TypescriptParser
2 | {
3 | public class Field
4 | {
5 | public Type type;
6 | public string name;
7 | public bool @readonly;
8 | public bool @static;
9 | public bool optional;
10 | public bool UsesNameAttribute;
11 | public string orgName;
12 | public string template;
13 | public Type ExplicitString;
14 | public Details details;
15 | }
16 | }
--------------------------------------------------------------------------------
/TypescriptParser/GenericDeclaration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace TypescriptParser
8 | {
9 | public class GenericDeclaration
10 | {
11 | public List Generics = new List();
12 | public Dictionary GenericsEquals = new Dictionary();
13 | public Dictionary> Wheres = new Dictionary>();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/TypescriptParser/NamedType.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace TypescriptParser
8 | {
9 | public class NamedType : Type
10 | {
11 | public string[] PreDots;
12 | public string Name;
13 | public Generics Generics;
14 | public TypeDeclaration TypeDeclaration;
15 | public MethodOrDelegate ReferenceDelegates;
16 | public TTypeDeclaration ReferenceTTypes;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/TypescriptParser/MethodOrDelegate.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace TypescriptParser
4 | {
5 | public class MethodOrDelegate
6 | {
7 | public string Name;
8 | public bool Static;
9 | public bool Indexer;
10 | public Arguments Arguments;
11 | public Type ReturnType;
12 | public GenericDeclaration GenericDeclaration;
13 | public bool UsesNameAttribute;
14 | public bool Readonly;
15 | public string orgName;
16 | public Type ExplicitString;
17 | public Details Details;
18 | }
19 | }
--------------------------------------------------------------------------------
/TypescriptParser/Type.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 |
3 | namespace TypescriptParser
4 | {
5 | public class Type
6 | {
7 | public static bool Equals (Type a, Type b)
8 | {
9 | if (a is NamedType namedTypeA)
10 | {
11 | if (!(b is NamedType namedTypeB))
12 | return false;
13 | if (namedTypeA.Name != namedTypeB.Name)
14 | return false;
15 | int count = (namedTypeA.Generics?.Generic?.Count ?? 0);
16 | if (count != (namedTypeB.Generics?.Generic?.Count ?? 0))
17 | return false;
18 | if (count == 0)
19 | return true;
20 | if (!namedTypeA.Generics.Generic.SequenceEqual(namedTypeB.Generics.Generic))
21 | return false;
22 | }
23 | return true;
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Michael Cheers
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/TypescriptToCS/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("TypescriptToCS")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TypescriptToCS")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("5bb02233-d60d-47e3-9ccf-ad3a3b0bc2ce")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/TypescriptParser/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("TypescriptParser")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("TypescriptParser")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("944dc173-20e0-4923-83f6-804d2708f0ed")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/TypescriptParser.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26403.7
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypescriptParser", "TypescriptParser\TypescriptParser.csproj", "{944DC173-20E0-4923-83F6-804D2708F0ED}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TypescriptToCS", "TypescriptToCS\TypescriptToCS.csproj", "{5BB02233-D60D-47E3-9CCF-AD3A3B0BC2CE}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {944DC173-20E0-4923-83F6-804D2708F0ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {944DC173-20E0-4923-83F6-804D2708F0ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {944DC173-20E0-4923-83F6-804D2708F0ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {944DC173-20E0-4923-83F6-804D2708F0ED}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {5BB02233-D60D-47E3-9CCF-AD3A3B0BC2CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {5BB02233-D60D-47E3-9CCF-AD3A3B0BC2CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {5BB02233-D60D-47E3-9CCF-AD3A3B0BC2CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {5BB02233-D60D-47E3-9CCF-AD3A3B0BC2CE}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/TypescriptToCS/TypescriptToCS.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {5BB02233-D60D-47E3-9CCF-AD3A3B0BC2CE}
8 | Exe
9 | TypescriptToCS
10 | TypescriptToCS
11 | v4.6.2
12 | 512
13 | true
14 |
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 |
39 | ..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | {944dc173-20e0-4923-83f6-804d2708f0ed}
60 | TypescriptParser
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/TypescriptParser/TypescriptParser.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {944DC173-20E0-4923-83F6-804D2708F0ED}
8 | Library
9 | Properties
10 | TypescriptParser
11 | TypescriptParser
12 | v4.6.2
13 | 512
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 | ..\packages\System.ValueTuple.4.3.1\lib\netstandard1.0\System.ValueTuple.dll
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
73 |
--------------------------------------------------------------------------------
/TypescriptParser/Namespace.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace TypescriptParser
6 | {
7 | public class Namespace
8 | {
9 | public List namespaces = new List();
10 | public List classes = new List();
11 | public List delegates = new List();
12 | public List ttypes = new List();
13 | public TypeDeclaration GlobalClass = new TypeDeclaration
14 | {
15 | name = "Global",
16 | fields = new List(),
17 | methods = new List(),
18 | delegates = new List(),
19 | nested = new List(),
20 | GenericDeclaration = new GenericDeclaration(),
21 | implements = new List(),
22 | kind = TypeDeclaration.Kind.Class,
23 | @static = true
24 | };
25 |
26 | public Namespace() { GlobalClass.upperNamespace = this; }
27 |
28 | public string name;
29 | public Namespace UpNamespace;
30 |
31 | public void ForeachType (Action @do, bool nested = true)
32 | {
33 | if (nested)
34 | namespaces?.ForEach(v => v.ForeachType(@do));
35 | classes?.ForEach(v => v.ForeachType(@do));
36 | }
37 |
38 | public void ForeachType (Action @do)
39 | {
40 | namespaces?.ForEach(v => v.ForeachType(@do));
41 | ttypes?.ForEach(@do);
42 | }
43 |
44 | public void ForeachType(Action @do)
45 | {
46 | namespaces?.ForEach(v => v.ForeachType(@do));
47 | delegates?.ForEach(@do);
48 | ForeachType(v => v.delegates?.ForEach(@do));
49 | }
50 | public List FindTypeName(string finding, HashSet remove, bool nested = true)
51 | {
52 | List result = new List();
53 | ForeachType(v =>
54 | {
55 | if (v.name == finding && !remove.Contains(v))
56 | result.Add(v);
57 | }, nested);
58 | return result;
59 | }
60 | public void ForeachTypeReference (Action toRun)
61 | {
62 | ForeachType(v => v.FindTypeReference(toRun));
63 | }
64 | public (List typesFound, List tTypesFound, List delegatesFound) FindType (NamedType finding, HashSet remove)
65 | {
66 | List typesFound = new List();
67 | List tTypesFound = new List();
68 | List delegatesFound = new List();
69 | ForeachType(@class =>
70 | {
71 | if (@class.GenericDeclaration?.Generics?.Count == finding.Generics?.Generic?.Count)
72 | if (@class.name == finding.Name)
73 | typesFound.Add(@class);
74 | });
75 | ForeachType(@delegate =>
76 | {
77 | if ((finding.Generics?.Generic?.Count ?? 0) == (@delegate.GenericDeclaration?.Generics?.Count ?? 0))
78 | if (@delegate.Name == finding.Name)
79 | delegatesFound.Add(@delegate);
80 | });
81 | ForeachType(tType =>
82 | {
83 | if (tType.Name == finding.Name)
84 | tTypesFound.Add(tType);
85 | });
86 | return (typesFound, tTypesFound, delegatesFound);
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/TypescriptParser/TypeDeclaration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace TypescriptParser
6 | {
7 | public class TypeDeclaration
8 | {
9 | public bool IsUnion;
10 | public List fields;
11 | public List methods;
12 | public List nested;
13 | public List delegates;
14 | public List implements;
15 | public bool IsStringLiteralEnum;
16 | public GenericDeclaration GenericDeclaration;
17 | public Details details;
18 | public string name;
19 | public string orgName;
20 | public Kind kind;
21 | public bool @static;
22 | public bool UsesNameAttribute;
23 | public Namespace upperNamespace;
24 |
25 | public enum Kind
26 | {
27 | Class,
28 | Interface,
29 | Struct,
30 | Enum
31 | }
32 |
33 | public void ForeachType (Action @do)
34 | {
35 | nested?.ForEach(v => v.ForeachType(@do));
36 | @do(this);
37 | }
38 | public (List, List) FindClassMembers(string name)
39 | {
40 | List fields = new List();
41 | List methods = new List();
42 | if (this.fields != null)
43 | fields.AddRange(this.fields?.Where(field => field.name == name));
44 | if (this.methods != null)
45 | methods.AddRange(this.methods.Where(method => method.Name == name));
46 | return (fields, methods);
47 | }
48 |
49 | public List FindSharedInterfaces (TypeDeclaration b)
50 | {
51 | bool IsObjectOrInterface (NamedType v) =>
52 | v.TypeDeclaration?.kind == Kind.Interface;
53 | var ancestorsA = AncestorTypes.Where(IsObjectOrInterface);
54 | var ancestorsB = b.AncestorTypes.Where(IsObjectOrInterface);
55 | List intersected = new List();
56 | foreach (var ancestor in ancestorsA)
57 | {
58 | foreach (var ancestorB in ancestorsB)
59 | {
60 | if (ancestor.Name == ancestorB.Name)
61 | {
62 | intersected.Add(ancestor);
63 | break;
64 | }
65 | }
66 | }
67 | return intersected;
68 | }
69 |
70 | public List AncestorTypes
71 | {
72 | get
73 | {
74 | List result = new List();
75 | result.Add(new NamedType
76 | {
77 | Name = name,
78 | TypeDeclaration = this
79 | });
80 | implements?.ForEach(v =>
81 | {
82 | if (v is NamedType namedType)
83 | if (namedType.TypeDeclaration != null)
84 | result.AddRange(namedType.TypeDeclaration.AncestorTypes);
85 | });
86 | return result;
87 | }
88 | }
89 |
90 | public void FindTypeReference (Action toRun)
91 | {
92 | if (methods != null)
93 | foreach (var method in methods)
94 | {
95 | method.Arguments?.FindTypeReference(toRun);
96 | toRun(method.ReturnType);
97 | }
98 | fields?.ForEach(v => toRun(v.type));
99 | implements?.ForEach(toRun);
100 | if (delegates != null)
101 | foreach (var @delegate in delegates)
102 | {
103 | toRun(@delegate.ReturnType);
104 | @delegate.Arguments?.FindTypeReference(toRun);
105 | }
106 | }
107 | }
108 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/TypescriptToCS/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using TypescriptParser;
8 |
9 | namespace TypescriptToCS
10 | {
11 | public enum ConversionSoftware
12 | {
13 | DuoCode,
14 | Bridge
15 | }
16 | class Program
17 | {
18 | static void Main(string[] args)
19 | {
20 | Console.WriteLine("Starting...");
21 | string location = args.Length > 0 ? args[0] : Console.ReadLine();
22 | const string argStart = "--converter:";
23 | string converterV = args.FirstOrDefault(v => v.StartsWith(argStart));
24 | if (converterV == null)
25 | Console.WriteLine(@"What software would you like to convert for?
26 | Currently Supported:
27 | Bridge,
28 | DuoCode");
29 | string converterValue = converterV == null ? Console.ReadLine() : converterV.Substring(argStart.Length);
30 | ConversionSoftware conversionSoftware = (ConversionSoftware)Enum.Parse(typeof(ConversionSoftware), converterValue);
31 | string file;
32 | Console.WriteLine("Reading file...");
33 | try
34 | {
35 | file = File.ReadAllText(location);
36 | }
37 | catch (Exception e)
38 | {
39 | Console.WriteLine(e.Message);
40 | return;
41 | }
42 | var parser = new MTypescriptParser
43 | {
44 | ParseString = file
45 | };
46 | Console.WriteLine("Parsing...");
47 | parser.Parse();
48 | Namespace globalNamespace = parser.globalNamespace;
49 | var converter = new TypescriptToCSConverter(conversionSoftware);
50 | globalNamespace.classes.AddRange(new[]
51 | {
52 | new TypeDeclaration
53 | {
54 | name = "NullType"
55 | },
56 | new TypeDeclaration
57 | {
58 | name = "UndefinedType",
59 | fields = new List
60 | {
61 | new Field
62 | {
63 | name = "Undefined",
64 | @readonly = true,
65 | @static = true,
66 | template = "undefined",
67 | type = new NamedType
68 | {
69 | Name = "UndefinedType"
70 | }
71 | }
72 | }
73 | },
74 | new TypeDeclaration
75 | {
76 | name = "VoidType",
77 | implements = new List
78 | {
79 | new NamedType{Name = "UndefinedType"}
80 | }
81 | },
82 | new TypeDeclaration
83 | {
84 | name = "Symbol",
85 | methods = new List
86 | {
87 | new MethodOrDelegate
88 | {
89 | Arguments = new Arguments
90 | {
91 | Parameters = new List
92 | {
93 | new Parameter
94 | {
95 | Name = "value",
96 | Type = new NamedType
97 | {
98 | Name = "string"
99 | }
100 | }
101 | }
102 | },
103 | Name = "constructor"
104 | },
105 | new MethodOrDelegate
106 | {
107 | Name = "constructor"
108 | }
109 | }
110 | }
111 | });
112 | converter.globalNamespace = globalNamespace;
113 | //Console.WriteLine("Dotting...");
114 | //globalNamespace.ForeachTypeReference(v =>
115 | //{
116 | // NamedType namedType = v as NamedType;
117 | // if (string.IsNullOrEmpty(namedType?.Name))
118 | // return;
119 | // string[] dots = namedType.Name.Split('.');
120 | // string[] preDots = new string[dots.Length - 1];
121 | // Array.Copy(dots, preDots, dots.Length - 1);
122 | // namedType.PreDots = preDots;
123 | // namedType.Name = dots.Last();
124 | //});
125 | //Console.WriteLine("Merging...");
126 | //converter.MergeEnums(globalNamespace);
127 | //converter.RemoveAll(globalNamespace);
128 | Console.WriteLine("Referencing...");
129 | globalNamespace.ForeachTypeReference(converter.Reference);
130 | globalNamespace.ForeachType(v => converter.Reference(v.Type));
131 | Console.WriteLine("Unioning...");
132 | parser.Unions.ForEach(v =>
133 | {
134 | var typeA = v.Generics.Generic[0] as NamedType;
135 | var typeB = v.Generics.Generic[1] as NamedType;
136 | var typeDeclA = typeA.TypeDeclaration;
137 | var typeDeclB = typeB.TypeDeclaration;
138 | NamedType result;
139 | if (typeDeclA == null || typeDeclB == null)
140 | result = new NamedType
141 | {
142 | Name = "object"
143 | };
144 | else
145 | {
146 | var shared = typeDeclA.FindSharedInterfaces(typeDeclB).Cast().ToList();
147 | shared.Insert(0, new NamedType
148 | {
149 | Name = "Union",
150 | Generics = new Generics
151 | {
152 | Generic = new List
153 | {
154 | typeA, typeB
155 | }
156 | }
157 | });
158 | string name = "Union_" + converter.Convert(typeA) + "_" + converter.Convert(typeB);
159 | TypeDeclaration @ref = null;
160 | globalNamespace.ForeachType(v2 => @ref = v2.name == name ? v2 : @ref);
161 | bool create = @ref == null;
162 | if (create)
163 | @ref = new TypeDeclaration
164 | {
165 | name = name,
166 | implements = shared,
167 | IsUnion = true,
168 | GenericDeclaration = new GenericDeclaration
169 | {
170 | Generics = new List {"A", "B"}
171 | }
172 | };
173 | v.Name = name;
174 | v.TypeDeclaration = @ref;
175 | if (create)
176 | globalNamespace.classes.Add(@ref);
177 | }
178 | });
179 | Console.WriteLine("Renaming...");
180 | globalNamespace.ForeachType((Action)(typeDeclaration =>
181 | {
182 | var delegatesFound = globalNamespace.FindType(new NamedType
183 | {
184 | Name = typeDeclaration.Name,
185 | Generics = new Generics
186 | {
187 | Generic = typeDeclaration.GenericDeclaration.Generics.ConvertAll(v2 => new NamedType { Name = v2 })
188 | }
189 | }, converter.remove).delegatesFound;
190 | if (delegatesFound.Count > 1)
191 | typeDeclaration.Name += "_" + delegatesFound.Count;
192 | }));
193 | Console.WriteLine("Removing duplicate fields...");
194 | converter.RemoveDuplicateFields();
195 | Console.WriteLine("Translating...");
196 | List toAdd = new List();
197 | globalNamespace.ForeachType(v => toAdd.AddRange(converter.Translate(v)));
198 | globalNamespace.ForeachType(v => converter.Cleanse(v.Type, v.GenericDeclaration, null));
199 | globalNamespace.classes.AddRange(toAdd);
200 | converter.remove.Clear();
201 | globalNamespace.ForeachType(converter.DeleteUnneededTypes);
202 | converter.RemoveAll(globalNamespace);
203 | Console.WriteLine("Writing C#...");
204 | //converter.ConvertUsingStatements(globalNamespace);
205 | converter.Result.Append(conversionSoftware == ConversionSoftware.Bridge ? "using Bridge;" : "using DuoCode.Runtime;");
206 | converter.Result.Append(
207 | @"
208 | //using number = System.Double;
209 | //using any = Bridge.Union;
210 | //using boolean = System.Boolean;
211 | #pragma warning disable CS0626
212 | #pragma warning disable CS0824
213 | //[assembly: Convention(Notation.LowerCamelCase)]
214 | ");
215 | converter.Convert(globalNamespace, false);
216 | Console.WriteLine("Writing...");
217 | File.WriteAllText($"{Path.GetFileNameWithoutExtension(location)}.cs", converter.Result.ToString());
218 | Console.WriteLine("Exiting...");
219 | }
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/TypescriptParser/MTypescriptParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace TypescriptParser
6 | {
7 | public class MTypescriptParser
8 | {
9 | public Namespace globalNamespace;
10 | public int index;
11 | public Namespace currentNamespace;
12 | public TypeDeclaration currentClass;
13 | public string ParseString;
14 | public char Current => CharAt(index);
15 | public Stack restorePoints = new Stack();
16 |
17 | public void CreateRestorePoint()
18 | {
19 | restorePoints.Push(index);
20 | }
21 |
22 | public void Restore ()
23 | {
24 | index = restorePoints.Pop();
25 | }
26 |
27 | public bool CurrentIs(char value)
28 | {
29 | SkipEmpty();
30 | return Current == value;
31 | }
32 |
33 | public bool GoForwardIf(char value)
34 | {
35 | SkipEmpty();
36 | bool result = CurrentIs(value);
37 | if (result)
38 | GoForwardOne();
39 | return result;
40 | }
41 |
42 | public bool CurrentIs(string value)
43 | {
44 | SkipEmpty();
45 | for (int n = 0; n < value.Length; n++)
46 | if (CharAt(index + n) != (value[n]))
47 | return false;
48 | return true;
49 | }
50 |
51 | public bool GoForwardIf(string value)
52 | {
53 | SkipEmpty();
54 | for (int n = 0; n < value.Length; n++)
55 | {
56 | if (!CurrentIs(value[n]))
57 | {
58 | GoForward(-n);
59 | return false;
60 | }
61 | GoForwardOne();
62 | }
63 | return true;
64 | }
65 |
66 | public Details ParseComment()
67 | {
68 | if (LastComment == null)
69 | return new Details();
70 | MTypescriptParser parser = new MTypescriptParser();
71 | parser.ParseString = LastComment;
72 | Details result = new Details();
73 | string header = null;
74 | string paramName = null;
75 | while (!parser.CurrentIs('\0'))
76 | {
77 | parser.GoForwardIf('*');
78 | if (!parser.GoForwardIf('@'))
79 | {
80 | string g = string.Empty;
81 | if (!parser.CurrentIs('\0'))
82 | {
83 | parser.CreateRestorePoint();
84 | parser.InSkipEmpty = true;
85 | parser.SkipUntil(LastComment.Substring(parser.index).Contains('@') ? '@' : '\0');
86 | parser.InSkipEmpty = false;
87 | while (parser.CurrentIs('\0'))
88 | parser.index--;
89 | int oldIndex = parser.restorePoints.Pop();
90 | g = LastComment.Substring(oldIndex, parser.index - oldIndex - 1).Replace("*", "");
91 | }
92 | switch (header)
93 | {
94 | case "param":
95 | result.paramDescription.Add(paramName, g);
96 | break;
97 | case "returns":
98 | case "return":
99 | result.returns = g;
100 | break;
101 | case null:
102 | result.summary = g;
103 | break;
104 | }
105 | }
106 | parser.GoForwardIf('*');
107 | header = parser.GetWord();
108 | paramName = null;
109 | if (parser.GoForwardIf('{'))
110 | parser.SkipUntil('}');
111 | if (header == "param")
112 | paramName = parser.GetWord();
113 | }
114 | return result;
115 | }
116 |
117 | public char CharAt (int index_) => index_ < 0 || index_ >= ParseString.Length ? '\0' : ParseString[index_];
118 | public void GoForwardOne() => GoForward(1);
119 | public void GoForward(int length) => index += length;
120 | public const string spaceChars = " \t\r\n";
121 | public const string wordChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$1234567890.";
122 |
123 | public string GetWord()
124 | {
125 | string result = "";
126 | SkipEmpty();
127 | while (wordChars.Contains(Current))
128 | {
129 | result += Current;
130 | GoForwardOne();
131 | }
132 | return result;
133 | }
134 |
135 | private void SkipUntil (char value)
136 | {
137 | while (!CurrentIs(value)) GoForwardOne();
138 | GoForwardOne();
139 | }
140 |
141 | private void SkipUntil(string value)
142 | {
143 | while (!CurrentIs(value) && !CurrentIs('\0')) GoForwardOne();
144 | GoForward(value.Length);
145 | }
146 |
147 | public string LastComment;
148 |
149 | private bool SkipEmpty(bool skipComments = true)
150 | {
151 | if (InSkipEmpty)
152 | return false;
153 | InSkipEmpty = true;
154 | bool skipped = false;
155 | while (spaceChars.Contains(Current) || (CurrentIs('/') && skipComments))
156 | {
157 | if (GoForwardIf('/'))
158 | {
159 | if (GoForwardIf('/'))
160 | SkipUntil('\n');
161 | else if (GoForwardIf('*'))
162 | {
163 | bool docs;
164 | if (docs = CurrentIs("*"))
165 | CreateRestorePoint();
166 | SkipUntil("*/");
167 | if (docs)
168 | {
169 | int orgIndex = restorePoints.Pop();
170 | int nextIndex = index - 2;
171 | string subString = ParseString.Substring(orgIndex, nextIndex - orgIndex + 1);
172 | LastComment = subString;
173 | }
174 | }
175 | else
176 | throw new Exception();
177 | }
178 | else
179 | GoForwardOne();
180 | skipped = true;
181 | }
182 | InSkipEmpty = false;
183 | return skipped;
184 | }
185 | string FunctionName;
186 | bool InSkipEmpty;
187 |
188 | public TypeDeclaration ParseClass(string name, GenericDeclaration genericDeclaration, List implements, bool @interface)
189 | {
190 | if (!GoForwardIf('{'))
191 | throw new Exception();
192 | currentClass = new TypeDeclaration
193 | {
194 | fields = new List(),
195 | methods = new List(),
196 | nested = new List(),
197 | delegates = new List(),
198 | implements = implements,
199 | GenericDeclaration = genericDeclaration,
200 | name = name,
201 | kind = @interface ? TypeDeclaration.Kind.Interface : TypeDeclaration.Kind.Class,
202 | upperNamespace = currentNamespace
203 | };
204 | while (true)
205 | if (ParseClassLine())
206 | return currentClass;
207 | }
208 | public bool ParseClassLine ()
209 | {
210 | bool @readonly = false;
211 | bool @static = false;
212 | bool indexer = false;
213 | Back:
214 | bool quoted = CurrentIs('"') || CurrentIs('\'');
215 | string word;
216 | if (!quoted)
217 | word = GetWord();
218 | else
219 | {
220 | int oldIdx = index;
221 | GoForwardUntilEndBracket('"', '\'', '"', '\'');
222 | word = '\x1' + ParseString.Substring(oldIdx + 1, index - 2 - oldIdx);
223 | }
224 | switch (word)
225 | {
226 | case "":
227 | if (GoForwardIf('}'))
228 | return true;
229 | else if (CurrentIs('(') || CurrentIs('<'))
230 | goto default;
231 | else if (GoForwardIf('['))
232 | {
233 | indexer = true;
234 | goto default;
235 | }
236 | else
237 | throw new Exception();
238 | case "static":
239 | case "let":
240 | case "var":
241 | if (CurrentIs(':') || CurrentIs('(') || CurrentIs('?'))
242 | goto default;
243 | @static = true;
244 | goto Back;
245 | case "declare":
246 | if (CurrentIs(':') || CurrentIs('(') || CurrentIs('?'))
247 | goto default;
248 | goto Back;
249 | case "readonly":
250 | if (CurrentIs(':') || CurrentIs('(') || CurrentIs('?'))
251 | goto default;
252 | @readonly = true;
253 | goto Back;
254 | case "const":
255 | if (CurrentIs(':') || CurrentIs('('))
256 | goto default;
257 | @static = true;
258 | goto case "readonly";
259 | case "function":
260 | @static = true;
261 | goto Back;
262 | default:
263 | if (!string.IsNullOrEmpty(word))
264 | if (word[0] == '\x1')
265 | word = word.Substring(1);
266 | bool optional = GoForwardIf('?');
267 | var generics = ParseGenericDeclaration();
268 | Details details = ParseComment();
269 | if (GoForwardIf('(') || indexer)
270 | {
271 | Inherit.Clear();
272 | Inherit.Add(generics);
273 | Inherit.Add(currentClass.GenericDeclaration);
274 | FunctionName = word;
275 | var arguments = ParseArguments();
276 | Type returnType;
277 | if (!GoForwardIf(':'))
278 | {
279 | returnType = new NamedType
280 | {
281 | Name = "void"
282 | };
283 | goto After;
284 | }
285 | TypeDeclName = word + "_ReturnType";
286 | returnType = ParseType();
287 | After:
288 | currentClass.methods.Add(new MethodOrDelegate
289 | {
290 | Arguments = arguments,
291 | Name = word,
292 | ReturnType = returnType,
293 | Static = @static,
294 | Indexer = indexer,
295 | GenericDeclaration = generics,
296 | Readonly = @readonly,
297 | Details = details
298 | });
299 | }
300 | else if (GoForwardIf(':'))
301 | {
302 | TypeDeclName = word + "_Type";
303 | Inherit.Clear();
304 | Inherit.Add(currentClass.GenericDeclaration);
305 | currentClass.fields.Add(new Field
306 | {
307 | name = word,
308 | type = ParseType(),
309 | @readonly = @readonly,
310 | @static = @static,
311 | optional = optional,
312 | details = details
313 | });
314 | }
315 | else throw new Exception();
316 | GoForwardIf(',');
317 | GoForwardIf(';');
318 | //if (!GoForwardIf(';'))
319 | // throw new Exception();
320 | break;
321 | }
322 | LastComment = null;
323 | return false;
324 | }
325 | string TypeDeclName;
326 |
327 | public Arguments ParseArguments()
328 | {
329 | Arguments result = new Arguments
330 | {
331 | Parameters = new List()
332 | };
333 | while (true)
334 | {
335 | bool optional = false;
336 | bool @params = GoForwardIf("...");
337 | string name = GetWord();
338 | if (GoForwardIf(')') || GoForwardIf(']'))
339 | break;
340 | if (GoForwardIf('?'))
341 | optional = true;
342 | if (!GoForwardIf(':'))
343 | throw new Exception();
344 | TypeDeclName = $"{FunctionName}_Param_{name}";
345 | result.Parameters.Add(new Parameter
346 | {
347 | Name = name,
348 | Optional = optional,
349 | Params = @params,
350 | Type = ParseType()
351 | });
352 | GoForwardIf(',');
353 | }
354 | return result;
355 | }
356 |
357 | public List Unions = new List();
358 |
359 | public Type ParseType()
360 | {
361 | Type typeResult = ParseTypeLevel1();
362 | if (GoForwardIf('|'))
363 | {
364 | TypeDeclName += "_UnionRight";
365 | var type2 = ParseType();
366 | typeResult = new NamedType
367 | {
368 | Name = "Union",
369 | Generics = new Generics
370 | {
371 | Generic = new List
372 | {
373 | typeResult,
374 | type2
375 | }
376 | }
377 | };
378 | Unions.Add(typeResult as NamedType);
379 | }
380 | else if (GoForwardIf('&'))
381 | {
382 | TypeDeclName += "_IntersectionRight";
383 | typeResult = new NamedType
384 | {
385 | Name = "Intersection",
386 | Generics = new Generics
387 | {
388 | Generic = new List
389 | {
390 | typeResult,
391 | ParseType()
392 | }
393 | }
394 | };
395 | }
396 | return typeResult;
397 | }
398 |
399 | public Type ParseTypeLevel1 ()
400 | {
401 | Type result = ParseTypeLevel2();
402 | while (GoForwardIf('['))
403 | {
404 | if (!GoForwardIf(']'))
405 | throw new Exception();
406 | result = new NamedType
407 | {
408 | Name = "Array`",
409 | Generics = new Generics
410 | {
411 | Generic = new List
412 | {
413 | result
414 | }
415 | }
416 | };
417 | }
418 | return result;
419 | }
420 |
421 | public Type CreateStringLiteralType (string name)
422 | {
423 | string actName = TypeDeclName + "_" + name.Replace('.', '_');
424 | TypeDeclaration @class;
425 | (currentClass?.nested ?? currentNamespace.classes).Add(@class = new TypeDeclaration
426 | {
427 | kind = TypeDeclaration.Kind.Enum,
428 | IsStringLiteralEnum = true,
429 | name = actName,
430 | fields = new List
431 | {
432 | new Field
433 | {
434 | name = name
435 | }
436 | },
437 | upperNamespace = currentNamespace
438 | });
439 | return new NamedType
440 | {
441 | Name = actName,
442 | TypeDeclaration = @class
443 | };
444 | }
445 |
446 | public Type ParseTypeLevel2 ()
447 | {
448 | bool @typeof = false;
449 | if (GoForwardIf("typeof"))
450 | @typeof = true;
451 | Type resultType = ParseTypeLevel3();
452 | if (@typeof)
453 | {
454 | if (!(resultType is NamedType namedType))
455 | throw new Exception();
456 | return CreateStringLiteralType(namedType.Name);
457 | }
458 | return resultType;
459 | }
460 | public List Inherit = new List();
461 |
462 | public Type ParseTypeLevel3 ()
463 | {
464 | Type resultType = null;
465 | string word = GetWord();
466 | switch (word)
467 | {
468 | case "":
469 | case "new":
470 | if (CurrentIs('(') || CurrentIs('<'))
471 | {
472 | bool function = true;
473 | if (!CurrentIs('<'))
474 | {
475 | CreateRestorePoint();
476 | GoForwardUntilEndBracket('(', ')');
477 | function = GoForwardIf("=>");
478 | Restore();
479 | }
480 | if (function)
481 | {
482 | string org = TypeDeclName;
483 | GenericDeclaration genericDeclaration = ParseGenericDeclaration();
484 | var newGen = new HashSet();
485 | foreach (var item in Inherit)
486 | item.Generics.ForEach(v => newGen.Add(v));
487 | genericDeclaration.Generics.AddRange(newGen);
488 | GoForwardOne();
489 | Inherit.Add(genericDeclaration);
490 | var arguments = ParseArguments();
491 | Inherit.RemoveAt(Inherit.Count - 1);
492 | if (!GoForwardIf("=>"))
493 | throw new Exception();
494 | org += "_ReturnType";
495 | TypeDeclName = org;
496 | var returnType = ParseType();
497 | MethodOrDelegate newType;
498 | (currentClass?.delegates ?? currentNamespace.delegates).Add(newType = new MethodOrDelegate
499 | {
500 | Arguments = arguments,
501 | ReturnType = returnType,
502 | Name = TypeDeclName,
503 | GenericDeclaration = genericDeclaration
504 | });
505 | resultType = new NamedType
506 | {
507 | Name = org,
508 | ReferenceDelegates = newType,
509 | Generics = new Generics
510 | {
511 | Generic = newGen.ToList().ConvertAll(v => new NamedType
512 | {
513 | Name = v
514 | })
515 | }
516 | };
517 | }
518 | else
519 | {
520 | GoForwardOne();
521 | resultType = ParseType();
522 | if (!GoForwardIf(')'))
523 | throw new Exception();
524 | }
525 | return resultType;
526 | }
527 | else if (CurrentIs('{'))
528 | {
529 | string org = TypeDeclName;
530 | TypeDeclaration created;
531 | var old = currentClass;
532 | (currentClass?.nested ?? currentNamespace.classes).Add(created = ParseClass(org, new GenericDeclaration(), new List(), true));
533 | currentClass = old;
534 | return new NamedType
535 | {
536 | Generics = new Generics
537 | {
538 | Generic = new List()
539 | },
540 | Name = org,
541 | TypeDeclaration = created
542 | };
543 | }
544 | else if (GoForwardIf('['))
545 | {
546 | List types = new List();
547 | string org = TypeDeclName;
548 | int n = 0;
549 | do
550 | {
551 | TypeDeclName = org + "_TupleParam" + n;
552 | types.Add(ParseType());
553 | ++n;
554 | }
555 | while (GoForwardIf(','));
556 | if (!GoForwardIf(']'))
557 | throw new Exception();
558 | return new NamedType
559 | {
560 | Generics = new Generics
561 | {
562 | Generic = types
563 | },
564 | Name = "Tuple"
565 | };
566 | }
567 | else if (CurrentIs('"') || CurrentIs('\''))
568 | {
569 | var oldIdx = index;
570 | GoForwardUntilEndBracket('"', '\'', '"', '\'');
571 | int gIdx = index - 2 - oldIdx;
572 | var stringLiteral = gIdx <= 0 ? string.Empty : ParseString.Substring(oldIdx + 1, gIdx);
573 | return CreateStringLiteralType(stringLiteral);
574 | }//
575 | throw new NotImplementedException();
576 | default:
577 | List dotsSplit = word.Split('.').ToList();
578 | string shortName = dotsSplit[dotsSplit.Count - 1];
579 | dotsSplit.RemoveAt(dotsSplit.Count - 1);
580 | List generics = new List();
581 | if (GoForwardIf('<'))
582 | {
583 | do
584 | generics.Add(ParseType());
585 | while (GoForwardIf(','));
586 | if (!GoForwardIf('>'))
587 | throw new Exception();
588 | }
589 | if (GoForwardIf("is"))
590 | {
591 | shortName = "boolean";
592 | dotsSplit.Clear();
593 | ParseType();
594 | }
595 | return new NamedType
596 | {
597 | Name = shortName,
598 | PreDots = dotsSplit.ToArray(),
599 | Generics = new Generics
600 | {
601 | Generic = generics
602 | }
603 | };
604 | }
605 | }
606 |
607 | public void GoForwardUntilEndBracket (params char[] inputArray)
608 | {
609 | List asList = new List(inputArray);
610 | char[] open = new char[inputArray.Length / 2];
611 | Array.Copy(inputArray, open, inputArray.Length / 2);
612 | asList.RemoveRange(0, inputArray.Length / 2);
613 | char[] closed = asList.ToArray();
614 | if (open.Contains('"'))
615 | InSkipEmpty = true;
616 | int parantheses = 0;
617 | do
618 | {
619 | if (open.Contains(Current) && (!open.All(v => closed.Contains(v)) || parantheses == 0))
620 | parantheses++;
621 | else if (closed.Contains(Current))
622 | parantheses--;
623 | GoForwardOne();
624 | } while (parantheses != 0);
625 | InSkipEmpty = false;
626 | }
627 |
628 | public GenericDeclaration ParseGenericDeclaration ()
629 | {
630 | var genericDeclaration = new GenericDeclaration();
631 | if (GoForwardIf('<'))
632 | {
633 | while (!GoForwardIf('>'))
634 | {
635 | string genericName = GetWord();
636 | if (GoForwardIf('='))
637 | {
638 | string genericName2 = GetWord();
639 | genericDeclaration.GenericsEquals.Add(genericName, genericName2);
640 | }
641 | else
642 | {
643 | genericDeclaration.Generics.Add(genericName);
644 | if (!genericDeclaration.Wheres.ContainsKey(genericName))
645 | genericDeclaration.Wheres.Add(genericName, new List());
646 | while (GoForwardIf("extends") || GoForwardIf("implements"))
647 | genericDeclaration.Wheres[genericName].Add(ParseType());
648 | }
649 | GoForwardIf(',');
650 | }
651 | }
652 | return genericDeclaration;
653 | }
654 |
655 | public void Parse()
656 | {
657 | globalNamespace = currentNamespace = new Namespace
658 | {
659 | name = "Global"
660 | };
661 | globalNamespace.classes.Add(globalNamespace.GlobalClass);
662 | while (true)
663 | {
664 | Back:
665 | if (CurrentIs('\0'))
666 | return;
667 | string word = GetWord();
668 | switch (word)
669 | {
670 | case "namespace":
671 | case "module":
672 | string name = GetWord();
673 | if (!GoForwardIf('{'))
674 | throw new Exception();
675 | var @namespace = new Namespace
676 | {
677 | name = name,
678 | UpNamespace = currentNamespace
679 | };
680 | @namespace.classes.Add(@namespace.GlobalClass);
681 | currentNamespace.namespaces.Add(@namespace);
682 | currentNamespace = @namespace;
683 | break;
684 | case "declare":
685 | case "export":
686 | goto Back;
687 | case "const":
688 | case "function":
689 | case "var":
690 | case "let":
691 | GoForward(-word.Length);
692 | currentClass = currentNamespace.GlobalClass;
693 | if (ParseClassLine())
694 | throw new Exception();
695 | break;
696 | case "type":
697 | currentClass = null;
698 | string typeName = TypeDeclName = GetWord();
699 | bool generic = CurrentIs('<');
700 | Inherit.Clear();
701 | GenericDeclaration genericDeclaration = ParseGenericDeclaration();
702 | if (!GoForwardIf('='))
703 | throw new Exception();
704 | Inherit.Add(genericDeclaration);
705 | var type = ParseType();
706 | bool created = false;
707 | if (type is NamedType namedType)
708 | if (namedType.Name == typeName)
709 | created = true;
710 | if (generic && created)
711 | currentNamespace.classes.Last(v => v.name == typeName).GenericDeclaration = genericDeclaration;
712 | if (!created)
713 | currentNamespace.ttypes.Add(new TTypeDeclaration
714 | {
715 | Name = typeName,
716 | Type = type,
717 | GenericDeclaration = genericDeclaration
718 | });
719 | if (!GoForwardIf(';'))
720 | throw new Exception();
721 | break;
722 | case "interface":
723 | case "class":
724 | var interfaceName = GetWord();
725 | var implements = new List();
726 | var genericDeclaration2 = ParseGenericDeclaration();
727 | Inherit.Clear();
728 | Inherit.Add(genericDeclaration2);
729 | while (GoForwardIf("extends") || GoForwardIf("implements"))
730 | {
731 | do implements.Add(ParseType());
732 | while (GoForwardIf(','));
733 | }
734 | Details details = ParseComment();
735 | TypeDeclaration @class;
736 | currentNamespace.classes.Add(@class = ParseClass(interfaceName, genericDeclaration2, implements, word == "interface"));
737 | @class.details = details;
738 | break;
739 | case "enum":
740 | string enumName = GetWord();
741 | var enumDecl = new TypeDeclaration
742 | {
743 | name = enumName,
744 | fields = new List(),
745 | kind = TypeDeclaration.Kind.Enum,
746 | upperNamespace = currentNamespace
747 | };
748 | if (!GoForwardIf('{'))
749 | throw new Exception();
750 | while (!GoForwardIf('}'))
751 | {
752 | var key = GetWord();
753 | if (string.IsNullOrWhiteSpace(key))
754 | throw new Exception();
755 | enumDecl.fields.Add(new Field
756 | {
757 | @readonly = true,
758 | @static = true,
759 | @name = key,
760 | type = new NamedType
761 | {
762 | Name = currentClass.name
763 | }
764 | });
765 | GoForwardIf(',');
766 | }
767 | currentNamespace.classes.Add(enumDecl);
768 | break;
769 | case "":
770 | if (GoForwardIf('}'))
771 | currentNamespace = currentNamespace.UpNamespace;
772 | break;
773 | }
774 | LastComment = null;
775 | }
776 | }
777 | }
778 | }
779 |
--------------------------------------------------------------------------------
/TypescriptToCS/TypescriptToCSConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using TypescriptParser;
7 |
8 | namespace TypescriptToCS
9 | {
10 | public class TypescriptToCSConverter
11 | {
12 | public int Indent = 0;
13 | public StringBuilder Result = new StringBuilder();
14 | public ConversionSoftware conversionSoftware;
15 | public TypescriptToCSConverter (ConversionSoftware conversionSoftware)
16 | {
17 | this.conversionSoftware = conversionSoftware;
18 | }
19 | public void WriteNewLine ()
20 | {
21 | Result.AppendLine();
22 | for (int n = 0; n < Indent; n++)
23 | Result.Append('\t');
24 | }
25 | public const string MethodEmptyName = "Invoke";
26 | public const string FieldEmptyName = "EmptyString";
27 | //public string FindingIdentifier;
28 | //public List FoundIdentifiers = new List();
29 | //public void FindIdentifier (Namespace @namespace)
30 | //{
31 | // @namespace.namespaces?.ForEach(FindIdentifier);
32 | // @namespace.classes?.ForEach(FindIdentifier);
33 | //}
34 | //public void FindIdentifier (TypeDeclaration type)
35 | //{
36 | // type.nested?.ForEach(FindIdentifier);
37 | // if (type.name == FindingIdentifier && !remove.Contains(type))
38 | // FoundIdentifiers.Add(type);
39 | //}
40 | public void DeleteUnneededTypes (TypeDeclaration type)
41 | {
42 | if (type.kind == TypeDeclaration.Kind.Enum && type.IsStringLiteralEnum)
43 | if (type.upperNamespace.FindTypeName(type.name, remove, false)?.Count > 1)
44 | remove.Add(type);
45 | }
46 | public void Translate (MethodOrDelegate methodOrDelegate)
47 | {
48 | if (string.IsNullOrEmpty(methodOrDelegate.orgName))
49 | {
50 | methodOrDelegate.orgName = methodOrDelegate.Name;
51 | methodOrDelegate.Name = ConvertToCSValidName(methodOrDelegate.Name, out bool nameAttribute, MethodEmptyName);
52 | methodOrDelegate.UsesNameAttribute = nameAttribute;
53 | }
54 | if (methodOrDelegate.Arguments?.Parameters?.Count > 0)
55 | for (int n = 0; n < methodOrDelegate.Arguments.Parameters.Count; n++)
56 | methodOrDelegate.Arguments.Parameters[n].Name = ConvertToCSValidName(methodOrDelegate.Arguments.Parameters[n].Name, out bool _temp);
57 | }
58 | public Namespace globalNamespace;
59 | public List Translate (TypeDeclaration @class)
60 | {
61 | @class.orgName = @class.name;
62 | @class.name = Shorten(ConvertToCSValidName(@class.name, out @class.UsesNameAttribute));
63 | @class.UsesNameAttribute = @class.UsesNameAttribute || @class.name != @class.orgName;
64 | @class.implements?.ForEach(v => Cleanse(v, @class.GenericDeclaration, @class));
65 | List toAdd = new List();
66 | @class.nested?.ForEach(v => toAdd.AddRange(Translate(v)));
67 | @class.delegates?.ForEach(v => Translate(v, null));
68 | if (@class.kind == TypeDeclaration.Kind.Interface)
69 | {
70 | if (@class.nested != null)
71 | {
72 | foreach (var nestedClass in @class.nested)
73 | nestedClass.name = @class.name + "_" + nestedClass.name;
74 | toAdd.AddRange(@class.nested);
75 | @class.nested = null;
76 | }
77 | if (@class.delegates != null)
78 | {
79 | foreach (var @delegate in @class.delegates)
80 | @delegate.Name = @class.name + "_" + @delegate.Name;
81 | globalNamespace.delegates.AddRange(@class.delegates);
82 | @class.delegates = null;
83 | }
84 | }
85 | if (@class.methods != null)
86 | foreach (var method in @class.methods)
87 | Translate(method, @class);
88 | if (@class.fields != null)
89 | foreach (var field in @class.fields)
90 | {
91 | field.orgName = field.name;
92 | field.name = ConvertToCSValidName(field.name, out bool nameAttribute);
93 | field.UsesNameAttribute = nameAttribute;
94 | Cleanse(field.type, @class.GenericDeclaration, @class);
95 | }
96 | return toAdd;
97 | }
98 | public void Translate (MethodOrDelegate methodOrDelegate, TypeDeclaration @class)
99 | {
100 | if (methodOrDelegate?.Name == @class?.name)
101 | {
102 | methodOrDelegate.orgName = methodOrDelegate.Name;
103 | methodOrDelegate.Name = "_" + methodOrDelegate.Name;
104 | methodOrDelegate.UsesNameAttribute = true;
105 | }
106 | List gens = new List
107 | {
108 | @class?.GenericDeclaration,
109 | methodOrDelegate?.GenericDeclaration
110 | };
111 | Translate(methodOrDelegate, gens, @class);
112 | }
113 | public void Translate (MethodOrDelegate methodOrDelegate, List genericDeclarations, TypeDeclaration @class)
114 | {
115 | void CCleanse (TypescriptParser.Type type, bool returnType)
116 | {
117 | foreach (var gen in genericDeclarations)
118 | Cleanse(type, gen, @class, returnType);
119 | }
120 | CCleanse(methodOrDelegate.ReturnType, true);
121 | if (methodOrDelegate.Arguments?.Parameters.Count > 0)
122 | foreach (var parameter in methodOrDelegate.Arguments.Parameters)
123 | CCleanse(parameter.Type, false);
124 | Translate(methodOrDelegate);
125 | }
126 |
127 | //public void ConvertUsingStatements (Namespace @namespace)
128 | //{
129 | // @namespace.namespaces?.ForEach(ConvertUsingStatements);
130 | // @namespace.ttypes?.ForEach(ConvertUsingStatements);
131 | //}
132 | //public void ConvertUsingStatements (TTypeDeclaration tType)
133 | //{
134 | // Result.Append("using ");
135 | // Result.Append(tType.Name);
136 | // GenericDeclaration gen = null;
137 | // if (tType.Type is NamedType namedType)
138 | // {
139 | // if (namedType.ReferenceTypes?.GenericDeclaration?.Generics?.Count > 0)
140 | // gen = namedType.ReferenceTypes.GenericDeclaration;
141 | // else if (namedType.ReferenceDelegates?.GenericDeclaration?.Generics?.Count > 0)
142 | // gen = namedType.ReferenceDelegates.GenericDeclaration;
143 | // if (gen != null)
144 | // {
145 | // tType.GenericDeclaration.Generics.AddRange(gen.Generics);
146 | // foreach (var item in gen.Wheres)
147 | // tType.GenericDeclaration.Wheres.Add(item.Key, item.Value);
148 | // }
149 | // }
150 | // Convert1(tType.GenericDeclaration);
151 | // Result.Append(" = ");
152 | // Result.Append(Convert(tType.Type));
153 | // if (gen != null)
154 | // Convert1(gen);
155 | // Result.Append(";");
156 | // WriteNewLine();
157 | //}
158 | public void Convert(Namespace @namespace, bool displayHeader = true)
159 | {
160 | if (displayHeader)
161 | {
162 | WriteNewLine();
163 | Result.Append($"namespace {@namespace.name}");
164 | WriteNewLine();
165 | Result.Append('{');
166 | Indent++;
167 | WriteNewLine();
168 | }
169 | foreach (var @namespaceItem in @namespace.namespaces)
170 | Convert(@namespaceItem);
171 | foreach (var classItem in @namespace.classes)
172 | Convert(classItem);
173 | foreach (var @delegate in @namespace.delegates)
174 | Convert(@delegate);
175 | //foreach (var tType in @namespace.ttypes)
176 | // Convert(tType);
177 | if (displayHeader)
178 | {
179 | Indent--;
180 | Result = Result.Remove(Result.Length - 1, 1);
181 | Result.Append('}');
182 | WriteNewLine();
183 | WriteNewLine();
184 | }
185 | }
186 |
187 | //public void Convert(TTypeDeclaration tType)
188 | //{
189 | // Result.Append("public class ");
190 | // Result.Append(tType.Name);
191 | // Result.Append(" : ");
192 | // Result.Append(Convert(tType.Type));
193 | // Result.Append(" {}");
194 | // WriteNewLine();
195 | //}
196 |
197 | static readonly string[] disallowedString =
198 | {
199 | "abstract",
200 | "as",
201 | "base",
202 | "bool",
203 | "break",
204 | "byte",
205 | "case",
206 | "catch",
207 | "char",
208 | "checked",
209 | "class",
210 | "const",
211 | "continue",
212 | "decimal",
213 | "default",
214 | "delegate",
215 | "do",
216 | "double",
217 | "else",
218 | "enum",
219 | "event",
220 | "explicit",
221 | "extern",
222 | "false",
223 | "finally",
224 | "fixed",
225 | "float",
226 | "for",
227 | "foreach",
228 | "goto",
229 | "if",
230 | "implicit",
231 | "in",
232 | "int",
233 | "interface",
234 | "internal",
235 | "is",
236 | "lock",
237 | "long",
238 | "namespace",
239 | "new",
240 | "null",
241 | "object",
242 | "operator",
243 | "out",
244 | "override",
245 | "params",
246 | "private",
247 | "protected",
248 | "public",
249 | "readonly",
250 | "ref",
251 | "return",
252 | "sbyte",
253 | "sealed",
254 | "short",
255 | "sizeof",
256 | "stackalloc",
257 | "static",
258 | "string",
259 | "struct",
260 | "switch",
261 | "this",
262 | "throw",
263 | "true",
264 | "try",
265 | "typeof",
266 | "uint",
267 | "ulong",
268 | "unchecked",
269 | "unsafe",
270 | "ushort",
271 | "using",
272 | "virtual",
273 | "volatile",
274 | "void",
275 | "while"
276 | };
277 | const string allowedCSChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890";
278 |
279 | //public void MergeEnums (Namespace @namespace)
280 | //{
281 | // @namespace.namespaces?.ForEach(MergeEnums);
282 | // var toAdd = new List();
283 | // @namespace.classes?.ForEach(v => toAdd.AddRange(MergeEnums(v)));
284 | // @namespace.classes?.AddRange(toAdd);
285 | //}
286 |
287 | //public List MergeEnums (TypeDeclaration @class)
288 | //{
289 | // List classes = new List();
290 | // var toAdd = new List();
291 | // @class.nested?.ForEach(v => toAdd.AddRange(MergeEnums(v)));
292 | // @class.nested?.AddRange(toAdd);
293 | // if (@class.kind == TypeDeclaration.Kind.Enum && !remove.Contains(@class))
294 | // {
295 | // Finding = new NamedType { Name = @class.name };
296 | // Found.Clear();
297 | // FoundB.Clear();
298 | // FindIn(globalNamespace);
299 | // foreach (var found in Found)
300 | // {
301 | // if (found == @class)
302 | // continue;
303 | // @class.fields.AddRange(found.fields);
304 | // remove.Add(found);
305 | // }
306 | // }
307 | // return classes;
308 | //}
309 |
310 | public void RemoveAll(TypeDeclaration @class, List classes)
311 | {
312 | var removeNested = new List();
313 | @class.nested?.ForEach(v => RemoveAll(v, removeNested));
314 | removeNested.ForEach(v => @class.nested?.Remove(v));
315 | if (remove.Contains(@class))
316 | classes.Add(@class);
317 | }
318 |
319 | public void RemoveAll(Namespace @namespace)
320 | {
321 | @namespace.namespaces?.ForEach(v => RemoveAll(v));
322 | var classRemove = new List();
323 | @namespace.classes?.ForEach(v => RemoveAll(v, classRemove));
324 | classRemove.ForEach(v => @namespace.classes.Remove(v));
325 | }
326 |
327 | public HashSet remove = new HashSet();
328 |
329 | public static string ConvertToCSValidName(string value, out bool nameAttribute, string emptyString = FieldEmptyName)
330 | {
331 | string org = value;
332 | if (value == "item")
333 | value = "_item";
334 | if (value?.Length != 0)
335 | if (char.IsNumber(value[0]))
336 | value = '_' + value;
337 | char[] @new = value.ToCharArray();
338 | for (int n = 0; n < value.Length; n++)
339 | if (!allowedCSChars.Contains(value[n]))
340 | @new[n] = '_';
341 | if (disallowedString.Contains(value))
342 | value = $"@{value}";
343 | if (string.IsNullOrEmpty(value))
344 | value = emptyString;
345 | if (value == org)
346 | value = new string(@new);
347 | nameAttribute = org != value;
348 | return value;
349 | }
350 |
351 | public void ConvertAsEnum(TypeDeclaration @enum)
352 | {
353 | Result.Append($"[External{(@enum.IsStringLiteralEnum ? ", Enum(Emit.StringNamePreserveCase)" : "")}]");
354 | WriteNewLine();
355 | Result.Append($"public enum {@enum.name}");
356 | WriteNewLine();
357 | Result.Append('{');
358 | Indent++;
359 | foreach (var value in @enum.fields)
360 | {
361 | WriteNewLine();
362 | if (value.UsesNameAttribute)
363 | UseNameAttribute(value.orgName);
364 | Result.Append(value.name);
365 | Result.Append(',');
366 | }
367 | Indent--;
368 | WriteNewLine();
369 | Result.Append('}');
370 | WriteNewLine();
371 | WriteNewLine();
372 | }
373 |
374 | public string Cleanse(string value, GenericDeclaration genericDeclaration, TypeDeclaration @class, bool returnType)
375 | {
376 | if (genericDeclaration?.GenericsEquals != null)
377 | foreach (var item in genericDeclaration.GenericsEquals)
378 | if (item.Key == value)
379 | {
380 | value = item.Value;
381 | break;
382 | }
383 | switch (value)
384 | {
385 | case "Union":
386 | value = "Bridge.Union";
387 | break;
388 | case "Tuple":
389 | value = "System.Tuple";
390 | break;
391 | case "string":
392 | return "System.String";
393 | case "boolean":
394 | return "System.Boolean";
395 | case "number":
396 | return "System.Double";
397 | case "any":
398 | return "System.Object";
399 | case "null":
400 | return "NullType";
401 | case "undefined":
402 | return "UndefinedType";
403 | case "void":
404 | if (returnType)
405 | break;
406 | return "VoidType";
407 | case "never":
408 | return returnType ? "void" : "Bridge.Union";
409 | case "symbol":
410 | return "Symbol";
411 | }
412 | return value;
413 | }
414 |
415 | //public List Found = new List();
416 |
417 | //public List FoundB = new List();
418 |
419 |
420 | //public List FoundC = new List();
421 | //public TypescriptParser.NamedType Finding;
422 |
423 | public void RemoveDuplicateFields () => globalNamespace.ForeachType(type =>
424 | {
425 | var oClasses = globalNamespace.FindTypeName(type.name, remove).Where(v => v != type);
426 | if (oClasses.Count() == 0)
427 | return;
428 | if (type.fields != null)
429 | foreach (var field in type.fields)
430 | foreach (var type_ in oClasses)
431 | {
432 | (var fields, var methods) = type_.FindClassMembers(field.name);
433 | foreach (var field_ in fields)
434 | type_.fields.Remove(field_);
435 | foreach (var method in methods)
436 | type_.methods.Remove(method);
437 | }
438 | if (type.methods != null)
439 | foreach (var method in type.methods)
440 | foreach (var type_ in oClasses)
441 | {
442 | (var fields, var methods) = type_.FindClassMembers(method.Name);
443 | foreach (var field_ in fields)
444 | type_.fields.Remove(field_);
445 | foreach (var method_ in methods)
446 | if (method != method_)
447 | {
448 | if (!ArgumentsEquals(method, method_))
449 | continue;
450 | type_.methods.Remove(method_);
451 | }
452 | }
453 | });
454 |
455 | public void Reference (TypescriptParser.Type @type)
456 | {
457 | switch (@type)
458 | {
459 | case NamedType namedType:
460 | if (namedType.TypeDeclaration != null || namedType.ReferenceDelegates != null)
461 | return;
462 | (
463 | List typesFound,
464 | List tTypesFound,
465 | List delegatesFound
466 | )
467 | =
468 | globalNamespace.FindType(namedType, remove);
469 | namedType.TypeDeclaration = typesFound.FirstOrDefault();
470 | namedType.ReferenceDelegates = delegatesFound.FirstOrDefault();
471 | namedType.ReferenceTTypes = tTypesFound.FirstOrDefault();
472 | if (namedType.Generics?.Generic?.Count > 0)
473 | foreach (var item in namedType.Generics.Generic)
474 | Reference(item);
475 | break;
476 | }
477 | }
478 |
479 | //public void Reference (Arguments arguments)
480 | //{
481 | // arguments?.Parameters?.ForEach(v => Reference(v.Type));
482 | //}
483 |
484 | //public void Reference (TypeDeclaration typeDeclaration)
485 | //{
486 | // if (typeDeclaration.methods != null)
487 | // foreach (var method in typeDeclaration.methods)
488 | // {
489 | // Reference(method.Arguments);
490 | // Reference(method.ReturnType);
491 | // }
492 | // if (typeDeclaration.fields != null)
493 | // foreach (var field in typeDeclaration.fields)
494 | // Reference(field.type);
495 | // typeDeclaration.implements?.ForEach(Reference);
496 | // typeDeclaration.delegates?.ForEach(Reference);
497 | //}
498 |
499 | //public void Reference (MethodOrDelegate @delegate)
500 | //{
501 | // Reference(@delegate.Arguments);
502 | // Reference(@delegate.ReturnType);
503 | //}
504 |
505 | public void Cleanse(TypescriptParser.Type type, GenericDeclaration genericDeclaration, TypeDeclaration @class, bool returnType = false)
506 | {
507 | if (type == null)
508 | return;
509 | switch (type)
510 | {
511 | case NamedType namedType:
512 | if (namedType.ReferenceDelegates != null)
513 | Translate(namedType.ReferenceDelegates, new List { genericDeclaration }, @class);
514 | if (namedType.Name == "this")
515 | {
516 | namedType.Name = @class.name;
517 | namedType.Generics.Generic.AddRange(@class.GenericDeclaration.Generics.ConvertAll(v => new NamedType { Name = v }));
518 | }
519 | namedType.Name = Cleanse(namedType.Name, genericDeclaration, @class, returnType);
520 | if (namedType.Generics?.Generic != null)
521 | foreach (var item in namedType.Generics.Generic)
522 | Cleanse(item, genericDeclaration, @class);
523 | break;
524 | default:
525 | throw new NotImplementedException();
526 | }
527 | }
528 | public string Convert (TypescriptParser.Arguments arguments)
529 | {
530 | if (arguments?.Parameters?.Count > 0)
531 | return string.Join(", ", arguments.Parameters.ConvertAll(v => (v.Params ? "params " : "") + Convert(v.Type) + " " + v.Name + (v.Optional ? $" = default({Convert(v.Type)})" : "")));
532 | return string.Empty;
533 | }
534 | public void Convert(TypescriptParser.MethodOrDelegate @delegate)
535 | {
536 | Result.Append("[External]");
537 | WriteNewLine();
538 | Result.Append("public delegate ");
539 | Result.Append(Convert(@delegate.ReturnType));
540 | Result.Append(" ");
541 | Result.Append(@delegate.Name);
542 | Convert1(@delegate.GenericDeclaration);
543 | Result.Append(" (");
544 | Result.Append(Convert(@delegate.Arguments));
545 | Result.Append(");");
546 | WriteNewLine();
547 | WriteNewLine();
548 | }
549 |
550 | public string ConvertToUpperCase(string value)
551 | //{
552 | // if (string.IsNullOrEmpty(value))
553 | // return value;
554 | // char[] newString = value.ToCharArray();
555 | // //newString[0] = char.ToUpper(newString[0]);
556 | // return new string(newString);
557 | //}
558 | => value;
559 | public void UseNameAttribute (string name)
560 | {
561 | if (conversionSoftware == ConversionSoftware.DuoCode)
562 | Result.Append($"[Js(Name=\"{name}\")]");
563 | else
564 | Result.Append($"[Name(\"{name}\")]");
565 | WriteNewLine();
566 | }
567 |
568 | public void Convert1 (GenericDeclaration genericDeclaration)
569 | {
570 | if (genericDeclaration.Generics?.Count > 0)
571 | Result.Append($"<{string.Join(", ", genericDeclaration.Generics)}>");
572 | }
573 |
574 | public void Convert2 (GenericDeclaration genericDeclaration)
575 | {
576 | List whereStrings = new List();
577 | foreach (var where in genericDeclaration.Wheres)
578 | if (where.Value.Count > 0)
579 | whereStrings.Add($" where {where.Key} : {string.Join(", ", where.Value.ConvertAll(Convert))}");
580 | Result.Append(string.Join(", ", whereStrings));
581 | }
582 |
583 | public int count = 0;
584 |
585 | public string Shorten (string value)
586 | {
587 | return value.Length > 512 ? $"___{count++}" : value;
588 | }
589 |
590 | public string CalibrateSpace (string value)
591 | {
592 | StringBuilder result = new StringBuilder();
593 | bool space = false;
594 | bool @return = false;
595 | bool currentSpace = false;
596 | bool gone = false;
597 | const string lineReturns = "\r\n";
598 | for (int n = 0; n < value.Length; n++)
599 | {
600 | currentSpace = false;
601 | char item = value[n];
602 | space = (currentSpace = MTypescriptParser.spaceChars.Contains(item)) ? true : space;
603 | @return = lineReturns.Contains(item) ? true : @return;
604 | if (currentSpace)
605 | continue;
606 | if (space)
607 | {
608 | if (gone || @return)
609 | result.Append(@return ? "\n" : " ");
610 | space = false;
611 | @return = false;
612 | }
613 | result.Append(item);
614 | gone = true;
615 | }
616 | return result.ToString();
617 | }
618 |
619 | public void Convert (Details details)
620 | {
621 | void NewLine()
622 | {
623 | WriteNewLine();
624 | Result.Append("/// ");
625 | }
626 | void WriteString (string toWrite)
627 | {
628 | string[] split = CalibrateSpace(toWrite).Split('\n');
629 | for (int n = 0; n < split.Length; n++)
630 | {
631 | var item = split[n];
632 | Result.Append(item);
633 | NewLine();
634 | }
635 | }
636 | Result.Append("/// ");
637 | if (details.summary != null)
638 | {
639 | Result.Append("");
640 | NewLine();
641 | WriteString(details.summary);
642 | Result.Append("");
643 | }
644 | foreach (var item in details.paramDescription)
645 | {
646 | Result.Append("");
649 | NewLine();
650 | WriteString(item.Value);
651 | Result.Append("");
652 | }
653 | if (details.returns != null)
654 | {
655 | Result.Append("");
656 | NewLine();
657 | WriteString(details.summary);
658 | Result.Append("");
659 | }
660 | WriteNewLine();
661 | }
662 |
663 | public void Convert(TypeDeclaration @class)
664 | {
665 | if (@class.details != null)
666 | {
667 | if (@class.details.paramDescription.Count > 0 || @class.details.summary != null || @class.details.returns != null)
668 | Convert(@class.details);
669 | }
670 | if (@class.kind == TypeDeclaration.Kind.Enum)
671 | {
672 | ConvertAsEnum(@class);
673 | return;
674 | }
675 | Result.Append(conversionSoftware == ConversionSoftware.Bridge ? "[External]" : "[Js(Extern=true)]");
676 | WriteNewLine();
677 | if (@class.name == "Global")
678 | {
679 | if (@class.upperNamespace == null)
680 | Result.Append("[Name(\"Bridge.global\")]");
681 | else
682 | {
683 | Result.Append("[Name(\"");
684 | Namespace current = @class.upperNamespace;
685 | while (current != null)
686 | {
687 | Result.Append(current.name);
688 | Result.Append('.');
689 | current = current.UpNamespace;
690 | }
691 | Result.Remove(Result.Length - 1, 1);
692 | Result.Append("\")]");
693 | }
694 | WriteNewLine();
695 | }
696 | if (@class.UsesNameAttribute)
697 | UseNameAttribute(@class.IsUnion ? "Object" : @class.orgName);
698 | Result.Append($"public {(@class.@static ? "static " : "")}partial {@class.kind.ToString().ToLower()} {@class.name}");
699 | if (@class.GenericDeclaration?.Generics?.Count > 0)
700 | Convert1(@class.GenericDeclaration);
701 | if (@class.implements?.Count > 0)
702 | Result.Append($" : {string.Join(", ", @class.implements.ConvertAll(Convert))}");
703 | if (@class.GenericDeclaration?.Wheres?.Count > 0)
704 | Convert2(@class.GenericDeclaration);
705 | WriteNewLine();
706 | Result.Append('{');
707 | Indent++;
708 | WriteNewLine();
709 | if (@class.nested != null)
710 | foreach (var @classItem in @class.nested)
711 | Convert(@classItem);
712 | if (@class.delegates != null)
713 | foreach (var @delegate in @class.delegates)
714 | Convert(@delegate);
715 | List fields = new List();
716 | List methods = new List();
717 | if (@class.fields != null)
718 | fields.AddRange(@class.fields);
719 | if (@class.methods != null)
720 | methods.AddRange(@class.methods);
721 | if (@class.kind != TypeDeclaration.Kind.Interface)
722 | if (@class.implements != null)
723 | foreach (var implement in @class.implements)
724 | {
725 | var namedType = implement as NamedType;
726 | if (namedType.TypeDeclaration != null)
727 | if (namedType.TypeDeclaration.kind == TypeDeclaration.Kind.Interface)
728 | {
729 | if (namedType.TypeDeclaration.fields != null)
730 | foreach (var field in namedType.TypeDeclaration.fields)
731 | //if (!fields.Any(v => v.name == field.name))
732 | fields.Add(new Field
733 | {
734 | name = field.name,
735 | type = field.type,
736 | ExplicitString = implement,
737 | optional = field.optional,
738 | orgName = field.orgName,
739 | @readonly = field.@readonly,
740 | @static = field.@static,
741 | template = field.template,
742 | UsesNameAttribute = field.UsesNameAttribute
743 | });
744 | //fields.AddRange(namedType.TypeDeclaration.fields);
745 | if (namedType.TypeDeclaration.methods != null)
746 | foreach (var method in namedType.TypeDeclaration.methods)
747 | //if (!methods.Any(v => v.Name == method.Name && ArgumentsEquals(v, method)))
748 | methods.Add(new MethodOrDelegate
749 | {
750 | Name = method.Name,
751 | GenericDeclaration = method.GenericDeclaration,
752 | Arguments = method.Arguments,
753 | Indexer = method.Indexer,
754 | orgName = method.orgName,
755 | UsesNameAttribute = method.UsesNameAttribute,
756 | Readonly = method.Readonly,
757 | Static = method.Static,
758 | ReturnType = method.ReturnType,
759 | ExplicitString = implement
760 | });
761 | }
762 | }
763 | if (@class.kind != TypeDeclaration.Kind.Interface && (@class.methods?.Any(v => v.Name == "constructor") != true) && !@class.@static)
764 | {
765 | Result.Append($"extern {@class.name}();");
766 | WriteNewLine();
767 | }
768 | if (@class.IsUnion)
769 | {
770 | var unionType = (NamedType)@class.implements[0];
771 | var genericA = unionType.Generics.Generic[0];
772 | var genericB = unionType.Generics.Generic[1];
773 | Result.Append($"public static extern implicit operator {@class.name}(A t);");
774 | WriteNewLine();
775 | Result.Append($"public static extern implicit operator {@class.name}(B t);");
776 | WriteNewLine();
777 | WriteNewLine();
778 | }
779 | foreach (var field in fields)
780 | {
781 | if (field.details?.paramDescription.Count > 0 || field.details?.returns != null || field.details?.summary != null)
782 | Convert(field.details);
783 | if (field.UsesNameAttribute)
784 | UseNameAttribute(field.orgName);
785 | string upperName = ConvertToUpperCase(field.name);
786 | Convert(upperName, field.name);
787 | if (field.ExplicitString == null)
788 | Convert(@class.kind != TypeDeclaration.Kind.Interface, field.@static);
789 | else
790 | Result.Append("extern ");
791 | Result.Append(Convert(field.type));
792 | Result.Append(" ");
793 | if (field.ExplicitString != null)
794 | {
795 | Result.Append(Convert(field.ExplicitString));
796 | Result.Append(".");
797 | }
798 | Result.Append(upperName);
799 | bool validTemplate = !string.IsNullOrEmpty(field.template);
800 | if (validTemplate)
801 | {
802 | PrintTemplateProperty(field.template, field.@readonly);
803 | }
804 | else
805 | {
806 | Result.Append(" { get;");
807 | if (!field.@readonly)
808 | Result.Append(" set;");
809 | Result.Append(" }");
810 | }
811 | WriteNewLine();
812 | }
813 | foreach (var method in methods)
814 | {
815 | if (method.Details?.returns != null || method.Details?.summary != null || method.Details?.paramDescription?.Count > 0)
816 | Convert(method.Details);
817 | string upperName = ConvertToUpperCase(method.Name);
818 | string template = null;
819 | if ((method.orgName == "new" || method.orgName == "") && string.IsNullOrEmpty(template))
820 | template = (method.orgName == "" ? "" : "new ") +
821 | "{this}" +
822 | (method.Indexer ? '[' : '(') +
823 | string.Join(", ",
824 | method.Arguments.Parameters.ConvertAll(v => "{" + v.Name + "}")) +
825 | (method.Indexer ? ']' : ')');
826 | else if (method.UsesNameAttribute)
827 | UseNameAttribute(method.orgName);
828 | else Convert(upperName, method.Name);
829 | if (!string.IsNullOrEmpty(template) && !method.Indexer)
830 | {
831 | Result.Append($"[Template(\"{template}\")]");
832 | WriteNewLine();
833 | }
834 | if (method.ExplicitString == null)
835 | Convert(@class.kind != TypeDeclaration.Kind.Interface, method.Static);
836 | else
837 | Result.Append("extern ");
838 | Result.Append(method.Name == "constructor" ? @class.name : Convert(method.ReturnType));
839 | Result.Append(" ");
840 | if (method.ExplicitString != null)
841 | {
842 | Result.Append(Convert(method.ExplicitString));
843 | Result.Append(".");
844 | }
845 | if (method.Name != "constructor")
846 | Result.Append(method.Indexer ? "this" : upperName);
847 | if (method.GenericDeclaration?.Generics?.Count > 0)
848 | Convert1(method.GenericDeclaration);
849 | if (method.Name != "constructor")
850 | Result.Append(" ");
851 | Result.Append(method.Indexer ? '[' : '(');
852 | Result.Append(Convert(method.Arguments));
853 | if (method.Indexer)
854 | {
855 | Result.Append(']');
856 | PrintTemplateProperty(template, method.Readonly);
857 | }
858 | else
859 | {
860 | Result.Append(")");
861 | if (method.GenericDeclaration?.Wheres?.Count > 0 && method.ExplicitString == null)
862 | Convert2(method.GenericDeclaration);
863 | Result.Append(";");
864 | }
865 | WriteNewLine();
866 | }
867 | Result.Remove(Result.Length - 1, 1);
868 | Indent--;
869 | Result.Append('}');
870 | WriteNewLine();
871 | WriteNewLine();
872 | }
873 |
874 | public bool ArgumentsEquals(MethodOrDelegate a, MethodOrDelegate b)
875 | {
876 | if (a.Arguments.Parameters.Count != b.Arguments.Parameters.Count)
877 | return false;
878 | for (int n = 0; n < a.Arguments.Parameters.Count; n++)
879 | {
880 | var param = a.Arguments.Parameters[n];
881 | var paramB = b.Arguments.Parameters[n];
882 | if (!TypescriptParser.Type.Equals(param.Type, paramB.Type))
883 | return false;
884 | }
885 | return true;
886 | }
887 |
888 | public void PrintTemplateProperty (string template, bool @readonly)
889 | {
890 | WriteNewLine();
891 | Result.Append("{");
892 | Indent++;
893 | WriteNewLine();
894 | PrintTemplate(template);
895 | Result.Append("get;");
896 | WriteNewLine();
897 | if (!@readonly)
898 | {
899 | PrintTemplate(template);
900 | Result.Append("set;");
901 | Indent--;
902 | WriteNewLine();
903 | }
904 | else
905 | {
906 | Indent--;
907 | Result = Result.Remove(Result.Length - 1, 1);
908 | }
909 | Result.Append("}");
910 | }
911 |
912 | public bool PrintTemplate (string template)
913 | {
914 | bool result;
915 | if (result = !string.IsNullOrEmpty(template))
916 | {
917 | Result.Append($"[Template(\"{template}\")]");
918 | WriteNewLine();
919 | }
920 | return result;
921 | }
922 |
923 | public void Convert (string upperName, string name)
924 | {
925 | //if (upperName == name)
926 | //{
927 | // Result.Append("[Convention(Notation.UpperCamelCase)]");
928 | // WriteNewLine();
929 | //}
930 | }
931 |
932 | public void Convert (bool isNotInterface, bool isStatic)
933 | {
934 | if (isNotInterface)
935 | Result.Append("public extern ");
936 | if (isStatic)
937 | Result.Append("static ");
938 | }
939 |
940 | public string Convert (TypescriptParser.Type type)
941 | {
942 | string result = string.Empty;
943 | switch (type)
944 | {
945 | case NamedType namedType:
946 | string name = namedType.Name;
947 | if (name == "Array`")
948 | return Convert(namedType.Generics.Generic[0]) + "[]";
949 | bool any = false;
950 | if (namedType.TypeDeclaration != null)
951 | {
952 | name = namedType.TypeDeclaration.name;
953 | any = true;
954 | }
955 | if (namedType.ReferenceDelegates != null)
956 | {
957 | name = namedType.ReferenceDelegates.Name;
958 | any = true;
959 | }
960 | if (namedType.ReferenceTTypes != null)
961 | return Convert(namedType.ReferenceTTypes.Type);
962 | if (namedType.PreDots?.Length > 0)
963 | if (any)
964 | name = string.Join(".", namedType.PreDots) + "." + name;
965 | result += name;
966 | if (namedType.Generics?.Generic.Count > 0)
967 | {
968 | result += "<";
969 | result += string.Join(", ", namedType.Generics.Generic.ConvertAll(Convert));
970 | result += ">";
971 | }
972 | break;
973 | }
974 | return result;
975 | }
976 | }
977 | }
978 |
--------------------------------------------------------------------------------