Skip to content

Commit

Permalink
Merge pull request #4348 from marcinjahn/fix-csharp-braces-new-line
Browse files Browse the repository at this point in the history
Put braces on new line in CSharp generator
  • Loading branch information
baywet authored Mar 18, 2024
2 parents 7e0a4c0 + b2b6370 commit e7e5c9b
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- PREVIEW: Moved preview configuration files to the .kiota directory. [#4310](https://github.com/microsoft/kiota/issues/4310)
- PREVIEW: Moved the copy descriptions to dedicated folders. [#4310](https://github.com/microsoft/kiota/issues/4310)
- PREVIEW: Renamed the config to workspace file. [#4310](https://github.com/microsoft/kiota/issues/4310)
- Changed Csharp code generation to put braces on new lines (where it makes sense). [#4347](https://github.com/microsoft/kiota/issues/4347)

## [1.12.0] - 2024-03-06

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public override void WriteCodeElement(ClassDeclaration codeElement, LanguageWrit
var derivation = derivedTypes.Length != 0 ? ": " + derivedTypes.Aggregate(static (x, y) => $"{x}, {y}") + " " : string.Empty;
conventions.WriteLongDescription(parentClass, writer);
conventions.WriteDeprecationAttribute(parentClass, writer);
writer.StartBlock($"public class {codeElement.Name.ToFirstCharacterUpperCase()} {derivation}{{");
writer.WriteLine($"public class {codeElement.Name.ToFirstCharacterUpperCase()} {derivation}");
writer.StartBlock();
}
}
3 changes: 2 additions & 1 deletion src/Kiota.Builder/Writers/CSharp/CodeEnumWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public override void WriteCodeElement(CodeEnum codeElement, LanguageWriter write
if (codeElement.Flags)
writer.WriteLine("[Flags]");
conventions.WriteDeprecationAttribute(codeElement, writer);
writer.StartBlock($"public enum {codeElement.Name.ToFirstCharacterUpperCase()} {{");
writer.WriteLine($"public enum {codeElement.Name.ToFirstCharacterUpperCase()}");
writer.StartBlock();
var idx = 0;
foreach (var option in codeElement.Options)
{
Expand Down
8 changes: 6 additions & 2 deletions src/Kiota.Builder/Writers/CSharp/CodeIndexerWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ public override void WriteCodeElement(CodeIndexer codeElement, LanguageWriter wr
conventions.WriteShortDescription(codeElement.IndexParameter, writer, $"<param name=\"position\">", "</param>");
conventions.WriteAdditionalDescriptionItem($"<returns>A {conventions.GetTypeStringForDocumentation(codeElement.ReturnType, codeElement)}</returns>", writer);
conventions.WriteDeprecationAttribute(codeElement, writer);
writer.StartBlock($"public {returnType} this[{conventions.GetTypeString(codeElement.IndexParameter.Type, codeElement)} position] {{ get {{");
writer.WriteLine($"public {returnType} this[{conventions.GetTypeString(codeElement.IndexParameter.Type, codeElement)} position]");
writer.StartBlock();
writer.WriteLine("get");
writer.StartBlock();
if (parentClass.GetPropertyOfKind(CodePropertyKind.PathParameters) is CodeProperty pathParametersProp)
conventions.AddParametersAssignment(writer, pathParametersProp.Type, pathParametersProp.Name.ToFirstCharacterUpperCase(), string.Empty, (codeElement.IndexParameter.Type, codeElement.IndexParameter.SerializationName, "position"));
conventions.AddRequestBuilderBody(parentClass, returnType, writer, conventions.TempDictionaryVarName, "return ");
writer.CloseBlock("} }");
writer.CloseBlock();
writer.CloseBlock();
}
}
58 changes: 26 additions & 32 deletions src/Kiota.Builder/Writers/CSharp/CodeMethodWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ private void WriteRawUrlBuilderBody(CodeClass parentClass, CodeMethod codeElemen
private static readonly CodePropertyTypeComparer CodePropertyTypeBackwardComparer = new(true);
private void WriteFactoryMethodBodyForInheritedModel(CodeMethod codeElement, CodeClass parentClass, LanguageWriter writer)
{
writer.StartBlock($"return {DiscriminatorMappingVarName} switch {{");
writer.WriteLine($"return {DiscriminatorMappingVarName} switch");
writer.StartBlock();
foreach (var mappedType in parentClass.DiscriminatorInformation.DiscriminatorMappings)
{
writer.WriteLine($"\"{mappedType.Key}\" => new {conventions.GetTypeString(mappedType.Value.AllTypes.First(), codeElement)}(),");
Expand All @@ -132,19 +133,15 @@ private void WriteFactoryMethodBodyForUnionModel(CodeMethod codeElement, CodeCla
if (propertyType.TypeDefinition is CodeClass && !propertyType.IsCollection)
{
var mappedType = parentClass.DiscriminatorInformation.DiscriminatorMappings.FirstOrDefault(x => x.Value.Name.Equals(propertyType.Name, StringComparison.OrdinalIgnoreCase));
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if(\"{mappedType.Key}\".Equals({DiscriminatorMappingVarName}, StringComparison.OrdinalIgnoreCase)) {{");
writer.IncreaseIndent();
writer.WriteLine($"{ResultVarName}.{property.Name.ToFirstCharacterUpperCase()} = new {conventions.GetTypeString(propertyType, codeElement)}();");
writer.CloseBlock();
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if(\"{mappedType.Key}\".Equals({DiscriminatorMappingVarName}, StringComparison.OrdinalIgnoreCase))");
writer.WriteBlock(lines: $"{ResultVarName}.{property.Name.ToFirstCharacterUpperCase()} = new {conventions.GetTypeString(propertyType, codeElement)}();");
}
else if (propertyType.TypeDefinition is CodeClass && propertyType.IsCollection || propertyType.TypeDefinition is null || propertyType.TypeDefinition is CodeEnum)
{
var typeName = conventions.GetTypeString(propertyType, codeElement, true, false);
var valueVarName = $"{property.Name.ToFirstCharacterLowerCase()}Value";
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({parseNodeParameter.Name.ToFirstCharacterLowerCase()}.{GetDeserializationMethodName(propertyType, codeElement)} is {typeName} {valueVarName}) {{");
writer.IncreaseIndent();
writer.WriteLine($"{ResultVarName}.{property.Name.ToFirstCharacterUpperCase()} = {valueVarName};");
writer.CloseBlock();
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({parseNodeParameter.Name.ToFirstCharacterLowerCase()}.{GetDeserializationMethodName(propertyType, codeElement)} is {typeName} {valueVarName})");
writer.WriteBlock(lines: $"{ResultVarName}.{property.Name.ToFirstCharacterUpperCase()} = {valueVarName};");
}
if (!includeElse)
includeElse = true;
Expand All @@ -164,9 +161,8 @@ private void WriteFactoryMethodBodyForIntersectionModel(CodeMethod codeElement,
{
var typeName = conventions.GetTypeString(propertyType, codeElement, true, false);
var valueVarName = $"{property.Name.ToFirstCharacterLowerCase()}Value";
writer.StartBlock($"{(includeElse ? "else " : string.Empty)}if({parseNodeParameter.Name.ToFirstCharacterLowerCase()}.{GetDeserializationMethodName(propertyType, codeElement)} is {typeName} {valueVarName}) {{");
writer.WriteLine($"{ResultVarName}.{property.Name.ToFirstCharacterUpperCase()} = {valueVarName};");
writer.CloseBlock();
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({parseNodeParameter.Name.ToFirstCharacterLowerCase()}.{GetDeserializationMethodName(propertyType, codeElement)} is {typeName} {valueVarName})");
writer.WriteBlock(lines: $"{ResultVarName}.{property.Name.ToFirstCharacterUpperCase()} = {valueVarName};");
}
if (!includeElse)
includeElse = true;
Expand Down Expand Up @@ -223,9 +219,8 @@ private static void WriteApiConstructorBody(CodeClass parentClass, CodeMethod me
WriteSerializationRegistration(method.DeserializerModules, writer, "RegisterDefaultDeserializer");
if (!string.IsNullOrEmpty(method.BaseUrl))
{
writer.StartBlock($"if (string.IsNullOrEmpty({requestAdapterPropertyName}.BaseUrl)) {{");
writer.WriteLine($"{requestAdapterPropertyName}.BaseUrl = \"{method.BaseUrl}\";");
writer.CloseBlock();
writer.WriteLine($"if (string.IsNullOrEmpty({requestAdapterPropertyName}.BaseUrl))");
writer.WriteBlock(lines: $"{requestAdapterPropertyName}.BaseUrl = \"{method.BaseUrl}\";");
if (pathParametersProperty != null)
writer.WriteLine($"{pathParametersProperty.Name.ToFirstCharacterUpperCase()}.TryAdd(\"baseurl\", {requestAdapterPropertyName}.BaseUrl);");
}
Expand Down Expand Up @@ -293,9 +288,8 @@ private void WriteDeserializerBodyForUnionModel(CodeMethod method, CodeClass par
.ThenBy(static x => x.Name)
.Select(static x => x.Name.ToFirstCharacterUpperCase()))
{
writer.StartBlock($"{(includeElse ? "else " : string.Empty)}if({otherPropName} != null) {{");
writer.WriteLine($"return {otherPropName}.{method.Name.ToFirstCharacterUpperCase()}();");
writer.CloseBlock();
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({otherPropName} != null)");
writer.WriteBlock(lines: $"return {otherPropName}.{method.Name.ToFirstCharacterUpperCase()}();");
if (!includeElse)
includeElse = true;
}
Expand All @@ -315,7 +309,8 @@ private void WriteDeserializerBodyForIntersectionModel(CodeClass parentClass, La
var propertiesNamesAsConditions = propertiesNames
.Select(static x => $"{x} != null")
.Aggregate(static (x, y) => $"{x} || {y}");
writer.StartBlock($"if({propertiesNamesAsConditions}) {{");
writer.WriteLine($"if({propertiesNamesAsConditions})");
writer.StartBlock();
var propertiesNamesAsArgument = propertiesNames
.Aggregate(static (x, y) => $"{x}, {y}");
writer.WriteLine($"return ParseNodeHelper.MergeDeserializersForIntersectionWrapper({propertiesNamesAsArgument});");
Expand All @@ -326,7 +321,8 @@ private void WriteDeserializerBodyForIntersectionModel(CodeClass parentClass, La
private void WriteDeserializerBodyForInheritedModel(bool shouldHide, CodeMethod codeElement, CodeClass parentClass, LanguageWriter writer)
{
var parentSerializationInfo = shouldHide ? $"(base.{codeElement.Name.ToFirstCharacterUpperCase()}())" : string.Empty;
writer.StartBlock($"return {DefaultDeserializerValue}{parentSerializationInfo} {{");
writer.WriteLine($"return {DefaultDeserializerValue}{parentSerializationInfo}");
writer.StartBlock();
foreach (var otherProp in parentClass
.GetPropertiesOfKind(CodePropertyKind.Custom)
.Where(static x => !x.ExistsInBaseType)
Expand Down Expand Up @@ -381,8 +377,8 @@ protected void WriteRequestExecutorBody(CodeMethod codeElement, RequestParams re
if (codeElement.ErrorMappings.Any())
{
errorMappingVarName = "errorMapping";
writer.WriteLine($"var {errorMappingVarName} = new Dictionary<string, ParsableFactory<IParsable>> {{");
writer.IncreaseIndent();
writer.WriteLine($"var {errorMappingVarName} = new Dictionary<string, ParsableFactory<IParsable>>");
writer.StartBlock();
foreach (var errorMapping in codeElement.ErrorMappings.Where(errorMapping => errorMapping.Value.AllTypes.FirstOrDefault()?.TypeDefinition is CodeClass))
{
writer.WriteLine($"{{\"{errorMapping.Key.ToUpperInvariant()}\", {conventions.GetTypeString(errorMapping.Value, codeElement, false)}.CreateFromDiscriminatorValue}},");
Expand Down Expand Up @@ -474,10 +470,8 @@ private void WriteSerializerBodyForUnionModel(CodeMethod method, CodeClass paren
.OrderBy(static x => x, CodePropertyTypeForwardComparer)
.ThenBy(static x => x.Name))
{
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({otherProp.Name.ToFirstCharacterUpperCase()} != null) {{");
writer.IncreaseIndent();
writer.WriteLine($"writer.{GetSerializationMethodName(otherProp.Type, method)}(null, {otherProp.Name.ToFirstCharacterUpperCase()});");
writer.CloseBlock();
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({otherProp.Name.ToFirstCharacterUpperCase()} != null)");
writer.WriteBlock(lines: $"writer.{GetSerializationMethodName(otherProp.Type, method)}(null, {otherProp.Name.ToFirstCharacterUpperCase()});");
if (!includeElse)
includeElse = true;
}
Expand All @@ -492,10 +486,8 @@ private void WriteSerializerBodyForIntersectionModel(CodeMethod method, CodeClas
.OrderBy(static x => x, CodePropertyTypeBackwardComparer)
.ThenBy(static x => x.Name))
{
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({otherProp.Name.ToFirstCharacterUpperCase()} != null) {{");
writer.IncreaseIndent();
writer.WriteLine($"writer.{GetSerializationMethodName(otherProp.Type, method)}(null, {otherProp.Name.ToFirstCharacterUpperCase()});");
writer.CloseBlock();
writer.WriteLine($"{(includeElse ? "else " : string.Empty)}if({otherProp.Name.ToFirstCharacterUpperCase()} != null)");
writer.WriteBlock(lines: $"writer.{GetSerializationMethodName(otherProp.Type, method)}(null, {otherProp.Name.ToFirstCharacterUpperCase()});");
if (!includeElse)
includeElse = true;
}
Expand Down Expand Up @@ -630,11 +622,13 @@ private void WriteMethodPrototype(CodeMethod code, CodeClass parentClass, Langua
conventions.GetParameterSignature(p, code))
.ToList());
CSharpConventionService.WriteNullableOpening(writer);
writer.WriteLine($"{conventions.GetAccessModifier(code.Access)} {staticModifier}{hideModifier}{completeReturnTypeWithNullable}{methodName}({nullableParameters}){baseSuffix} {{");
writer.WriteLine($"{conventions.GetAccessModifier(code.Access)} {staticModifier}{hideModifier}{completeReturnTypeWithNullable}{methodName}({nullableParameters}){baseSuffix}");
writer.WriteLine("{");
CSharpConventionService.WriteNullableMiddle(writer);
}

writer.WriteLine($"{conventions.GetAccessModifier(code.Access)} {staticModifier}{hideModifier}{completeReturnType}{methodName}({parameters}){baseSuffix} {{");
writer.WriteLine($"{conventions.GetAccessModifier(code.Access)} {staticModifier}{hideModifier}{completeReturnType}{methodName}({parameters}){baseSuffix}");
writer.WriteLine("{");

if (includeNullableReferenceType)
CSharpConventionService.WriteNullableClosing(writer);
Expand Down
8 changes: 4 additions & 4 deletions src/Kiota.Builder/Writers/CSharp/CodePropertyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ private void WritePropertyInternal(CodeProperty codeElement, LanguageWriter writ
switch (codeElement.Kind)
{
case CodePropertyKind.RequestBuilder:
writer.WriteLine($"{conventions.GetAccessModifier(codeElement.Access)} {propertyType} {codeElement.Name.ToFirstCharacterUpperCase()} {{ get =>");
writer.IncreaseIndent();
writer.WriteLine($"{conventions.GetAccessModifier(codeElement.Access)} {propertyType} {codeElement.Name.ToFirstCharacterUpperCase()}");
writer.StartBlock();
writer.Write("get => ");
conventions.AddRequestBuilderBody(parentClass, propertyType, writer);
writer.DecreaseIndent();
writer.WriteLine("}");
writer.CloseBlock();
break;
case CodePropertyKind.AdditionalData when backingStoreProperty != null:
case CodePropertyKind.Custom when backingStoreProperty != null:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ public void WritesModelFactoryBodyForUnionModels()
writer.Write(factoryMethod);
var result = tw.ToString();
Assert.Contains("var mappingValue = parseNode.GetChildNode(\"@odata.type\")?.GetStringValue()", result);
Assert.DoesNotContain("return mappingValue switch {", result);
Assert.DoesNotContain("return mappingValue switch", result);
Assert.Contains("var result = new UnionTypeWrapper()", result);
Assert.Contains("if(\"#kiota.complexType1\".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))", result);
Assert.Contains("ComplexType1Value = new ComplexType1()", result);
Expand Down Expand Up @@ -600,7 +600,7 @@ public void WritesModelFactoryBodyForIntersectionModels()
writer.Write(factoryMethod);
var result = tw.ToString();
Assert.DoesNotContain("var mappingValue = parseNode.GetChildNode(\"@odata.type\")?.GetStringValue()", result);
Assert.DoesNotContain("return mappingValue switch {", result);
Assert.DoesNotContain("return mappingValue switch", result);
Assert.Contains("var result = new IntersectionTypeWrapper()", result);
Assert.DoesNotContain("if(\"#kiota.complexType1\".Equals(mappingValue, StringComparison.OrdinalIgnoreCase))", result);
Assert.Contains("if(parseNode.GetStringValue() is string stringValueValue)", result);
Expand Down Expand Up @@ -710,7 +710,7 @@ public void WritesModelFactoryBodyAndDisambiguateAmbiguousImportedTypes()
var result = tw.ToString();

Assert.Contains("var mappingValue = parseNode.GetChildNode(\"@odata.type\")?.GetStringValue()", result);
Assert.Contains("return mappingValue switch {", result);
Assert.Contains("return mappingValue switch", result);
Assert.Contains("\"namespaceLevelOne.ConflictingModel\" => new namespaceLevelOne.ConflictingModel(),", result); //Assert the disambiguation happens due to the enum imported
Assert.Contains("_ => new ConflictingModelBaseClass()", result);
AssertExtensions.CurlyBracesAreClosed(result);
Expand Down Expand Up @@ -765,7 +765,7 @@ public void WritesModelFactoryBodyForInheritedModels()
writer.Write(factoryMethod);
var result = tw.ToString();
Assert.Contains("var mappingValue = parseNode.GetChildNode(\"@odata.type\")?.GetStringValue()", result);
Assert.Contains("return mappingValue switch {", result);
Assert.Contains("return mappingValue switch", result);
Assert.Contains("\"ns.childmodel\" => new ChildModel()", result);
Assert.Contains("_ => new ParentModel()", result);
AssertExtensions.CurlyBracesAreClosed(result);
Expand Down Expand Up @@ -859,7 +859,7 @@ public void DoesntWriteFactorySwitchOnEmptyPropertyName()
var result = tw.ToString();
Assert.DoesNotContain("var mappingValue = parseNode.GetChildNode(\"@odata.type\")?.GetStringValue()", result);
Assert.DoesNotContain("var mappingValue = mappingValueNode?.GetStringValue()", result);
Assert.DoesNotContain("return mappingValue switch {", result);
Assert.DoesNotContain("return mappingValue switch", result);
Assert.DoesNotContain("\"ns.childmodel\" => new ChildModel()", result);
Assert.Contains("return new ParentModel()", result);
AssertExtensions.CurlyBracesAreClosed(result);
Expand Down Expand Up @@ -900,7 +900,7 @@ public void DoesntWriteFactorySwitchOnEmptyMappings()
var result = tw.ToString();
Assert.DoesNotContain("var mappingValue = parseNode.GetChildNode(\"@odata.type\")?.GetStringValue()", result);
Assert.DoesNotContain("var mappingValue = mappingValueNode?.GetStringValue()", result);
Assert.DoesNotContain("return mappingValue switch {", result);
Assert.DoesNotContain("return mappingValue switch", result);
Assert.DoesNotContain("\"ns.childmodel\" => new ChildModel()", result);
Assert.Contains("return new ParentModel()", result);
AssertExtensions.CurlyBracesAreClosed(result);
Expand Down

0 comments on commit e7e5c9b

Please sign in to comment.