Skip to content

Commit

Permalink
Fix function writer (#5809)
Browse files Browse the repository at this point in the history
* Fix function writer

* enable tests

* fix documentation

* ling re-qrite

* Fix default value for escaped enum options

* Fix enum default value

* fix

* fix signature for composed types of collections

* fix missing data types

* fix test

* Fix

* Adds readme

* Format code

* Update src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs

---------

Co-authored-by: Vincent Biret <[email protected]>
  • Loading branch information
rkodev and baywet authored Nov 22, 2024
1 parent ca0f832 commit 84d2c07
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 24 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed Python error when a class inherits from a base class and implements an interface. [5637](https://github.com/microsoft/kiota/issues/5637)
- Fix anyOf/oneOf generation in TypeScript. [5353](https://github.com/microsoft/kiota/issues/5353)
- Fixed invalid code in Php caused by "*/*/" in property description. [5635](https://github.com/microsoft/kiota/issues/5635)
- Fixed TypeScript generation error when generating usings from shaken serializers. [#5634](https://github.com/microsoft/kiota/issues/5634)

## [1.20.0] - 2024-11-07

Expand Down
4 changes: 0 additions & 4 deletions it/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@
"apisguru::github.com:api.github.com": {
"MockServerITFolder": "gh",
"Suppressions": [
{
"Language": "typescript",
"Rationale": "https://github.com/microsoft/kiota/issues/5634"
},
{
"Language": "ruby",
"Rationale": "https://github.com/microsoft/kiota/issues/1816"
Expand Down
28 changes: 16 additions & 12 deletions src/Kiota.Builder/Refiners/TypeScriptRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1493,22 +1493,26 @@ private static void AddDeserializerUsingToDiscriminatorFactory(CodeElement codeE

foreach (var mappedType in parsableFactoryFunction.OriginalMethodParentClass.DiscriminatorInformation.DiscriminatorMappings)
{
if (mappedType.Value is CodeType type && type.TypeDefinition is CodeClass mappedClass)
if (mappedType.Value is not
{ TypeDefinition: CodeClass { Parent: CodeNamespace codeNamespace } mappedClass }
|| codeNamespace.FindChildByName<CodeFunction>(
$"{ModelDeserializerPrefix}{mappedClass.Name.ToFirstCharacterUpperCase()}") is not
{ } deserializer)
{
var deserializer = GetSerializationFunctionsForNamespace(mappedClass).Item2;
continue;
}

if (deserializer.Parent is not null)
if (deserializer.Parent is not null)
{
parsableFactoryFunction.AddUsing(new CodeUsing
{
parsableFactoryFunction.AddUsing(new CodeUsing
Name = deserializer.Parent.Name,
Declaration = new CodeType
{
Name = deserializer.Parent.Name,
Declaration = new CodeType
{
Name = deserializer.Name,
TypeDefinition = deserializer
},
});
}
Name = deserializer.Name,
TypeDefinition = deserializer
},
});
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Kiota.Builder/Writers/TypeScript/CodeConstantWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private void WriteRequestsMetadataConstant(CodeConstant codeElement, LanguageWri
var isStream = conventions.StreamTypeName.Equals(returnType, StringComparison.OrdinalIgnoreCase);
var isEnum = executorMethod.ReturnType is CodeType codeType && codeType.TypeDefinition is CodeEnum;
var returnTypeWithoutCollectionSymbol = GetReturnTypeWithoutCollectionSymbol(executorMethod, returnType);
var isPrimitive = IsPrimitiveType(returnTypeWithoutCollectionSymbol);
var isPrimitive = IsPrimitiveType(returnTypeWithoutCollectionSymbol) || IsKiotaPrimitive(returnTypeWithoutCollectionSymbol);
var isPrimitiveAlias = GetPrimitiveAlias(returnTypeWithoutCollectionSymbol) is not null;
writer.StartBlock($"{executorMethod.Name.ToFirstCharacterLowerCase()}: {{");
var urlTemplateValue = executorMethod.HasUrlTemplateOverride ? $"\"{executorMethod.UrlTemplateOverride}\"" : uriTemplateConstant.Name.ToFirstCharacterUpperCase();
Expand Down Expand Up @@ -169,7 +169,7 @@ private string GetTypeFactory(bool isVoid, bool isStream, CodeMethod codeElement
{
if (isVoid) return string.Empty;
var typeName = conventions.TranslateType(codeElement.ReturnType);
if (isStream || IsPrimitiveType(typeName)) return $" \"{typeName}\"";
if (isStream || IsPrimitiveType(typeName) || IsKiotaPrimitive(typeName)) return $" \"{typeName}\"";
if (GetPrimitiveAlias(typeName) is { } alias && !string.IsNullOrEmpty(alias))
return $" \"{alias}\"";
return $" {GetFactoryMethodName(codeElement.ReturnType, codeElement, writer)}";
Expand Down
16 changes: 12 additions & 4 deletions src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private void WriteComposedTypeSerializer(CodeFunction codeElement, LanguageWrite

private void WriteSerializationFunctionForCodeIntersectionType(CodeComposedTypeBase composedType, CodeParameter composedParam, CodeFunction method, LanguageWriter writer)
{
foreach (var mappedType in composedType.Types.Where(x => !IsPrimitiveType(x, composedType)))
foreach (var mappedType in composedType.Types.Where(x => !IsPrimitiveType(x, composedType) && x.TypeDefinition != null))
{
var functionName = GetSerializerFunctionName(method, mappedType);
var variableName = composedParam.Name.ToFirstCharacterLowerCase();
Expand Down Expand Up @@ -611,9 +611,17 @@ private static string GetDefaultValueSuffix(CodeProperty otherProp)
private static string GetDefaultValueLiteralForProperty(CodeProperty codeProperty)
{
if (string.IsNullOrEmpty(codeProperty.DefaultValue)) return string.Empty;
if (codeProperty.Type is CodeType propertyType && propertyType.TypeDefinition is CodeEnum enumDefinition && enumDefinition.CodeEnumObject is not null)
return $"{enumDefinition.CodeEnumObject.Name.ToFirstCharacterUpperCase()}.{codeProperty.DefaultValue.Trim('"').CleanupSymbolName().ToFirstCharacterUpperCase()}";
return codeProperty.DefaultValue;
if (codeProperty.Type is CodeType propertyType && propertyType.TypeDefinition is CodeEnum enumDefinition &&
enumDefinition.CodeEnumObject is not null)
{
var codeEnumOption = enumDefinition.Options.First(x =>
x.SymbolName.Equals(codeProperty.DefaultValue.Trim('"').CleanupSymbolName(),
StringComparison.OrdinalIgnoreCase));
return $"{enumDefinition.CodeEnumObject.Name.ToFirstCharacterUpperCase()}.{codeEnumOption.Name.Trim('"').CleanupSymbolName().ToFirstCharacterUpperCase()}";
}

// only string primitive should keep quotes
return codeProperty.Type.Name.Equals("string", StringComparison.Ordinal) ? codeProperty.DefaultValue : codeProperty.DefaultValue.Trim('"');
}
private void WriteDefensiveStatements(CodeMethod codeElement, LanguageWriter writer)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public override string GetParameterSignature(CodeParameter parameter, CodeElemen

// add a 'Parsable' type to the parameter if it is composed of non-Parsable types
var parsableTypes = (
composedType != null && !composedType.IsComposedOfObjects(IsPrimitiveType),
composedType != null && (!composedType.IsComposedOfObjects(IsPrimitiveType) || composedType.Types.Any(x => x.IsCollection)),
parameter.Parent is CodeMethod method && (method.IsOfKind(CodeMethodKind.Deserializer, CodeMethodKind.Serializer))
) switch
{
Expand Down Expand Up @@ -237,6 +237,18 @@ TYPE_LOWERCASE_BOOLEAN or
};
}

// Types that are imported from kiota-abstractions and considered as primitive types
public static bool IsKiotaPrimitive(string typeName)
{
return typeName switch
{
TYPE_DATE_ONLY or
TYPE_TIME_ONLY or
TYPE_DURATION => true,
_ => false,
};
}

public static string? GetPrimitiveAlias(string typeName)
{
return typeName switch
Expand All @@ -252,7 +264,18 @@ TYPE_LOWERCASE_BOOLEAN or

private static bool IsPrimitiveTypeOrPrimitiveCollection(CodeType codeType, CodeComposedTypeBase codeComposedTypeBase) => IsPrimitiveType(codeType, codeComposedTypeBase, false);

internal static string RemoveInvalidDescriptionCharacters(string originalDescription) => originalDescription?.Replace("\\", "/", StringComparison.OrdinalIgnoreCase) ?? string.Empty;
private static Dictionary<string, string> InvalidCharactersReplacements = new(StringComparer.OrdinalIgnoreCase) {
{ "\\", "/"},
{ "/*", "//*"}
};

internal static string RemoveInvalidDescriptionCharacters(string originalDescription)
{
if (string.IsNullOrEmpty(originalDescription)) return string.Empty;
originalDescription = InvalidCharactersReplacements
.Aggregate(originalDescription, (current, replacement) => current.Replace(replacement.Key, replacement.Value, StringComparison.OrdinalIgnoreCase));
return originalDescription;
}
public override bool WriteShortDescription(IDocumentedElement element, LanguageWriter writer, string prefix = "", string suffix = "")
{
ArgumentNullException.ThrowIfNull(writer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,23 @@ public async Task WritesConstructorWithEnumValueAsync()
{
Name = "pictureSize"
}).First();

codeEnum.AddOption(
new CodeEnumOption
{
Name = "256x256",
SerializationName = "256x256"
},
new CodeEnumOption
{
Name = "512x512",
SerializationName = "512x512"
},
new CodeEnumOption
{
Name = "1024x1024",
SerializationName = "1024x1024"
});
parentClass.AddProperty(new CodeProperty
{
Name = propName,
Expand Down

0 comments on commit 84d2c07

Please sign in to comment.