diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml index c5e7a5fcf4..1c80abd070 100644 --- a/.azure-pipelines/ci-build.yml +++ b/.azure-pipelines/ci-build.yml @@ -567,8 +567,6 @@ extends: baselineFile: $(Build.SourcesDirectory)/guardian/SDL/common/.gdnbaselines suppression: suppressionFile: $(Build.SourcesDirectory)/guardian/SDL/common/.gdnsuppress - variables: - - group: kiota-vscode-extension-publish dependsOn: - github_release steps: @@ -586,18 +584,24 @@ extends: - pwsh: npm i -g @vscode/vsce - pwsh: $(Build.SourcesDirectory)/scripts/get-prerelease-version.ps1 -currentBranch $(Build.SourceBranch) -previewBranch ${{ parameters.previewBranch }} displayName: "Set version suffix" - - pwsh: | - Get-ChildItem -Path $(Pipeline.Workspace) -Filter *.vsix -Recurse | ForEach-Object { - Write-Host "Publishing $_.FullName" - if ($Env:isPrerelease -eq "true") { - Write-Host "Publishing $_.FullName as a pre-release" - vsce publish --pat "$(vs-marketplace-token)" --packagePath $_.FullName --pre-release - } - else { - Write-Host "Publishing $_.FullName as a release" - vsce publish --pat "$(vs-marketplace-token)" --packagePath $_.FullName + - task: AzureCLI@2 + inputs: + azureSubscription: "kiota-vscode-marketplace-publish" + scriptType: "pscore" + scriptLocation: 'inlineScript' + inlineScript: | + $aadToken = az account get-access-token --query accessToken --resource 499b84ac-1321-427f-aa17-267ca6975798 -o tsv + Get-ChildItem -Path $(Pipeline.Workspace) -Filter *.vsix -Recurse | ForEach-Object { + Write-Host "Publishing $_.FullName" + if ($Env:isPrerelease -eq "true") { + Write-Host "Publishing $_.FullName as a pre-release" + vsce publish --pat "$aadToken" --packagePath $_.FullName --pre-release + } + else { + Write-Host "Publishing $_.FullName as a release" + vsce publish --pat "$aadToken" --packagePath $_.FullName + } } - } env: isPrerelease: $(isPrerelease) - deployment: github_release diff --git a/CHANGELOG.md b/CHANGELOG.md index 40d175922f..bbc3658e93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Suppress CS1591 when generating CSharp code and documentation is not available + ### Changed - Changed URI template generation to reuse templates when required templates are absent across operations. - Updated reserved name providers for Java and Php so that "object" can be escaped. +- Do not generate CS8603 warnings when enabling backing store in CSharp generation. ## [1.13.0] - 2024-04-04 diff --git a/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs b/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs index 1444ae03d9..62e01592b3 100644 --- a/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs +++ b/src/Kiota.Builder/Writers/CSharp/CSharpConventionService.cs @@ -39,15 +39,16 @@ public static void WriteNullableClosing(LanguageWriter writer) private const string ReferenceTypePrefix = ""; #pragma warning disable S1006 // Method overrides should not change parameter defaults - public override void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") + public override bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") #pragma warning restore S1006 // Method overrides should not change parameter defaults { ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(element); - if (element is not CodeElement codeElement) return; - if (!element.Documentation.DescriptionAvailable) return; + if (element is not CodeElement codeElement) return false; + if (!element.Documentation.DescriptionAvailable) return false; var description = element.Documentation.GetDescription(type => GetTypeStringForDocumentation(type, codeElement), normalizationFunc: static x => x.CleanupXMLString()); writer.WriteLine($"{DocCommentPrefix}{prefix}{description}{suffix}"); + return true; } public void WriteAdditionalDescriptionItem(string description, LanguageWriter writer) { @@ -55,12 +56,12 @@ public void WriteAdditionalDescriptionItem(string description, LanguageWriter wr ArgumentNullException.ThrowIfNull(description); writer.WriteLine($"{DocCommentPrefix}{description}"); } - public void WriteLongDescription(IDocumentedElement element, LanguageWriter writer) + public bool WriteLongDescription(IDocumentedElement element, LanguageWriter writer) { ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(element); - if (element.Documentation is not { } documentation) return; - if (element is not CodeElement codeElement) return; + if (element.Documentation is not { } documentation) return false; + if (element is not CodeElement codeElement) return false; if (documentation.DescriptionAvailable || documentation.ExternalDocumentationAvailable) { writer.WriteLine($"{DocCommentPrefix}"); @@ -72,7 +73,9 @@ public void WriteLongDescription(IDocumentedElement element, LanguageWriter writ if (documentation.ExternalDocumentationAvailable) writer.WriteLine($"{DocCommentPrefix}{documentation.DocumentationLabel} "); writer.WriteLine($"{DocCommentPrefix}"); + return true; } + return false; } public override string GetAccessModifier(AccessModifier access) { diff --git a/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs index cca625a398..27b7954379 100644 --- a/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs +++ b/src/Kiota.Builder/Writers/CSharp/CodeClassDeclarationWriter.cs @@ -35,9 +35,11 @@ public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWrit .Select(static x => x.ToFirstCharacterUpperCase()) .ToArray(); var derivation = derivedTypes.Length != 0 ? ": " + derivedTypes.Aggregate(static (x, y) => $"{x}, {y}") + " " : string.Empty; - conventions.WriteLongDescription(parentClass, writer); + bool hasDescription = conventions.WriteLongDescription(parentClass, writer); conventions.WriteDeprecationAttribute(parentClass, writer); + if (!hasDescription) writer.WriteLine("#pragma warning disable CS1591"); writer.WriteLine($"public class {codeElement.Name.ToFirstCharacterUpperCase()} {derivation}"); + if (!hasDescription) writer.WriteLine("#pragma warning restore CS1591"); writer.StartBlock(); } } diff --git a/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs index 207468f20f..d74a7e6f6f 100644 --- a/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs +++ b/src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs @@ -29,22 +29,26 @@ public override void WriteCodeElement(CodeEnum codeElement, LanguageWriter write writer.WriteLine(x); writer.StartBlock($"namespace {codeNamespace.Name} {{"); } - conventions.WriteShortDescription(codeElement, writer); + bool hasDescription = conventions.WriteShortDescription(codeElement, writer); if (codeElement.Flags) writer.WriteLine("[Flags]"); conventions.WriteDeprecationAttribute(codeElement, writer); + if (!hasDescription) writer.WriteLine("#pragma warning disable CS1591"); writer.WriteLine($"public enum {codeElement.Name.ToFirstCharacterUpperCase()}"); + if (!hasDescription) writer.WriteLine("#pragma warning restore CS1591"); writer.StartBlock(); var idx = 0; foreach (var option in codeElement.Options) { - conventions.WriteShortDescription(option, writer); + hasDescription = conventions.WriteShortDescription(option, writer); if (option.IsNameEscaped) { writer.WriteLine($"[EnumMember(Value = \"{option.SerializationName}\")]"); } + if (!hasDescription) writer.WriteLine("#pragma warning disable CS1591"); writer.WriteLine($"{option.Name.ToFirstCharacterUpperCase()}{(codeElement.Flags ? " = " + GetEnumFlag(idx) : string.Empty)},"); + if (!hasDescription) writer.WriteLine("#pragma warning restore CS1591"); idx++; } if (codeNamespace != null) diff --git a/src/Kiota.Builder/Writers/CSharp/CodePropertyWriter.cs b/src/Kiota.Builder/Writers/CSharp/CodePropertyWriter.cs index 3f00038af6..4b0baaf35c 100644 --- a/src/Kiota.Builder/Writers/CSharp/CodePropertyWriter.cs +++ b/src/Kiota.Builder/Writers/CSharp/CodePropertyWriter.cs @@ -50,10 +50,12 @@ private void WritePropertyInternal(CodeProperty codeElement, LanguageWriter writ case CodePropertyKind.AdditionalData when backingStoreProperty != null: case CodePropertyKind.Custom when backingStoreProperty != null: var backingStoreKey = codeElement.WireName; + var nullableOp = !codeElement.IsOfKind(CodePropertyKind.AdditionalData) ? "?" : string.Empty; + var nullableEx = codeElement.IsOfKind(CodePropertyKind.AdditionalData) ? " ?? throw new InvalidOperationException(\"AdditionalData can not be null\")" : string.Empty; writer.WriteLine($"{conventions.GetAccessModifier(codeElement.Access)} {propertyType} {codeElement.Name.ToFirstCharacterUpperCase()} {{"); writer.IncreaseIndent(); - writer.WriteLine($"get {{ return {backingStoreProperty.Name.ToFirstCharacterUpperCase()}?.Get<{propertyType}>(\"{backingStoreKey}\"); }}"); - writer.WriteLine($"set {{ {backingStoreProperty.Name.ToFirstCharacterUpperCase()}?.Set(\"{backingStoreKey}\", value); }}"); + writer.WriteLine($"get {{ return {backingStoreProperty.Name.ToFirstCharacterUpperCase()}{nullableOp}.Get<{propertyType}>(\"{backingStoreKey}\"){nullableEx}; }}"); + writer.WriteLine($"set {{ {backingStoreProperty.Name.ToFirstCharacterUpperCase()}{nullableOp}.Set(\"{backingStoreKey}\", value); }}"); writer.DecreaseIndent(); writer.WriteLine("}"); break; diff --git a/src/Kiota.Builder/Writers/CommonLanguageConventionService.cs b/src/Kiota.Builder/Writers/CommonLanguageConventionService.cs index 313583b196..f94a289408 100644 --- a/src/Kiota.Builder/Writers/CommonLanguageConventionService.cs +++ b/src/Kiota.Builder/Writers/CommonLanguageConventionService.cs @@ -41,5 +41,5 @@ public string TranslateType(CodeTypeBase type) } public abstract string TranslateType(CodeType type); - public abstract void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = ""); + public abstract bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = ""); } diff --git a/src/Kiota.Builder/Writers/Go/GoConventionService.cs b/src/Kiota.Builder/Writers/Go/GoConventionService.cs index 5582ba25b8..02870aaca5 100644 --- a/src/Kiota.Builder/Writers/Go/GoConventionService.cs +++ b/src/Kiota.Builder/Writers/Go/GoConventionService.cs @@ -168,12 +168,12 @@ currentEnumDefinition.Parent is CodeNamespace enumNS && return string.Empty; } - public override void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") + public override bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") { ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(element); - if (!element.Documentation.DescriptionAvailable) return; - if (element is not CodeElement codeElement) return; + if (!element.Documentation.DescriptionAvailable) return false; + if (element is not CodeElement codeElement) return false; var description = element.Documentation.GetDescription(x => GetTypeString(x, codeElement, true, false)); if (!string.IsNullOrEmpty(prefix)) @@ -181,6 +181,7 @@ public override void WriteShortDescription(IDocumentedElement element, LanguageW description = description.ToFirstCharacterLowerCase(); } WriteDescriptionItem($"{prefix}{description}{suffix}", writer); + return true; } public void WriteDescriptionItem(string description, LanguageWriter writer) { diff --git a/src/Kiota.Builder/Writers/ILanguageConventionService.cs b/src/Kiota.Builder/Writers/ILanguageConventionService.cs index 8b65e9018f..8cdedaf3a0 100644 --- a/src/Kiota.Builder/Writers/ILanguageConventionService.cs +++ b/src/Kiota.Builder/Writers/ILanguageConventionService.cs @@ -27,5 +27,5 @@ string TempDictionaryVarName string GetTypeString(CodeTypeBase code, CodeElement targetElement, bool includeCollectionInformation = true, LanguageWriter? writer = null); string TranslateType(CodeType type); string GetParameterSignature(CodeParameter parameter, CodeElement targetElement, LanguageWriter? writer = null); - void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = ""); + bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = ""); } diff --git a/src/Kiota.Builder/Writers/Java/JavaConventionService.cs b/src/Kiota.Builder/Writers/Java/JavaConventionService.cs index 33d6b49fa4..29d4191c63 100644 --- a/src/Kiota.Builder/Writers/Java/JavaConventionService.cs +++ b/src/Kiota.Builder/Writers/Java/JavaConventionService.cs @@ -98,16 +98,18 @@ internal string GetReturnDocComment(string returnType) } private const string ReferenceTypePrefix = "{@link "; private const string ReferenceTypeSuffix = "}"; - public override void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") + public override bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") { ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(element); - if (!element.Documentation.DescriptionAvailable) return; - if (element is not CodeElement codeElement) return; + if (!element.Documentation.DescriptionAvailable) return false; + if (element is not CodeElement codeElement) return false; var description = element.Documentation.GetDescription(x => GetTypeReferenceForDocComment(x, codeElement), ReferenceTypePrefix, ReferenceTypeSuffix, RemoveInvalidDescriptionCharacters); writer.WriteLine($"{DocCommentStart} {description}{DocCommentEnd}"); + + return true; } internal string GetTypeReferenceForDocComment(CodeTypeBase code, CodeElement targetElement) { diff --git a/src/Kiota.Builder/Writers/Php/PhpConventionService.cs b/src/Kiota.Builder/Writers/Php/PhpConventionService.cs index b2f1096153..67cee78295 100644 --- a/src/Kiota.Builder/Writers/Php/PhpConventionService.cs +++ b/src/Kiota.Builder/Writers/Php/PhpConventionService.cs @@ -136,18 +136,20 @@ private string GetCollectionDocString(CodeParameter codeParameter) } internal static string RemoveInvalidDescriptionCharacters(string originalDescription) => originalDescription.Replace("\\", "/", StringComparison.OrdinalIgnoreCase); - public override void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") + public override bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") { ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(element); - if (!element.Documentation.DescriptionAvailable) return; - if (element is not CodeElement codeElement) return; + if (!element.Documentation.DescriptionAvailable) return false; + if (element is not CodeElement codeElement) return false; var description = element.Documentation.GetDescription(type => GetTypeString(type, codeElement), normalizationFunc: RemoveInvalidDescriptionCharacters); writer.WriteLine(DocCommentStart); writer.WriteLine($"{DocCommentPrefix}{description}"); writer.WriteLine(DocCommentEnd); + + return true; } public void WriteLongDescription(IDocumentedElement element, LanguageWriter writer, IEnumerable? additionalRemarks = default) diff --git a/src/Kiota.Builder/Writers/Python/PythonConventionService.cs b/src/Kiota.Builder/Writers/Python/PythonConventionService.cs index b4b58b8ad3..2ff655901d 100644 --- a/src/Kiota.Builder/Writers/Python/PythonConventionService.cs +++ b/src/Kiota.Builder/Writers/Python/PythonConventionService.cs @@ -155,17 +155,19 @@ private string WriteInlineDeclaration(CodeType currentType, CodeElement targetEl return "object"; return $"{{{innerDeclaration}}}"; } - public override void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") + public override bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") { ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(element); - if (!element.Documentation.DescriptionAvailable) return; - if (element is not CodeElement codeElement) return; + if (!element.Documentation.DescriptionAvailable) return false; + if (element is not CodeElement codeElement) return false; var description = element.Documentation.GetDescription(type => GetTypeString(type, codeElement), normalizationFunc: RemoveInvalidDescriptionCharacters); writer.WriteLine(DocCommentStart); writer.WriteLine(description); writer.WriteLine(DocCommentEnd); + + return true; } public void WriteLongDescription(IDocumentedElement element, LanguageWriter writer, IEnumerable? additionalRemarks = default) { diff --git a/src/Kiota.Builder/Writers/Ruby/RubyConventionService.cs b/src/Kiota.Builder/Writers/Ruby/RubyConventionService.cs index ea89e6c986..93533ceb0f 100644 --- a/src/Kiota.Builder/Writers/Ruby/RubyConventionService.cs +++ b/src/Kiota.Builder/Writers/Ruby/RubyConventionService.cs @@ -52,16 +52,18 @@ public override string TranslateType(CodeType type) _ => type.Name.ToFirstCharacterUpperCase() is string typeName && !string.IsNullOrEmpty(typeName) ? typeName : "object", }; } - public override void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") + public override bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") { ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(element); - if (!element.Documentation.DescriptionAvailable) return; - if (element is not CodeElement codeElement) return; + if (!element.Documentation.DescriptionAvailable) return false; + if (element is not CodeElement codeElement) return false; var description = element.Documentation.GetDescription(type => GetTypeString(type, codeElement)); writer.WriteLine($"{DocCommentPrefix}"); writer.WriteLine($"# {description}"); + + return true; } #pragma warning disable CA1822 // Method should be static public string GetNormalizedNamespacePrefixForType(CodeTypeBase type) diff --git a/src/Kiota.Builder/Writers/Swift/SwiftConventionService.cs b/src/Kiota.Builder/Writers/Swift/SwiftConventionService.cs index 62edbb6dd2..8b3001058b 100644 --- a/src/Kiota.Builder/Writers/Swift/SwiftConventionService.cs +++ b/src/Kiota.Builder/Writers/Swift/SwiftConventionService.cs @@ -20,15 +20,17 @@ public SwiftConventionService(string clientNamespaceName) public static readonly char NullableMarker = '?'; public static string NullableMarkerAsString => "?"; public override string ParseNodeInterfaceName => "ParseNode"; - public override void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") + public override bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") { ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(element); - if (!element.Documentation.DescriptionAvailable) return; - if (element is not CodeElement codeElement) return; + if (!element.Documentation.DescriptionAvailable) return false; + if (element is not CodeElement codeElement) return false; var description = element.Documentation.GetDescription(type => GetTypeString(type, codeElement)); writer.WriteLine($"{DocCommentPrefix}{prefix}{description}{prefix}"); + + return true; } public override string GetAccessModifier(AccessModifier access) { diff --git a/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs b/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs index 7d7bd6a39b..9770e7ad57 100644 --- a/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs +++ b/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs @@ -132,15 +132,17 @@ public bool IsPrimitiveType(string typeName) } #pragma warning restore CA1822 // Method should be static internal static string RemoveInvalidDescriptionCharacters(string originalDescription) => originalDescription?.Replace("\\", "/", StringComparison.OrdinalIgnoreCase) ?? string.Empty; - public override void WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") + public override bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "") { ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(element); - if (!element.Documentation.DescriptionAvailable) return; - if (element is not CodeElement codeElement) return; + if (!element.Documentation.DescriptionAvailable) return false; + if (element is not CodeElement codeElement) return false; var description = element.Documentation.GetDescription(type => GetTypeString(type, codeElement), ReferenceTypePrefix, ReferenceTypeSuffix, RemoveInvalidDescriptionCharacters); writer.WriteLine($"{DocCommentStart} {description}{DocCommentEnd}"); + + return true; } internal const string ReferenceTypePrefix = "{@link "; internal const string ReferenceTypeSuffix = "}"; diff --git a/tests/Kiota.Builder.Tests/Writers/CSharp/CodePropertyWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/CSharp/CodePropertyWriterTests.cs index 27516fbfd2..a1d78fd859 100644 --- a/tests/Kiota.Builder.Tests/Writers/CSharp/CodePropertyWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/CSharp/CodePropertyWriterTests.cs @@ -113,8 +113,8 @@ public void MapsAdditionalDataPropertiesToBackingStore() property.Kind = CodePropertyKind.AdditionalData; writer.Write(property); var result = tw.ToString(); - Assert.Contains("get { return BackingStore?.Get(\"propertyName\"); }", result); - Assert.Contains("set { BackingStore?.Set(\"propertyName\", value);", result); + Assert.Contains("get { return BackingStore.Get(\"propertyName\") ?? throw new InvalidOperationException(\"AdditionalData can not be null\"); }", result); + Assert.Contains("set { BackingStore.Set(\"propertyName\", value);", result); } [Fact] public void WritesSerializationAttribute()