diff --git a/CHANGELOG.md b/CHANGELOG.md index 250104a864..67f4939389 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,9 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Include the type which a promise resolves to in PHPDocs for PHP. [#3542](https://github.com/microsoft/kiota/issues/3542) - Added null check for null content type instances when getting deprecation information [#3588](https://github.com/microsoft/kiota/issues/3588) - Aligns header management in Python with other languages. [#3430](https://github.com/microsoft/kiota/issues/3430) -- Fixed parameters that are in camelcase to snakecase in Python. [#3525](https://github.com/microsoft/kiota/issues/3525 +- Fixed parameters that are in camelcase to snakecase in Python. [#3525](https://github.com/microsoft/kiota/issues/3525) - Fixed missing imports for method parameters that are query parameters. - Replaces the use of "new" by "override" and "virtual" in CSharp models. - Fixed query parameters type mapping for arrays. [#3354](https://github.com/microsoft/kiota/issues/3354) diff --git a/src/Kiota.Builder/Refiners/PhpRefiner.cs b/src/Kiota.Builder/Refiners/PhpRefiner.cs index ff068c8a95..1d12aef87d 100644 --- a/src/Kiota.Builder/Refiners/PhpRefiner.cs +++ b/src/Kiota.Builder/Refiners/PhpRefiner.cs @@ -192,7 +192,7 @@ public override Task Refine(CodeNamespace generatedCode, CancellationToken cance "Microsoft\\Kiota\\Abstractions\\Store", "BackingStoreFactory", "BackingStoreFactorySingleton"), new (x => x is CodeProperty prop && prop.IsOfKind(CodePropertyKind.BackingStore), "Microsoft\\Kiota\\Abstractions\\Store", "BackingStore", "BackedModel", "BackingStoreFactorySingleton" ), - new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.RequestExecutor), "Http\\Promise", "Promise", "RejectedPromise"), + new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.RequestExecutor), "Http\\Promise", "Promise"), new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.RequestExecutor), "", "Exception"), new (x => x is CodeEnum, "Microsoft\\Kiota\\Abstractions\\", "Enum"), new(static x => x is CodeProperty {Type.Name: {}} property && property.Type.Name.Equals("DateTime", StringComparison.OrdinalIgnoreCase), "", "\\DateTime"), diff --git a/src/Kiota.Builder/Writers/Php/CodeMethodWriter.cs b/src/Kiota.Builder/Writers/Php/CodeMethodWriter.cs index b439ea8e0a..5108394264 100644 --- a/src/Kiota.Builder/Writers/Php/CodeMethodWriter.cs +++ b/src/Kiota.Builder/Writers/Php/CodeMethodWriter.cs @@ -259,7 +259,7 @@ private static void AssignPropertyFromParameter(CodeClass parentClass, CodeMetho private void WriteMethodPhpDocs(CodeMethod codeMethod, LanguageWriter writer) { var methodDescription = codeMethod.Documentation.Description; - + var methodThrows = codeMethod.IsOfKind(CodeMethodKind.RequestExecutor); var hasMethodDescription = !string.IsNullOrEmpty(methodDescription.Trim()); if (!hasMethodDescription && !codeMethod.Parameters.Any()) { @@ -276,13 +276,15 @@ private void WriteMethodPhpDocs(CodeMethod codeMethod, LanguageWriter writer) { var nullableSuffix = (codeMethod.ReturnType.IsNullable ? "|null" : ""); returnDocString = (codeMethod.Kind == CodeMethodKind.RequestExecutor) - ? "@return Promise" + ? $"@return Promise<{returnDocString}|null>" : $"@return {returnDocString}{nullableSuffix}"; } else returnDocString = String.Empty; + + var throwsArray = methodThrows ? new[] { "@throws Exception" } : Array.Empty(); conventions.WriteLongDescription(codeMethod.Documentation, writer, - parametersWithOrWithoutDescription.Union(new[] { returnDocString }) + parametersWithOrWithoutDescription.Union(new[] { returnDocString }).Union(throwsArray) ); } @@ -294,6 +296,7 @@ private string GetDocCommentReturnType(CodeMethod codeMethod) CodeMethodKind.Deserializer => "array", CodeMethodKind.Getter when codeMethod.AccessedProperty?.IsOfKind(CodePropertyKind.AdditionalData) ?? false => "array", CodeMethodKind.Getter when codeMethod.AccessedProperty?.Type.IsCollection ?? false => $"array<{conventions.TranslateType(codeMethod.AccessedProperty.Type)}>", + CodeMethodKind.RequestExecutor when codeMethod.ReturnType.IsCollection => $"array<{conventions.TranslateType(codeMethod.ReturnType)}>", _ => conventions.GetTypeString(codeMethod.ReturnType, codeMethod) }; } @@ -735,8 +738,6 @@ private void WriteRequestExecutorBody(CodeMethod codeElement, CodeClass parentCl var returnTypeName = conventions.GetTypeString(codeElement.ReturnType, codeElement, false); writer.WriteLine($"$requestInfo = $this->{generatorMethodName}({joinedParams});"); - writer.WriteLine("try {"); - writer.IncreaseIndent(); var errorMappings = codeElement.ErrorMappings; var hasErrorMappings = false; var errorMappingsVarName = "$errorMappings"; @@ -772,15 +773,17 @@ private void WriteRequestExecutorBody(CodeMethod codeElement, CodeClass parentCl ? $", '{returnTypeName}'" : returnEnumType; var requestAdapterProperty = parentClass.GetPropertyOfKind(CodePropertyKind.RequestAdapter) ?? throw new InvalidOperationException("Request adapter property not found"); - writer.WriteLine( - $"return {GetPropertyCall(requestAdapterProperty, string.Empty)}->{methodName}({RequestInfoVarName}{finalReturn}, {(hasErrorMappings ? $"{errorMappingsVarName}" : "null")});"); - writer.DecreaseIndent(); - writer.WriteLine("} catch(Exception $ex) {"); - writer.IncreaseIndent(); - writer.WriteLine("return new RejectedPromise($ex);"); - writer.DecreaseIndent(); - writer.WriteLine("}"); + var methodCall = $"{GetPropertyCall(requestAdapterProperty, string.Empty)}->{methodName}({RequestInfoVarName}{finalReturn}, {(hasErrorMappings ? $"{errorMappingsVarName}" : "null")});"; + if (methodName.Contains("sendPrimitive", StringComparison.OrdinalIgnoreCase)) + { + writer.WriteLines($"/** @var Promise<{GetDocCommentReturnType(codeElement)}|null> $result */", + $"$result = {methodCall}", + "return $result;" + ); + } + else writer.WriteLines( + $"return {methodCall}"); } private static void WriteApiConstructorBody(CodeClass parentClass, CodeMethod codeMethod, LanguageWriter writer) diff --git a/tests/Kiota.Builder.Tests/Writers/Php/CodeClassDeclarationWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/Php/CodeClassDeclarationWriterTests.cs index 64e1cba133..582208c25c 100644 --- a/tests/Kiota.Builder.Tests/Writers/Php/CodeClassDeclarationWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/Php/CodeClassDeclarationWriterTests.cs @@ -134,8 +134,7 @@ public async Task ImportRequiredClassesWhenContainsRequestExecutor() codeElementWriter.WriteCodeElement(dec, writer); var result = tw.ToString(); - Assert.Contains("use Http\\Promise\\Promise;", result); - Assert.Contains("use Http\\Promise\\RejectedPromise;", result); + Assert.Contains(@"use Http\Promise\Promise;", result); Assert.Contains("use Exception;", result); } diff --git a/tests/Kiota.Builder.Tests/Writers/Php/CodeMethodWriterTests.cs b/tests/Kiota.Builder.Tests/Writers/Php/CodeMethodWriterTests.cs index c0f8cd3783..f9d62812c0 100644 --- a/tests/Kiota.Builder.Tests/Writers/Php/CodeMethodWriterTests.cs +++ b/tests/Kiota.Builder.Tests/Writers/Php/CodeMethodWriterTests.cs @@ -287,11 +287,10 @@ public async void WriteRequestExecutor() Assert.Contains("public function post(): Promise", result); Assert.Contains("$requestInfo = $this->createPostRequestInformation();", result); - Assert.Contains("RejectedPromise", result); Assert.Contains("@link https://learn.microsoft.com/ Learning", result); - Assert.Contains("catch(Exception $ex)", result); Assert.Contains("'401' => [Error401::class, 'createFromDiscriminatorValue']", result); - Assert.Contains("return $this->requestAdapter->sendPrimitiveAsync($requestInfo, StreamInterface::class, $errorMappings);", result); + Assert.Contains("$result = $this->requestAdapter->sendPrimitiveAsync($requestInfo, StreamInterface::class, $errorMappings);", result); + Assert.Contains("return $result;", result); } [Fact] @@ -380,13 +379,14 @@ public async void WritesRequestExecutorForEnumTypes() _codeMethodWriter.WriteCodeElement(codeMethod, languageWriter); var result = stringWriter.ToString(); + Assert.Contains("@throws Exception", result); Assert.Contains("public function post(): Promise", result); Assert.Contains("$requestInfo = $this->createPostRequestInformation();", result); - Assert.Contains("RejectedPromise", result); Assert.Contains("@link https://learn.microsoft.com/ Learning", result); - Assert.Contains("catch(Exception $ex)", result); Assert.Contains("'401' => [Error401::class, 'createFromDiscriminatorValue']", result); - Assert.Contains("return $this->requestAdapter->sendPrimitiveAsync($requestInfo, PhoneNumberPrefix::class, $errorMappings);", result); + Assert.Contains("/** @var Promise $result", result); + Assert.Contains("$result = $this->requestAdapter->sendPrimitiveAsync($requestInfo, PhoneNumberPrefix::class, $errorMappings);", result); + Assert.Contains("return $result;", result); } public static IEnumerable SerializerProperties => new List