Skip to content

Commit

Permalink
Remove unused code and enhance JSON request body output
Browse files Browse the repository at this point in the history
  • Loading branch information
koros committed Nov 15, 2024
1 parent bac834f commit 31c3c53
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 42 deletions.
45 changes: 14 additions & 31 deletions src/Kiota.Builder/Refiners/HttpRefiner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,6 @@ public override Task RefineAsync(CodeNamespace generatedCode, CancellationToken
static s => s
);
cancellationToken.ThrowIfCancellationRequested();
AddPropertiesAndMethodTypesImports(
generatedCode,
true,
false,
true);
AddDefaultImports(
generatedCode,
defaultUsingEvaluators);
cancellationToken.ThrowIfCancellationRequested();
SetBaseUrlForRequestBuilderMethods(generatedCode, GetBaseUrl(generatedCode));
// Remove unused code from the DOM e.g Models, BarrelInitializers, e.t.c
RemoveUnusedCodeElements(generatedCode);
Expand All @@ -54,24 +45,6 @@ public override Task RefineAsync(CodeNamespace generatedCode, CancellationToken
CorrectImplements);
}, cancellationToken);
}
private static readonly AdditionalUsingEvaluator[] defaultUsingEvaluators = {
new (x => x is CodeProperty prop && prop.IsOfKind(CodePropertyKind.RequestAdapter),
"MicrosoftKiotaAbstractions", "RequestAdapter"),
new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.RequestGenerator),
"MicrosoftKiotaAbstractions", "RequestInformation", "HttpMethod", "RequestOption"),
new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.RequestExecutor),
"MicrosoftKiotaAbstractions", "ResponseHandler"),
new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.Serializer),
"MicrosoftKiotaAbstractions", "SerializationWriter"),
new (x => x is CodeMethod method && method.IsOfKind(CodeMethodKind.Deserializer, CodeMethodKind.Factory),
"MicrosoftKiotaAbstractions", "ParseNode", "Parsable"),
new (x => x is CodeClass codeClass && codeClass.IsOfKind(CodeClassKind.Model),
"MicrosoftKiotaAbstractions", "Parsable"),
new (x => x is CodeClass @class && @class.IsOfKind(CodeClassKind.Model) &&
(@class.Properties.Any(x => x.IsOfKind(CodePropertyKind.AdditionalData)) ||
@class.StartBlock.Implements.Any(x => KiotaBuilder.AdditionalHolderInterface.Equals(x.Name, StringComparison.OrdinalIgnoreCase))),
"MicrosoftKiotaAbstractions", "AdditionalDataHolder"),
};
private static void CorrectImplements(ProprietableBlockDeclaration block)
{
block.ReplaceImplementByName(KiotaBuilder.AdditionalHolderInterface, "AdditionalDataHolder");
Expand Down Expand Up @@ -228,18 +201,28 @@ private static void SetBaseUrlForRequestBuilderMethods(CodeElement current, stri

private static void RemoveUnusedCodeElements(CodeElement element)
{
if (element is CodeClass code && (code.IsOfKind(CodeClassKind.Model) || code.IsOfKind(CodeClassKind.BarrelInitializer) || IsBaseRequestBuilder(code)))
if (!IsRequestBuilderClass(element) || IsBaseRequestBuilder(element) || IsRequestBuilderClassWithoutAnyHttpOperations(element))
{
var parentNameSpace = element.GetImmediateParentOfType<CodeNamespace>();
parentNameSpace?.RemoveChildElement(element);
}

CrawlTree(element, RemoveUnusedCodeElements);
}

private static bool IsBaseRequestBuilder(CodeClass codeClass)
private static bool IsRequestBuilderClass(CodeElement element)
{
return codeClass.IsOfKind(CodeClassKind.RequestBuilder) &&
return element is CodeClass code && code.IsOfKind(CodeClassKind.RequestBuilder);
}

private static bool IsBaseRequestBuilder(CodeElement element)
{
return element is CodeClass codeClass && codeClass.IsOfKind(CodeClassKind.RequestBuilder) &&
codeClass.Properties.Any(property => property.IsOfKind(CodePropertyKind.UrlTemplate) && string.Equals(property.DefaultValue, "\"{+baseurl}\"", StringComparison.Ordinal));
}

private static bool IsRequestBuilderClassWithoutAnyHttpOperations(CodeElement element)
{
return element is CodeClass codeClass && codeClass.IsOfKind(CodeClassKind.RequestBuilder) &&
!codeClass.Methods.Any(method => method.IsOfKind(CodeMethodKind.RequestExecutor));
}
}
44 changes: 33 additions & 11 deletions src/Kiota.Builder/Writers/HTTP/CodeClassDeclarationWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ private static void WriteQueryParameters(CodeElement codeElement, LanguageWriter
queryParams.ForEach(prop =>
{
var documentation = prop.Documentation.DescriptionTemplate;
writer.WriteLine($"# {documentation}");
writer.WriteLine($"# {prop.Documentation.DescriptionTemplate}");
writer.WriteLine($"@{prop.Name} = ");
writer.WriteLine();
});
Expand All @@ -87,8 +86,7 @@ private static void WriteHttpMethods(CodeElement codeElement, LanguageWriter wri

httpMethods?.ForEach(method =>
{
var documentation = method.Documentation.DescriptionTemplate;
writer.WriteLine($"# {documentation}");
writer.WriteLine($"# {method.Documentation.DescriptionTemplate}");
writer.WriteLine($"{method.Name.ToUpperInvariant()} {GetUrlTemplate(codeElement)}");
WriteRequestBody(method, writer);
Expand All @@ -115,10 +113,9 @@ private static void WriteRequestBody(CodeMethod method, LanguageWriter writer)
var requestBody = method.Parameters.FirstOrDefault(param => param.IsOfKind(CodeParameterKind.RequestBody));
if (requestBody is null) return;

var contentType = method.RequestBodyContentType;
// Empty line before content type
writer.WriteLine();
writer.WriteLine($"Content-Type: {contentType}");
writer.WriteLine($"Content-Type: {method.RequestBodyContentType}");

// loop through the properties of the request body and write a JSON object
if (requestBody.Type is CodeType ct && ct.TypeDefinition is CodeClass requestBodyClass)
Expand All @@ -130,13 +127,37 @@ private static void WriteRequestBody(CodeMethod method, LanguageWriter writer)
writer.WriteLine("}");
}
}

private static void WriteProperties(CodeClass codeClass, LanguageWriter writer)
{
// Write properties of the current class
foreach (var prop in codeClass.Properties.Where(prop => prop.IsOfKind(CodePropertyKind.Custom)))
var properties = codeClass.Properties.Where(prop => prop.IsOfKind(CodePropertyKind.Custom)).ToList();
for (int i = 0; i < properties.Count; i++)
{
writer.WriteLine($"{prop.Name}: {GetDefaultValueForProperty(prop)}");
var prop = properties[i];
var propName = $"\"{prop.Name}\"";
writer.Write($"{propName}: ");
if (prop.Type is CodeType propType && propType.TypeDefinition is CodeClass propClass)
{
// If the property is an object, write a JSON representation recursively
writer.WriteLine("{", includeIndent: false);
writer.IncreaseIndent();
WriteProperties(propClass, writer);
writer.DecreaseIndent();
writer.Write("}");
}
else
{
writer.Write(GetDefaultValueForProperty(prop), includeIndent: false);
}

// Add a trailing comma if there are more properties to be written
if (i < properties.Count - 1)
{
writer.WriteLine(",", includeIndent: false);
}
else
{
writer.WriteLine();
}
}

// If the class extends another class, write properties of the base class
Expand All @@ -154,8 +175,9 @@ private static string GetDefaultValueForProperty(CodeProperty prop)
"string" => "\"string\"",
"bool" or "boolean" => "false",
_ when prop.Type is CodeType enumType && enumType.TypeDefinition is CodeEnum enumDefinition =>
enumDefinition.Options.FirstOrDefault()?.Name ?? "null",
enumDefinition.Options.FirstOrDefault()?.Name is string enumName ? $"\"{enumName}\"" : "null",
_ => "null"
};
}

}

0 comments on commit 31c3c53

Please sign in to comment.