From bdd85a1567cd00f0685699a46459fbbb3c7e956f Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 18 Sep 2023 14:12:12 -0400 Subject: [PATCH 1/2] - adds auto-generated comment for typescript file - fixes functions comment emission Signed-off-by: Vincent Biret --- CHANGELOG.md | 2 + .../Writers/TypeScript/CodeBlockEndWriter.cs | 9 +- .../TypeScript/CodeClassDeclarationWriter.cs | 2 + .../Writers/TypeScript/CodeFunctionWriter.cs | 1 + .../CodeInterfaceDeclarationWriter.cs | 32 ++--- .../TypeScript/TypeScriptConventionService.cs | 11 ++ .../Writers/TypeScript/TypeScriptWriter.cs | 2 +- .../CodeClassDeclarationWriterTests.cs | 8 ++ .../TypeScript/CodeClassEndWriterTests.cs | 6 +- .../TypeScript/CodeFunctionWriterTests.cs | 25 ++++ .../CodeInterfaceDeclarationWriterTests .cs | 124 +++++++++--------- 11 files changed, 143 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b15d0d68d2..fd1ad37cf7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added auto-generated comment for TypeScript generation. [#3244](https://github.com/microsoft/kiota/issues/3244) + ### Changed - Localhost based descriptions are not cached anymore to facilitate development workflows. [#3316](https://github.com/microsoft/kiota/issues/3316) diff --git a/src/Kiota.Builder/Writers/TypeScript/CodeBlockEndWriter.cs b/src/Kiota.Builder/Writers/TypeScript/CodeBlockEndWriter.cs index b867201b9e..ad1e6d07e9 100644 --- a/src/Kiota.Builder/Writers/TypeScript/CodeBlockEndWriter.cs +++ b/src/Kiota.Builder/Writers/TypeScript/CodeBlockEndWriter.cs @@ -2,13 +2,18 @@ using Kiota.Builder.CodeDOM; namespace Kiota.Builder.Writers.TypeScript; -public class CodeBlockEndWriter : ICodeElementWriter +public class CodeBlockEndWriter : BaseElementWriter { - public void WriteCodeElement(BlockEnd codeElement, LanguageWriter writer) + public CodeBlockEndWriter(TypeScriptConventionService conventionService) : base(conventionService) + { + } + public override void WriteCodeElement(BlockEnd codeElement, LanguageWriter writer) { ArgumentNullException.ThrowIfNull(codeElement); ArgumentNullException.ThrowIfNull(writer); if (codeElement.Parent is CodeNamespace) return; writer.CloseBlock(); + if (codeElement.Parent?.Parent is CodeNamespace) + conventions.WriteAutoGeneratedEnd(writer); } } diff --git a/src/Kiota.Builder/Writers/TypeScript/CodeClassDeclarationWriter.cs b/src/Kiota.Builder/Writers/TypeScript/CodeClassDeclarationWriter.cs index a2c86fab5b..a5614cf670 100644 --- a/src/Kiota.Builder/Writers/TypeScript/CodeClassDeclarationWriter.cs +++ b/src/Kiota.Builder/Writers/TypeScript/CodeClassDeclarationWriter.cs @@ -16,6 +16,8 @@ public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWrit { ArgumentNullException.ThrowIfNull(codeElement); ArgumentNullException.ThrowIfNull(writer); + if (codeElement.Parent?.Parent is CodeNamespace) + conventions.WriteAutoGeneratedStart(writer); var parentNamespace = codeElement.GetImmediateParentOfType(); _codeUsingWriter.WriteCodeElement(codeElement.Usings, parentNamespace, writer); diff --git a/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs b/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs index 5a7c0a2eaa..851e4bd1fe 100644 --- a/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs +++ b/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs @@ -23,6 +23,7 @@ public override void WriteCodeElement(CodeFunction codeElement, LanguageWriter w if (codeElement.OriginalLocalMethod == null) throw new InvalidOperationException($"{nameof(codeElement.OriginalLocalMethod)} should not be null"); ArgumentNullException.ThrowIfNull(writer); if (codeElement.Parent is not CodeNamespace) throw new InvalidOperationException("the parent of a function should be a namespace"); + conventions.WriteAutoGeneratedStart(writer); _codeUsingWriter.WriteCodeElement(codeElement.StartBlock.Usings, codeElement.GetImmediateParentOfType(), writer); var codeMethod = codeElement.OriginalLocalMethod; diff --git a/src/Kiota.Builder/Writers/TypeScript/CodeInterfaceDeclarationWriter.cs b/src/Kiota.Builder/Writers/TypeScript/CodeInterfaceDeclarationWriter.cs index bb938fd1a1..71b86539fc 100644 --- a/src/Kiota.Builder/Writers/TypeScript/CodeInterfaceDeclarationWriter.cs +++ b/src/Kiota.Builder/Writers/TypeScript/CodeInterfaceDeclarationWriter.cs @@ -4,26 +4,26 @@ using Kiota.Builder.CodeDOM; using Kiota.Builder.Extensions; -namespace Kiota.Builder.Writers.TypeScript +namespace Kiota.Builder.Writers.TypeScript; +public class CodeInterfaceDeclarationWriter : BaseElementWriter { - public class CodeInterfaceDeclarationWriter : BaseElementWriter + private readonly CodeUsingWriter _codeUsingWriter; + public CodeInterfaceDeclarationWriter(TypeScriptConventionService conventionService, string clientNamespaceName) : base(conventionService) { - private readonly CodeUsingWriter _codeUsingWriter; - public CodeInterfaceDeclarationWriter(TypeScriptConventionService conventionService, string clientNamespaceName) : base(conventionService) - { - _codeUsingWriter = new(clientNamespaceName); - } + _codeUsingWriter = new(clientNamespaceName); + } - public override void WriteCodeElement(InterfaceDeclaration codeElement, LanguageWriter writer) - { - ArgumentNullException.ThrowIfNull(codeElement); - ArgumentNullException.ThrowIfNull(writer); + public override void WriteCodeElement(InterfaceDeclaration codeElement, LanguageWriter writer) + { + ArgumentNullException.ThrowIfNull(codeElement); + ArgumentNullException.ThrowIfNull(writer); - var parentNamespace = codeElement.GetImmediateParentOfType(); - _codeUsingWriter.WriteCodeElement(codeElement.Usings, parentNamespace, writer); + var parentNamespace = codeElement.GetImmediateParentOfType(); + if (codeElement.Parent?.Parent is CodeNamespace) + conventions.WriteAutoGeneratedStart(writer); + _codeUsingWriter.WriteCodeElement(codeElement.Usings, parentNamespace, writer); - var derivation = codeElement.Implements.Any() ? $" extends {codeElement.Implements.Select(static x => x.Name).Aggregate(static (x, y) => x + ", " + y)}" : string.Empty; - writer.StartBlock($"export interface {codeElement.Name.ToFirstCharacterUpperCase()}{derivation} {{"); - } + var derivation = codeElement.Implements.Any() ? $" extends {codeElement.Implements.Select(static x => x.Name).Aggregate(static (x, y) => x + ", " + y)}" : string.Empty; + writer.StartBlock($"export interface {codeElement.Name.ToFirstCharacterUpperCase()}{derivation} {{"); } } diff --git a/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs b/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs index bad753c134..5d0d63f64c 100644 --- a/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs +++ b/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs @@ -15,6 +15,17 @@ public TypeScriptConventionService(LanguageWriter languageWriter) { writer = languageWriter; } + internal void WriteAutoGeneratedStart(LanguageWriter writer) + { + writer.WriteLine("// tslint:disable"); + writer.WriteLine("// eslint-disable"); + writer.WriteLine("// Generated by Microsoft Kiota"); + } + internal void WriteAutoGeneratedEnd(LanguageWriter writer) + { + writer.WriteLine("// tslint:enable"); + writer.WriteLine("// eslint-enable"); + } private readonly LanguageWriter writer; public override string StreamTypeName => "ArrayBuffer"; public override string VoidTypeName => "void"; diff --git a/src/Kiota.Builder/Writers/TypeScript/TypeScriptWriter.cs b/src/Kiota.Builder/Writers/TypeScript/TypeScriptWriter.cs index e63a6174eb..d941c5ec81 100644 --- a/src/Kiota.Builder/Writers/TypeScript/TypeScriptWriter.cs +++ b/src/Kiota.Builder/Writers/TypeScript/TypeScriptWriter.cs @@ -9,7 +9,7 @@ public TypeScriptWriter(string rootPath, string clientNamespaceName, bool usesBa PathSegmenter = new TypeScriptPathSegmenter(rootPath, clientNamespaceName); var conventionService = new TypeScriptConventionService(this); AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService, clientNamespaceName)); - AddOrReplaceCodeElementWriter(new CodeBlockEndWriter()); + AddOrReplaceCodeElementWriter(new CodeBlockEndWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeEnumWriter(conventionService)); AddOrReplaceCodeElementWriter(new CodeMethodWriter(conventionService, usesBackingStore)); AddOrReplaceCodeElementWriter(new CodeFunctionWriter(conventionService, clientNamespaceName)); diff --git a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeClassDeclarationWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeClassDeclarationWriterTests.cs index e1dbdf0448..a33b8f81fe 100644 --- a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeClassDeclarationWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeClassDeclarationWriterTests.cs @@ -37,6 +37,14 @@ public void Dispose() GC.SuppressFinalize(this); } [Fact] + public void WritesAutoGenerationStart() + { + codeElementWriter.WriteCodeElement(parentClass.StartBlock, writer); + var result = tw.ToString(); + Assert.Contains("// eslint-disable", result); + Assert.Contains("// tslint:disable", result); + } + [Fact] public void WritesSimpleDeclaration() { codeElementWriter.WriteCodeElement(parentClass.StartBlock, writer); diff --git a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeClassEndWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeClassEndWriterTests.cs index f1af0e7b4c..1513b0e70c 100644 --- a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeClassEndWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeClassEndWriterTests.cs @@ -19,8 +19,8 @@ public class CodeClassEndWriterTests : IDisposable private readonly CodeClass parentClass; public CodeClassEndWriterTests() { - codeElementWriter = new CodeBlockEndWriter(); writer = LanguageWriter.GetLanguageWriter(GenerationLanguage.TypeScript, DefaultPath, DefaultName); + codeElementWriter = new CodeBlockEndWriter(new(writer)); tw = new StringWriter(); writer.SetTextWriter(tw); var root = CodeNamespace.InitRootNamespace(); @@ -45,12 +45,16 @@ public void ClosesNestedClasses() codeElementWriter.WriteCodeElement(child.EndBlock, writer); var result = tw.ToString(); Assert.Equal(1, result.Count(x => x == '}')); + Assert.DoesNotContain("// eslint-enable", result); + Assert.DoesNotContain("// tslint:enable", result); } [Fact] public void ClosesNonNestedClasses() { codeElementWriter.WriteCodeElement(parentClass.EndBlock, writer); var result = tw.ToString(); + Assert.Contains("// eslint-enable", result); + Assert.Contains("// tslint:enable", result); Assert.Equal(1, result.Count(x => x == '}')); } } diff --git a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs index aeca11d3f7..cb45af6c10 100644 --- a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeFunctionWriterTests.cs @@ -33,6 +33,31 @@ public void Dispose() GC.SuppressFinalize(this); } + [Fact] + public async Task WritesAutoGenerationStart() + { + var parentClass = TestHelper.CreateModelClass(root, "parentClass", true); + TestHelper.AddSerializationPropertiesToModelClass(parentClass); + await ILanguageRefiner.Refine(new GenerationConfiguration { Language = GenerationLanguage.TypeScript }, root); + var serializeFunction = root.FindChildByName($"deserializeInto{parentClass.Name.ToFirstCharacterUpperCase()}"); + writer.Write(serializeFunction); + var result = tw.ToString(); + Assert.Contains("// eslint-disable", result); + Assert.Contains("// tslint:disable", result); + } + [Fact] + public async Task WritesAutoGenerationEnd() + { + var parentClass = TestHelper.CreateModelClass(root, "parentClass", true); + TestHelper.AddSerializationPropertiesToModelClass(parentClass); + await ILanguageRefiner.Refine(new GenerationConfiguration { Language = GenerationLanguage.TypeScript }, root); + var serializeFunction = root.FindChildByName($"deserializeInto{parentClass.Name.ToFirstCharacterUpperCase()}"); + writer.Write(serializeFunction); + var result = tw.ToString(); + Assert.DoesNotContain("// eslint-enable", result); //written by code end block writer + Assert.DoesNotContain("// tslint:enable", result); + } + [Fact] public async Task WritesModelFactoryBody() { diff --git a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeInterfaceDeclarationWriterTests .cs b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeInterfaceDeclarationWriterTests .cs index f22a8500d5..4250c495ec 100644 --- a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeInterfaceDeclarationWriterTests .cs +++ b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodeInterfaceDeclarationWriterTests .cs @@ -3,71 +3,77 @@ using Kiota.Builder.CodeDOM; using Xunit; -namespace Kiota.Builder.Writers.TypeScript.Tests +namespace Kiota.Builder.Writers.TypeScript.Tests; +public class CodeInterfaceDeclaraterWriterTests : IDisposable { - public class CodeInterfaceDeclaraterWriterTests : IDisposable - { - private const string DefaultPath = "./"; - private const string DefaultName = "name"; - private readonly StringWriter tw; - private readonly LanguageWriter writer; - private readonly CodeInterface parentInterface; + private const string DefaultPath = "./"; + private const string DefaultName = "name"; + private readonly StringWriter tw; + private readonly LanguageWriter writer; + private readonly CodeInterface parentInterface; - public CodeInterfaceDeclaraterWriterTests() - { - writer = LanguageWriter.GetLanguageWriter(GenerationLanguage.TypeScript, DefaultPath, DefaultName); - tw = new StringWriter(); - writer.SetTextWriter(tw); - var root = CodeNamespace.InitRootNamespace(); - var ns = root.AddNamespace("graphtests.models"); - parentInterface = new CodeInterface() - { - Name = "parent" - }; - ns.AddInterface(parentInterface); - } - public void Dispose() - { - tw?.Dispose(); - GC.SuppressFinalize(this); - } - [Fact] - public void WritesSimpleDeclaration() + public CodeInterfaceDeclaraterWriterTests() + { + writer = LanguageWriter.GetLanguageWriter(GenerationLanguage.TypeScript, DefaultPath, DefaultName); + tw = new StringWriter(); + writer.SetTextWriter(tw); + var root = CodeNamespace.InitRootNamespace(); + var ns = root.AddNamespace("graphtests.models"); + parentInterface = new CodeInterface() { - writer.Write(parentInterface.StartBlock); - var result = tw.ToString(); - Assert.Contains("export interface", result); - } + Name = "parent" + }; + ns.AddInterface(parentInterface); + } + public void Dispose() + { + tw?.Dispose(); + GC.SuppressFinalize(this); + } + [Fact] + public void WritesAutoGenerationStart() + { + writer.Write(parentInterface.StartBlock); + var result = tw.ToString(); + Assert.Contains("// eslint-disable", result); + Assert.Contains("// tslint:disable", result); + } + [Fact] + public void WritesSimpleDeclaration() + { + writer.Write(parentInterface.StartBlock); + var result = tw.ToString(); + Assert.Contains("export interface", result); + } - [Fact] - public void WritesInheritance() - { + [Fact] + public void WritesInheritance() + { - parentInterface.StartBlock.AddImplements(new CodeType() - { - Name = "someInterface" - }); - writer.Write(parentInterface.StartBlock); - var result = tw.ToString(); - Assert.Contains("extends", result); - } - [Fact] - public void WritesImports() + parentInterface.StartBlock.AddImplements(new CodeType() + { + Name = "someInterface" + }); + writer.Write(parentInterface.StartBlock); + var result = tw.ToString(); + Assert.Contains("extends", result); + } + [Fact] + public void WritesImports() + { + parentInterface.StartBlock.AddUsings(new CodeUsing { - parentInterface.StartBlock.AddUsings(new CodeUsing + Name = "Objects", + Declaration = new() { - Name = "Objects", - Declaration = new() - { - Name = "util", - IsExternal = true, - } - }); - writer.Write(parentInterface.StartBlock); - var result = tw.ToString(); - Assert.Contains("import", result); - Assert.Contains("from", result); - Assert.Contains("'util'", result); - } + Name = "util", + IsExternal = true, + } + }); + writer.Write(parentInterface.StartBlock); + var result = tw.ToString(); + Assert.Contains("import", result); + Assert.Contains("from", result); + Assert.Contains("'util'", result); } } From 5f2cb2cb914d3d83df01457b74c1cfe6219c75cb Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Mon, 18 Sep 2023 14:20:08 -0400 Subject: [PATCH 2/2] - removes redundant undefined qualifier in TypeScript for properties --- CHANGELOG.md | 1 + src/Kiota.Builder/Writers/TypeScript/CodePropertyWriter.cs | 4 ++-- .../Writers/TypeScript/CodePropertyWriterTests.cs | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd1ad37cf7..ef03f8118c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Localhost based descriptions are not cached anymore to facilitate development workflows. [#3316](https://github.com/microsoft/kiota/issues/3316) +- Removed redundant undefined qualifier in TypeScript for properties. [#3244](https://github.com/microsoft/kiota/issues/3244) ## [1.6.1] - 2023-09-11 diff --git a/src/Kiota.Builder/Writers/TypeScript/CodePropertyWriter.cs b/src/Kiota.Builder/Writers/TypeScript/CodePropertyWriter.cs index 20e4cbc36a..f12b8815df 100644 --- a/src/Kiota.Builder/Writers/TypeScript/CodePropertyWriter.cs +++ b/src/Kiota.Builder/Writers/TypeScript/CodePropertyWriter.cs @@ -30,7 +30,7 @@ public override void WriteCodeElement(CodeProperty codeElement, LanguageWriter w private static void WriteCodePropertyForInterface(CodeProperty codeElement, LanguageWriter writer, string returnType, bool isFlagEnum) { - writer.WriteLine($"{codeElement.Name.ToFirstCharacterLowerCase()}?: {returnType}{(isFlagEnum ? "[]" : string.Empty)}{(codeElement.Type.IsNullable ? " | undefined" : string.Empty)};"); + writer.WriteLine($"{codeElement.Name.ToFirstCharacterLowerCase()}?: {returnType}{(isFlagEnum ? "[]" : string.Empty)};"); } private void WriteCodePropertyForClass(CodeProperty codeElement, CodeClass parentClass, LanguageWriter writer, string returnType, bool isFlagEnum) @@ -45,7 +45,7 @@ private void WriteCodePropertyForClass(CodeProperty codeElement, CodeClass paren writer.CloseBlock(); break; default: - writer.WriteLine($"{conventions.GetAccessModifier(codeElement.Access)} {codeElement.NamePrefix}{codeElement.Name.ToFirstCharacterLowerCase()}{(codeElement.Type.IsNullable ? "?" : string.Empty)}: {returnType}{(isFlagEnum ? "[]" : string.Empty)}{(codeElement.Type.IsNullable ? " | undefined" : string.Empty)};"); + writer.WriteLine($"{conventions.GetAccessModifier(codeElement.Access)} {codeElement.NamePrefix}{codeElement.Name.ToFirstCharacterLowerCase()}{(codeElement.Type.IsNullable ? "?" : string.Empty)}: {returnType}{(isFlagEnum ? "[]" : string.Empty)};"); break; } } diff --git a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodePropertyWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodePropertyWriterTests.cs index 9d9e2ef90e..8961fc4114 100644 --- a/tests/Kiota.Builder.Tests/Writers/TypeScript/CodePropertyWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/TypeScript/CodePropertyWriterTests.cs @@ -75,7 +75,8 @@ public void WritesCustomProperty() property.Kind = CodePropertyKind.Custom; writer.Write(property); var result = tw.ToString(); - Assert.Contains($"{PropertyName}?: {TypeName} | undefined", result); + Assert.Contains($"{PropertyName}?: {TypeName}", result); + Assert.DoesNotContain("| undefined", result); // redundant with ? } [Fact] public void WritesFlagEnums()