Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix function writer #5809

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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() {
{ "\\", "/"},
{ "/*", "//*"}
};

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
Loading