From 6535ea175334de141fe1bc1d8f3aca538b99b41c Mon Sep 17 00:00:00 2001
From: Pavel Vostretsov
Date: Sun, 21 Jun 2020 20:00:46 +0500
Subject: [PATCH] Update docs
---
CHANGELOG.md | 7 ++
Directory.Build.targets | 2 +-
MIGRATION.md | 10 ++-
README.md | 80 ++++++++-----------
TypeScript.ContractGenerator.Cli/Program.cs | 2 +-
.../AdhocProject.cs | 5 +-
.../RoslynCustomizationProvider.cs | 23 ------
.../RoslynTypeExtensions.cs | 17 +++-
.../TestBase.cs | 2 +-
.../TypeScript.ContractGenerator.Tests.csproj | 2 +-
version.json | 2 +-
11 files changed, 73 insertions(+), 79 deletions(-)
delete mode 100644 TypeScript.ContractGenerator.Roslyn/RoslynCustomizationProvider.cs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b506caf..e69e21e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## v2.0.xx - 2020.06.xx
+- Remove deprecated options (See [MIGRATION](MIGRATION.md))
+- Use abstractions instead of reflection types in public api (See [MIGRATION](MIGRATION.md))
+- Fix nullability issues with Nullable Reference Types
+- Add Roslyn support
+- Add dotnet tool
+
## v1.10.3 - 2020.05.28
- Fix eslint-ignore comment
- Add public modifier to function definition
diff --git a/Directory.Build.targets b/Directory.Build.targets
index b5c9432..4e7a62f 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -9,7 +9,7 @@
- Eugene Tihonov
+ Eugene Tihonov, Pavel Vostretsov
A tool that can generate TypeScript types from C# classes
TypeScript CodeGenerator
git
diff --git a/MIGRATION.md b/MIGRATION.md
index 61c1fb5..83bc549 100644
--- a/MIGRATION.md
+++ b/MIGRATION.md
@@ -54,4 +54,12 @@ public static class TypeScriptGeneratorHelpers
+ return typeGenerator.ResolveType(type).ReferenceFrom(type, typeScriptUnit, typeGenerator);
+ }
}
-```
\ No newline at end of file
+```
+
+## Roslyn
+
+When using Roslyn to generate TypeScript, Customization code is preprocessed, replacing `TypeInfo.From()` and `TypeInfo.From(typeof(T))` invocations with `RoslynTypeInfo` instances and then compiled to in-memory assembly. Therefore, several changes to customization code are required to use Roslyn:
+
+- There should be no `typeof(T)` invocations not wrapped with `TypeInfo.From()`
+- All customization-related code should be in the same namespace
+- Customization-related code should not depend on any third party packages
diff --git a/README.md b/README.md
index 1dea05b..76bd70e 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# TypeScript.ContractGenerator
-A tool that can generate TypeScript or Flow types from C# classes
+A tool that can generate TypeScript types from C# classes
| | Build Status
|--------------|:--------------:
@@ -35,7 +35,7 @@ Then generate TypeScript files with:
```csharp
var generator = new TypeScriptGenerator(TypeScriptGenerationOptions.Default, CustomTypeGenerator.Null, new RootTypesProvider(typeof(SecondType)));
-generator.GenerateFiles("./output", JavaScriptTypeChecker.TypeScript);
+generator.GenerateFiles("./output");
```
By default, this will generate file with name `.ts` with following content:
@@ -58,36 +58,9 @@ If you want generated files to have different name or to generate some typings d
## Generation options
-### EnumGenerationMode
+### LinterDisableMode
-This options is set to `FixedStringsAndDictionary` by default.
-
-```csharp
-public enum EnumGenerationMode
-{
- FixedStringsAndDictionary = 0,
- TypeScriptEnum = 1,
-}
-```
-
-Setting option value equal to `FixedStringsAndDictionary` produces following output:
-
-```ts
-export type SomeEnum = 'A' | 'B';
-export const SomeEnums = {
- ['A']: ('A') as SomeEnum,
- ['B']: ('B') as SomeEnum,
-};
-```
-
-Option value `TypeScriptEnum` produces following:
-
-```ts
-export enum SomeEnum {
- A = 'A',
- B = 'B',
-}
-```
+Use `/* eslint-disable */` or `// tslint:disable` comment in generated files. `EsLint` is default option.
### EnableOptionalProperties
@@ -102,27 +75,44 @@ export type SomeType = {
```
When **disabled**, all properties produced as required.
-### EnableExplicitNullability
-
-This option is **enabled** by default. When **enabled** produces nullable types for members which may contain nulls.
-
-```ts
-export type SomeType = {
- nullablePropertyDefinition: null | string;
- nonNullablePropertyDefinition: string;
-};
-```
-
-When **disabled** produces all types as-is.
-
### UseGlobalNullable
This option is **disabled** by default. When **enabled**, global `Nullable` is used instead of union `null | T`
### NullabilityMode
-This option is set to `Pessimistic` by default. When set to `Pessimistic`, generates `Nullable` property for properties that have no nullability attributes. When set to `Optimistic`, generates not null property for properties that have no nullability attributes.
+NullabilityMode has 4 options:
+- None - all generated properties are not null
+- Pessimistic (default) - generates `Nullable` property for properties that have no JetBrains nullability attributes
+- Optimistic - generates not null property for properties that have no JetBrains nullability attributes
+- NullableReference - generates not null properties based on C# 8 Nullable Reference Type attributes
+
+Options `Pessimistic` or `Optimistic` can be combined with `NullableReference` option, this way generator first looks for C# 8 Nullable Reference Type attributes, then JetBrains nullability attributes
## Attributes
There is `ContractGeneratorIgnore` attribute that can be applied to properties and makes generator skip current property.
+
+## Roslyn usage
+
+To use Roslyn you should get a `Compilation` object of your project. It can be done with helper method `AdhocProject.GetCompilation(string[] directories, string[] assemblies)`.
+You can then get customization info from this compilation by calling extension method `compilation.GetCustomization()` and call `TypeScriptGenerator` with this customization:
+```csharp
+var (customTypeGenerator, typesProvider) = AdhocProject.GetCompilation(directories, assemblies).GetCustomization();
+var typeGenerator = new TypeScriptGenerator(options, customTypeGenerator, typesProvider);
+typeGenerator.GenerateFiles(outputDirectory);
+```
+
+## dotnet tool usage
+
+Install tool with command:
+
+`dotnet tool install -g SkbKontur.TypeScript.ContractGenerator.Cli`
+
+Use tool with command:
+
+`dotnet ts-gen --assembly ./Api/bin/Api.dll --outputDir ./src/Api`
+
+dotnet tool also supports Roslyn:
+
+`dotnet ts-gen --directory ./Api;./Core --assembly ./External/Dependency.dll --outputDir ./src/Api`
diff --git a/TypeScript.ContractGenerator.Cli/Program.cs b/TypeScript.ContractGenerator.Cli/Program.cs
index 99358a1..117765d 100644
--- a/TypeScript.ContractGenerator.Cli/Program.cs
+++ b/TypeScript.ContractGenerator.Cli/Program.cs
@@ -77,7 +77,7 @@ private static void GenerateByOptions(Options o)
if (o.Assembly.Count() != 1 || o.Directory.Any())
{
- var (customTypeGenerator, typesProvider) = RoslynCustomizationProvider.GetCustomization(o.Directory.ToArray(), o.Assembly.ToArray());
+ var (customTypeGenerator, typesProvider) = AdhocProject.GetCompilation(o.Directory.ToArray(), o.Assembly.ToArray()).GetCustomization();
var typeGenerator = new TypeScriptGenerator(o.ToTypeScriptGenerationOptions(), customTypeGenerator, typesProvider);
typeGenerator.GenerateFiles(o.OutputDirectory);
return;
diff --git a/TypeScript.ContractGenerator.Roslyn/AdhocProject.cs b/TypeScript.ContractGenerator.Roslyn/AdhocProject.cs
index f207615..6c9545b 100644
--- a/TypeScript.ContractGenerator.Roslyn/AdhocProject.cs
+++ b/TypeScript.ContractGenerator.Roslyn/AdhocProject.cs
@@ -32,11 +32,12 @@ public static Project FromDirectory(params string[] directories)
return project;
}
- public static Compilation GetCompilation(params string[] directories)
+ public static Compilation GetCompilation(string[] directories, string[] assemblies)
{
var project = FromDirectory(directories);
var compilation = project.GetCompilationAsync().GetAwaiter().GetResult()!;
- return compilation.AddReferences(GetMetadataReferences());
+ return compilation.AddReferences(GetMetadataReferences())
+ .AddReferences(assemblies.Select(x => MetadataReference.CreateFromFile(x)));
}
public static Assembly CompileAssembly(SyntaxTree[] tree)
diff --git a/TypeScript.ContractGenerator.Roslyn/RoslynCustomizationProvider.cs b/TypeScript.ContractGenerator.Roslyn/RoslynCustomizationProvider.cs
deleted file mode 100644
index 29a5418..0000000
--- a/TypeScript.ContractGenerator.Roslyn/RoslynCustomizationProvider.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Linq;
-
-using Microsoft.CodeAnalysis;
-
-namespace SkbKontur.TypeScript.ContractGenerator.Roslyn
-{
- public static class RoslynCustomizationProvider
- {
- public static (ICustomTypeGenerator, IRootTypesProvider) GetCustomization(string[] directories, string[] assemblies)
- {
- var compilation = AdhocProject.GetCompilation(directories)
- .AddReferences(assemblies.Select(x => MetadataReference.CreateFromFile(x)));
-
- var customGenerationTypes = compilation.GetCustomGenerationTypes();
- var assembly = AdhocProject.CompileAssembly(customGenerationTypes);
-
- var customTypeGenerator = assembly.GetImplementations().Single();
- var typesProvider = assembly.GetImplementations().Single();
-
- return (customTypeGenerator, typesProvider);
- }
- }
-}
\ No newline at end of file
diff --git a/TypeScript.ContractGenerator.Roslyn/RoslynTypeExtensions.cs b/TypeScript.ContractGenerator.Roslyn/RoslynTypeExtensions.cs
index 0ddeb0a..48155cd 100644
--- a/TypeScript.ContractGenerator.Roslyn/RoslynTypeExtensions.cs
+++ b/TypeScript.ContractGenerator.Roslyn/RoslynTypeExtensions.cs
@@ -15,10 +15,15 @@ public static IAttributeInfo[] GetAttributesInfo(this ISymbol symbol)
return symbol.GetAttributes().Select(x => (IAttributeInfo)new RoslynAttributeInfo(x)).ToArray();
}
- public static SyntaxTree[] GetCustomGenerationTypes(this Compilation compilation)
+ public static (ICustomTypeGenerator, IRootTypesProvider) GetCustomization(this Compilation compilation)
{
- return GetNamespaceTypes(compilation, x => !x.IsEqualTo() &&
- x.Interfaces.Any(i => i.IsEqualTo()));
+ var customGenerationTypes = GetCustomGenerationTypes(compilation);
+ var assembly = AdhocProject.CompileAssembly(customGenerationTypes);
+
+ var customTypeGenerator = assembly.GetImplementations().Single();
+ var typesProvider = assembly.GetImplementations().Single();
+
+ return (customTypeGenerator, typesProvider);
}
public static bool IsEqualTo(this ITypeSymbol typeSymbol)
@@ -53,5 +58,11 @@ private static IEnumerable GetNestedTypes(INamedTypeSymbol typ
foreach (var nestedType in type.GetTypeMembers().SelectMany(GetNestedTypes))
yield return nestedType;
}
+
+ private static SyntaxTree[] GetCustomGenerationTypes(Compilation compilation)
+ {
+ return GetNamespaceTypes(compilation, x => !x.IsEqualTo() &&
+ x.Interfaces.Any(i => i.IsEqualTo()));
+ }
}
}
\ No newline at end of file
diff --git a/TypeScript.ContractGenerator.Tests/TestBase.cs b/TypeScript.ContractGenerator.Tests/TestBase.cs
index b5c9637..d5d1a10 100644
--- a/TypeScript.ContractGenerator.Tests/TestBase.cs
+++ b/TypeScript.ContractGenerator.Tests/TestBase.cs
@@ -27,7 +27,7 @@ protected static (ICustomTypeGenerator, IRootTypesProvider) GetCustomization
-
+
diff --git a/version.json b/version.json
index 63272c0..6865661 100644
--- a/version.json
+++ b/version.json
@@ -1,5 +1,5 @@
{
- "version": "2.0-pre10",
+ "version": "2.0",
"assemblyVersion": {
"precision": "build"
},