├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── TypescriptParser.sln ├── TypescriptParser ├── Arguments.cs ├── Details.cs ├── Field.cs ├── GenericDeclaration.cs ├── Generics.cs ├── MTypescriptParser.cs ├── MethodOrDelegate.cs ├── NamedType.cs ├── Namespace.cs ├── Parameter.cs ├── Properties │ └── AssemblyInfo.cs ├── TTypeClassDeclaration.cs ├── Type.cs ├── TypeDeclaration.cs ├── TypescriptParser.csproj └── packages.config └── TypescriptToCS ├── App.config ├── Program.cs ├── Properties └── AssemblyInfo.cs ├── TypescriptToCS.csproj ├── TypescriptToCSConverter.cs └── packages.config /.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 | -------------------------------------------------------------------------------- /.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 -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TypescriptToCS2 2 | 3 | [![Gitter](https://badges.gitter.im/TypescriptToCS2/Lobby.svg)](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.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 | -------------------------------------------------------------------------------- /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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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 | } -------------------------------------------------------------------------------- /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 | } -------------------------------------------------------------------------------- /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/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /TypescriptToCS/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /TypescriptToCS/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | --------------------------------------------------------------------------------