Skip to content

Commit

Permalink
handle union of objects in typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
koros committed May 21, 2024
1 parent 4f36114 commit 663798e
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 152 deletions.
82 changes: 43 additions & 39 deletions src/Kiota.Builder/Refiners/TypeScriptRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -295,10 +295,11 @@ private static bool IsRelevantFactory(CodeFunction codeFunction, CodeInterface c

private static List<CodeElement> GetCodeFileElementsForComposedType(CodeInterface codeInterface, CodeNamespace codeNamespace, CodeComposedTypeBase composedType, CodeFunction[] functions)
{
var children = new List<CodeElement>(functions);

// Add the composed type, The writer will output the composed type as a type definition e.g export type Pet = Cat | Dog
children.Add(composedType);
var children = new List<CodeElement>(functions)
{
// Add the composed type, The writer will output the composed type as a type definition e.g export type Pet = Cat | Dog
composedType
};

ReplaceFactoryMethodForComposedType(codeInterface, codeNamespace, composedType, children);
ReplaceSerializerMethodForComposedType(codeInterface, codeNamespace, composedType, children);
Expand All @@ -309,12 +310,13 @@ private static List<CodeElement> GetCodeFileElementsForComposedType(CodeInterfac

private static void ReplaceFactoryMethodForComposedType(CodeInterface codeInterface, CodeNamespace codeNamespace, CodeComposedTypeBase composedType, List<CodeElement> children)
{
var factoryMethods = children.OfType<CodeFunction>().Where(function => function.OriginalLocalMethod.Kind is CodeMethodKind.Factory).ToList();
var factoryMethod = children.OfType<CodeFunction>().FirstOrDefault(function => function.OriginalLocalMethod.Kind is CodeMethodKind.Factory);

foreach (var factoryMethod in factoryMethods)
if (factoryMethod is not null)
{
var method = CreateFactoryMethodForComposedType(codeInterface, composedType, factoryMethod);
var factoryFunction = new CodeFunction(method) { Name = method.Name };
var factoryFunction = new CodeFunction(method) { Name = method.Name, Parent = codeInterface.OriginalClass };
factoryFunction.AddUsing(factoryMethod.Usings.ToArray());

children.Remove(factoryMethod);
RemoveChildElementFromInterfaceAndNamespace(codeInterface, codeNamespace, factoryMethod);
Expand All @@ -324,29 +326,26 @@ private static void ReplaceFactoryMethodForComposedType(CodeInterface codeInterf

private static void ReplaceSerializerMethodForComposedType(CodeInterface codeInterface, CodeNamespace codeNamespace, CodeComposedTypeBase composedType, List<CodeElement> children)
{
var serializerMethod = children.OfType<CodeFunction>().FirstOrDefault(function => function.OriginalLocalMethod.Kind is CodeMethodKind.Serializer);
if (serializerMethod is not null)
var function = children.OfType<CodeFunction>().FirstOrDefault(function => function.OriginalLocalMethod.Kind is CodeMethodKind.Serializer);
if (function is not null)
{
var method = CreateSerializerMethodForComposedType(codeInterface, composedType, serializerMethod);
var method = CreateSerializerMethodForComposedType(codeInterface, composedType, function);
var serializerFunction = new CodeFunction(method) { Name = method.Name };
serializerFunction.AddUsing(function.Usings.ToArray());

children.Remove(serializerMethod);
RemoveChildElementFromInterfaceAndNamespace(codeInterface, codeNamespace, serializerMethod);
children.Remove(function);
RemoveChildElementFromInterfaceAndNamespace(codeInterface, codeNamespace, function);
children.Add(serializerFunction);
}
}

private static void ReplaceDeserializerMethodForComposedType(CodeInterface codeInterface, CodeNamespace codeNamespace, CodeComposedTypeBase composedType, List<CodeElement> children)

Check warning on line 342 in src/Kiota.Builder/Refiners/TypeScriptRefiner.cs

View workflow job for this annotation

GitHub Actions / Build

Remove this unused method parameter 'composedType'. (https://rules.sonarsource.com/csharp/RSPEC-1172)
{
// Completely remove the deserializer method if the composed type is a union of primitive values
if (composedType is CodeUnionType && ConventionServiceInstance.IsComposedOfPrimitives(composedType))
var deserializerMethod = children.OfType<CodeFunction>().FirstOrDefault(function => function.OriginalLocalMethod.Kind is CodeMethodKind.Deserializer);
if (deserializerMethod is not null)
{
var deserializerMethod = children.OfType<CodeFunction>().FirstOrDefault(function => function.OriginalLocalMethod.Kind is CodeMethodKind.Deserializer);
if (deserializerMethod is not null)
{
children.Remove(deserializerMethod);
RemoveChildElementFromInterfaceAndNamespace(codeInterface, codeNamespace, deserializerMethod);
}
children.Remove(deserializerMethod);
RemoveChildElementFromInterfaceAndNamespace(codeInterface, codeNamespace, deserializerMethod);
}
}

Expand All @@ -356,29 +355,41 @@ private static void RemoveChildElementFromInterfaceAndNamespace(CodeInterface co
codeNamespace.RemoveChildElement(function);
}

private static CodeMethod CreateFactoryMethodForComposedType(CodeInterface codeInterface, CodeComposedTypeBase composedTypeBase, CodeFunction function)
private static CodeMethod CreateFactoryMethodForComposedType(CodeInterface codeInterface, CodeComposedTypeBase composedType, CodeFunction function)
{
var method = CreateCodeMethod(codeInterface, composedTypeBase, function);
method.ReturnType = composedTypeBase;
method.AddParameter(CreateParseNodeCodeParameter());
var method = CreateCodeMethod(codeInterface, function);
if (composedType is CodeUnionType && ConventionServiceInstance.IsComposedOfPrimitives(composedType))
method.ReturnType = composedType;
return method;
}

private static CodeMethod CreateSerializerMethodForComposedType(CodeInterface codeInterface, CodeComposedTypeBase composedType, CodeFunction function)

Check warning on line 366 in src/Kiota.Builder/Refiners/TypeScriptRefiner.cs

View workflow job for this annotation

GitHub Actions / Build

Remove this unused method parameter 'composedType'. (https://rules.sonarsource.com/csharp/RSPEC-1172)
{
var method = CreateCodeMethod(codeInterface, composedType, function);
var method = CreateCodeMethod(codeInterface, function);
// Add the key parameter if the composed type is a union of primitive values
if (composedType is CodeUnionType && ConventionServiceInstance.IsComposedOfPrimitives(composedType))
method.AddParameter(CreateKeyParameter());
method.AddParameter(CreateKeyParameter());
method.AddParameter(function.OriginalLocalMethod.Parameters.ToArray());
return method;
}

private static CodeMethod CreateCodeMethod(CodeInterface codeInterface, CodeComposedTypeBase composedTypeBase, CodeFunction function)
private static CodeMethod CreateDeserializerMethodForComposedType(CodeInterface codeInterface, CodeComposedTypeBase composedType, CodeFunction function)

Check warning on line 375 in src/Kiota.Builder/Refiners/TypeScriptRefiner.cs

View workflow job for this annotation

GitHub Actions / Build

Remove the unused private method 'CreateDeserializerMethodForComposedType'. (https://rules.sonarsource.com/csharp/RSPEC-1144)
{
var method = CreateCodeMethod(codeInterface, function);
// Add the key parameter if the composed type is a union of primitive values
if (composedType is CodeUnionType && ConventionServiceInstance.IsComposedOfPrimitives(composedType))
{
method.ReturnType = new CodeType { Name = composedType.Name, IsExternal = false, TypeDefinition = composedType };
method.ClearParameters();
method.AddParameter(CreateParseNodeCodeParameter());
}
return method;
}

private static CodeMethod CreateCodeMethod(CodeInterface codeInterface, CodeFunction function)
{
var method = new CodeMethod
{
Name = GetSerializerOrDeserializerMethodName(composedTypeBase, function),
Name = function.OriginalLocalMethod.Name,
ReturnType = function.OriginalLocalMethod.ReturnType,
Kind = GetComposedTypeMethodKind(function),
Access = function.OriginalLocalMethod.Access,
Expand All @@ -388,6 +399,8 @@ private static CodeMethod CreateCodeMethod(CodeInterface codeInterface, CodeComp
Parent = codeInterface.OriginalClass,
};

method.AddParameter(function.OriginalLocalMethod.Parameters.ToArray());

return method;
}

Expand All @@ -402,16 +415,6 @@ private static CodeMethodKind GetComposedTypeMethodKind(CodeFunction function)
};
}

private static string GetSerializerOrDeserializerMethodName(CodeComposedTypeBase composedTypeBase, CodeFunction function)
{
return function.OriginalLocalMethod.Kind switch
{
CodeMethodKind.Factory => GetFactoryMethodName(composedTypeBase, function),
CodeMethodKind.Serializer => GetSerializationMethodName(composedTypeBase),
_ => throw new InvalidOperationException($"Unsupported method type :: {function.OriginalLocalMethod.Kind}")
};
}

private static CodeParameter CreateParseNodeCodeParameter()
{
return new CodeParameter
Expand Down Expand Up @@ -456,6 +459,7 @@ private static CodeParameter CreateKeyParameter()
{
return codeType?.TypeDefinition switch
{
CodeComposedTypeBase composedType => composedType,
CodeInterface ci => GetOriginalComposedType(ci),
CodeClass cc => GetOriginalComposedType(cc),
_ => null,
Expand Down
Loading

0 comments on commit 663798e

Please sign in to comment.